//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
更多原创“uC/OS-II学习笔记之:系列”基础及嵌入式相关知识详解,请访问可乐虎博客:
相信不会让您失望!!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
a[0]的D0到D7位分别对应着 0到 7这几个优先级别;
a[1]的D0到D7位分别对应着 8到15这几个优先级别;
a[2]的D0到D7位分别对应着16到23这几个优先级别;
a[3]的D0到D7位分别对应着24到31这几个优先级别;
a[4]的D0到D7位分别对应着32到39这几个优先级别;
a[5]的D0到D7位分别对应着40到47这几个优先级别;
a[6]的D0到D7位分别对应着48到55这几个优先级别;
a[7]的D0到D7位分别对应着56到63这几个优先级别。
首先声明:关于uC/OS-II任务就绪表的基本概念就不在这里啰嗦了,任何一本相关书籍都介绍的很清楚了,网上更是一搜一火车。本篇博文仅适合看过uC/OS-II任务就绪表的基本内容,然后又有些许疑惑的同学们!如果您属于这种情况那么恭喜您了。请继续……一定要看完哦。当然,如果您是高手那也请给点建设性的意见和建议。
由图,可看出优先级别为0到63即00000000b到00111111b,所以可把优先级别看成是一个6位的二进制数(最大为111111b)。那么怎么将这6个二进制数与上图中的a[x]与y的值对应起来呢?
以优先级别52(110100b)为例,阐述规则如下:
(1)将其低3位100(十进制数4)用来指示任务在数组a[x]值D0到D7中对应Dx的x值。
(2)将其高3位110(十进制数6)用来指示数组a[x]的下标x,和y值中二进制位Dx中的x;
故:任务优先级别52在数组a[6]中的D4位,观察上图确实如此。有兴趣的同学可以多试验几个例子,以加深印象!
再如:已知某个就绪任务的优先级别为29,那么就续表中哪些位应该置1?
答:29对应二进制数011101b,高3位为011(十进制数3),低3位为101(十进制数5),所以就续表中a[3]的D5应该置1,同时y值D3也要置1。
疑惑(1):到这里就有同学要问了,这个规则的理论依据是什么呢?难道只是个巧合吗?
答:显然不是巧合,但确实又很巧。原因就在于低3位二进制数能表示的范围为000b到111b,也就是十进制数的0到7,而数组a元素的值恰好又是8位二进制数,每当低3位值超过7(溢出)就会向高3位进1,那么高3位的值就充当了计数器的作用(对低3位溢出的次数进行计数)。现在假设优先级别prio从0增长到63:第1次溢出后,优先级别显然就在a[1]中,第2次溢出后,优先级别显然就在a[2]中……直到第7次溢出,优先级别就在a[7]中。这样低3位始终就在0到7间变化(反应的就是D0到D7中的Dx了),高3位始终在a[0]到a[7]间变化(反应的就是a[x]了)。
疑惑(2):可能有同学现在仅知道了数组a的作用,但还不知道数值y的作用。那么y的作用是什么呢?
答:现假设数组a中优先级别为61的任务已就绪(即a[7]的D5处已被置1),那么我们如何将这个已就绪的任务找出来呢?我们列举两种方法:
(方法一):从0到63依次遍历数组a中每一位,这样得查询62次才能得到结果。
(方法二):先查询y中的D0到D7,看哪位值为1,显然查询8次后得D7为1;然后再查询a[7],从a[7]的D0查到D5共查询6次发现其值为1,完毕。这样共查询了14次就得到了结果。
显然:方法二要比一节省时间的多。这就是y值的作用了——先确定数组a的行号——以提高查询效率!
最后阐明:本文中的数组a就是uC/OS-II中的数组OSRdyTbl,数值y就是OSRdyGrp了!之所以用a和y来代替它们是为了能更容易让人接收,特别是防止那些刚刚从51过渡到操作系统的同学们对这种变量产生畏惧感,而不敢往下看了,呵呵!所以在此提醒下,变量命名一定要改掉那种只用一个简单字母就搞定的坏习惯,哈哈!