0x00摘要
本文对上一节中任务优先级就绪表相关内容进行讲解,介绍任务就绪表如何工作,ucos如何利用任务就绪表实现调度时的时间无关性,这也是ucos能够满足实时性的一个重要原因.
0x01引言
Ucos任务调度中依据就绪表中的优先级进行调度,ucos如何根据就绪表来判断哪个优先级最高,其原理又是什么.如果将所有优先级进行遍历虽然可以实现任务的调度,但是却不能保证任务的实时性,因为每次调度的时间是不一样的,如果通过遍历方式优先级越靠前的任务就绪时,调度的时间少,如果优先级靠后则调度的时间较长,无法满足实时性的要求.ucos采用了一种比较合理的方式-查表法,实现了任务调度的实时性.下面将对查表法进行讲解,让大家了解一下这种方式的实现方法,也便于在以后的工程中采用类似的思想.
0x02原理
Ucos-ii支持64\128\256个优先级,为了简便我们这里以64个优先级为例进行讲解.
Ucos将64个任务分为八组,每组八个任务,这样就可以将其进行分组管理,其实就是建立一个用于标记组的变量和一个由于标记每个任务的数组,可以根据组变量对这个数组进行查找得到最高优先级.组变量对数组的标记可用如下图表示
当数组OSRdyTbl中任意一个位被标记为1表明对应的优先级准备就绪,同时将OSRdyGrp中对应的位标记为1,表明其代表的组中有就绪的任务.
系统通过对OSRdyGrp进行映射得到优先级最高任务所在OSRdyTbl中的位置,然后将OSRdyTbl中的对应的数取出,然后在映射得到对应的优先级.
通过对OSRdyTbl分析可以发现一个任务的优先级,其实就是0~63的数,它的低3bit(转换成十进制就是0~7)决定了其在OSRdyTbl[ ] 这个数中的比特位位置,其3~5bit决定了OSRdyTbl的下标,也就是OSRdyGrp中的比特位位置.这个大家可以随便列几个数自己计算一下,能够更好的理解.ucos中的实现方式为
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
ptcb->OSTCBBitY和ptcb->OSTCBBitX在任务建立的时候就进行了设置,如下:
ptcb->OSTCBY = (INT8U)(prio >> 3);
ptcb->OSTCBX = (INT8U)(prio & 0x07);
ptcb->OSTCBBitY= (INT8U)(1 OSTCBY);
ptcb->OSTCBBitX = (INT8U)(1 OSTCBX);
把上面过程反过来就是ucos通过就绪表得到最高优先级的过程,这个过程仅需要一个简单的映射就能实现.这里的映射表为
这里其实就是将OSRdyGrp为下标,分别列出每个数的映射到OSRdyTbl中的数组下标,比如OSRdyGrp比特位0为1(xxxx xxx1),其他位不论为什么值都将其映射为0,同理比特位1为1且比特位0为0(xxxx xx10),则不论其他位为什么值,都映射为1,其他位置同理.这样就可得到映射表.
通过这个表得到了OSRdyGrp的映射值,就是优先级的3~5bit的值,同理可以得到OSRdyTbl[ ]的映射值,就是优先级的0~2bit的值.将两者组合便可以得到了优先级.
0x03小结
上面就是ucos优先级的设置和反解映射的过程,通过上述的查表方式ucos可以达到不受任务数的影响,能够实时的得到任务的优先级.查表法也是很多其他工程中常用的方式,可能表现方式并不一样,但原理基本一致.
欢知识传播是一种美德
让更多人少走弯路
才能有更多人与你携手前进
欢迎扫码一起分享经验
如有任何疑问请后台回复
或添加作者Waiting_B_H
|