什么是中断?
简介:让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)即可完成设置
中断相关寄存器
三个系统中断优先级配置寄存器:
分别为 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 寄存器,
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”后缀的函数