uCO/OS-ii OSUnMapTbl、OSRdyGrp、OSRdyTbl用法

原博客地址:http://blog.csdn.net/d521000121/article/details/53678252

变量定义

//OSUnMapTbl 表
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 OSRdyGrp;     /* Ready list group                         */
INT8U OSRdyTbl[8];  /* Table of tasks which are ready to run    */

实例分析

他们3个用的都是INT8U的变量,也就是无符号的8bit变量。
那么现在来一个个解释它们代表的意思:
OSRdyGrp,它将64个优先级分为8组,恰好就是与这个变量的8bit一一对应;

任务就绪表

任务就绪表

举个例子,假设OSRdyGrp = 00000100B 那么就可以说明第2组存在一个就绪任务,也就是说优先级为16~23中有一个或多个任务已就绪。

OSRdyTbl[8],就是对应的8个分组了;
继续刚刚的例子,在OSRdyGrp = 00000100B 的情况下,我们可以肯定OSRdyTbl[2] 中一定有一位或者多位为1。

那么OSRdyTbl[2]的作用就是记录究竟哪一个优先级的任务已就绪,假设OSRdyTbl[2] = 10000001B,结合任务就绪表,那么我们就可以知道,应该是这一组第0和7的任务就绪了。

最后就剩下 OSUnMapTbl[256],它其实就是用于查找为1的最低位,他是一个数组,而数组记录的数字是事先写好的,那么它有什么意义呢?

我们继续刚刚的例子,已知OSRdyGrp = 00000100B ,OSRdyTbl[2] = 10000001B ,现在有一段这样的查表代码

y = OSUnMapTbl[OSRdyGrp];  
x = OSUnMapTbl[OSRdyTbl[y]];  
prio = (y << 3) + x;  

y = OSUnMapTbl[OSRdyGrp]; 将 00000100B 转换为十进制后是4,也就是 y = OSUnMapTbl[4] , 即 y = 2(结合OSUnMapTbl表);其代表的含义就是 4 转换为二进制后为1的最低位在第二位。
这就告诉了我们,第二组是有就绪任务的组中的最高优先级的组。
然后x = OSUnMapTbl[OSRdyTbl[y]]; , x = OSUnMapTbl[OSRdyTbl[3]], 即 x = OSUnMapTbl[10000001B] -> x = OSUmMapTbl[129] -> x = 0(结合OSUnMapTbl表)

这又告诉了我们,第二组中,就绪的最高优先级任务是第二组的第0个任务。

prio = y << 3 + x 就是 y * 8 + x, 就是我们想要找的所有任务中已就绪的最高优先级任务

小结

其实归根结底这是一种典型的用空间换取时间的方法,在设置就绪任务时设置一个标记,就能以O(1)的时间查找出已就绪的最高优先级任务,这个方法在这个系统里其他地方还有应用,以切合系统的实时性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章