二. 任务的调度管理
对于多任务的操作系统来说,多任务之间的调度是系统的核心。调度就是确定在多任务中确定哪个任务先运行。所谓的调度器就是实现这个功能的函数。
1. 任务就绪表
uc/os-II的任务调度思想:一直让优先级最高的而且就绪的任务处于运行状态,使用调度器来确定要运行的任务并运行任务。uc/os-II的调度依据就是任务就绪表。
在RAM中设立一个记录表,用来记录哪些任务已经就绪,哪些没有就绪。-----任务就绪状态表。
任务就绪表:INT8U OSRdyTbl[8]来充当这个就绪表。OSRdyGrp表示那个任务组有任务就绪。
2. 任务就绪表的操作
设置就绪态:OSRdyGrp |=OSMapTbl[prio>>3];
OSRdyTbl[prio >>3] =OSMapTbl[prio &0x07];
其中:OSMapTbl[]是加快运算速度定义的一个数组,
优先级prio脱离就绪状态:
if((OSRdyTbl[prio >>3] &=-OSMapTbl[prio&0x07]) == 0)
OSRdyGrp &= -OSMapTbl[prio >> 3];
从任务就绪表中获取优先级最高的就绪任务:
y= OSUnMapTal[OSRdyGrp]; //获得优先级别的D5,D4,D3
x=OSUnMapTal[OSRdyTb[y]; //获得优先级别的D2,D1,D0
prio =(y << 3) +x; //获得就绪任务的优先级别
3. 任务的调度
任务调度器的主要工作:1. 在任务就绪表中查找最高级别的就绪任务;2. 实现任务的切换。
l两种调度器:1.任务级的调度器,用OSSched()来实现; 2. 中断级的调度器,用函数OSIntExt()来实现。
任务切换的主要工作就是获得待运行任务的任务控制块指针和当前任务的任务控制块指针;被中止的任务控制块指针存放在全局变量OSTCBCur中。
任务级调度用OSSched(),应用程序通过函数OSSchedLock(),OSSchedUnlock()给调度器上锁解锁,OSLockNesting记录调度器的上锁和解锁情况。
任务切换宏:OS_TASK_SW(),任务的切换工作是靠OSCtxSw()来完成。
任务的切换就是断点数据的切换,断点数据的切换就是CPU堆栈指针的切换,被中止运行任务的任务堆栈指针要保存到该任务的任务控制块中,待运行任务的任务堆栈指针要由该任务控制块转存到CPU的SP中。完成调度操作,OSCtxSw()要依次做的工作:
1. 把被中止任务的断点指针保存到任务堆栈中;
2. 把CPU通用寄存器的内容保存到任务堆栈中;
3.把被中止任务的任务堆栈指针当前值保存到该任务的任务控制块的OSTCBStkPtr中;
4.获得待运行任务的任务控制块;
5. 使CPU通过任务控制块获得待运行任务的任务堆栈指针;
6.把待运行任务堆栈中通用寄存器的内容恢复到CPU的通用寄存器;
7.是CPU获得待运行任务断点指针。