解读uCos中优先级判定表OSUnMapTbl原理

来源:互联网 发布:ubuntu qt5.7.1 ftp 编辑:程序博客网 时间:2024/04/27 18:39
OSOSRdyTbl[0]的bit7-bit0对应于优先级7-0, 
OSOSRdyTbl[1]的bit7-bit0对应于优先级15-8, 
OSOSRdyTbl[2]的bit7-bit0对应于优先级23-16, 
OSOSRdyTbl[3]的bit7-bit0对应于优先级31-24, 
OSOSRdyTbl[4]的bit7-bit0对应于优先级39-32, 
OSOSRdyTbl[5]的bit7-bit0对应于优先级47-40, 
OSOSRdyTbl[6]的bit7-bit0对应于优先级55-48, 
OSOSRdyTbl[7]的bit7-bit0对应于优先级63-56 
OSRdyGrp确定了优先级的次低三位(bit5-bit3),OSOSRdyTbl确定了优先级的低三位(bit2-bit0), 

OSRdyGrp = 0x011;  //0b00010001 
OSRdyTbl[0] = 0x0a; //0b00001010 
OSRdyTbl[4] = 0x01; //0b00000001 
计算出存在的几个优先级为;0*8+1=1,0*8+3=3,4*8+0=32 
假设OSRdyGrp最低位为1的是X位,OSRdyTbl[X]最低为1的是Y位, 
则优先级=X*8+Y 
因此只要知道了上述的X,Y就可算出最高优先级 
OSUnMapTbl就是将0x00-0xff每个数据中最低位为1的位数一一列举出来 
INT8U  const  OSUnMapTbl[256] = { 
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */ 
    //OSUnMapTbl[0]     
    //OSUnMapTbl[1]    1        bit0        
    //OSUnMapTbl[2]    2        bit1  
    //OSUnMapTbl[3]    3        bit0  
    //................ 

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             */ 
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             */ 
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             */ 
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             */ 

}; 

其中第一行
0u==0x00 ==00000000b 最低位为1的位数为 bit0==0u (其实为空,空的情况默认为0,不影响计算)
1u==0x01 ==00000001b 最低位为1的位数为 bit0==0u
2u==0x02 ==00000010b 最低位为1的位数为 bit1==1u
3u==0x03 ==00000011b 最低位为1的位数为 bit0==0u (有两个为1的位,bit0,bit1,取最小的,因为OSRdyGrp或OSOSRdyTbl中最小的位数 对应的优先级越大)
4u==0x04 ==00000100b 最低位为1的位数为 bit2==2u
5u==0x05 ==00000101b 最低位为1的位数为 bit0==0u
6u==0x06 ==00000110b 最低位为1的位数为 bit1==1u
7u==0x07 ==00000111b 最低位为1的位数为 bit0==0u
8u==0x08 ==00001000b 最低位为1的位数为 bit3==3u
9u==0x09 ==00001001b 最低位为1的位数为 bit0==0u
Au==0x0A ==00001010b 最低位为1的位数为 bit1==1u
Bu==0x0B ==00001011b 最低位为1的位数为 bit0==0u
Cu==0x0C ==00001100b 最低位为1的位数为 bit2==2u
Du==0x0D ==00001101b 最低位为1的位数为 bit0==0u
Eu==0x0E ==00001110b 最低位为1的位数为 bit1==1u
Fu==0x0F ==00001111b 最低位为1的位数为 bit0==0u

其他行类推,能得出上表,其实通过上面的推导,可以看出,上表中主要是求0~255(0x00~0xFF)之间数的最低位为1的所在的位数,


X = OSUnMapTbl[OSRdyGrp]; 
Y = OSUnMapTbl[OSRdyTbl[X]]; 

最高优先级为X*8+Y 


----------------------------------

      咋一看这个数组还真有点怪异。数组如下:

INT8U const OSUnMapTbl[256] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             */
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             */
};

        INT8U是为防止不同编译器相同数据类型的长度不一导致代码可移植差而在在os_cpu.h中声明的一个数据类型,跟unsigned char相同,表示无符号的8位数。

       这个有256个元素的数组是通过任务就绪表找到就绪任务中优先级最高的任务所用到的数组。代码如下:

y=OSUnMapTal[OSRdyGrp];//获得优先级别的D5、D4、D3位

x=OSUnMapTal[OSRdyTbl[y]]; //获得优先级别的D2、D1 、D0位

