今天和一个小伙伴讨论了一下基于cortex-m3内核的RTOS在任务切换时的程序流程,小伙伴说国内某搜索引擎都搜不到这类的信息,所以我才打算写下来,硬件平台是stm32f1​。

这里的切换有两种情况:

第一种:从main函数跳到任务一时的程序流程;

第二种:从任务一跳到任务二时的程序流程。

先说第一种:从stm32f1上电复位说起吧,上电复位之后,CPU执行以下代码:

Reset_Handler    PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP

可见代码先去执行SystemInit()这个函数,执行结束之后去执行main()函数。我为什么要说这个呢,因为在《cortex-m3权威指南》里面有这样一句:“主堆栈指针( MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)”

也就是说当cpu复位之后执行的SystemInit()和main()函数时用的都是MSP。我为什么要提MSP,因为下面还有个PSP。

继续说main()函数,执行main()函数的时候,肯定会执行一大堆初始化(这里就不多赘述初始化了些啥),然后去找优先级最高的任务,并把这个找到的任务赋给nextTask变量,这时会启动任务调度——也就是触发PendSV异常。注意到这里用的都是MSP。

这里插一句任务切换的本质:“保存上一个任务的运行状态,恢复下个任务的运行状态”。

触发PendSV异常必然会去执行PendSV_Handler()异常处理函数,在这个函数里执行的就是上面这句红字,但是从main函数到任务一的时候,是没有上一个任务的,所以不需要保存上一个任务,直接恢复下一个任务就行。恢复下一个任务就是把下一个任务的运行状态(这时任务一的运行状态是该任务初始化完成的状态)通过弹栈弹入CPU的寄存器里面然后占据CPU的控制权运行该任务,这时就不用MSP了(因为有专门给任务跑的栈),通过下面这句代码 ORR LR, LR, #0x04  切换到PSP堆栈,就是下图的第二位 并把它置1,这个PSP是啥呢,同样在《cortex-m3权威指南》里面有这句解释,进程堆栈指针( PSP):由用户的应用程序代码使用。这个PSP就是专门给任务用的栈指针,这个时候任务就在PSP上运行了。

这时就是任务一占据CPU的控制权在运行!

再来说第二种:当任务一占据了CPU的使用权在运行时,PendSV异常触发需要切换到任务二。这时CPU会通过压栈的方式把当前任务一的运行状态(就是任务一占据cpu控制权时寄存器的值)压入只属于任务一的独立栈中,这就是保存上一个任务的运行状态;然后恢复下一个任务,任务二的运行状态就是一开始在main()函数中初始化的状态,cpu通过弹栈的方式 把 这些保存在任务二独立栈中的运行状态数据  弹入CPU的寄存器,让任务二占据CPU的控制权并运行。

当然了,在这里多说一句,触发PendSV异常时执行的PendSV_Handler()函数时 用的是MSP指针运行的,任务一与任务二运行时用的是PSP指针。

最新文章

  1. Objective-C之KVC、KVO
  2. Sqli-LABS通关笔录-11[sql注入之万能密码以及登录框报错注入]
  3. POJ 3264 Balanced Lineup 线段树 第三题
  4. [读书笔记]ASP.NET的URL路由引擎
  5. Effective Java 第三版——38. 使用接口模拟可扩展的枚举
  6. 《笨方法学Python》加分题35
  7. Chapter 4 Invitations——3
  8. python - zipfile模块
  9. PHP实现IP访问限制及提交次数的方法详解
  10. (译) 在AngularJS中使用的表单验证功能【转】
  11. CodeForces 1059C
  12. python sys.path[0] 的解释
  13. 线程8--GCD常见用法
  14. 2016.6.1——Min Stack
  15. Algorithm4.子数组求和贪心
  16. Spring cloud Eureka高可用 - 配置
  17. 【调试】Linux下超强内存检测工具Valgrind
  18. [转]iBatis简单入门教程
  19. 6. datasource - mysql【从零开始学Spring Boot】
  20. mac上傻瓜式java安装环境配置

热门文章

  1. 反向代理远端 单台tomcat 使用ip+端口
  2. js 基本类型与引用类型的存储
  3. 神经网络(NN)实现多分类-----Keras实现
  4. .Netcore 2.0 Ocelot Api网关教程(9)- QoS
  5. 使用微软的WinAppDriver进行Windows客户端自动化测试
  6. power bi可视化--乘用车案例
  7. 在图中寻找最短路径-----深度优先算法C++实现
  8. Nginx 小入门记录 之 Nginx 配置文件解读(二)
  9. 深度学习-LeCun、Bengio和Hinton的联合综述
  10. [Agc029B]Powers of two_贪心_树形dp