5.5.7 · D2Embedded Systems & Real-Time Software

Visual walkthrough — Interrupts — ISR design, NVIC priority, interrupt latency

1,983 words9 min readBack to topic

This is the visual companion to the parent Interrupts note. If a word here feels new, it is defined the moment it appears.


Step 0 — the words we will use (earned before we draw)

We are going to lay these on a horizontal time arrow: left = the doorbell rings, right = your handler's first instruction runs. The length of that arrow is the latency.


Step 1 — the event fires, but the CPU is busy

WHAT. At some instant, a peripheral pulls its interrupt wire high. The CPU is mid-instruction — maybe halfway through a slow one.

WHY it matters. The CPU is not allowed to abandon most instructions halfway. It must reach a clean stopping point first. So the very first slice of our latency is waiting for the current instruction to finish.

PICTURE. The red bolt is the event. The blue block is the instruction still executing. The gap between them is our first cost, .

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

Step 2 — but were interrupts even allowed right now?

WHAT. Before anything hardware-y happens, we must ask: did the programmer mask (switch off) interrupts? Code often does this around a critical section — a few lines that must not be disturbed.

WHY. If interrupts are masked, the doorbell is ignored until they are switched back on. The event sits waiting. This is the single biggest thing you, the programmer, control.

PICTURE. The orange bar is the critical section where interrupts are off. The event (red bolt) lands inside it, so it waits until the bar ends.

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

Step 3 — the NVIC notices and decides

WHAT. Once interrupts are allowed, the NVIC (the traffic-controller peripheral) sees the pending request, compares its priority against whatever is running, and decides "yes, preempt."

WHY a separate step. Noticing is not instant. The NVIC needs a couple of clock ticks to synchronise the incoming signal and run its comparison. Tiny, but real.

PICTURE. The gray gear is the NVIC's decision. Notice how small this slice is compared to the ones you control.

Figure — Interrupts — ISR design, NVIC priority, interrupt latency
Recall Why compare priorities at all?

If two doorbells ring at once, someone must lose. The NVIC uses priority (lower number = more urgent) to pick a winner and to decide whether a new IRQ can barge in on a running one. Full mechanics live in the parent note and ARM Cortex-M Architecture.


Step 4 — stacking: the CPU saves your place for free

WHAT. Before jumping to the ISR, hardware automatically pushes 8 registers onto the stack: .

WHY. The ISR is about to scribble over the CPU's scratch registers. To resume the interrupted code perfectly afterward, the CPU snapshots the "caller-saved" registers first. Because hardware does this, your ISR can be a plain C function — no assembly needed.

PICTURE. Eight boxes slide onto the stack, one per register. Each box is one memory write (~one cycle plus a little).

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

Step 5 — vector fetch: where do I jump?

WHAT. The CPU reads the ISR's address out of the vector table (a plain array of handler addresses) and loads it into the program counter .

WHY. The CPU has no idea where your handler lives in memory. The vector table is the lookup: interrupt number → address. Fetching that address costs a few cycles.

PICTURE. An arrow from slot "IRQ #k" in the table into the register. The instant holds the address, latency is over.

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

Step 6 — assemble the full formula

WHAT. Add every slice we drew, left to right, into one number.

WHY. Latency is a sum of independent delays. Nothing overlaps in our model — each stage must finish before the next begins — so we just add them.

PICTURE. The complete timeline, colour-matched to the earlier steps, stacked end to end.

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

Step 7 — plug in numbers (the worked case)

WHAT. Compute a concrete worst case.

WHY. A formula you can't put numbers into is useless for real-time design. We need an actual nanosecond count to check against a deadline (see Real-Time Scheduling & Deadlines).

Given: clock , so . Hardware part cycles. Your longest critical section masks interrupts for cycles.

  • ::: the fixed hardware cost (detect + finish + stack + vector, lumped).
  • ::: worst-case masking, if the event fires one cycle after you disabled interrupts.
  • ::: convert cycles → time at .

PICTURE. The 12-cycle hardware block dwarfed by the 50-cycle blocking block — a visual argument for keeping critical sections short.

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

Step 8 — the degenerate & edge cases (never skip these)

WHAT. What happens at the extremes?

WHY. Real systems live in the corners. If you only understand the average case, a rare event breaks your deadline.


The one-picture summary

Figure — Interrupts — ISR design, NVIC priority, interrupt latency

The whole derivation compressed: the event fires, waits out any masking and the current instruction, the NVIC decides, hardware stacks 8 registers and fetches the vector — and then, and only then, your handler's first instruction runs. Add the slices, convert cycles to nanoseconds, done.

Recall Feynman retelling — explain it to a friend in plain words

Picture a worker (the CPU) doing chores off a list. A bell rings (an event). First, if the worker had told everyone "don't ring me for a minute" (masked interrupts), the bell just waits — that wait is the biggest chunk and it's the worker's own fault, so keep those "quiet minutes" short. Next, the worker has to finish the one chore already in hand (can't drop a half-done division). Then a manager (the NVIC) takes a couple of seconds to confirm "yes, go answer it, it's important enough." Before leaving, the worker jots down exactly what they were doing on a sticky-note pad (stacks 8 registers) so they can come back perfectly. Then they look up which door to answer (vector fetch). Only now do they start the new task — and that start is where latency ends. Add up all the little waits, and if the clock is million ticks per second, each tick is . Twelve ticks of unavoidable hardware plus however long your "quiet minute" lasted — that's your number.

Recall Quick self-test

A CPU, -cycle hardware part, worst critical section cycles. Worst-case latency? ::: ; .