精华总结:
中断优先级0为最高,任务优先级0为最低
中断优先级分组中为方便rtos管理4bit全部设置成抢占优先级
32单片机的中断管理是由3个寄存器完成(名字忽略,具体功能忽略),三个寄存器都是32bit,通过移位可操作设置寄存器上的bit位,比如可设置pendsv中断和systick中断优先级
最终,pendsv与systick被设置成15,pendsv与systick切换任务的时候不会影响到其它中断的触发(比如外部中断)
上面三个寄存器是设置中断优先级;还有三个寄存器用于屏蔽中断,freertos使用了寄存器BASEPRI用于中断屏蔽,为0x50代表关闭(也可以说屏蔽)5-15优先级的中断,为0代表不关闭(屏蔽)任何中断(就是这个寄存器规定了freertos只能控制5-15优先级的中断),如果为0x60,则就是6-15
1、中断优先级分组全部设置成抢占优先级->是为了方便freertos管理中断
即:HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
2、你的中断优先级设置必须是5-15(当然也可以为0-4,但这样不受控了)
3、freertos只能控制5-15优先级的中断
4、0-4的中断因为rtos不可控,所以禁止0-4的中断调用rtos的api函数,因此设置抢占优先级必须≥5才行,如果你设置成了4则rtos控制不了则无法控制别人抢占你或者你抢占别人
什么是中断?
简介:让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断
例:
中断执行机制,可简单概括为三步:
中断优先级分组设置
ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级,这个寄存器就
是中断优先级配置寄存器,因此最大中断的优先级配置范围位 0~255。但是芯片厂商一般用不
完这些资源,对于 STM32,只用到了中断优先级配置寄存器的高 4 位[7:4],低四位[3:0]取零处
理,因此 STM32 提供了最大 2^4=16 级的中断优先等级
中断优先级配置寄存器的值与对应的优先等级成反比,即中断优先级配置寄存器的值越小,
中断的优先等级越高。
STM32 的中断优先级可以分为抢占优先级和子优先级,抢占优先级和子优先级的区别如下:
抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断,即中断嵌套。
子优先级: 抢占优先级相同时,子优先级高的中断不能打断正在执行但子优先级低的中的
中断,即子优先级不支持中断嵌套。
STM32 中每个中断的优先级就由抢占优先级和子优先级共同组成,使用中断优先级配置寄
存器的高 4 位来配置抢占优先级和子优先级,那么中断优先级配置寄存器的高 4 位是如何分配
设置抢占优先级和子优先级的呢?
一共有 5 种分配方式,对应着中断优先级分组的 5 个组
通过调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)即可完成设置
老生常谈,FreeRTOS只用分组4,因为这样方便打断,不用考虑子优先级了
中断优先级0为最高,任务优先级0为最低
中断相关寄存器
三个系统中断优先级配置寄存器:
分别为 SHPR1、 SHPR2、 SHPR3
SHPR1寄存器地址:0xE000ED18
SHPR2寄存器地址:0xE000ED1C
SHPR3寄存器地址:0xE000ED20
表出自:《Cortex M3权威指南(中文)》第286页
1. SHPR1
SHPR1 寄存器的地址为 0xE000ED18, 用于配置 MemManage、 BusFault、 UsageFault 的中
断优先级, 各比特位的功能描述如下表所示:
2. SHPR2
SHPR2 寄存器的地址为 0xE000ED1C,用于配置 SVCall 的中断优先级, 各比特位的功能
描述如下表所示:
3. SHPR3
SHPR3 寄存器的地址为 0xE000ED20,用于配置 PendSV、 SysTick 的中断优先级, 各比特
位的功能描述如下表所示:
FreeRTOS 在配置 PendSV 和 SysTick 中断优先级的时,就使用到了 SHPR3 寄存器
FreeRTOS 如何配置 PendSV 和 SysTick 中断优先级:
PendSV和SysTick设置最低优先级
设置最低:保证系统任务切换不会阻塞系统其他中断的响应
三个中断屏蔽寄存器:
分别为 PRIMASK、 FAULTMASK 和BASEPRI
FreeRTOS所使用的中断管理就是利用的BASEPRI这个寄存器
BASEPRI:屏蔽优先级低于某一个阈值的中断
比如: BASEPRI设置为0x50,代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常执行
建议参考知识库中:GPT对话知识库——FreeRTOS中寄存器BASEPRI的作用
BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断
关中断程序示例:
#define portDISABLE_INTERRUPTS()
vPortRaiseBASEPRI()
static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
__asm
{
msr basepri, ulNewBASEPRI
dsb
isb
}
}
#define configMAX_SYSCALL_INTERRUPT_PRIORITY
( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
5
/* FreeRTOS可管理的最高中断优先级 */
中断优先级在5 ~ 15的全部被关闭
开中断程序示例:
#define portENABLE_INTERRUPTS()
vPortSetBASEPRI( 0 )
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
__asm
{
msr basepri, ulBASEPRI
}
}
FreeRTOS中断管理就是利用BASEPRI寄存器实现的
当BASEPRI设置为0x50时:
在中断服务函数中调度FreeRTOS的API函数需注意:
1、中断服务函数的优先级需在FreeRTOS所管理的范围内
2、在中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数
参考链接:
https://blog.csdn.net/weixin_44639540/article/details/129007015