μC/OS任务就绪和优先级查找过程理解

任务创建时,任务加入就绪表的过程

1. μC/OS任务共64个优先级,本文中一个优先级只对应一个任务,最低优先级用二进制表示为00111111,只需占用6位,如图1所示。

图1

2. 创建任务时,会设置任务优先级prio,任务优先级被设置在任务控制块TCB中,并且任务控制块被加入到任务控制块优先级表OSTCBPrioTbl[]中,即任务控制块优先级表存储指向任务控制块的指针,如图2所示。

图2

任务优先级为19的任务,指针指向任务控制块,可以通俗理解为一个任务控制块代表一个任务。

3. 任务就绪表OSRdyGrp采用位图表的方式,64个优先级分成8组,每组对应8个优先级,优先级0~7为一组,8~15为一组……56~63为一组。

1)   当某一优先级有对应任务就绪时,该优先级标志位置1;优先级没有对应任务就绪,标志位为0。

2)   当某组优先级有至少一个任务就绪时,即至少一个优先级标志位为1,那么这一组的优先级标志位为1;若某一组优先级都没有对应任务就绪,则这一组的优先级标志位为0,就绪索引表OSRdyGrp是一个8位的数值,该数值的二进制每一位即对应优先级组的标志位,如图3所示。

图3

 

4.  如图4所示

1)  就绪表当前状态下第2个任务组存在优先级19的就绪任务、第4个任务组存在优先级35、38的两个就绪任务,第7个任务组中有存在优先级60的就绪任务,那么此时就绪索引表值应为10010100;

2)  反过来已知就绪表索引值为10010100,表明就绪表第2个任务组、第4个任务组、第7个任务组中有就绪任务,但是此时还无法确定每个任务组具体哪一个优先级或哪几个优先级存在就绪任务。

图4

5.  详细介绍X,Y的意义以及使用:

1)  前文提到,优先级prio只需要6位即可表示64个优先级,其中高3位D5D4D3组成Y值表示该任务优先级所在组序号,低3位D2D1D0组成X值表示该任务在当前任务组的位置,如图4所示比如优先级19的二进制为00010011,则Y=010B=2,X=011B=3,我们就能通过查表的方式轻松知道优先级19位于就绪表第2任务组中的第3位;

2)  以优先级19的任务举例细说,假设此时就绪表一个任务都没有,空闲任务IDLE也不存在,那么最初就绪表索引值为00000000,优先级19任务创建后把任务放入就绪表时,我们先看该任务优先级的Y值为2,知道把他放在就绪表第2任务组,放入之后对应的就绪表索引值应该变为00000100,X值为3,那么第2任务组里面的第3位要置1,第2任务组的状态即OSRdyTbl[2]=00001000;

3)  假设之后又有优先级30的任务加入就绪表,其对应的就绪表索引值00001000要和之前就绪表索引值进行或运算得到索引值00001100表示此时就绪表第2、第3任务组有就绪任务, 第3个任务组的状态OSRdyTbl[3]=01000000;

4)  再加入优先级31的任务,也是在第3个任务组,就绪表索引值经过计算没有变化,但是第3个任务组的状态OSRdyTbl[3]=11000000,表示第3任务存在优先级31,30的就绪任务。

 

如图5所以,OSMapTbl[]的作用就是将Y,X值映射为对应位置,优先级19任务的Y值为2,第2任务组,表示就绪表索引值第2位为1,映射为二进制就是00000100即十六进制0x04,X值映射类似。

图5

任务调度时,任务优先级查找的过程这是一个任务加入就绪表的逆过程

任务加入就绪表过程,是根据优先级prio数值,把就绪表索引值和就绪表每个任务组的状态改变了

任务优先级查找过程,则是根据就绪表索引值和就绪表每个任务组的状态,来恢复优先级prio的数值

如图6所示优先级判定表OSUnMapTbl[256]和3行代码,你也许此时有个疑惑这个优先级判定表好乱好杂没有规律,不急,当你明白任务优先级如何查找时你也就知道优先级判定表是怎么样的规律了。

1)   我们接着之前的例子继续,之前例子中从就绪表没有任何任务到优先级19的任务,优先级30的任务和优先级31的任务加入后,就绪表索引值OSRdyGrp =00001100,第2任务组状态OSRdyTbl[2]=00001000,第3任务组状态OSRdyTbl[3]=11000000,这些你都应该理解了!

2)   现在我们查找优先级最高的任务,先看就绪表索引值OSRdyGrp的值00001100,如果你理解他的值得含义,你应该知道我们应该找就绪表第2个任务组,而不是查找第3个任务组,因为第2个任务组任务优先级都比第3个任务组的任务优先级高,更不会查找其他的任务组,因为其他的任务组都没有就绪任务,于是我们根据就绪表索引值OSRdyGrp的值00001100得到了最高优先级的Y值为2,这是你的理解,如果你用00001100=0x0C,得到的也是2,是不是很巧!

3)  知道查找第2个任务组了,就要看第2个任务组的状态OSRdyTbl[2]=00001000=0x08,你应该知道这里当前只有第3个位置的优先级存在就绪任务,即优先级19,如果用0x08查表,也是3,又一次巧合!倘若OSRdyTbl[2]=01001011=0x4B,你应该知道我们要找的是最高的优先级是第2任务组的第0位的16,不再是19,此时我们用0x4B查表的话,答案你应该可以猜出来了,至于优先级判定表大小为什么是256,原因:就绪表8个任务组,每组8个优先级,每一位都是2个状态,所以才有优先级判定表大小28。

图6

至此,查找到最高优先级,我们再从图2的任务控制块优先级表找到这个优先级任务指针,去执行那个任务。

任务删除过程

任务执行完毕删除时,其对应的就绪表优先级位要置0,如果它所在任务组优先级位都为0了,是不是应该也要把就绪表索引值对应的任务组标志位也置为0?任务释放掉相应资源,任务控制块优先级表的对应位置存放的指针也要清空了……

任务删除的详细过程再次就不叙述了。

 

一点体会:任务就绪表算法和优先级查找算法,把计算方式改为查表方式,牺牲内存换取的不仅仅是执行效率,更多是执行时间的可确定性,实时操作系统的任何操作都必须可预知的,而计算和循环则无法确定其执行的时间。

你可能感兴趣的:(ucos)