μC/OS-II进行任务调度的依据就是任务就绪表 。
为了能够使系统清楚地知道,系统中哪些任务已经就绪,哪些还没有就绪,μC/OS-II在RAM中设立了一个记录表,系统中的每个任务都在这个表中占据一个位置,并用这个位置的状态(1或者0)来表示任务是否处于就绪状态,这个表就叫做任务就绪状态表,简称叫任务就绪表 。
任务就绪表能够保证每次任务切换时间的可确定性、一致性和高速性而设置的,操作整个就绪表的算法由两个变量、一个表格和三个程序组成。
- 两个变量分别是OSRdyGrp和OSRdyTbl[]
OS_EXT INT8U OSRdyGrp; /* Ready list group */
OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */
- 一个表格分别是优先级判定表OSUnMapTbl[]
INT8U const OSUnMapTbl[256] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
};
- 三个程序分别是使任务进入就绪、使任务脱离就绪、寻找准备就绪的最高优先级任务
ptcb->OSTCBY = (INT8U)(prio >> 3); /* Make task ready to run */
ptcb->OSTCBX = (INT8U)(prio & 0x07);
ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
y = ptcb->OSTCBY;
OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Make task not ready */
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~ptcb->OSTCBBitY;
y = OSUnMapTbl[OSRdyGrp]; /* find highest priority of ready task */
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
uCos中优先级判定表OSUnMapTbl原理参考:http://blog.csdn.net/xumaojun/article/details/6896661
OSUnMapTbl数组中元素OSUnMapTbl[n]表示一个任意的8位无符号数n对应的最低位为1的那个最低位数,例如二进制数00000001B最低位为1的是bit0,如是OSUnMapTbl[00000001B]= 0, 又例如1000000B最低位为1的是bit7,所以OSUnMapTbl[10000000B] = 7,及OSUnMapTbl[128]也就是上面OSUnMapTbl第9行第一列为7.
Y = OSUnMapTbl[OSRdyGrp];
X = OSUnMapTbl[OSRdyTbl[Y]];
最高优先级为X*8+Y