查看原文
其他

uCOS II 系列文章之就绪表

鱼鹰Osprey 鱼鹰谈单片机 2021-02-01

预计阅读时间: 4 分钟


就绪表记录着等待运行的任务优先级号,优先级号也可以认为是任务 ID(系统任务有专用 ID) ,即一个任务只有唯一的一个优先级并且这个优先级对应着该任务,知道优先级,就知道了是哪个任务。她们是一一对应的关系。 就绪表大小可以裁剪,即可以小于 8 个字节大小。


就绪表是一个数组,以 0-63 个优先级为例(最高优先级为 0)。


使用二进制表示(这里从左往右数偏移,方便观察,一般来说都是从右往左的),方便说明。



以该数组为例(内容随便写的,如果都为 0 ,说明没有任务准备运行,但实际上空闲任务是一直处于就绪态),某一 bit 置 1 表示一个任务处于就绪态,准备运行。



从 OSRdyTbl[ 0 ] = 0100 0101 b(b 表示二进制) 内容中我们可以看出优先级为 0*8 + 1 = 1 、0*8 + 5 = 5 、0*8 + 7 = 7 的任务已经准备好,可以开始运行了。


从 OSRdyTbl[ 1 ] = 0000 0100 b(b 表示二进制) 内容中我们可以看出优先级为 1*8 + 5 = 13 的任务已经准备好,可以开始运行了。


从 OSRdyTbl[ 2 ] = 0001 0010 b(b 表示二进制) 内容中我们可以看出优先级为 2*8 + 3 = 11 、2*8 + 6 = 5 的任务已经准备好,可以开始运行了。


继续分析其他字节内容 ...........最后一个字节为 0 表示该组没有任务准备运行。


从当前的分析,可以由就绪表得出准备运行的任务:


随便找一个 bit 为 1 的位置,就说明一个任务处于就绪态,我们可以根据该任务在就绪表的位置计算优先级(优先级在 u/COS II 中就是任务代号,任务调度就是根据它进行调度)设置该 bit 在一个字节中的 bit 偏移为 x ,在数组中的字节偏移为 y(OSRdyTbl[ y ])


那么得出优先级公式为: priority = y*8 + x。


通过优先级我们也可以确定该任务是否处于就绪态:


OSRdyTbl[ Priority / 8 ] & (1 << (Priority % 8)) 如果不为 0 (注意这里左移是因为习惯上是从右边往左边数 bit 偏移位置的),那么表明该任务处于就绪态。否则就是没有就绪。


(以下二进制和上表内容无关,就别看上面的表了)


为了更快的对就绪表进行操作,任务控制块(每一个任务都有一个单独的任务控制块,记录着任务的一些信息)设置了两组变量记录优先级,



前面是实际的位索引(根据优先级计算得出),后面的两个是位掩码(根据位索引左移得出)。OSTCBY 记录该任务在就绪表中的哪一个字节,方便查找就绪表中的组号(即某一个字节,比如 OSTCBY = 1(从 0 开始),表示第二个字节),找到组号就可以通过 OSTCBBitX 对这个任务进行就绪和删除就绪操作了,因为 OSTCBBitX 记录着任务的位掩码,比如 0000 1000 b (这里从右往左数偏移,从 0 开始)表示偏移为 3。找到了组号(即某一个字节),又知道位掩码,就可以对就绪表中该任务的状态进行就绪(置 1 :OSRdyTbl[y] |= OSTCBBitX)和非就绪(清 0 ,OSRdyTbl[y] &=( ~ OSTCBBitX)  )操作 , 不需要每次进行操作前都需要通过优先级计算这些信息了。


INT8U OSTCBBitY 可以用于对就绪组 OSRdyGrp(记录着就绪任务的组掩码,这是一个字节,其中一位置一,就表示该组有就绪任务,如:0000 1001 b,表示第 0 组和第 3 组有任务就绪)进行操作,当就绪表中的一个组为 0 时,就可以用 OSTCBBitY 删除就绪组,OSRdyGrp &= ~OSTCBBitY;增加就绪组 OSRdyGrp |= OSTCBBitY。


注意:就绪表是可以裁剪的,最少一个字节,在最低优先级大于 63 时,可以最大 32 个字节(这时分组单位是两个字节一组)。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存