关于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 ...
随机推荐
- Kuhn-Munkras算法解决二分图最优权值匹配
在看这篇博文之前建议看一下上一篇匈牙利法解决二分图最大匹配问题: https://www.cnblogs.com/fangxiaoqi/p/10808729.html 这篇博文参考自:https:// ...
- PHPNamespace命名空间
命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误.这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀. 例:项目中有两个 ...
- smoothstep(),平滑阶梯函数,平滑过渡函数【转】
函数定义: 参考:https://en.wikipedia.org/wiki/Smoothstep 相关函数图形如下: 计算机图形中经常用到正如上图所示的:两个smooth()函数相减. 相关C+ ...
- Impacket网络协议工具包介绍
转载自FreeBuf.COM Impacket是一个Python类库,用于对SMB1-3或IPv4 / IPv6 上的TCP.UDP.ICMP.IGMP,ARP,IPv4,IPv6,SMB,MSRPC ...
- 金士顿U盘PS2251-07东芝闪存白片量产CDROM成功教程-群联量产教程-U盘量产网
之前我们发布过金士顿DT100 G3的黑片量产工具教程,因为白片的MPALL量产工具无法量产,所有版本的Phison_MPALL都爆红,最近出了新的白片MPALL V5.03.0A版本,所以试了一下结 ...
- 【DSP开发】硬件信号量在多核处理器核间通信中的应用
硬件信号量在多核处理器核间通信中的应用 刘德保1,汪安民1,韩道文2 1.同方电子科技有限公司研究所,九江 332009:2.解放军电子工程学院 摘要: 在多核处理器的软件设计中,核间通信机制是关键所 ...
- [转帖]ubuntu 修改 apt源的方法
https://www.cnblogs.com/dadonggg/p/11129973.html ubuntu 和 centos 是不一样的 ubunut 里面 用deb开头 放置到 /etc/apt ...
- Kubernetes---容器的生命周期
⒈ ⒉Init容器 介绍: Pod 能够具有一个或多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的Init容器. Init容器与普通的容器非常像,除了如下两点: >Ini ...
- shell实践--简单抓取网页内容
#!/bin/bash base_path="https://testerhome.com/"user_path="ycwdaaaa/topics?page=" ...
- Snoopy.class.php介绍
Snoopy是一个开源的模拟抓取工具,找到一个不错的介绍网页 记录一下: php开源采集类Snoopy.class.php功能使用介绍与下载地址 Snoopy.class.php使用手册 还有一个介绍 ...