There are two priority concepts in STM32 (Cortex-M3): preemptive priority and response priority. The response priority is also called "sub-priority" or "sub-priority". Each interrupt source needs to be assigned these two priorities.
1. What is pre-emption priority?
Interrupt events with high preemptive priority will interrupt the current main program/interrupt program execution—preemptive priority response, commonly known as interrupt nesting.
2. What is subpriority?
In the case of the same preemptive priority, the interrupt with higher sub-priority will be responded to first;
In the case of the same preemptive priority, if a lower sub-priority interrupt is being executed, the higher sub-priority interrupt must wait until the lower sub-priority interrupt that has been responded to is completed before it can be responded to - non-preemptive response (cannot be nested).
3. Basis for judging whether an interrupt will be responded to
First is the preemptive priority, followed by the secondary priority;
The preemptive priority determines whether interrupts will be nested;
Reset, NMI, and Hard Fault have negative priorities (higher than normal interrupt priorities) and cannot be adjusted.
4. Handling priority conflicts
An interrupt with a high preemptive priority can be responded to during the interrupt processing with a low preemptive priority, that is, interrupt nesting, or an interrupt with a high preemptive priority can nest an interrupt with a low preemptive priority.
When the preemptive priority of two interrupt sources is the same, there will be no nesting relationship between the two interrupts. When one interrupt arrives, if another interrupt is being processed, the later interrupt will have to wait until the previous interrupt is processed. If the two interrupts arrive at the same time, the interrupt controller decides which one to process first based on their response priority; if their preemptive priority and response priority are equal, the order of their ranking in the interrupt table determines which one to process first.
5. Definition of interrupt priority in Cortex-M3
Since each interrupt source needs to be assigned these two priorities, there needs to be a corresponding register bit to record the priority of each interrupt; in Cortex-M3, 8 bits are defined to set the priority of the interrupt source. These 8 bits can be allocated in 8 ways, as follows:
All 8 bits are used to specify the response priority
The highest 1 bit is used to specify the preemptive priority, and the lowest 7 bits are used to specify the response priority
The highest 2 bits are used to specify the preemptive priority, and the lowest 6 bits are used to specify the response priority
The highest 3 bits are used to specify the preemptive priority, and the lowest 5 bits are used to specify the response priority
The highest 4 bits are used to specify the preemptive priority, and the lowest 4 bits are used to specify the response priority
The highest 5 bits are used to specify the preemptive priority, and the lowest 3 bits are used to specify the response priority
The highest 6 bits are used to specify the preemptive priority, and the lowest 2 bits are used to specify the response priority
The highest 7 bits are used to specify the preemptive priority, and the lowest 1 bit is used to specify the response priority
This is the concept of priority grouping.
6. Definition of interrupt priority in stm32
Cortex-M3 allows fewer interrupt sources to use fewer register bits to specify the priority of the interrupt source, so the STM32 reduces the register bits for specifying interrupt priority to 4 bits. The grouping of these 4 register bits is as follows:
Group 0: All 4 bits are used to specify the response priority
Group 1: The highest 1 bit is used to specify the preemptive priority, and the lowest 3 bits are used to specify the response priority
Group 2: The highest 2 bits are used to specify the preemptive priority, and the lowest 2 bits are used to specify the response priority
Group 3: The highest 3 bits are used to specify the preemptive priority, and the lowest 1 bit is used to specify the response priority
Group 4: All 4 bits are used to specify the preemptive priority
Interrupt priority grouping is to allocate the number of bits occupied by each priority number in the upper four bits of the interrupt priority register to the preemptive priority and response priority. It can only be set once in a program.
There are 4 bits in the AIRC (Application Interrupt and Reset Register) register for specifying priorities. These 4 bits are used to assign preemption priority and sub priority, and are defined in the STM32 firmware library as follows:
/* PreemptionPriority Group */
#define NVIC_PriorityGroup_0 ((u32)0x700)/* 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((u32)0x600) /* 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((u32)0x500) /* 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((u32)0x400) /* 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((u32)0x300) /* 4 bits for pre-emption priority
0 bits for subpriority */
NVIC_PriorityGroup |
Preemption Priority |
From the priority |
describe |
NVIC_PriorityGroup_0 |
0 |
0-15 |
Preempting priority 0 from priority 4 |
NVIC_PriorityGroup_1 |
0-1 |
0-7 |
Preempting priority 1 from priority 3 |
NVIC_PriorityGroup_2 |
0-3 |
0-3 |
Preempts priority 2 from priority 2 |
NVIC_PriorityGroup_3 |
0-7 |
0-1 |
Preempting priority 3 from priority 1 |
NVIC_PriorityGroup_4 |
0-15 |
0 |
Preempts priority 4 from priority 0 |
NVIC_PriorityGroup_0 => Select Group 0
NVIC_PriorityGroup_1 => Select Group 1
NVIC_PriorityGroup_2 => Select Group 2
NVIC_PriorityGroup_3 => Select Group 3
NVIC_PriorityGroup_4 => Select Group 4
The next step is to specify the priority of the interrupt source. The following is a simple example to illustrate how to specify the preemptive priority and response priority of the interrupt source:
// Select to use priority group 1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// Enable EXTI0 interrupt
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // Specify preemptive priority level 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // Specify response priority level 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable EXTI9_5 interrupt
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Specify preemptive priority level 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // Specify response priority level 1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
-------------------------------------------------- ----------------------------------
A few points to note are:
1. If the specified preemptive priority or response priority exceeds the range of the selected priority group, unexpected results may occur;
2. There is no nesting relationship between interrupt sources with the same preemptive priority level;
3. If an interrupt source is assigned a preemptive priority level and there is no other interrupt source at the same preemptive priority level, any valid response priority level can be assigned to this interrupt source.
2. Switch total interruption
In STM32/Cortex-M3, interrupts are enabled or disabled by changing the current CPU priority.
PRIMASK bit: Only NMI and hard fault exceptions are allowed, and all other interrupts/exceptions are masked (current CPU priority = 0).
FAULTMASK bit: Only NMI is allowed, and all other interrupts/exceptions are masked (current CPU priority = -1).
In the STM32 firmware library (stm32f10x_nvic.c and stm32f10x_nvic.h), four functions are defined to operate the PRIMASK bit and the FAULTMASK bit to change the current priority level of the CPU, thereby achieving the purpose of controlling all interrupts.
The following two functions are equivalent to turning off the general interrupt:
void NVIC_SETPRIMASK(void);
void NVIC_SETFAULTMASK(void);
The following two functions are equivalent to opening the global interrupt:
void NVIC_RESETPRIMASK(void);
void NVIC_RESETFAULTMASK(void);
The above two groups of functions should be used in pairs, but cannot be used interchangeably.
For example:
The first method:
NVIC_SETPRIMASK(); //Disable the general interrupt
NVIC_RESETPRIMASK(); //Enable the general interrupt
The second method:
NVIC_SETFAULTMASK(); //Disable the general interrupt
NVIC_RESETFAULTMASK(); //Enable the general interrupt
Commonly used:
NVIC_SETPRIMASK(); // Disable Interrupts
NVIC_RESETPRIMASK(); // Enable Interrupts
-----------------------------------------------------------------------------------------------------------------
Supplement:
You can use:
#define CLI() __set_PRIMASK(1)
#define SEI() __set_PRIMASK(0)
to implement the function of switching the main interrupt.
Previous article:STM32 precise delay function
Next article:STM32 library function configuration
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Industry first! Xiaopeng announces P7 car chip crowdfunding is completed: upgraded to Snapdragon 8295, fluency doubled
- P22-009_Butterfly E3106 Cord Board Solution
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- RT-Thread device framework learning RTC device
- Orcad learning notes (three) class and sub class in PCB
- [Hua Diao Experience] 17 Beetle ESP32C3 and WS2812 screen music visualization rhythm light
- EEWORLD University----42/5000 Power over Ethernet (PoE) Training Series
- How to effectively program a microcontroller active buzzer driver
- MSP430 SPI reads AFE4400 register value code
- WPG Live Broadcast Registration | Thundercomm, Lianda, Qualcomm IOT Platform Solutions and Success Stories
- The rain is a surprise in spring, the valley is clear, the summer is full of grains, and the summer heat is connected
- [Anxinke NB-IoT Development Board EC-01F-Kit] 4. Serial port MQTT networking and information sending and receiving test
- Microchip Live FAQ|ADAS Platform Root of Trust