Understanding STM32 Interrupt Priority: Preemptive and Response Priority

1. Preemptive Priority and Response Priority
The STM32 interrupt vector has two attributes: preemptive priority and response priority, with a smaller attribute number indicating a higher priority level.Preemption refers to the ability to interrupt other interrupts, meaning that it allows for nested interrupts (interrupt B can interrupt the execution of interrupt service function A, and once interrupt B is serviced, execution of function A continues). The preemptive attribute is configured by the NVIC_IRQChannelPreemptionPriority parameter.Response priority is applicable when the preemptive priorities are the same; if two interrupts arrive simultaneously, the one with the higher response priority is serviced first. The response attribute is configured by NVIC_IRQChannelSubPriority parameter. For example, if we have three interrupt vectors as shown in the table below:
Understanding STM32 Interrupt Priority: Preemptive and Response Priority
If the kernel is executing the interrupt service function for C, it can be interrupted by the higher preemptive priority interrupt A. Since B and C have the same preemptive priority, C cannot be interrupted by B. However, if interrupts B and C arrive simultaneously, the kernel will respond to the higher response priority interrupt B first.
2. NVIC Priority Groups
When configuring priorities, an important consideration is the number of interrupt types. The NVIC can only configure the priorities for 16 types of interrupt vectors, meaning that the number of preemptive and response priorities is determined by a 4-bit number, which is allocated between the preemptive and response priority portions. There are 5 allocation methods:
Group 0: All 4 bits used for response priority:16 interrupt vectors have different response priorities.
Group 1: Highest 1 bit for preemptive priority, lowest 3 bits for response priority.This means there are 2 levels of preemptive priority (level 0, level 1), and 8 response priorities: there are 8 interrupts with preemptive priority level 0, with response priorities from 0 to 7; the remaining 8 interrupt vectors have preemptive priority level 1, with response priorities also from 0 to 7.
Group 2: 2 bits for preemptive priority, 2 bits for response priority:4 levels of preemptive priority and 4 levels of response priority.
Group 3: Highest 3 bits for preemptive priority, lowest 1 bit for response priority:8 levels of preemptive priority and 2 levels of response priority.
Group 4: All 4 bits used for preemptive priority:16 interrupt vectors only have preemptive attributes, with no response attributes.

To configure these priority groups, you can use the library function NVIC_PriorityGroupConfig(), with input parameters ranging from NVIC_PriorityGroup_0 to NVIC_PriorityGroup_4, corresponding to the above 5 allocation groups.

Some readers may be confused: with such a powerful STM32, all GPIOs can be configured as external interrupts, and peripherals like USART and ADC also have interrupts, but the NVIC can only configure 16 interrupt vectors. What if more than 16 interrupts are used in a project? Note that NVIC configures 16 types of interrupt vectors, not 16 interrupts. When a project has more than 16 interrupt vectors, there will necessarily be two or more interrupt vectors using the same interrupt type, and interrupt vectors of the same type cannot nest.
3. Steps to Set Interrupt Priority
1. After the system starts, first set the interrupt priority grouping.
In the main function, call the function:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
2. The interrupt grouping is set only once during the entire system execution.
3. For each interrupt, set the corresponding preemptive and response priorities:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);// Configuration processNVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;// USART1 interrupt, can be changed to any module with interrupt functionality like timers, external interrupts, etc.NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// Preemptive priority set to 1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// Sub-priority set to 2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;// Enable IRQ channelNVIC_Init(&NVIC_InitStructure); // Initialize NVIC register with specified parameters
4. If you need to suspend/resume, check the current activation status of the interrupt, and call the relevant functions accordingly.
5. The priority grouping only allocates bits for the preemptive and response priorities in the interrupt priority register, and can only be set once in the program.
6. Every program related to interrupt priority must include the following two functions:
void NVIC_PriorityGroup(); // Written in the main program;NVIC_Init();  // Written in the initialization configuration
4. Code Example
{// Enable EXTI0 interruptNVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // Set preemptive priority to level 1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // Set response priority to level 0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// Enable EXTI9_5 interruptNVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Set preemptive priority to level 0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // Set response priority to level 1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// TIM3 interruptNVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // TIM3 interruptNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Highest preemptive priority level 0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // Sub-priority level 3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ channel enabledNVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM3, ENABLE);  // Enable TIMx peripheral}
In the example above, the lower the number for preemptive priority, the higher the priority. Similarly, for response priority, the lower the number, the higher the priority.
5. Notes
1) If the specified preemptive or response priority exceeds the range defined by the selected priority grouping, unexpected results may occur;
2) There is no nesting relationship between interrupt sources with the same preemptive priority;
3) If an interrupt source is assigned a certain preemptive priority and no other interrupt source shares the same preemptive priority, any valid response priority can be assigned to that interrupt source.

Leave a Comment