Embedded & Bare-Metal

the NVIC (nested vectored interrupt controller)

/ EN-vick /

When dozens of things can demand a processor's attention at once — a timer, three serial ports, two buttons, a network packet — something has to act as the traffic officer: deciding which interrupt gets through, in what order, and whether an urgent one may cut ahead of a less urgent one already in progress. On ARM Cortex-M chips that traffic officer is a dedicated piece of hardware called the NVIC, the nested vectored interrupt controller.

Break the name down, because it describes exactly what it does. VECTORED means it works directly with the vector table: when an interrupt is accepted, the NVIC supplies the handler address so the CPU jumps straight to the right ISR with no software lookup. NESTED means it supports priorities and preemption: every interrupt source is assigned a priority number (lower number = higher priority on Cortex-M), and if a higher-priority interrupt fires while a lower-priority ISR is running, the NVIC can preempt the running handler, run the urgent one, and then resume the first — interrupts nested inside interrupts. The NVIC is configured through registers in the system region (around 0xE000E000): you enable a specific interrupt (set-enable register), set its priority, and can pend or clear it in software. On many Cortex-M parts the priority field is split into preemption bits and sub-priority bits, where preemption decides who can interrupt whom and sub-priority only breaks ties among equal-preemption interrupts that are pending at the same moment.

It matters because it lets you build a responsive system where critical events (a motor fault) always win over routine ones (a status LED), with the hardware doing the bookkeeping. The honest cautions: priority numbers are backwards from intuition (smaller is MORE urgent), the number of usable priority bits varies by chip (so a value of 0x10 may mean different things on different parts), and deep nesting uses more stack — each preemption stacks another frame. Also, the NVIC controls peripheral interrupts; the lowest few exceptions like reset and HardFault have fixed priorities the NVIC does not let you change.

// Configure a peripheral interrupt via the NVIC (CMSIS API): NVIC_SetPriority(USART2_IRQn, 2); // smaller number = higher priority NVIC_EnableIRQ(USART2_IRQn); // allow this interrupt to fire // If a priority-0 interrupt arrives while the priority-2 ISR runs, // the NVIC preempts it (nesting), then resumes the priority-2 ISR.

Set a priority and enable the interrupt; the NVIC then lets higher-priority (lower-numbered) interrupts preempt lower-priority ones.

On Cortex-M a SMALLER priority number means MORE urgent — the reverse of most people's intuition. And only the upper few bits of the priority field are implemented (chip-dependent), so the same numeric value can mean different effective priorities across parts.

Also called
nested vectored interrupt controllerinterrupt controller巢狀向量中斷控制器中斷控制器