参考任哲的《
嵌入式实时操作系统μC_OS-II原理及应用》,对
UCOS的任务调度做了下整理。
UCOS有两种调度器,一种是任务级的调度器,一种是中断级的调度器。任务级的调度器由OSSHED()来实现。而中断级的调度由函数
OSINTEXT()来实现。
调度器把任务切换的工作分为两个步骤:第一步是获得待运行任务的TCB指针。第二步是进行断点数据的切换。调度器实施任务切换前的主要工作就是要获得待运行任务的任务控制块指针和当前任务的任务控制块指针。因为被中止任务的任务控制块指针存放在全局变量OSTCBCUR中,所以调度器这部分的工作主要就是获得待运行任务的任务控制块指针。
任务切换的工作靠
OSCTXSW()来完成。
任务切换就是中止正在运行的任务(当前任务),转而去运行另外一个任务的操作。当然,这个任务应该是就绪任务中优先级最高的那个任务。
ARM中R13相当于51中的SP,在系统发生异常中断时,中断服务
程序把要保存的寄存器的值压入R13指向的堆栈。在退出中断服务时,再把堆栈中的数据弹出来。
ARM中的R14又称为链接寄存器(LR),子程序调用时,处理器硬件自动把调用处的地址存放在R14中,在子程序执行完后,使用一条指令把R14的地址恢复给PC,这样就可以返回子程序的调用处。
OSCTXSW()切换任务时依次做以下7项工作:
1、 把被中止任务的断点指针保存在任务堆栈中。
任务被中止时,断点指针被硬件自动存放在R14中,所以先要把R14的值压入堆栈。
2、 把CPU通用寄存器的内容保存到任务堆栈中
把R0-R12的值压入被中止任务的堆栈
3、 把被中止任务的任务堆栈指针当前值保存到该任务的任务控制块的OSTCBSTKPTR中
OSTCBSTKPTR定义在任务控制块结构的开始处,和任务控制块地址相同。指向任务堆栈栈顶。
4、 获得待运行任务的控制块地址
5、 使CPU通过任务控制块获得待运行任务的任务堆栈指针
6、 把待运行任务堆栈中通用寄存器的内容恢复到CPU的通用寄存器中
把堆栈中保存的R0-R12值弹回到ARM的R0-R12
7、 使CPU获得待运行任务的断点指针(该指针是待运行任务在上一次被调度器中止运行时保留在任务堆栈中的)
把堆栈中保存的断点指针值传送给LR和PC
任务切换和51子程序调用、中断的区别
51子程序掉用时,硬件自动保存断点地址,返回时,通过RET把断点地址弹回到PC中
任务切换时,硬件自动保存断点地址,然后把断点地址压入任务堆栈,然后得到另一个任务的任务堆栈指针,把新任务的任务堆栈中的断点地址弹给PC,完成任务切换。
ARM中的R13就是SP,指向当前任务的堆栈。
在被中止任务切换前,R13指向被中止任务的栈顶,压入断点指针和CPU通用寄存器后,R13指向被中止任务的栈中。然后把R13的值送给被中止任务的
OSTTCBSTKPTR。再把待运行任务控制块的OSTTCBSTKPTR送给R13,这时,R13指向待运行任务的任务堆栈栈中。把堆栈中的通用寄存器值和断点指针弹回给CPU后,R13就指向了待运行任务的堆栈顶,完成了任务切换。
文章评论(0条评论)
登录后参与讨论