prio=(y<<3)+x;

        prio是表示优先级的一个无符号八位数,不过只有低六位有效。prio与就绪任务表的两个数组的关系是这样的:prio高三位表示组数,即OSRdyGrp[]中的哪一位是一。低三位表示这一组中的位数,即OSRdyTbl[]中的哪一位是一。例如,如果prio是00011001,即优先级是25。则OSRdyGrp[]中的第三位是被置一的,OSRdyTbl[]中的第一位是被置一的。

        由于有可能有很多任务是处于就绪状态的,也就是说OSRdyGrp[]和OSRdyTbl[]中均有可能不止一位是被置一的。由于优先级的数字越小,级数越高,所以要从这些就绪的任务中找出优先级最高的任务,就需要找出这两个数组中被置为一的最低位。

        于是这个数组就这样产生了:当OSRdyGrp[]中被置为一的最低位是第三位(0~7位)时,表示优先级最高位是处于第三组(0~7),也就是说prio的有效位的高三位应该是011。于是OSUnMapTbl[]数组中所有对应于x x x x1000的元素的值都是011(3)。其它元素值同理可得。

         低三位同理。由就绪任务表通过这个数组就找到了所有就绪任务中优先级最高的任务的优先级了。

        当然由任务表找出处于就绪状态的拥有最高优先级的任务的优先级也可以编写一个循环程序在就绪表中查找。但是这样比较耗时,并且犯了实时系统的大忌——运算时间不可预测。所以采用了这样一个查表的方法。也算是用空间换取时间吧。

为了您的安全,请只打开来源可靠的网址

打开网站    取消

来自: http://hi.baidu.com/xqgoth/blog/item/015ee4a9fbc8fcfa1f17a275.html
---------------------------------------------

uCOS-II中就绪表到最高优先级的查表表格解读

刚开始接触uCOS-II的时候,对于OSUnMapTbl[]中的数据比较模糊,害得自己折腾了一段时间才弄明白,为了方便像我这样的新手学习,现将当时的笔记整理出来,以下是整理出来的学习笔记。

 

    接触过uCOS-II的都应该知道,任务调度中的就绪表由两部分组成:OSRdyGrp和OSRdyTbl[]。在需要进行任务切换时,通过:

                   y = OSUnMapTbl[OSRdyGrp];-----------(1)

                   x = OSUnMapTbl[OSRdyTbl[y]];--------(2)

                   prio = (y << 3) + x;----------------(3)

    即可以查到当前就绪态的任务中的最高优先级任务。

 

在此,便有一个疑问:为什么通过查找OSUnMapTbl[]中的数据,便能间接得到当前就绪态的任务中的最高优先级呢?

首先,来看看OSRdyGrp和OSRdyTbl[]。

 

    接着,再看看OSUnMapTbl[]的数据内容:

 

INT8U  const  OSUnMapTbl[] = {

    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F     */

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F     */

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F     */

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F     */

    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F     */

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF     */

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF     */

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF     */

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF     */

};

 

    我们知道,OSRdyGrp和OSRdyTbl[]均为INT8U的类型,每个数据均为8bit,每一个bit均可独立设置,故存在各个位均已设置的情况,从而需要考虑的最多情况为2^8=256种,如上表所示。

    对于OSRdyGrp而言,其查表方式为:OSUnMapTbl[OSRdyGrp];易知:OSRdyGrp为奇数时(即bit0 = 1时),对应的有效的bit mask为bit 0(如OSRdyGrp=0x03、0x07,此时优先级最高的bit mask为bit 0),所以OSUnMapTbl[]表中的所有奇数下标位置对应的值全为0(如OSUnMapTbl[1]=OSUnMapTbl[3]=OSUnMapTbl[5]=0)。同理,OSRdyGrp最低有效位为bit 1时(OSRdyGrp=0x020、0x06,此时优先级最高的bit mask为bit 1),对应的有效的bit mask为bit 1,故该表中的所有0b00000010 + 0b00000100*n(n=0,1,2...)的位置的下标位置的值全为1(如OSUnMapTbl[2]=OSUnMapTbl[6]=OSUnMapTbl[10]=1)。

    对于OSRdyTbl[]而言,其查表方式为:OSUnMapTbl[OSRdyTbl[y]] ,其中y =OSUnMapTbl[OSRdyGrp];该表达式的意义为:根据查得的最高优先级对应的Group,找出该Group中的就绪态的最高优先级号,其思路跟上面完全一致。

    综上,可得:

    y = 0x01<<a+(0x01<<(a+1))*n=(0x01<<a)*(1+2n)

    a表示Group中的最低有效位(最低的非0的位)的位置,同时表示在该表中的数据,范围0-7;(n=0,1,2...),y表示表中的位置,该位置对应的值为a。

    即:对于OSUnMapTbl[]中的任意位置y,其值为a,对应公式为上面的表达式。

   

    由此,我们可以清楚的看出OSUnMapTbl[]表格是如何生成的,反过来也可以发现,该表是为了满足嵌入式系统实时性的特性而使用的,这种通过查表降低运算量提高实时性的思想在做项目的时候可以进行借鉴

0 0
原创粉丝点击