STM32中断优先级
NVIC(Nested Vectored Interrupt Controller)嵌套向量中断控制器,管理着整个芯片与中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。各个芯片厂商在设计芯片的时候会对 Cortex-M7 内核里面的 NVIC 进行裁剪,把不需要的部分去掉,所以说 STM32 的 NVIC 是 Cortex-M7 的 NVIC 的一个子集。
STM32H743 将中断分为 5 个组。该分组的设置是由 SCB–>AIRCR 寄存器的 bit10~8 来定义的,以下仅以 STM32H743xx 为例讲解。
组 | AIRCR[10:8] | 分配结果 |
---|---|---|
0 | 111 | 0 位抢占优先级,4位响应优先级 |
1 | 110 | 1位抢占优先级, 3位响应优先级 |
2 | 101 | 2位抢占优先级, 2位响应优先级 |
3 | 100 | 3位抢占优先级, 1位响应优先级 |
4 | 011 | 4位抢占优先级, 0位响应优先级 |
- 两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
- 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的,而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断
抢占优先级的级别高于响应优先级
数值越小所代表的中断优先级就越高
FreeRTOS中断优先级
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-
#define configPRIO_BITS 4
此宏定义用于配置 STM32 的 8 位优先级设置寄存器实际使用的位数。每个中断的优先级都是用寄存器中的8位来设置的。8位的话就可以设置2^8 = 256级中断,实际中用不了这么多,所以芯片厂商根据自己生产的芯片做出了调整。比如ST的STM32只使用了8位中的高四位,低四位取零,这样2^4=16,只能表示16级中断嵌套
-
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
当这个宏定义配置为 5 的时候,中断优先级数值在 0、 1、 2、 3、 4 的这些中断是不受 FreeRTOS 屏蔽的, 也就是说即使在系统进入临界段的时候,这些中断也能被触发而不是等到退出临界段的时候才被触发,当然,这些中断服务函数中也不能调用 FreeRTOS 提供的 API 函数接口,而中断优先级在 5 到 15 的这些中断是可以被屏蔽的,也能安全调用 FreeRTOS 提供的 API 函数接口。
-
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
用于配置 SysTick 与 PendSV 的,让 SysTick 与 PendSV配置为最低优先级。写成15的原因是因为NVIC都是抢占优先级0-15,15是最低优先级。
-
#define configKERNEL_INTERRUPT_PRIORITY 240
240=15<<4,这个数值是赋值给寄存器basepri使用的,是实际的优先级数值,而我们说的NVIC里面的抢占优先级和子优先级配置是仅考虑高4bit,因为我们调用NVIC的时候它已经帮我们配置好了。其中SysTick和PendSV中断的优先级240就是15左移4位的结果。这里为什么要左移四位呢,STM32的优先级设置仅使用高4位。而SVC的优先级就是0,可以理解为0左移4位还是0。
-
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 80
80=5<<4,这个数值是赋值给寄存器basepri使用的,是实际的优先级数值,而我们说的NVIC里面的抢占优先级和子优先级配置是仅考虑高4bit,因为我们调用NVIC的时候它已经帮我们配置好了
FreeRTOS任务优先级
任务优先级与中断优先级毫无关系,注意别把自己整懵咯,这里只是顺便提一下
FreeRTOS 中任务的最高优先级是通过 FreeRTOSConfig.h
文件中的 configMAX_PRIORITIES 进行配置的,用户实际可以使用的优先级范围是 0 到 configMAX_PRIORITIES – 1
#define configMAX_PRIORITIES (32)
任务的优先级数值越小,任务的优先级越低
空闲任务的优先级是 0