一:UC/OS-II的TCB池初始化:
static void OS_InitTCBList (void)
{
INT8U i;
OS_TCB *ptcb1;
OS_TCB *ptcb2;
OSTCBList = (OS_TCB*)0;
for (i = 0;i < (OS_LOWEST_PRIO + 1); i++){
OSTCBPrioTbl = (OS_TCB *)0;
}
ptcb1 =&OSTCBTbl[0];
ptcb2 =&OSTCBTbl[1];
for (i = 0;i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++){
ptcb1->OSTCBNext = ptcb2;
ptcb1++;
ptcb2++;
}
ptcb1->OSTCBNext = (OS_TCB*)0;
OSTCBFreeList = &OSTCBTbl[0];
}
是建立一个单向的空TCB链表,OSTCBFreelist指向表头,表尾指向(OS_TCB*)0.以后建立一个任务就从中取出一个TC块。
UC/OS-II在任务处理中维护两个TCB链表,一个:空的单向TCB链表,如图(1)二:已建立的双向TCB链表,如图(2)
OSTCBTbl[0]是TCB池的实体。
OSTCBFreelist:指向TCB池中空闲的TCB快的表头,
OSTCBPrioTbl[]是一个指向TCB结构的指针数组,他把任务的优先级和任务的TCB块联系起来,他优先级排序,每个优先级的指针指向相应的TCB快。如果指向空指针就说明未建立任务,未分配TCB块。指向(OSTCB*)1说明正在给这个优先级建立任务。
OSTCBlist指向已建立的双向TCB表的表头,每次建立新的任务,都会把他的TCB快插进表头,
建立任务的时候:一:把OSTCBFreeList给OSTCBPreiTbl[],
二:让OSTCBFreeList指向下一个空TCB,//从空链表中拿出。
三:初始化TCB个变量,OSTCBPreiTbl[]的NEX=TOSTCBlist,也就是指向TOSTCBlist
四:TOSTCBlist在指向县新建立的TCB块,//压进双向任务链表。
删除任务的时候:一样。
任务的就绪表就不用多说了资料上都讲得很清晰:
每个任务被赋予不同的优先级等级,从0级到最低优先级OS_LOWEST_PR1O,包括0和OS_LOWEST_PR1O在内(见文件OS_CFG.H)。当μC/OS-Ⅱ初始化的时候,最低优先级OS_LOWEST_PR1O总是被赋给空闲任务idletask。注意,最多任务数目OS_MAX_TASKS和最低优先级数是没有关系的。用户应用程序可以只有10个任务,而仍然可以有32个优先级的级别(如果用户将最低优先级数设为31的话)。
每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRedyGrp和OSRdyTbl[]。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置位。就绪表OSRdyTbl[]数组的大小取决于OS_LOWEST_PR1O(见文件OS_CFG.H)。当用户的应用程序中任务数目比较少时,减少OS_LOWEST_PR1O的值可以降低μC/OS-Ⅱ对RAM(数据空间)的需求量。
为确定下次该哪个优先级的任务运行了,内核调度器总是将OS_LOWEST_PR1O在就绪表中相应字节的相应位置1。OSRdyGrp和OSRdyTbl[]之间的关系见图3.3,是按以下规则给出的:
当OSRdyTbl[0]中的任何一位是1时,OSRdyGrp的第0位置1,
当OSRdyTbl[1]中的任何一位是1时,OSRdyGrp的第1位置1,
当OSRdyTbl[2]中的任何一位是1时,OSRdyGrp的第2位置1,
当OSRdyTbl[3]中的任何一位是1时,OSRdyGrp的第3位置1,
当OSRdyTbl[4]中的任何一位是1时,OSRdyGrp的第4位置1,
当OSRdyTbl[5]中的任何一位是1时,OSRdyGrp的第5位置1,
当OSRdyTbl[6]中的任何一位是1时,OSRdyGrp的第6位置1,
当OSRdyTbl[7]中的任何一位是1时,OSRdyGrp的第7位置1, |