首页 > 代码库 > uCOS-II中任务优先级的判定和处理方法
uCOS-II中任务优先级的判定和处理方法
转载请注明原文出处,http://www.cnblogs.com/flyingcloude/p/6992346.html
在uCOS-II中,最多有64个优先级,把这64个优先级每8个分成一组,总共可以分成8组。对应的数组名称是OSRdyTbl[x] (0≦x≦7)。为了更快捷的判断出进入就绪态的
任务,又引入了变量OSRdyGrp。OSRdyGrp来标识哪组任务中有进入就绪态的任务。例如:
优先级为12的任务进入就绪态,那么OSRdyTbl[1]的第四位置1,OSRdyGrp的第一位置1。通过下面的图表能更明确的看出来。
通过这个表格,我们也能看出,对于OSRdyTbl[x] (0≦x≦7),如果OSRdyTbl[x]的某一位置1,那么OSRdyGrp对应的第x位也置1。
假设优先级为12的任务进入就绪态,其对应的十六进制数为0x1100,那么相应的表达式为:
OSRdyGrp |= 0x02;
OSRdyTbl[1] |= 0x10;
而0x02是2的1次方,0x10是2的4次方;而1和4又恰好为0x1100的次第三位和第三位。其实OSRdyTbl[x]中存放的是优先级的低三位;OSRdyGrp存放的是优先级的高三位。
为了加快计算速度,uCOS-II中增加了一下数组,这样CPU就没必要再去计算诸如乘方等运算了,这是一种用空间换速度的做法。这个数足就是
OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
同样当优先级为12时:
OSRdyGrp |= OSMapTbl [prio >>3];
OSRdyTbl[1] |= OSMapTbl [prio & 0x07];
其实,所有进入就绪态的任务都可以通过上述方法进入就绪表。
感兴趣的话你可以测试其他的优先级情况。
那么,uCOS-II是如何找到优先级最高的任务的呢(优先级的数值最小)。
假设OSRdyGrp = 0x11;OSRdyTbl[0] = 0x11;OSRdyTbl[4] = 0x22;则进入就绪态的任务的优先级分别为:0*8+0 = 0; 0*8+3 = 3; 4*8+1 = 33; 4*8+5 = 37。
通过上面的情况可以看出,优先级最高的任务肯定是在OSRdyGrp中为1的最低位对应的那一组OSRdyTbl[]中,而OSRdyTbl[]里面的为1的最低位对应的任务也就是就绪表中
优先级最高的任务。所以,如果想找出优先级最高的任务,其实就是找出OSRdyGrp中为1的最低位x以及OSRdyTbl[x]中为1的最低位y。然后优先级就是prio = x*8+y;现在的问题就
变成确定x和y了。
跟上面提到的相同,在uCOS-II中有定义了一个数组,
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
};
y = OSUnMapTbl[OSRdyGrp];
x = OSUnMapTbl[OSRdyTbl[y]];
到此为止,处于就绪态的优先级最高的任务就确定了。
数组OSUnMapTbl[]为优先级判定表,书上和网上对优先级判定表没做详细的说明,经过和王老师一番探讨,对优先级判定表的制作原理作如下解析:
首先,我们要明确一点,我们是要查找优先级最高的任务。
其次,假设OSRdyGrp = 0x11,OSRdyGrp十进制表示为17,二进制表示为00010001,OSRdyGrp的二进制第一位和第五位为1说明第一行和第五行有就绪任务,优先级高的当然是第一行的,所以y=OSUnMapTbl[OSRdyGrp]=0, 也就是说OSUnMapTbl[]的第十八个元素为0。假设OSRdyTbl[0]=0x11,同样的OSRdyTbl[0]十进制表示为17,二进制表 示为00010001,OSRdyGrp的二进制第一位和第五位为1说明第一列和第五列有就绪任务,所以优先级高的当然是第一列的。
最后,不难发现不管是找行优先级高的还是列优先级高的,它们的本质一样的,就是行数低的优先级高,列数低的优先级高,按照这样的原则以OSRdyGrp或 就绪表元素值为下标,以优先级高任务的行数或列数所对应的优先级(行数减一或列数减一)为值创建出来的就是优先级判定表了!
转载请注明原文出处,http://www.cnblogs.com/flyingcloude/p/6992346.html
uCOS-II中任务优先级的判定和处理方法