浅谈对ucos-ii任务就绪表的理解

之前一直没弄明白这两条程序的意思,尤其是第二条:
OSRdyGrp|=OSMapTbl[prio>>3]; (1)
OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];(2)
我一直以为,OSRdyGrp代表的是行,OSRdyTbl代表的是列,经过一段时间的查阅资料,现在有点眉目了。
我的理解是这样的:把就绪表的8行看成数组OSRdyTbl[]的八个元素,每个元素是8位的,每一位是一个优先级,这样总共是64个优先级,如OSRdyTbl[0]代表的是数组中第一个元素,也就是第一行,优先级为0—7;其他以此类推。ucos中又定义了一个变量OSRdGrp,这个变量是8位的,每一位对应着每一行,也就对应着数组中的一个元素,如OSRdyGrp的第0位代表的是数组的第一个元素,也就是就绪表的第一行。
现在要将某个任务至于就绪状态,那么必须在就绪表中将其优先级所在的位置置1,1代表就绪,0代表未就绪。现在我们来看第一条程序。我们将优先级prio写成二进制,优先级最大为63,写成二进制就是00111111,结合就绪表和二进制形式可以看出:低三位即第0位到第2位代表的是优先级在就绪表的每一行的位置,因为每行是8位,每满8就向第3位进1,所以当每行优先级都置成1才能跳到下一行,同时向第3位进1。所以从第三行到第五行代表的是优先级在哪一行。OSMapTbl是定义的一个数组,如下图所示: 浅谈对ucos-ii任务就绪表的理解_第1张图片
我们将prio右移3位,高位补0,低三位丢失。即prio>>3代表的是优先级所在的行,OSMapTbl[prio>>3]查表就可以得到对应的值,代表的就是某行。然后 OSRdyGrp|=OSMapTbl[prio>>3]表示的是将OSRdyGrp对应位置1,代表的就是被置1的位所表示的行有任务就绪。再看第二条程序  OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07] ,prio&0x07是读取低三位,代表的是优先级在某行的位置,带入到OSMapTbl[]中查出具体的值,OSRdyTbl[prio>>3]代表的是优先级所在的行,将它与查出的值相或,也就是将对应行的对应位置置1.至此完成将任务放入就绪表中,使其就绪。。。  如有不到位之处请指正
浅谈对ucos-ii任务就绪表的理解_第2张图片
找出进入就绪态的优先级最高的任务,使用了一张表OSUnMapTbl[16*16],正张表的生成方法其实就是找到优先级最高的那一位,也就是8bit中最低一位不为0的位的位数。举例说明,OSRdyGrp = 01101000 , 第四位为1且为最低的不为0的位,所以通过查表,OSUnMapTbl[0x01101000] = 3。同理可以查出 OSRdyTbl = 11100100 在 OSUnMapTbl中的值为2。为了更好的理解这个表,我自己写了个小程序来生成OSUnMapTbl这张表,里面OSUnMapTbl用了二维数组OSUnMapTbl[16][16]。
unsigned char OSUnMapTbl[16][16];
     unsigned char count = 0;
 
     for (int i = 0; i < 16; i++)
     {
         for (int j = 0; j < 16; j++)
         {
             unsigned char temp = count;
             int           bit = 0;
             while ((temp & 0x01) == 0 && bit <8)
             {
                 temp >>= 1;
                 bit++;
             }
             if(bit == 8)
                 bit = 0;
             OSUnMapTbl[i][j] = bit;
             count++;
         }
     }
 
     for (int i = 0; i < 16; i++)
     {
         for (int j = 0; j < 16; j++)
         {
             printf("%d,",(int)OSUnMapTbl[i][j]);
         }
         printf("\n");
     }

之后通过以下计算就可以得出进入就绪状态的优先级最高的任务
  y = OSUnMapTbl[OSRdyGrp];
  x = OSUnMapTbl[OSRdyTbl[y]];
  prio = y << 3 + x;

你可能感兴趣的:(浅谈对ucos-ii任务就绪表的理解)