CM3内核有16个中断, 优先级通过 SCB->SHP[0] to SCB->SHP[11] 设置
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt SCB->SHP[0] */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt SCB->SHP[11] */
STM32最多有240个中断(通常外部中断写作IRQs): 优先级通过 NVIC->IP[0] to NVIC->IP[239] 设置
void NVIC_SetPriority( IRQn_Type IRQn, uint32_t priority )
{
/* set Priority for Cortex-M System Interrupts */
if ( IRQn < 0 )
{
SCB->SHP[ ( (uint32_t) ( IRQn ) & 0xF ) - 4 ] =
( ( priority << ( 8 - __NVIC_PRIO_BITS ) ) & 0xff );
}
/* set Priority for device specific Interrupts */
else
{
NVIC->IP[ (uint32_t) ( IRQn ) ] =
( ( priority << ( 8 - __NVIC_PRIO_BITS ) ) & 0xff );
}
}
在STM32中将一个中断的优先级分为 : 抢占优先级和响应优先级。上述的4个bit可以灵活分配给抢先优先级和响应优先级
-
抢占优先级(pre-emption priority)高抢占优先级的中断会打断当前的主程序/中断程序运行, 俗称中断嵌套
-
响应优先级(subpriority)在抢占优先级相同的情况下, 高响应优先级的中断优先被响应 ( 但是不能嵌套 )
-
如果有低响应优先级中断正在执行, 高响应优先级的中断要等待已被响应的低响应优先级中断执行结束后才能得到响应
-
优先级处理
-
优先级数值较小的优先级较高, 优先级0x00 有最高的优先级, 优先级0xF0 有最低的优先级
-
在进行优先级判断的时候先是比较抢占优先级, 然后比较响应优先级。
-
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。
-
/*!< 0 bits for pre-emption priority 4 bits for subpriority */
#define NVIC_PriorityGroup_0 ((uint32_t)0x700)
/*!< 1 bits for pre-emption priority 3 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600)
/*!< 2 bits for pre-emption priority 2 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500)
/*!< 3 bits for pre-emption priority 1 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400)
/*!< 4 bits for pre-emption priority 0 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300)
**
- 在中断中需要调用FreeRTOS中的API,很多API是需要屏蔽掉中断的,但是如果中断优先级设置的数字小于 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY,即中断有优先级高于系统能够管理的最大优先级,导致FreeRTOS并不能管理中断,会导致错误print 错误Error:…\FreeRTOS\portable\RVDS\ARM_CM3\port.c,680,解决办法是把串口中断的优先级设置为6 小于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY,这样FreeRTOS就可以管理中断。
NVIC_Usart5.NVIC_IRQChannel = UART5_IRQn;
NVIC_Usart5.NVIC_IRQChannelPreemptionPriority =6;
NVIC_Usart5.NVIC_IRQChannelSubPriority = 0;
NVIC_Usart5.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Usart5);
参考 stm32中断优先级设置