Explain preemption priority vs sub-priority on the NVIC. How does PRIGROUP configure them?
The Cortex-M NVIC assigns each interrupt a priority value stored in the upper bits of an 8-bit priority register (most STM32 implementations use only 4 bits, giving 16 priority levels, where 0 is the highest priority). The PRIGROUP field in the Application Interrupt and Reset Control Register (AIRCR) splits these priority bits into two fields: preemption priority (also called group priority) and sub-priority (also called subgroup priority). The split is configurable — for example, with 4 implemented bits, PRIGROUP can be set to give 4 bits of preemption and 0 bits of sub-priority (16 preemption levels, no sub-priority), or 3 bits and 1 bit (8 preemption levels with 2 sub-priority levels each), or 2 and 2, and so on.
Preemption priority determines whether one interrupt can preempt (nest inside) another. A numerically lower preemption priority value means higher urgency. If a preemption-priority-1 interrupt fires while a preemption-priority-3 ISR is running, the hardware immediately preempts: it stacks the ISR context and begins executing the higher-priority handler. Interrupts at the same preemption priority level never preempt each other, regardless of sub-priority values. Sub-priority is only a tie-breaker: when two interrupts with the same preemption priority are pending simultaneously, the one with the lower sub-priority number is serviced first. Once the first one starts executing, the second one waits — it does not preempt.
In practice, most bare-metal projects use the default PRIGROUP setting that allocates all bits to preemption priority and zero bits to sub-priority (e.g., HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4) on STM32). This gives the maximum number of nesting levels and simplifies reasoning about preemption. Sub-priority only matters when you have interrupts that should be serviced in a defined order but must never preempt each other — a rare scenario. A common mistake is confusing the two and assuming that a lower sub-priority interrupt will preempt a higher sub-priority one at the same preemption level — it will not.
Source: Interrupts & Priorities Q&A
