uCOS-II中任务优先级的判定和处理方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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中任务优先级的判定和处理方法的主要内容,如果未能解决你的问题,请参考以下文章

uCOS-II学习笔记之就绪表

常见的嵌入式OS内存管理和进程调度方式

(转载)uCOS-II的嵌入式串口通信模块设计

NIOS2随笔——uCOS-II实时操作系统

微服务异常的三种场景和处理方法

uCOS-II