任务切换机制与寄存器
任务切换机制应该怎么实现
不同架构的实现方式可以不同,但总体要满足下面这条逻辑链:
- 调度器选出下一个要运行的任务
- 调用
yr_task_switch() - 底层保存当前任务上下文
- 底层恢复目标任务上下文
- CPU 回到线程模式继续执行
对于 Cortex-M,一般建议:
- 使用
PendSV承担普通任务切换 - 使用
SVC承担首任务启动 - 使用
PSP作为任务栈 - 将
PendSV设置为最低优先级,避免破坏中断实时性
如果你移植到非 Cortex-M 架构,可以不使用 SVC/PendSV,但要保证:
- 普通任务切换可重入性正确
- 切换原子性正确
- 任务上下文保存/恢复完整
需要保存哪些寄存器
这取决于目标架构 ABI 和异常模型,但原则上要保证:
- 任务被切出前,它的运行现场能完整保存
- 任务被切回时,能从上次停下的位置继续执行
以当前 Cortex-M3 实现为例:
- 硬件异常进入时自动压栈:
r0-r3r12lrpcxPSR
- 软件额外保存:
r4-r11
所以移植到新架构时,你首先要搞清楚:
- 哪些寄存器由硬件自动保存
- 哪些寄存器必须由软件自己保存
- 线程栈与异常栈是否分离
- 返回线程模式时需要恢复哪些特殊状态位