UCOSII原理与应用----就绪表

为系统处于就绪状态的任务分配CPU是多任务操作系统的核心工作。涉及两项技术:
1、判断哪些任务处于就绪状态。
2、任务调度,也就是通过一个算法在就绪任务中确定应该,马上运行的任务,操作系统用于负责这下工作的程序模块叫做调度器。
从任务状态转化图可以看到,系统总是从处于就绪状态的任务来选择一个任务运行。所以需要一个就绪任务登记表,来登记系统中私有处于就绪状态的任务。

就绪表结构
在UCOSII中,就绪表就是一个位图,系统中的每个任务都在位图中占据一个二进制位,该位置的状态(0或1)就表示任务是否处于就绪状态。

下图表示最多记录32个任务的就绪状态的任务就绪表。实际上是一个类型为INT8U的数组OSRdyTbl[],只不过每一个二进制对应一个任务。任务的优先级别(任务的标识)的高低为顺序,为每个任务安排一个二进制位。1表示处于就绪状态,0表示位处于非就绪状态。
在这里插入图片描述

从上图可以看出,OSRdyTbl的一个元素可以有8个任务,本例中的4个元素可以表示32个元素。
也就是说可以把8个任务看出一个任务组。即定义INT8U的变量OSRdyGrp,并是该变量的每一位对应OSRdyTbl[]的一个任务组(也就是数组一个元素)。如果OSRdyGrp = 11100101,表示OSRdyTbl[0]、OSRdyTbl[2]、OSRdyTbl[5]、OSRdyTbl[6]、OSRdyTbl[7]任务组中有任务就绪。变量OSRdyGrp的格式如图
在这里插入图片描述
在这里插入图片描述

这样确定了就绪表的格式,那我们如何通过任务的优先级别来确定其在就绪表中的位置呢?
由于优先级别是一个单字节数字,而且最大值不会超过63,所以可以把优先级看出一个6位的二进制数。这样我们通过高三位(D5D4D3)来确定OSRdyGrp的具体数据来确定就绪表元素的下标,通过低三位(D2D1D0)来确定中该元素下的具体数据位。
例:已知一个已经就绪的任务的优先级prio = 30,判断哪一位置1。
30 = 00011110。低6位 011 110。所以OSRdyTbl[3]的D6位置1,同时OSRdyGrp的D3位置1。

就绪表的操作:
登记:
把优先级prio的任务置为就绪状态,把就绪表的对应位置为1:
OSRdyGrp |= OSMapTbl[prio >> 3];
OSRdyTbl[prio >> 3] |= OSMapTbl[prio&0x07];
不理解的话,可以根据上述例子代进去算一下。
OSMapTbl[]是为了加快运算速度定义的。
OSMapTbl[0] = 0000 0001B
OSMapTbl[1] = 0000 0010B
OSMapTbl[2] = 0000 0100B
OSMapTbl[3] = 0000 1000B
OSMapTbl[4] = 0001 0000B
OSMapTbl[5] = 0010 0000B
OSMapTbl[6] = 0100 0000B
OSMapTbl[7] = 1000 0000B
注销:
把优先级prio的任务置为非就绪状态,把就绪表的对应位置为0:
if( (OSRdyTbl[prio >> 3] &= -OSMapTbl[prio&0x07]) == 0)
(OSRdyGrp&= -OSMapTbl[prio >> 3];

最高优先级就绪任务的查找
前面谈到的,系统调度器总是把CPU控制器交给优先级最高的就绪任务,因此调度器必须从任务就绪表中查出最高优先级任务的能力。UCOSII调度器获取优先级最高的就绪任务代码如下
y = OSUnMapTal[OSRdyGrp]; //获得优先级别的D5、D4、D3位
x = OSUnMapTal[OSRdyTbl[y]]; //获得优先级别的D2、D1、D0位
prio = (y << 3) + x;
改代码执行后的得到的最高优先级别(即任务标识),OSUnMapTbl[]同样是为了提高查找速度定义的数组。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值