Bird
Raised Fist0
Embedded Cprogramming~10 mins

Interrupt vector table in Embedded C - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Interrupt vector table
CPU Reset
↓
Fetch Interrupt Vector
↓
Jump to ISR Address
↓
Execute ISR
↓
Return to Main Program
When an interrupt occurs, the CPU looks up the interrupt vector table to find the address of the correct Interrupt Service Routine (ISR) and jumps there to handle the interrupt.
Execution Sample
Embedded C
void ISR_Timer(void) {
    // Timer interrupt code
}

void (* const interrupt_vector_table[])(void) = {
    ISR_Timer
};
Defines an interrupt vector table with one entry pointing to the Timer ISR function.
Execution Table
StepEventActionVector Table LookupISR CalledResult
1CPU ResetFetch reset vectorAddress of Reset ISRReset ISRStart main program
2Timer InterruptFetch timer vectorAddress of ISR_TimerISR_TimerExecute timer ISR code
3ISR_Timer completesReturn from ISRN/AMain program resumesContinue normal execution
4No more interruptsIdleN/AN/AProgram runs main loop
💡 No interrupts pending, CPU runs main program continuously
Variable Tracker
VariableStartAfter InterruptAfter ISRFinal
Program Counter (PC)Reset vector addressISR_Timer addressReturn address after ISRMain program address
Interrupt Flag0 (no interrupt)1 (interrupt triggered)0 (interrupt handled)0 (idle)
Key Moments - 3 Insights
Why does the CPU jump to a specific address when an interrupt occurs?
Because the CPU uses the interrupt vector table to find the address of the ISR to handle that interrupt, as shown in execution_table step 2.
What happens to the program counter during an interrupt?
The program counter saves the current address and loads the ISR address from the vector table, as tracked in variable_tracker under Program Counter.
How does the CPU know when to return to the main program?
After the ISR finishes, the CPU uses the saved return address to resume the main program, shown in execution_table step 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what ISR is called at step 2?
AReset ISR
BMain program
CISR_Timer
DNo ISR
💡 Hint
Check the 'ISR Called' column at step 2 in execution_table
According to variable_tracker, what happens to the Interrupt Flag after the ISR completes?
AIt stays 1
BIt resets to 0
CIt becomes 2
DIt is undefined
💡 Hint
Look at the Interrupt Flag values after ISR in variable_tracker
If a new interrupt occurs, how would the execution_table change?
AA new step with fetching vector and calling ISR would be added
BThe CPU would ignore the interrupt
CThe program counter would not change
DThe main program would stop permanently
💡 Hint
Refer to the flow in execution_table steps 2 and 3 for interrupt handling
Concept Snapshot
Interrupt vector table holds addresses of ISRs.
CPU uses it to jump to correct ISR on interrupt.
Program counter changes to ISR address.
After ISR, CPU returns to main program.
Each interrupt type has a vector entry.
Full Transcript
An interrupt vector table is a list of addresses where the CPU can find the code to handle different interrupts. When the CPU resets, it starts at the reset vector. When an interrupt happens, the CPU looks up the vector table to find the ISR address and jumps there. The program counter changes to this ISR address. After the ISR runs, the CPU returns to where it left off in the main program. The interrupt flag signals when an interrupt is active and resets after handling. This process ensures the CPU responds quickly and correctly to hardware events.

Practice

(1/5)
1.

What is the main purpose of an interrupt vector table in embedded C programming?

easy
A. To store global variables for the program
B. To link interrupt events to their handler functions
C. To manage memory allocation dynamically
D. To perform arithmetic operations automatically

Solution

  1. Step 1: Understand the role of interrupt vector table

    The interrupt vector table is a special array that holds addresses of interrupt handler functions.
  2. Step 2: Identify its purpose in program flow

    When an interrupt occurs, the processor uses this table to jump to the correct handler automatically.
  3. Final Answer:

    To link interrupt events to their handler functions -> Option B
  4. Quick Check:

    Interrupt vector table = links interrupts to handlers [OK]
Hint: Interrupt vector table connects interrupts to handlers [OK]
Common Mistakes:
  • Thinking it stores variables
  • Confusing with memory management
  • Assuming it performs calculations
2.

Which of the following is the correct way to declare an interrupt vector table as an array of function pointers in embedded C?

