Bird
Raised Fist0
Embedded Cprogramming~10 mins

Writing an ISR (Interrupt Service Routine) in Embedded C - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Writing an ISR (Interrupt Service Routine)
Interrupt Occurs
↓
CPU Pauses Main Code
↓
Jump to ISR Function
↓
Execute ISR Code
↓
Clear Interrupt Flag
↓
Return from ISR
↓
Resume Main Code Execution
When an interrupt happens, the CPU stops the main program, runs the ISR code to handle the event, then returns to the main program.
Execution Sample
Embedded C
void ISR_Timer(void) {
    timer_flag = 1;  // Set flag to signal timer event
    clear_timer_interrupt();  // Clear interrupt flag
}
This ISR sets a flag when a timer interrupt occurs and clears the interrupt flag to allow future interrupts.
Execution Table
StepEventActionVariable ChangeNext Step
1Timer Interrupt OccursCPU pauses main codeNo changeJump to ISR_Timer
2Enter ISR_TimerSet timer_flag = 1timer_flag: 0 -> 1Clear interrupt flag
3Inside ISR_TimerCall clear_timer_interrupt()Interrupt flag clearedReturn from ISR
4Return from ISRCPU resumes main codeNo changeMain code continues
5Main codeCheck timer_flagtimer_flag = 1Handle timer event
💡 ISR finishes and returns, main program resumes with updated timer_flag
Variable Tracker
VariableStartAfter Step 2After Step 3Final
timer_flag0111
interrupt_flagsetsetclearedcleared
Key Moments - 3 Insights
Why must the interrupt flag be cleared inside the ISR?
If the interrupt flag is not cleared (see Step 3 in execution_table), the CPU will think the interrupt is still active and may immediately re-enter the ISR, causing an infinite loop.
Does the main program continue running while the ISR executes?
No, as shown in Step 1 and Step 4, the CPU pauses the main program to run the ISR, then resumes it after the ISR finishes.
Why do we set a flag variable inside the ISR instead of doing all work there?
The ISR should be short and fast (Step 2). Setting a flag lets the main program handle the detailed work later, avoiding long ISR execution.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of timer_flag after Step 2?
A1
B0
CUndefined
D2
💡 Hint
Check the 'Variable Change' column in Step 2 where timer_flag changes from 0 to 1.
At which step does the CPU resume the main program?
AStep 2
BStep 4
CStep 3
DStep 1
💡 Hint
Look at the 'Next Step' column and 'Action' in Step 4 indicating return from ISR and resume main code.
If the interrupt flag is not cleared in Step 3, what happens?
AISR will not run again
BMain program runs faster
CISR may run repeatedly causing a loop
Dtimer_flag resets to 0
💡 Hint
Refer to key_moments explanation about clearing interrupt flag to avoid repeated ISR calls.
Concept Snapshot
ISR (Interrupt Service Routine) runs when an interrupt occurs.
CPU pauses main code, jumps to ISR function.
ISR must clear interrupt flag to avoid repeated calls.
Keep ISR short; use flags to signal main code.
After ISR, CPU resumes main program.
Full Transcript
When an interrupt happens, the CPU stops the main program and jumps to the ISR function. The ISR runs code to handle the interrupt, such as setting a flag and clearing the interrupt flag. Clearing the interrupt flag is important to prevent the ISR from running repeatedly. After the ISR finishes, the CPU returns to the main program, which can check the flag and respond accordingly. This process ensures quick response to events without long delays in the ISR.

Practice

(1/5)
1. What is the main purpose of an ISR (Interrupt Service Routine) in embedded C?
easy
A. To allocate memory dynamically
B. To handle hardware events immediately when they occur
C. To run the main program loop continuously
D. To compile the program code

Solution

  1. Step 1: Understand ISR role

    An ISR is a special function that runs automatically when a hardware event happens, like a button press or timer overflow.
  2. Step 2: Compare options

    Only To handle hardware events immediately when they occur describes this immediate handling of hardware events. Other options describe unrelated tasks.
  3. Final Answer:

    To handle hardware events immediately when they occur -> Option B
  4. Quick Check:

    ISR = handle hardware events [OK]
Hint: ISRs respond instantly to hardware signals [OK]
Common Mistakes:
  • Thinking ISR runs like normal functions
  • Confusing ISR with main program loop
  • Assuming ISR manages memory
