
前言 一般来讲,MCU 相关的操作系统都具有最基本的多任务管理功能。多任务管理功能包含任务的上下文切换,因其涉及到特定寄存器的操作,都是使用汇编代码开发,相应代码由软件厂商提供。 在 STM32 技术人员的实际支持工作中,例如 IDE 移植,可能需要读懂和修改这些汇编代码。本文就是从这一需求出发,描述AliOS 操作系统里的任务上下文切换的基本原理。读者在明白了上下文切换原理后,去阅读和修改任何 MCU 操作系统的关于任务上下文切换的汇编代码就不会是个难题。本文包含的代码引用基于 STM32F4(ARM Cortex-M4 内核)芯片上的实现。 上下文切换的源动力 带操作系统的应用程序,上下文切换的逻辑在 PendSV 中断处理函数中完成。 为什么是 PendSV 中断,而不是其它的中断? ARM 技术文档里提到,PendSV 设计为上下文切换服务的中断请求,优先级最低。任务切换的策略可以根据时间片和优先级来制定。切换时机可由系统滴答时钟(SysTick)触发,或者由操作系统根据已有策略来触发 PendSV 中断。 以 AliOS 的系统时钟中断处理函数为例,则可以看到有如下代码:
其中 krhino_intrpt_exit 则会通过 cpu_intrpt_switch 触发 PendSV 中断,然后 PendSV 中断处理函数负责完成上下文切换。
在 AliOS 中有很多地方,根据系统的需要,还可直接调用 cpu_task_switch 来触发 PendSV 中断。这一部分是纯软件的设计,不再列举。
上下文切换 上下文切换的汇编代码实现的功能就是把前一个与当前任务相关的寄存器信息进行压栈保存,比如当前栈指针、TCB 信息等,把将要运行的新任务的栈内信息恢复到对应寄存器中为新任务的执行做好准备。这里的上下文就是指各个寄存器信息。 寄存器分类 通用寄存器 R0-R12 是 32 位通用寄存器。 堆栈指针 SP R13 是堆栈指针寄存器。堆栈分为复位后缺省使用的主堆栈(由 MSP 指向)以及用户应用程序使用的任务堆栈(由PSP 指向)。可以通过控制寄存器控制当前正在使用的堆栈。 链接寄存器 LR R14 是链接寄存器,用在函数或者异常/中断返回。 程序计数器 PC R15 是程序计数器。它指向当前运行的指令地址。 程序状态寄存器 xPSR 程序状态寄存器包含三个寄存器:应用程序状态寄存器 APSR, 中断程序状态寄存器 IPSR 和执行程序状态寄存器EPSR。APSR 包含上一条指令执行后的条件标志,IPSR 包含有中断号,EPSR 包含有被中断指令的待执行寄存器信息,诸如 LDM、STM、PUSH、POP,或 IF-THEN 条件指令的信息以及当前是否运行在 Thumb 状态。 优先级掩码寄存器 PRIMASK(1 位) PRIMASK 置 1 后,系统阻止除 NMI 和 hard fault 外的所有异常/中断。 故障掩码寄存器 FAULTMASK(1 位) FAULTMASK 置 1 后,系统阻止除 NMI 外的 所有异常/中断。 基线掩码寄存器 BASEPRI(9 位) 根据在 BASEPRI 中的优先级设置,系统阻止优先级小于等于它的所有异常/中断。 控制寄存器 CONTROL CONTROL 寄存器控制在线程(THREAD)模式下所处的特权级别(特权级还是用户级),以及当前系统使用的堆栈。中断处理(Handler)模式只能处于特权级,总是使用主堆栈(由 MSP 指向)。可以通过读出 SPSEL 位来进行验证。线程(THREAD)模式可以通过 CONTROL 寄存器切换是使用主堆栈(由 MSP 指向),还是任务堆栈(由 PSP 指向)。 完整版请查看:附件 |
Analysis the principle of Alios task context switch.pdf
下载345.93 KB, 下载次数: 0
STM32 GUI LTDC 最大像素时钟评估方法
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
OpenBLT移植到STM32F405开发板
为什么要先开启STM32外设时钟?
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【经验分享】STM32实例-RTC实时时钟实验④-获取RTC时间函数与中断服务函数
STM32 以太网 MAC Loopback 的实现
STM32功能安全设计包,助力产品功能安全认证
基于STM32启动过程startup_xxxx.s文件经验分享
HRTIM 指南