uc/os中每个任务的优先级都是不同的,这样就使得每个任务都有与之相对应的独一无二的优先级。因此,任务就绪状态就可以根据优先级别的数量建立一个表,通过这个表,调度器就可以决定下一次该哪个优先级的任务开始运行了。
就绪表中有两个变量OSRdyGrp和OSRdyTbl[],两者关系如下图。
找出进入就绪态的优先级最高的任务,使用了一张表OSUnMapTbl[16*16],正张表的生成方法其实就是找到优先级最高的那一位,也就是8bit中最低一位不为0的位的位数。举例说明,OSRdyGrp = 01101000 , 第四位为1且为最低的不为0的位,所以通过查表,OSUnMapTbl[0x01101000] = 3。同理可以查出 OSRdyTbl = 11100100 在 OSUnMapTbl中的值为2。为了更好的理解这个表,我自己写了个小程序来生成OSUnMapTbl这张表,里面OSUnMapTbl用了二维数组OSUnMapTbl[16][16]。
1 unsigned char OSUnMapTbl[ 16 ][ 16 ]; 2 unsigned char count = 0 ; 3 4 for ( int i = 0 ; i < 16 ; i ++ ) 5 { 6 for ( int j = 0 ; j < 16 ; j ++ ) 7 { 8 unsigned char temp = count; 9 int bit = 0 ; 10 while ((temp & 0x01 ) == 0 && bit < 8 ) 11 { 12 temp >>= 1 ; 13 bit ++ ; 14 } 15 if (bit == 8 ) 16 bit = 0 ; 17 OSUnMapTbl[i][j] = bit; 18 count ++ ; 19 } 20 } 21 22 for ( int i = 0 ; i < 16 ; i ++ ) 23 { 24 for ( int j = 0 ; j < 16 ; j ++ ) 25 { 26 printf( " %d, " ,( int )OSUnMapTbl[i][j]); 27 } 28 printf( " \n " ); 29 }
之后通过以下计算就可以得出进入就绪状态的优先级最高的任务
1 y = OSUnMapTbl[OSRdyGrp]; 2 x = OSUnMapTbl[OSRdyTbl[y]]; 3 prio = y << 3 + x;