UCOS学习日(2)-任务堆栈和任务切换的更详细的剖析

UCOS任务调度解析
本文深入探讨了UCOS-II中的任务堆栈与任务控制块概念,解析了任务就绪表的工作原理,以及任务调度器如何高效地进行任务切换。通过具体的步骤说明,帮助读者理解任务切换过程中的关键环节。

任务堆栈

昨天详细说了任务控制块,今天接着说一下任务堆栈
昨天说到STM32的堆栈地址是默认这种类型的,简单的说就是,栈顶高地址,向下增长
◎ Full descending 满递减堆栈 堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。

任务控制块及其链表

UCOS中一次定义了两个链表。一个空白的任务控制块链表,一个是已经初始化好分配给任务的任务控制块链表(这样系统会有更快的执行效率)
UCOS中有一个变量专门记录当前任务控制块的指针—OSTCBCur
如果UCOS删除一个任务,那么被删除的任务的任务控制块,就会归还给空白的任务控制块链表

已经分配给任务的TCB(任务控制块)就连接在一起。

UCOS还用了一个OSTCBPrioTbl[]指针数组,把已经创建好的任务的TCB地址,存起来。数组的下标就是任务的优先级

任务就绪表

UCOS中用一个 u8类型的OSRydTbl[8] 数组来表示任务的就绪(1)和等待(0)状态
8*8=64所以UCOS-II支持64个任务

为了方便查询再用一个u8变量的每一位来表示那个数组元素中有任务已经处于就绪状态 OSRydGrp
在这里插入图片描述
那么如何根据任务的优先级别来找到它在变量和数组元素中的位置,
例如一个任务的优先级为30,任务就绪 0001 1110 它的低六位是011 110
011则表示它在OSRydGrp中对应的位是第3位,110则表示它在元素中所对应的位即 第6位置1
那么就是OSRydTbl[3]的第6位置1
在这里插入图片描述

在UCOS系统中对优先级的登记(置1),注销(清0),以及最高优先级就绪任务的查找

都是通过常量来进行操作的。这样会让系统实时性更好,不过这都是系统写好的,我觉得了解一下就可以了。也贴出来

登记

在这里插入图片描述

注销

在这里插入图片描述

最高优先级的就绪任务的查找

在这里插入图片描述
在这里插入图片描述

关于任务的调度更详细的剖析

任务调度器有两种,一个是任务级的调度器,一个是中断级的调度器。

任务调度器,切换任务有两步

任务调度器也可以用函数OSSchedLock();和函数OSSchedUnlock();来加锁和解锁,还可以嵌套。

1.获取待运行任务的TCP指针

在任务就绪表中查找已经就绪的最高优先级的任务。任务优先级数
|
ˇ
通过任务优先级,去访问OSTCBPrioTbl[]数组,来获取任务TCB的指针。
|
ˇ
用指针变量OSTCBHighRdy来保存待运行任务的TCB指针
上面还说到UCOS用一个OSTCBCur的指针变量指向当前运行任务的TCB指针

2.进行断点数据的保存和切换

任务在进行调度的时候,会把当前运行任务的CPU寄存器中的数据保存下来(保存现场数据,书中说叫断点数据看读者自己是怎么理解的。)
|
ˇ
将待运行任务的现场数据恢复到CPU的各寄存器中去
|
ˇ
关键是的要让CPU的堆栈指针SP(进程堆栈指针或主堆栈指针,具体的应用还是要看程序在执行什么操作)指向任务TCB块中的堆栈指针(OSTCBStkPtr)来实现任务的切换

也就是
被中断的任务,CPU的SP指针要保存到自己TCB块中的堆栈指针中,
待运行任务的TCB块中的堆栈指针要,恢复到CPU的SP堆栈指针中去在这里插入图片描述
但是处理器没有对程序计数器(PC)压栈出栈命令。用任务调度函数来实现一个软中断,进入中断服务程序时会自动把断点指针(就是上一次任务被中断时PC寄存器中的值)压入任务栈,而利用中断返回指令IRET能把待运行任务 的断点指针,推入CPU的PC寄存器。这样恢复待运行任务的断点。
由此我自己理解
1.任务进行切换的时候把正在运行任务的CPU各寄存器值SP,R1…等保存自己的任务堆栈-

2.触发软中断,CPU自动把 正在运行任务CPU中PC寄存器值 压入自己的任务堆栈

3.在软中断中,把待运行任务的堆栈中保存的断点数据恢复到CPU寄存器中

4.利用中断返回指令IRET命令把待运行任务的
断点指针(就是上一次任务被中断时PC寄存器中的值),推入CPU的PC寄存器中。

5.至此实现了完整的任务切换

简单来说就是在实现任务切换时被中止的任务要保存CPU寄存器的全部数据。

待运行的任务要把
1.任务堆栈的指针放到CPU的SP(堆栈指针寄存器)中
2.任务堆栈中保存的其他的CPU各寄存器(如R0R1R2等寄存器)的值也要放到CPU中去
3.CPU的PC的值也在任务堆栈中,在任务切换时PC值要推入CPU中比较麻烦,要使用OSCtxSw()函数触发一个软中断(UCOS已经写好了)
我的理解大概就是这样子,至于这些又是SP指针(堆栈指针寄存器)又是CPU的PC(程序计数器)真的很烦,可能本来很简单的事情被我越描述越复杂,不好理解。举一个简单的例子。

一个书房只能一个学生在里面写作业。 A现在书房里面写作业,写到一半,大姨妈来了,放弃了对书房的占有权,把自己的课桌搬到自己的房间。现在书房空了,拳头比较大的B抢到了占有房间的权利,把自己的课桌搬到书房里面去写作业。写了一段时间A的大姨妈走了,要回书房写作业,B把自己的课桌搬到自己的房间去。A把自己的课桌搬进去,就可以继续接着写作业了。

例子可能不太恰当,但大概是这个意思,A和B的课桌,也就是自己的现场数据,自己失去对书房(CPU)的占有权的时候,也就把课桌(现场数据)搬回自己的房间(自己的任务堆栈)

举例子可能是最好的理解,学习本来就是由浅及深的过程,温故而知新,写博客也是为了这个目的。如果还是理解不清楚,我自己理解的不够深刻,语言描述能力也不好直接看下面 图吧
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值