uC/OS-II就绪任务的管理

uC/OS-II就绪任务的管理

 

      uC/OS-II总是在已就绪的任务中选择一个任务来运行。为了了解系统中的任务哪些是就绪任务,uC/OS-II在系统初始化时间里了一个供就绪任务登记的表,整个表就叫做就绪任务表。

      uC/OS-II的就绪任务表实质上是一个类型为INT8U的数组OSRdyTbl[ ]。其中的每一位对应一个任务。OSRdyTbl[]数组的一个元素就可以表示8个任务的就绪状态。为了方便对就绪表的查找,uC/OS-II又定义了一个数据类型为INT8U的变量OSRdyGrp,并使该变量的每一个位都对应OSRdyTbl[]的一个任务祖(即数组的一个元素)。如果某任务组中有任务就绪,则在变量OSRdyGrp里把该任务组所对应的位置为1;否则置为0。

      由于优先级别是一个单字节的数字,而且其最大值不会超过63,即二进制形式的00111111,因此可把优先级看成是一个6位的二进制数。这样高3位(D5,D4,D3)来指明变量OSRdyGrp的具体数据位,并用来确定就绪表数组元素的下标。低3位(D2,D1,D0)来指明该数组元素的具体数据位。

      例如Prio=30的就绪任务,其二进制形式为00011110,其低6位为011110,于是D5,D4,D3为011,故任务在OSRdyTbl[3]上,因此OSRdyGrp的D3位置1,D2,D1,D0为110,故OSRdyTbl[3]上的D5位上要置1。

 

就绪任务表的操作

      对就绪任务表的操作有两项:一是把应就绪的任务在就绪表中进行登记;二是在需要时把任务从就绪表中删除。

1.     在程序中可以用类似下面的代码把优先级别为prio的任务置为就绪状态;

OSRdyGrp |= OSMapTbl[prio >> 3];

OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];

其中OSMapTbl[]是uC/OS-II为加快运算速度定义的一个数组,其各元素的值为:

INT8U const OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};(在文件OS_CORE.C中定义)

     

2.     从就绪表中删除任务

如果要使一个优先级别为prio的任务脱离就绪状态,则可使用如下代码:

if ((OSRdyTbl[prio >> 3] &= -OSMapTbl[prio & 0x07] == 0)

//将OSRdyTbl[]对应位清0后,作判断

{

        OSRdyGrp &= -OSMapTbl[prio >> 3];

 }

3.     从就绪表中获取优先级别最高的就绪任务

由于uC/OS-II是以优先级别来对任务进行标识的,所以也就是要获得就绪任务中优先级别最高任务的优先级别。从就绪表中获取优先级别最高的就绪任务可用如下代码:(在文件OS_CORE.C中定义)

y             = OSUnMapTbl[OSRdyGrp];        /* Find highest priority's task priority number   */

        x             = OSUnMapTbl[OSRdyTbl[y]];

        OSPrioHighRdy = (INT8U)((y << 3) + x);

该代码执行后得到的最高优先级就绪任务的优先级别(即任务的标识),其中OSUnMapTbl[]同样是uC/OS-II为提高查找速度定义的一个数组,它共有256个元素,其定义如下

INT8U const OSUnMapTbl[] = {

    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0

};

由于在使用数组OSUnMapTbl[]时是以OSRdyGrp为下标的因此这个数组一共有256个元素。也就是说,无论OSRdyGrp是多少,在数组OSUnMapTbl[]中总能找到对应的元素值,而且这个元素值就是最高级就绪任务优先级别的y。因为数组OSUnMapTbl[]各个元素的值是基于这样一个思想来设置的:表示任务组的变量OSRdyGrp是一个8位二进制数,从这个数的最低位向高位查找,碰到的第一个为1的位所对应的就绪任务足一定是最高优先级别任务所在的组,所以它的组号一定是最高优先级别就绪任务的级别(6位数)的高3位。例如:OSRdyGrp中第一个为1的位为D3,那么最高优先级别就绪任务级别的高3位一定为011(十进制的3),于是在数组OSUnMapTbl[]德256个元素中,凡是其下标的D3位1,且D2,D1,D0都为0的元素值均定义为3。

      所以有了这样一个数组,在查找最高级就绪任务时,只要以变量OSRdyGrp为下标,就可直接在数组OSUnMapTbl[]得到就绪任务的y值了;否则,就要编写一个循环程序在就绪表中进行查找。这样不但耗时,而且犯了实时系统的大忌——运算时间不可预测。

      同样,这个数组也用来查找最高级就绪任务的x值。当然,这时是以OSRdyTbl[y]为下标来进行查找的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值