目录
0 简介
利用5个实例对uCOSII的任务就绪过程进行分析,给了详细的出图解步骤。
1.变量说明
注:假设priority最大值为63。
INT8U OSTCBX
:记录任务优先级priority 的低三位的值;
INT8U OSTCBY
:记录任务优先级priority 的高三位的值;
INT8U OSTCBBitX
:记录当前任务优先级在就绪表中的第几位;
INT8U OSTCBBitY
:记录当前任务优先级在就绪组中的第几位;
INT8U OSRdyGrp
:就绪组,将64个优先级分为8组,每组8个优先级;
INT8U OSRdyTbl[8]
:就绪表,包含8个8位元素的数组,每位代表一个优先级;
INT8U OSMapTbl[8]
:位掩码表,其中,OSMapTbl[i]=1<<i;
INT8U OSUnMapTbl[256]
:反向掩码表,用于查找当前就绪表中的最高优先级;
就绪组与就绪表的初始状态如图 1所示。
2.各个变量的计算方法
2.1 OSTCBY
OSTCBY=priority>>3;
取出优先级的高3位,亦即优先级除以8得到的商,用于定位就绪表中的行
2.2 OSTCBBitY
OSTCBBitY=OSMapTbl[priority>>3]=OSMapTbl[OSTCBY]= 1 <<OSTCBY;
用于定位当前优先级在就绪组的位置
2.3 OSTCBX
OSTCBX=priority&0x07;
取出优先级的低3位,亦即优先级除以8得到的余数,用于定位就绪表中的列
2.4 OSTCBBitX
OSTCBBitX=OSMapTbl[priority&0x07]= OSMapTbl[OSTCBX]=1<< OSTCBX;
用于定位当前优先级在就绪表中当前行中的列位置
3 使任务进入就绪态
3.1 代码
OSRdyGrp |=OSMapTbl[priority>>3] = OSMapTbl[OSTCBY];
OSRdyTbl[priority>>3] |= OSMapTbl[priority&0x07] = OSMapTbl[OSTCBX];
3.2 解释
分别将就绪组与就绪表中对应的位置为1即可。
4 使任务脱离就绪态(进入等待态)
4.1 代码
if((OSRdyTbl[priority>>3]&=~OSMapTbl[priority&0x07])==0)
{
OSRdyGrp&=~OSMapTbl[priority>>3];
}
4.2 解释
其中,(OSRdyTbl[priority>>3]&=~OSMapTbl[priority&0x07])
,用于将指定优先级的任务脱离就绪态。仅在当前优先级所在就绪组中的所有优先级都脱离了就绪态后(OSRdyTbl[priority>>3])
,才将就绪组对应的位设置为0(OSRdyGrp&=~OSMapTbl[priority>>3]
)。
5 从就绪表中查找当前最高优先级任务
5.1 代码
y=OSUnMapTbl[OSRdyGrp];
x=OSUnMapTbl[OSRdyTbl[y]];
high_priority=y<<3+x;
5.2 解释
首先从就绪组中找到当前就绪的优先级最高的一个组,将其索引赋值给y。然后利用y,查找就绪表中第y行的优先级最高的一位,将其值赋给x。
从而,y指定了8*8的就绪表的行,x指定了8*8的就绪表的列,可以定位出当前的最高优先级。最后利用公式:high_priority=y<<3+x
即可获取当前就绪表在的的最高优先级。
6 实例
6.1 例1:将优先级为27的任务设为就绪态
priority=27;
1.计算各个变量
OSTCBY = priority>>3=27/8=3;
OSTCBBitY = OSMapTbl[priority>>3]=OSMapTbl[OSTCBY]=1 <<OSTCBY=1<<3=0b1000=8;
OSTCBX =priority&0x07=27&0x7=27%8=3;
OSTCBBitX = OSMapTbl[priority&0x07]= OSMapTbl[OSTCBX]=1<<OSTCBX=1<<3=0b1000=8;
2.更新就绪组与就绪表对应位的值
OSRdyGrp |=OSMapTbl[priority>>3]= OSMapTbl[OSTCBY]
|= OSTCBBitY
|=8;
OSRdyTbl[3] |= OSMapTbl[priority&0x07] =OSMapTbl[OSTCBX];
|= OSTCBBitX
|=8;
3.将优先级27设为就绪后,就绪组与就绪表的位图状态如图 2所示
6.2 例2:分别将优先级30、52设为就绪态
就绪组与就绪表的位图状态如图 3所示。
6.3 例3:从就绪表中查找当前最高的优先级
y=OSUnMapTbl[OSRdyGrp]=OSUnMapTbl[72]=3;
x=OSUnMapTbl[OSRdyTbl[y]]=OSUnMapTbl[72]=3;
high_priority=y<<3+x=3*8+3=27;
计算结果为27,与先前添加的优先级结果一致。
6.4 例4:使优先级为27的任务脱离就绪态
priority=27;
OSRdyTbl[priority>>3]&=~OSMapTbl[priority&0x07]
OSRdyTbl[3]&=~OSMapTbl[3]
OSRdyTbl[3]&=0b11110111
OSRdyTbl[3]=64;
因为OSRdyTbl[3]=64
,不等于0表示当前就绪组中仍有优先级处于就绪态,故不对就绪组对应的位清0。(参考如下代码)
if((OSRdyTbl[priority>>3]&=~OSMapTbl[priority&0x07])==0)
{
OSRdyGrp&=~OSMapTbl[priority>>3];
}
使优先级为27的任务脱离就绪态后的就绪表位图如图 4所示。
6.5 例5:再从就绪表中查找当前最高的优先级
y=OSUnMapTbl[OSRdyGrp]=OSUnMapTbl[72]=3;
x=OSUnMapTbl[OSRdyTbl[y]]=OSUnMapTbl[64]=6;
high_priority=y<<3+x=3*8+6=30;
计算结果为30,与先前添加的优先级结果一致。