ucos-ii内核学习2--任务管理

 

1.任务管理的数据结构

 

#define  OS_RDY_TBL_SIZE   ((OS_LOWEST_PRIO) / 8 + 1)

 

OS_EXT  INT8U             OSRdyTbl[OS_RDY_TBL_SIZE];//创建一个8位数组

 

 

 

 

4.任务就绪表的初始化

首先我们调用了OSInit();

然后:

 

 

 void OSInit (void) { .............. /*初始化就绪任务表及相关变量*/ OS_InitRdyList(); ................. }

 

 

 

 static void OS_InitRdyList (void) { INT8U i; INT8U *prdytbl; OSRdyGrp = 0x00; /* Clear the ready list */ prdytbl = &OSRdyTbl[0]; for (i = 0; i < OS_RDY_TBL_SIZE; i++) { *prdytbl++ = 0x00; } OSPrioCur = 0; OSPrioHighRdy = 0; OSTCBHighRdy = (OS_TCB *)0; OSTCBCur = (OS_TCB *)0; }

 

就是初始化就绪表了

 

5.在OSTaskCreate() 中创建

OSTaskCreate(),首先对由参数prio传递进来的优先级别进行一系列判断,确认优先级合法且未被使用,随之调用函数OSTaskStkInitOS_TCBInit对任务堆栈和TCB进行初始化。

再看OS_TCBInit中对就绪任务表的登记:

 INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt) { OS_TCB *ptcb; /*新任务的tcb*/ ……. ptcb->OSTCBY = (INT8U)(prio >> 3); /*取y */ ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY]; /*取得就绪表的行*/ ptcb->OSTCBX = (INT8U)(prio & 0x07); /*取x*/ ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];/*取得就绪表的所在列*/ ……. OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = ptcb; ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */ ptcb->OSTCBPrev = (OS_TCB *)0; if (OSTCBList != (OS_TCB *)0) { OSTCBList->OSTCBPrev = ptcb; } OSTCBList = ptcb; /*任务就绪表登记*/ OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OSTaskCtr++; /* Increment the #tasks counter */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); }

 

 

2.根据优先级来找到就绪表的位置

                            7|6 | 5|    4 |  3|  2|  1|  0|

                            x|x|1/0|1/0|1/0|1/0|1/0|1/0|

                                     |     y    |     x    |

高3位 (3/4/5)      指明OSRdyGrp

地3位                       指明数组元素中具体位置

3.就绪表操作:

   以下的就续表操作会在调度程序中频繁看到,需要细细研读!

         a.登记任务(变为就绪状态)

         先看这个数组:

 

INT8U const OSMapTbl[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

 

         是为了加速访问而定义的数组

         登记语句(脱离就绪状态)

         Prio为优先级

 

OSRdyGrp |= OSMapTabl[prio>>3]; //prio右移3位即是y ,访问到组 OSRdyTbl[prio>>3] |=OSMapTbl[prio & 0x07]; //访问组中该处数组元素,取低3位,即是x,并且登记为1

 

                  b.删除任务:

         代码如下:

 

         //这里可谓“一箭双雕”,先取消对应优先级的登记,然后判断所在组是否还有任务在登记 //若没有,就把OSRdyGrp的对应标志取消 If( ( OSRdyTbl[prio>>3] &=~ OSMapTbl[prio & 0x07]) == 0) //把OSRdyGrp的对应标志取消 OSRdyGrp &= ~OSMapTbl[prio >> 3];

 

         c.获取最高级别就绪任务

         代码:

 

//取行 Y = OSUnMapTbl[OSRdyGrp]; //获得优先级 Prio = (INT8U) ( (y << 3) + OSUnMapTbl[OSRdyTbl[y]]); INT8U const OSUnMapTbl[256] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; //这个数组其实就是算最低非0位,系统可以根据任务查表快速找到最高级任务

 

OSRdyTbl数组中每一个数据成员为8bit数据,故可以构成8*n的状态,规定1为就绪状态,0位非就绪状态,为方便对就绪表查找,又定义了一个8bit变量OSRdyGrp,对应着OSRdyTbl[bitx],该位为1表示OSRdyTbl[bitx]有任务就绪。最多可管理64个任务。

 

你可能感兴趣的:(数据结构,list,OS,ext,任务)