Interrupt Priority
Preemption priority vs sub-priority.
Interrupt priority in ARM Cortex-M is not a single number but a two-level hierarchical system called preemption priority and sub-priority. This distinction determines both which interrupts can nest inside each other and how ties are broken when multiple interrupts of the same preemption level are pending simultaneously. Getting priority configuration wrong leads to unexpected ISR behavior and is a frequently tested topic in GATE and university exams.
Core Concept Explanation
Each interrupt in Cortex-M has an 8-bit priority register (IPR). However, most Cortex-M devices implement only the upper 4 bits of this byte (N = 4), giving 16 priority levels (0 to 15). These 4 implemented bits are further split into two fields controlled by the PRIGROUP field in the SCB_AIRCR register: preemption priority and sub-priority.
The preemption priority determines whether one ISR can interrupt another currently executing ISR. If ISR_A is running at preemption priority 4 and ISR_B arrives with preemption priority 2, ISR_B will preempt ISR_A because 2 < 4 (lower number = higher priority). This is called nesting or preemption.
The sub-priority only applies when two or more pending interrupts have the same preemption priority and none of them is currently active. In that case, the one with the lower sub-priority number is served first. Sub-priority has absolutely no effect on preemption. Two ISRs with the same preemption priority cannot preempt each other, no matter how different their sub-priorities are.
Mathematical Expression
With N implemented priority bits and PRIGROUP = P, the split is:
Preemption bits = N - (P - 3), clamped to [0, N]. Sub-priority bits = N - Preemption bits. For example, if N = 4 and PRIGROUP = 5: Preemption bits = 4 - (5 - 3) = 4 - 2 = 2. Sub-priority bits = 4 - 2 = 2. This gives 4 preemption levels and 4 sub-priority levels.
The CMSIS function NVIC_SetPriority takes a single value representing the combined preemption+sub-priority. The function NVIC_EncodePriority(PRIGROUP, preemptPriority, subPriority) computes the correct 8-bit value to write to IPR based on the current PRIGROUP setting, making the encoding transparent to the programmer.
Practical Understanding
In most STM32 HAL-based projects, the default PRIGROUP setting is group 4, which means all 4 implemented bits are preemption priority and there are no sub-priority bits. This simplifies priority management because NVIC_SetPriority values directly map to preemption levels without any sub-priority encoding. This is also the configuration recommended by ST for most applications.
A practical priority assignment example: assign SysTick the lowest preemption priority (15), assign UART receive at priority 3 for time-sensitive data, assign a button press EXTI at priority 6, and assign a background task PendSV at priority 14. Since all are different preemption priorities, each can preempt those with higher numerical values, giving full deterministic nesting behavior.
The FreeRTOS priority rule is important for GATE aspirants studying RTOS-based embedded systems. FreeRTOS uses only priorities numerically above configMAX_SYSCALL_INTERRUPT_PRIORITY for ISRs that call FreeRTOS API functions (FromISR variants). ISRs with priority values lower than this threshold (higher preemption priority) cannot call any FreeRTOS API and may only signal tasks via task notifications or direct ISR-safe mechanisms.
Given:
Cortex-M3, 4 implemented priority bits, PRIGROUP = 5.
Two ISRs: IRQ_A at preemption=2, sub=1 and IRQ_B at preemption=2, sub=0.
IRQ_C at preemption=1, sub=3.
Why this formula applies:
PRIGROUP=5 with N=4: preempt bits = 4-(5-3) = 2, sub bits = 2.
So 4 preemption levels and 4 sub-priority levels.
Formula:
Priority byte = (preempt << sub_bits) | sub
Substitution:
IRQ_A priority byte = (2 << 2) | 1 = 8 | 1 = 9 = 0x09
IRQ_B priority byte = (2 << 2) | 0 = 8 | 0 = 8 = 0x08
IRQ_C priority byte = (1 << 2) | 3 = 4 | 3 = 7 = 0x07
Calculation:
IRQ_C (preempt=1) CAN preempt IRQ_A (preempt=2): 1 < 2 -> YES
IRQ_C (preempt=1) CAN preempt IRQ_B (preempt=2): 1 < 2 -> YES
IRQ_B (preempt=2) CANNOT preempt IRQ_A (preempt=2): same preempt level
If IRQ_A and IRQ_B both pending: IRQ_B served first because sub=0 < sub=1.
Final Answer:
IRQ_C nests over both IRQ_A and IRQ_B. Between IRQ_A and IRQ_B, IRQ_B is served first (lower sub-priority).Exam Tip: The most tested trap is confusing preemption priority with sub-priority. Sub-priority NEVER causes preemption. Two ISRs with the same preemption priority value cannot interrupt each other. Also, lower numerical value always means higher priority in Cortex-M, opposite to some other architectures.
Priority Interaction Rules
- Preemption priority controls nesting. A lower numerical preemption priority value can interrupt a higher numerical value ISR while it is executing. This is the only way nesting occurs in Cortex-M.
- Sub-priority has no effect on nesting. It only determines which pending interrupt at the same preemption priority level is served first when the processor returns to Thread Mode and picks the next pending exception.
- PRIGROUP is set globally in SCB_AIRCR and applies to all configurable exceptions. It is set once at startup and should not be changed during runtime in a production system.
- CMSIS function NVIC_EncodePriority(PRIGROUP, preemptPri, subPri) computes the correct IPR byte value to write. NVIC_DecodePriority() does the reverse. Use these instead of manually shifting bits to avoid encoding mistakes.
- FreeRTOS and RTOS systems typically set PRIGROUP such that all configured interrupt priorities are in the preemption field only (no sub-priority bits), simplifying RTOS-aware interrupt management and satisfying configMAX_SYSCALL_INTERRUPT_PRIORITY constraints.
Quick Revision
- Preemption priority = determines nesting. Lower number = higher priority = can interrupt active ISRs with higher number.
- Sub-priority = tie-breaking only. Does NOT cause preemption. Only relevant when two pending IRQs share the same preemption priority.
- PRIGROUP field in SCB_AIRCR splits the 4 implemented bits between preemption and sub-priority fields.
- Formula: preemption bits = N - (PRIGROUP - 3). Sub-priority bits = N - preemption bits. (N = implemented bits, typically 4.)
- Default STM32 HAL configuration: PRIGROUP = 4 (all 4 bits = preemption, 0 sub-priority bits, 16 preemption levels).
- IPR byte value = (preemptPriority << sub_bits) | subPriority. Upper N bits only are used.
- Trap: Do not assume sub-priority causes preemption. This is the single most common mistake in interrupt priority exam questions.
Interrupt Priority Practice
Test your knowledge on this topic!
Q1.In the NVIC priority scheme, how does preemption priority operate?
Related Articles
Priority Inversion
Problem and inheritance protocol solution.
12 min read
GPIO Programming
Pin configuration, input/output modes, pull-up/down.
7 min read
Interrupts
Hardware vs Software, IVT structure, INT n instruction.
6 min read
BIOS Interrupts
INT 10h video services, INT 16h keyboard.
10 min read
Priority Encoder
Multiple inputs, highest priority output, valid bit.
11 min read