一、任务就绪表的结构
每个任务被赋予不同的优先等级,从0级到最低优先级OS_LOWEST_PRIO,包括0和OS_LOWEST_PRIO在内。当uC/OS-II初始化时,最低优先级OS_LOWEST_PRIO总是被赋给空闲任务idle task。
注意:最多任务数目OS_MAX_TASKS和最低优先级数是没有关系的。应用程序可以有10个任务,而仍然可以有32个优先级的级别(如果将最低优先级别数设为31的话)。
每个就绪的任务都放在就绪表中,就绪表中有2个变量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中相应元素的相应位也置为1。如图:
就绪表OSRdyTbl[]数组的大小取决于OS_LOWEST_PRIO。
#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) /* Size of ready table */ OS_EXT INT8U OSRdyGrp; /* Ready list group */ OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */
为确定下一次该哪个优先级的任务运行了,uC/OS-II中调度器总是将最低优先级的任务在就绪表中相应位置1。
二、任务就绪表的操作
系统对就绪表主要有三个操作:登记、注销和从就绪表的就绪任务中得知具有最高优先级任务的标识。
1、登记
使任务进入就绪态,即在就绪表中将该任务的对应位置1。
任务优先级的低3位用于确定在OSRdyTbl[]的位置,接下来3位用于确定在OSRdyGrp中的位置。
2、注销
使一个任务脱离就绪态,即在就绪表中将该任务的对应位置0。
3、最高优先级就绪任务的查找
为了找到进入就绪态的优先级最高的任务,并不需要从OSRdyTbl[0]开始扫描整个就绪任务表,只需查找优先级判定表OSUnMapTbl[]。OSUnMapTbl[]表中的数值表示的是一个8bit的数据最低位为1的位置,例如:1000 0000 最低位为1的位置是在第7位,那么OSUnMapTbl[128]的值就是7;1000 0010 最低位为1的位置是在第1位,那么OSUnMapTbl[130]的值就是1。
1 INT8U const OSUnMapTbl[] = { 2 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */ 3 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */ 4 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */ 5 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */ 6 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */ 7 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */ 8 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */ 9 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */ 10 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */ 11 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */ 12 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */ 13 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */ 14 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */ 15 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */ 16 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */ 17 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */ 18 };
1 y = OSUnMapTbl[OSRdyGrp]; /* Find highest priority‘s task priority number */ 2 x = OSUnMapTbl[OSRdyTbl[y]]; 3 OSPrioHighRdy = (INT8U)((y << 3) + x);