为了标识当前系统中哪些任务(该任务由优先级标识)处于就绪状态,以便于系统在调度时可以快速地访问到处于就绪状态的最高优先级的任务,操作系统定义了以下两个全局变量以构成任务就绪表,用以标识所有处于就绪状态的任务。
#if OS_LOWEST_PRIO <= 63 //如果优先级范围在0-63之间
OS_EXT INT8U OSRdyGrp; //标识某范围内有任务处于就绪状态
OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE];//就绪表,标识某优先级任务就绪
#else //如果优先级在0-256之间
OS_EXT INT16U OSRdyGrp;
OS_EXT INT16U OSRdyTbl[OS_RDY_TBL_SIZE];
OSRdyTbl[ ]数组成员类型为INT8U(unsigned char),因此每个成员共有位,共同声明个成员。某位为了,标识某一个优先级的任务处于就绪状态,例如OSRdyTbl[0]的第一位为了,则标识优先级为0的任务处于就绪状态;OSRdyTbl[7]的第7位为1,则标识优先级为63的任务处于就绪状态。如果该位为0,则标识该任务没处于就绪状态(也许没创建该任务),因此共可以创建8*8=64个任务(扩展16位时可以创建256个任务)。
为了查找某个优先级任务在对应就绪表中的位置,可以采用以下基本算法。
将该优先级值转换为6位二进制数(高两位未使用,因为优先级范围0-63),此6位二进制的高3位决定该优先级在任务就绪表中的行,低3位决定该优先级在任务就绪表中的列。
例如,在创建任务时,采用以下方法来使用函数 OS_TCBInit() 更新就绪表。
ptcb->OSTCBY =(INT8U)(prio >> 3) //得到优先级值的前三位
ptcb->OSTCBBitY =1 << ptcb->OSTCBY;//得到优先级就绪表的行号
ptcb->OSTCBX =(INT8U)(prio >> 3) //得到优先级值的低三位
ptcb->OSTCBBitX =1 << ptcb->OSTCBY;//得到优先级就绪表的列号
对OSRdyGrp 和 OSRdyTbl[ptcb -> OSTCBY] 修改算法如下:
OSRdyTbl[ptcb -> OSTCBY =ptcb->OSTCBBitX //将就绪表的对应位置位
OSRdyGrp = ptcb->OSTCBBitY //将OSRdyGrp对应位置位
上面的算法可能有些难懂,但看多了就知道了,这是其经典算法之一。
下节讲其任务级任务调度算法分析。