快速理解RTOS中的pendsv中断和systick中断
概述
pendsv中断(优先级最低防止打断其他任务)
用于任务上下文切换的中断,人为设置为挂起状态不会自动触发
🔹 例子:
void PendSV_Handler(void)
{// 保存当前任务上下文// 切换堆栈指针// 恢复下一个任务上下文
}
systick中断(优先级高于pendsv即可)
周期性系统节拍中断,每次各种固定时间中断一次,用于计时、延时任务调度判断等
🔹 启用方式:
使用 SysTick_Config(SystemCoreClock / 1000); 设置 1ms 节拍
会自动触发 SysTick_Handler() 函数,在handler处理函数中去调用mcu的时基处理函数(mcu的定时器),同时在这里执行系统任务调度
void SysTick_Handler(void)
{// 每毫秒调用一次HAL_IncTick(); // HAL库系统时基osSystickHandler(); // RTOS调度处理(如CMSIS-RTOS)
}
调度流程
下面这个调度图很详细说明调用关系:
每ms触发systick在中断中判断是否需要切换,需要切换的话设置pendsv挂起,等待systick中断结束,中断优先级机制触发Pendsv中断执行上下文切换
每 1ms → SysTick 中断 → 检查是否该切任务↓如果需要切任务:设 PendSV 挂起(SCB->ICSR)↓中断退出后执行 PendSV → 执行上下文切换
时间线:
|-- SysTick_Handler() --| (中断触发 → 判断调度)↓设置 PendSV 挂起位(待执行)↓
|-- PendSV_Handler() --| (在所有中断处理完后才执行 → 真正切换任务)
注意
pendsv中断的pend是挂起意思,意思是这个中断需要先挂起后,等待中断触发执行,只有这个中断是这种处理机制,其他中断当达到触发条件就会触发中断。
异常名 | 是否自动触发 | 是否需要挂起 | 说明 |
---|---|---|---|
PendSV | ❌ 否 | ✅ 需要 | 人为触发,RTOS切任务时使用 |
SVC | ❌ 否 | ✅ 需要 | 软件中断,用于执行系统调用(触发SVC指令) |
SysTick | ✅ 是 | ❌ 不需要 | 周期自动触发,用作系统节拍 |
HardFault | ✅ 是 | ❌ 不需要 | 异常错误(非法访问、除0)立即触发 |