2. Which of the following is the correct way to declare an ISR function in embedded C?
easy
A. void ISR_Handler() __interrupt { /* code */ }
B. void ISR_Handler() interrupt { /* code */ }
C. void ISR_Handler() __interrupt(0) { /* code */ }
D. void ISR_Handler() __isr { /* code */ }

Solution

  1. Step 1: Recall ISR syntax in embedded C

    ISRs are declared with the __interrupt keyword followed by the interrupt vector number in parentheses.
  2. Step 2: Check options

    void ISR_Handler() __interrupt(0) { /* code */ } uses __interrupt(0), which is the correct syntax. The others either miss the vector number, use the wrong keyword ('interrupt'), or a non-standard keyword ('__isr').
  3. Final Answer:

    void ISR_Handler() __interrupt(0) { /* code */ } -> Option C
  4. Quick Check:

    ISR syntax = __interrupt(vector) [OK]
Hint: Use __interrupt(vector_number) to declare ISR [OK]
Common Mistakes:
  • Omitting interrupt vector number
  • Using 'interrupt' instead of '__interrupt'
  • Using non-standard keywords
3. Given the following ISR code snippet, what will be the value of flag after the interrupt occurs?
volatile int flag = 0;
void ISR_Timer() __interrupt(1) {
    flag = 1;
    // Interrupt flag cleared here
}

int main() {
    flag = 0;
    // Interrupt occurs here
    // ISR_Timer runs
    return flag;
}
medium
A. 1
B. 0
C. Undefined behavior
D. Compilation error

Solution

  1. Step 1: Understand ISR effect on flag

    The ISR sets the variable 'flag' to 1 when the interrupt occurs.
  2. Step 2: Check main function return

    Main sets flag to 0, then interrupt triggers ISR which sets flag to 1, so return value is 1.
  3. Final Answer:

    1 -> Option A
  4. Quick Check:

    ISR sets flag = 1, so return = 1 [OK]
Hint: ISR changes flag to 1 before main returns [OK]
Common Mistakes:
  • Ignoring ISR effect on flag
  • Assuming flag stays 0
  • Confusing volatile usage
4. Identify the error in this ISR code snippet:
void ISR_UART() __interrupt(4) {
    if (UART_Interrupt_Flag) {
        // Handle UART interrupt
        UART_Interrupt_Flag = 0;
    }
}
medium
A. ISR should not clear interrupt flags inside it
B. ISR function must return an int value
C. ISR must be declared with 'interrupt' keyword, not '__interrupt'
D. Missing volatile keyword for UART_Interrupt_Flag variable

Solution

  1. Step 1: Check variable usage in ISR

    Interrupt flags accessed in ISR should be declared volatile to prevent compiler optimization issues.
  2. Step 2: Analyze other options

    Clearing flags inside ISR is correct practice; __interrupt is correct keyword; ISR functions return void, not int.
  3. Final Answer:

    Missing volatile keyword for UART_Interrupt_Flag variable -> Option D
  4. Quick Check:

    Interrupt flags must be volatile [OK]
Hint: Declare interrupt flags volatile to avoid optimization bugs [OK]
Common Mistakes:
  • Not declaring flags volatile
  • Wrong ISR declaration keyword
  • Expecting ISR to return a value
5. You want to write an ISR for a timer interrupt that increments a counter and clears the interrupt flag. Which of the following is the best practice to ensure correct ISR behavior?
hard
A. Increment counter, then clear interrupt flag inside ISR
B. Clear interrupt flag, then increment counter inside ISR
C. Increment counter outside ISR and clear flag inside ISR
D. Do not clear interrupt flag; let main program clear it

Solution

  1. Step 1: Understand ISR order for flag and counter

    Best practice is to handle the event (increment counter) first, then clear the interrupt flag to acknowledge the interrupt.
  2. Step 2: Evaluate options

    Increment counter, then clear interrupt flag inside ISR follows this order. Clear interrupt flag, then increment counter inside ISR clears flag before handling event, which may cause missed interrupts. Increment counter outside ISR and clear flag inside ISR splits logic incorrectly. Do not clear interrupt flag; let main program clear it risks repeated interrupts.
  3. Final Answer:

    Increment counter, then clear interrupt flag inside ISR -> Option A
  4. Quick Check:

    Handle event first, then clear flag [OK]
Hint: Process event before clearing interrupt flag [OK]
Common Mistakes:
  • Clearing flag before handling event
  • Leaving flag uncleared causing repeated interrupts
  • Handling event outside ISR
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard