关于rtos中任务切换时的程序流程
今天和一个小伙伴讨论了一下基于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指针。
关于rtos中任务切换时的程序流程的更多相关文章
- 在docker中运行elasticsearch时go程序无法连接到节点
错误信息: panic: no active connection found: no Elasticsearch node available 在docker中运行es时,默认启动sniffing ...
- Android中Activity切换时共享视图元素的切换动画(5.0以上)
同一时候公布在我的博客 点此进入 背景 说来这个的背景很easy,常常在使用图片列表的时候就会想,假设"列表中的图片放大到整个屏幕"作为 Activity 的补间动画.就很完美了. ...
- 关于含RecyclerView的fragment来回切换时页面自动滑动到底部的解决方法
原因: 在fragment中来回切换时RecyclerView获得了焦点,而RecyclerView的 focusableOnTouchMode属性默认是true,所以在切换时RecyclerView ...
- Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程
最近在面试Android,今天出了一个这样的题目,即如题: 我当时以为生命周期是这样的: onCreate --> onStart -- ---> onResume ---> onP ...
- 在使用Qt5.8完成程序动态语言切换时遇到的问题
因为之前了解过一些Qt国际化的东西,所以在写程序的时候需要显示给用户的字符都使用了 tr(" ")的形式,然后使用 Qt Linguist得到相应的 qm(Qt message)文 ...
- 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法
重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...
- 从Excel中导入数据时,提示“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决办法
注意,64位系统,用64位的补丁文件; https://www.cnblogs.com/A2008A/articles/2438962.html 操作系统:使用的是64位的Windows Server ...
- 解决微信小程序的wx-charts插件tab切换时的显示会出现位置移动问题-tab切换时,图表显示错乱-实现滑动tab
解决Echarts在微信小程序tab切换时的显示会出现位置移动问题 tab切换时,图表显示错乱 <canvas class="kcanvas" canvas-id=" ...
- Android 如何去掉手机中横竖屏切换时的转屏动画?
前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net ...
随机推荐
- pycharm连接linux版python
1.建立连接 2.测试连接 3.同步目录 4.查看同步的目录 5.设置永久同步目录 6.设置连接 可以看到添加进来了 参照文档: https://www.cnblogs.com/xiao-apple3 ...
- python 操作mysql数据库(mac)包括如何处理安装MySQL-python
一.数据库的安装,https://www.jianshu.com/p/fd3aae701db9 https://jingyan.baidu.com/article/fa4125ac0e3c2 ...
- spring boot工程如何启用 热启动功能
1.在pom.xml里面添加一个依赖即可 关键代码 <dependency> <groupId>org.springframework.boot</groupId> ...
- 数据结构——关于任一二叉树n0=n2+1的证明
对于任一二叉树,若度为2的结点有n2个,则叶子结点数必为n2+1 证明: 假设该二叉树总共有n个结点(n=n0+n1+n2),则该二叉树总共会有n-1条边,度为2的结点会延伸出两条边, 同理,度为1的 ...
- linux文本处理三剑客(一)---grep
在linux种有一句话,叫做一切皆文件.文件有个特点,它是个文本.它可以读.可以写,如果是二进制文件,它还能执行.这样的话,我们在使用linux的时候,多数时间都是要和各式各样文件打交道的.那么,熟悉 ...
- 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用
目录 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用 21.1 read命令键盘读取变量的值 21.1.1 read常用见用法及参数 21.2 流程控制语句if 21.2 ...
- PTA(Advanced Level)1033.To Fill or Not to Fill
With highways available, driving a car from Hangzhou to any other city is easy. But since the tank c ...
- 【转帖】龙芯将两款 CPU 核开源,这意味着什么?
龙芯将两款 CPU 核开源,这意味着什么? https://www.oschina.net/news/78316/loongson-open-source-two-cpu-core 文章挺不错的 也讲 ...
- 怎么才能记住java线程的start()和run()谁是启动方法
start()和run()开始的时候总是记不住那个是线程的启动方法,现在是记得很真切了! 如果用run()启动线程就跟不用线程效果是一样的,因为是run是顺序执行的.start()才是线程的启动方法. ...
- Ubuntu18.04中安装Python3.7教程
Ubuntu18.04中安装Python3.7教程 链接https://blog.csdn.net/weixin_42056625/article/details/82970358