开启辅助访问 切换到窄版

打印 上一主题 下一主题

任务调度的汇编实现

[复制链接]
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式



0x01

摘要
前面对任务调度系统的主要内容进行了详细的介绍,剩下任务调度的最后一部分,也就是任务调度的汇编实现,这部分和具体的平台有关,也是ucos移植需要修改的地方。一般这部分都有别人已经移植成功的,如果大家只是拿来用的,不是具体研究其实现的机理的话,可以不必深究,因为这部分涉及到具体的平台。本文以stm32为例。


0x02

引言

汇编是最接近芯片工作原理的部分,也是最难学习的部分,对于汇编大家只需要根据自己需要进行学习,不必完整学习,因为完整学习花费的代价很高。
因为汇编语言的高效性,所以一般对于像任务调度这种很频繁的操作才建议使用汇编来实现,这样可以极大的提高系统的效率。对于汇编的分析涉及到芯片的具体工作方式,这里我们仅对汇编的功能进行分析,其涉及到的芯片深层工作原理大家自行翻阅芯片手册。


0x03

原理

首先我们看一下任务调度函数OS_CPU_PendSVHandler,这是PendSV的中断函数,前面我们说了,ucos是通过出发PendSV中断实现的任务调度。因为PendSV在所有芯片级的中断中级别最小,不会对芯片级的其他中断造成影响,以便等到芯片其他的重要中断完成后才进行调度,保证了芯片工作的稳定性和可靠性。我们对其代码进行分段讲解
OS_CPU_PendSVHandler
CPSID I
MRS R0, PSP
CBZ R0, OS_CPU_PendSVHandler_nosave
这一段是关闭系统的中断避免在任务切换时被其他中断打扰,并将PSP中的内容加载到R0中,判断R0是否为零,若为零则表示第一次切换任务,直接跳转到OS_CPU_PendSVHandler_nosave而不需要进行下面的寄存器存储操作。
SUBS R0, R0, #0x20
STM R0, {R4-R11}


LDR R1, =OSTCBCur
LDR R1, [R1]
STR R0, [R1]
这一段表示对当前任务的寄存器R4-R11进行存储,这里R0R3LRPC指针会自动存储到PSP指向的堆栈,这是由芯片自动完成的,无需进行人工操作。然后将当前堆栈的栈顶指针存放到TCB中的OSTCBStkPtr变量中。  

OS_CPU_PendSVHandler_nosave
PUSH {R14}
LDR R0, =OSTaskSwHook
BLX R0
POP {R14}
这一段主要是为了实现systick的钩子函数OSTaskSwHook的实现,现将R14入栈然后执行函数,返回,将R14出栈。
LDR R0, =OSPrioCur
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
这一段主要是将最高优先级赋值给当前优先级。
LDR R0, =OSTCBCur
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
这一段是将最够优先级的任务TCB赋值给当前任务的TCB
LDR R0, [R2]
LDM R0, {R4-R11}
ADDS R0, R0, #0x20
MSR PSP, R0
ORR LR, LR, #0x04
CPSIE I
BX LR
这一段将最高优先级任务的R4-R11寄存器内容恢复,然后将R0地址跳过芯片自动存储的区域,并将地址赋值给PSP,然后将LR寄存器4字节对其,打开全局中断,跳转到调用函数的位置。


0x04

结论

这一篇将ucos任务切换的汇编实现进行了详细的讲解,这些汇编代码和具体的平台有关,有时候相同的芯片代码可能也不同,但是其思路是一样的,都是存储当前任务的寄存器值,然后恢复将要调用任务的寄存器值。
OS

你的努力
我的付出
大家的支持
终将化作生命辉煌
如有任何疑问请后台回复

或添加作者Waiting_B_H





知识传播是一种美德

让更多人少走弯路
才能有更多人与你携手前进

欢迎扫码一起分享经验




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表