Interrupts and NVIC

Nested Vectored Interrupt Controller concepts.

Darshan N
Updated: 19 March 2026
9 min read

The Nested Vectored Interrupt Controller (NVIC) is the core mechanism in ARM Cortex-M processors that manages all exceptions and interrupts. It determines which interrupt is served, in what order, and how the processor transitions between normal execution and interrupt service routines. Understanding NVIC is essential for building responsive and deterministic embedded systems.

Cortex-M NVIC Architecture OverviewInterrupt SourcesIRQ0 (e.g. EXTI0)IRQ1 (e.g. TIM2)IRQ2 (e.g. USART1)IRQ3 (e.g. SPI1)... up to IRQ239Fixed ExceptionsNMI (priority -2)HardFault (priority -1)SysTick (configurable)NVIC CorePriority ComparatorEnable / Disable LogicPending Status TrackingActive Status TrackingVector Fetch InterfaceNVIC RegistersISER (Enable Set)ICER (Enable Clear)ISPR (Pend Set)ICPR (Pend Clear)IABR (Active Status)IPR (Priority)STIR (Software Trigger)NVIC supports up to 240 external IRQs + system exceptions. All configurable via memory-mapped registers at 0xE000E100.Accessed using CMSIS functions: NVIC_EnableIRQ(), NVIC_SetPriority(), NVIC_GetPriority()
Figure 1: NVIC sits between interrupt sources and the processor core, managing priority, enabling, pending, and active states.

Core Concept Explanation

The NVIC is a hardware block tightly integrated with the Cortex-M core. It supports up to 240 external interrupt requests (IRQs) in addition to system exceptions like HardFault, NMI, SysTick, SVC, and PendSV. Each interrupt has a unique exception number starting from 16 for IRQ0. System exceptions have fixed or configurable negative priority numbers (NMI = -2, HardFault = -1), which means they always take precedence over application interrupts.

The NVIC maintains four states for each interrupt: inactive (not triggered), pending (triggered but not yet served), active (currently being executed by the processor), and active-pending (currently active but another occurrence has arrived). The state machine transitions between these based on peripheral trigger signals, NVIC enable flags, and processor acknowledgment.

The NVIC is accessed through memory-mapped registers in the System Control Space at addresses starting at 0xE000E100. The ARM CMSIS (Cortex Microcontroller Software Interface Standard) library provides portable C functions such as NVIC_EnableIRQ(), NVIC_DisableIRQ(), NVIC_SetPriority(), and NVIC_GetPendingIRQ() that map to these registers, making code portable across Cortex-M devices.

Mathematical Expression

The NVIC uses priority registers (IPRx) where each byte corresponds to one interrupt. However, not all 8 bits of each byte are implemented. If N priority bits are implemented (typically 4 bits on STM32), then the priority value is stored in the upper N bits of the byte. The lower (8-N) bits are always read as zero.

Effective priority value = (configured value) shifted left by (8 - N) bits. For a 4-bit implementation, writing priority value 5 (binary 0101) into IPR is stored as 0101_0000 = 0x50. The actual comparison between priorities uses this shifted value. Two interrupts can be preemptively nested only if the preempting interrupt has a strictly lower numerical priority value in the preemption priority field.

Practical Understanding

To use an interrupt in practice, four steps are required: enable the peripheral interrupt at the peripheral level (for example, set UIE bit in TIM2_DIER for a timer), configure priority in NVIC IPR, enable the interrupt in NVIC ISER, and enable global interrupts (CPSIE I instruction, or equivalently __enable_irq() in CMSIS). If any of these steps is missed, the interrupt will not fire even if the peripheral generates a trigger.

The ISER (Interrupt Set-Enable Register) and ICER (Interrupt Clear-Enable Register) are separate write-only registers used to set and clear enable bits atomically. Writing 1 to a bit in ISER enables the corresponding IRQ. Writing 1 to ICER disables it. Writing 0 has no effect in either register. This design avoids the need for read-modify-write operations when enabling or disabling individual IRQs.

The ISPR (Interrupt Set-Pending Register) can be used to manually trigger an interrupt in software by setting its pending bit. This is useful for deferred processing, testing ISR code without hardware, and communicating between ISRs at different priority levels.

