Ground Embedded KO Subscribe

Notes / Computer Architecture

Interrupts and exceptions: stopping what you are doing and coming back

When an event occurs, the CPU saves its state, jumps to a handler and returns. How that happens on Cortex-M.

GROUND EMBEDDED · NOTEComputer Architecture 08Interrupts and exceptionsMCU

Polling, where you keep checking whether a button was pressed, wastes the CPU and responds late. An interrupt is the hardware calling the CPU to say "something has happened".

What happens on Cortex-M

  1. The peripheral raises an interrupt signal
  2. The NVIC checks the priority and notifies the CPU
  3. The CPU automatically saves r0 to r3, r12, lr, pc and xPSR on the stack
  4. It looks up the handler address in the vector table and jumps there
  5. When the handler ends, the saved registers are restored and execution returns to where it was

Because register saving is done automatically in hardware, a Cortex-M interrupt function is written just like an ordinary C function.

Exceptions

An interrupt is one kind of exception. Reset, NMI, HardFault, SysTick and SVCall are all exceptions and have slots at the front of the vector table. A problem such as an access to a bad address or a division by zero enters the HardFault exception.

Rules for writing handlers

  • Short. Set a flag or put data in a buffer and finish.
  • Variables shared with main code are volatile, and multi-byte values are protected so they are read atomically.
  • If you do not clear the flag that caused the interrupt, the function is entered again the moment it ends.

What happens in one interrupt

IRQ signalMain codeHandlerrequestentryreturn
From the instant the button is pressed until the handler ends. The main code stops and resumes at exactly the same place.

On Cortex-M the following sequence is done automatically in hardware.

  1. The instruction in progress is completed.
  2. Eight registers (R0 to R3, R12, LR, PC, xPSR) are saved on the stack.
  3. The handler address is read from the vector table and execution jumps there.
  4. When the handler ends, the saved values are popped and the interrupted work continues.

Because the hardware saves the registers, a handler can be written as a plain C function. From request to the first handler instruction takes 12 cycles on a Cortex-M3/M4.

3D labRun what you have read so far→

Short handlers, work in main

volatile uint8_t  btn_flag;
volatile uint32_t btn_tick;

void EXTI0_IRQHandler(void) {
    EXTI->PR = EXTI_PR_PR0;      // 1) clear the flag first
    btn_tick = sys_tick;         // 2) just record the time
    btn_flag = 1;                // 3) just raise the flag
}

int main(void) {
    while (1) {
        if (btn_flag) { btn_flag = 0; handle_button(btn_tick); }
    }
}

Call printf or run a delay function inside a handler and every other interrupt of the same or lower priority is held up meanwhile.

Problems that come up in practice

Symptom Cause
The handler is called again endlessly The interrupt flag is not cleared
The main loop seems to have stopped The handler is too long or fires too often
A value is occasionally corrupted Main and the handler modify the same variable without protection
Fails only in release builds volatile missing on a shared variable
Never called at all The handler name differs from the name in the vector table (the weak symbol is called instead)

The last case is the one beginners spend longest on. If the name differs by even one character from the one in the startup file, the linker silently connects the default handler (an infinite loop).

Check yourself

  • In a control loop that needs constant interrupt latency, what goes wrong if main code keeps interrupts off for a long time?
  • If two interrupts of the same priority arrive at once, which is handled first?
3D LABInterrupts and Priority SimulationRun what this note explains and watch it respond.Open the lab →FREE PDFGet the 3 free ebooksIf you want to keep reading this topic as one book: BLDC motor control, serial communication and sensors at book length. PDFs are in Korean.Get them free →