首页 > 代码库 > 任务就绪表的结构与操作(uC/OS-II)

任务就绪表的结构与操作(uC/OS-II)

一、任务就绪表的结构

 每个任务被赋予不同的优先等级,从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);

任务就绪表的结构与操作(uC/OS-II)