Understanding of NVIC (Nested Vectored Interrupt Control) in STM32 (Cortex-M3)

Publisher:浊酒Latest update time:2016-10-08 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
1. The concept of priority in STM32 (Cortex-M3)

   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

    You can choose which priority grouping method to use by calling the function NVIC_PriorityGroupConfig() in the STM32 firmware library. This function has the following five parameters:

 

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.

Keywords:STM32 Reference address:Understanding of NVIC (Nested Vectored Interrupt Control) in STM32 (Cortex-M3)

Previous article:STM32 precise delay function
Next article:STM32 library function configuration

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号