Example
Given:
STM32F4, configure TIM2 interrupt (IRQ28) at priority 2 (on 4-bit priority system).
CMSIS functions used.

Why this formula applies:
NVIC requires enabling both at peripheral and controller level.
Priority bits = 4 (STM32F4 implements upper 4 bits of IPR byte).

Formula:
IPR byte value = priority_value << (8 - NVIC_PRIO_BITS)

Substitution:
IPR byte = 2 << (8 - 4) = 2 << 4 = 32 = 0x20

Calculation (CMSIS code):
Step 1: TIM2->DIER |= TIM_DIER_UIE;         // enable TIM2 update interrupt at peripheral
Step 2: NVIC_SetPriority(TIM2_IRQn, 2);      // set priority = 2, stored as 0x20 in IPR
Step 3: NVIC_EnableIRQ(TIM2_IRQn);           // write 1 to ISER bit 28
Step 4: __enable_irq();                       // CPSIE I - enable global interrupts

Final Answer:
TIM2 update interrupt (IRQ28) is active at priority level 2 (0x20 in IPR register).
Exam Tip: Remember that NMI and HardFault have fixed negative priorities (-2 and -1 respectively) and CANNOT be disabled by software. They will always preempt any application IRQ. Also, NVIC_EnableIRQ alone is not enough. The peripheral must also have its interrupt output enabled separately.
NVIC Interrupt State Machine and Nested Interrupt ExecutionInterrupt State MachineInactivePendingtriggerActiveActive+PendingCPU acceptsISR endsISR endsnew triggerNested Interrupt ExecutionMain Thread (priority 256)ISR_A (priority 4) startsISR_B (priority 2) preemptsISR_B completesISR_A resumes and completesMain Thread resumespriority256 (lowest)priority 2priority 4NVIC 4-Step Checklist for Any Interrupt1. Peripheral interrupt enable(e.g. TIM2 UIE bit)2. NVIC_SetPriority()Set IPR value3. NVIC_EnableIRQ()Write 1 to ISER4. __enable_irq()Global enable (CPSIE I)
Figure 2: NVIC interrupt state machine and nested preemption timeline showing ISR_B preempting ISR_A due to higher priority.

NVIC Key Mechanisms

  • ISER and ICER provide atomic set and clear for interrupt enables. Writing 1 to ISER enables; writing 1 to ICER disables. Writing 0 has no effect in either register, ensuring no accidental modification of other bits.
  • ISPR allows software to manually pend an interrupt. This is used for deferred processing (pend a lower-priority interrupt from within a high-priority ISR) or for software-triggered interrupt testing.
  • IPR registers hold priority bytes. The actual usable bits are the upper N bits. STM32 typically uses 4 bits, giving 16 priority levels (0 to 15 where 0 is highest priority).
  • IABR (Interrupt Active Bit Register) shows which interrupts are currently active. Reading IABR is useful for debugging unexpected nested execution or priority inversion scenarios.
  • Global interrupt enable and disable uses the PRIMASK register (1 = all interrupts disabled except NMI and HardFault). The BASEPRI register masks all interrupts at or below a set priority level, which is more precise than PRIMASK.

Quick Revision

  • NVIC supports up to 240 external IRQs. System exceptions (NMI, HardFault, SysTick) are separate with fixed or configurable priorities.
  • Four steps to enable any interrupt: peripheral enable, NVIC_SetPriority(), NVIC_EnableIRQ(), __enable_irq().
  • IPR byte stores priority in upper N bits. For 4-bit priority, writing value 2 results in 0x20 in IPR.
  • ISER sets enable (write 1 to enable, write 0 has no effect). ICER clears enable (write 1 to disable, write 0 has no effect).
  • NMI priority = -2, HardFault priority = -1. These cannot be disabled and always preempt application IRQs.
  • PRIMASK disables all maskable interrupts. BASEPRI masks interrupts at or below a configured priority level.
  • Trap: Enabling IRQ in NVIC but forgetting peripheral-level interrupt enable is the most common mistake. Both must be set.

NVIC Interrupt Practice

Test your knowledge on this topic!

Question 1 of 3

Q1.Which statement accurately describes a core feature of the Nested Vectored Interrupt Controller (NVIC)?