void (*interrupt_vector_table[])(void) = {
easy
A. void interrupt_vector_table(void) = {handler1, handler2};
B. int interrupt_vector_table[] = {handler1, handler2};
C. void (*interrupt_vector_table[])(void) = {handler1, handler2};
D. void *interrupt_vector_table = {handler1, handler2};

Solution

  1. Step 1: Recognize function pointer array syntax

    Function pointers to void functions with no parameters are declared as void (*name[])(void).
  2. Step 2: Match declaration with initialization

    void (*interrupt_vector_table[])(void) = {handler1, handler2}; correctly declares an array of such pointers and initializes it with handler functions.
  3. Final Answer:

    void (*interrupt_vector_table[])(void) = {handler1, handler2}; -> Option C
  4. Quick Check:

    Function pointer array syntax = void (*interrupt_vector_table[])(void) = {handler1, handler2}; [OK]
Hint: Function pointer arrays use void (*name[])(void) syntax [OK]
Common Mistakes:
  • Using int type instead of function pointers
  • Declaring as a single function, not array
  • Using void* without function pointer cast
3.

Given the following code snippet, what will be the output when the interrupt at index 1 occurs?

void handler0(void) { printf("Handler 0 called\n"); }
void handler1(void) { printf("Handler 1 called\n"); }
void (*interrupt_vector_table[])(void) = {handler0, handler1};

// Simulate interrupt 1
interrupt_vector_table[1]();
medium
A. Handler 1 called
B. Handler 0 called
C. No output, runtime error
D. Compilation error

Solution

  1. Step 1: Identify the function called by interrupt_vector_table[1]

    Index 1 points to handler1, which prints "Handler 1 called".
  2. Step 2: Understand the output of the function call

    Calling interrupt_vector_table[1]() executes handler1, printing the message.
  3. Final Answer:

    Handler 1 called -> Option A
  4. Quick Check:

    interrupt_vector_table[1]() calls handler1 [OK]
Hint: Index 1 calls handler1, prints its message [OK]
Common Mistakes:
  • Confusing index 0 and 1
  • Expecting no output or error
  • Misreading function pointer call syntax
4.

Consider this interrupt vector table declaration:

void handlerA(void) { /* ... */ }
void handlerB(void) { /* ... */ }

void (*interrupt_vector_table[])(void) = {handlerA, handlerB};

// Somewhere else in code
interrupt_vector_table[2]();

What is the problem here?

medium
A. Index 2 is out of bounds, causing undefined behavior
B. handlerB is not a valid function pointer
C. interrupt_vector_table must be declared as int array
D. No problem, code runs fine

Solution

  1. Step 1: Check the size of interrupt_vector_table

    The array has 2 elements at indices 0 and 1 only.
  2. Step 2: Analyze the call to interrupt_vector_table[2]()

    Index 2 is outside the array bounds, leading to undefined behavior or crash.
  3. Final Answer:

    Index 2 is out of bounds, causing undefined behavior -> Option A
  4. Quick Check:

    Accessing beyond array size = out of bounds error [OK]
Hint: Array indices start at 0; index 2 is invalid here [OK]
Common Mistakes:
  • Assuming array auto-expands
  • Thinking handlerB is invalid
  • Ignoring out-of-bounds errors
5.

You want to add a new interrupt handler handler2 to an existing vector table with 2 handlers. Which is the correct way to update the vector table to include handler2 at index 2?

void handler0(void) { /* ... */ }
void handler1(void) { /* ... */ }
void handler2(void) { /* ... */ }

// Existing vector table
void (*interrupt_vector_table[])(void) = {handler0, handler1};

// How to add handler2 correctly?
hard
A. No need to add; interrupts beyond index 1 are ignored
B. Assign handler2 directly: interrupt_vector_table[2] = handler2;
C. Use a pointer cast to add handler2 at index 2
D. Redefine the vector table with all three handlers: {handler0, handler1, handler2}

Solution

  1. Step 1: Understand array size fixed at declaration

    Arrays in C have fixed size; you cannot add elements dynamically.
  2. Step 2: Update vector table by redefining with all handlers

    To include handler2, redefine the array with three elements: {handler0, handler1, handler2}.
  3. Final Answer:

    Redefine the vector table with all three handlers: {handler0, handler1, handler2} -> Option D
  4. Quick Check:

    Arrays fixed size; redefine to add elements [OK]
Hint: Arrays fixed size; redefine to add handlers [OK]
Common Mistakes:
  • Trying to assign beyond array size
  • Using pointer casts unsafely
  • Assuming interrupts beyond defined handlers work
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