您的位置:首页 > 其它

uCOs 查找最高优先级任务的方法和我个人的见解

2016-11-17 19:50 162 查看
之前自己在研究 ucos-II内核调度的时候,对于内核查找最高优先级的方法进行了一些总结,下面结合一些代码进行讲解!

uCos-II的优先级是值越小,优先级越高。在创建task的时候,传入一个prio的参数,就是优先级,比如prio == 12;

ptcb->OSTCBY             = (INT8U)(prio >> 3u);//获取优先级的bit 3,4,5

ptcb->OSTCBX             = (INT8U)(prio & 0x07u);//获取优先级的bit 0,1,2

ptcb->OSTCBBitY          = (OS_PRIO)(1uL << ptcb->OSTCBY);

ptcb->OSTCBBitX          = (OS_PRIO)(1uL << ptcb->OSTCBX);

OSRdyGrp               |= ptcb->OSTCBBitY;//赋值到OS就绪组里面        

OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;//赋值到OS就绪组对于的Tbl里面

就想下图所示,OSRdyGrp放着高三位对应的bit位,自己想想3+3=6bit,6bit可以表示64个优先级,所以高3位对应OSRdyGrp,因为2的3次方 == 8,

比如prio == 12 == 0x0A= 0b 0000 1010,划分3位和3为的话,高3为为001 ,低3位为 010.

所以OSRdyGrp需要 |  bit1位,如果高3位为 011,则OSRdyGrp需要 |  bit3位,

低3位的原理也是一样的,OSRdyTbl[高3位的值] | == OSRdyTbl[1|  |= 2 == 0b 010,就如下图优先级10所在的位置。



表 - 1

INT8U  const  OSUnMapTbl[256] = {

    0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x00 to 0x0F                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x10 to 0x1F                   */

    5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x20 to 0x2F                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x30 to 0x3F                   */

    6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x40 to 0x4F                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x50 to 0x5F                   */

    5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x60 to 0x6F                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x70 to 0x7F                   */

    7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x80 to 0x8F                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x90 to 0x9F                   */

    5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xA0 to 0xAF                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xB0 to 0xBF                   */

    6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xC0 to 0xCF                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xD0 to 0xDF                   */

    5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xE0 to 0xEF                   */

    4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u  /* 0xF0 to 0xFF                   */

};

下面介绍一下 在调度的时候怎样获取最高优先级。

代码如下:

y    = OSUnMapTbl[OSRdyGrp];             //查找高3位

x    = OSUnMapTbl[OSRdyTbl[y]];//查找低3位

prio = (INT8U)((y << 3u) + x); 

其实最高优先级是数值越小的,所以你看 表 - 1 的时候,想法是找OSRdyGrp里面bit0 到bit7 中,最先置为1的那位,然后根据找到了OSRdyGrp最低位,假设是Y,Y<=8,再从OSRdyTbl[Y]里面 bit0 到bit7 中,最先置为1的那位,假设为X,接下来就可以算出优先级最高的是那个了,根据这个想法,就容易明白OSUnMapTbl的表了,其实就是这个原理了,可以举例试一下,比如最高优先级为10时,高3位为001,即 OSRdyGrp
bit1位置1,所以OSRdyGrp 值等于 2,

即OSUnMapTbl[2] = 0x01,所以y == 1了,同理也可以得出 x == 2,所以就可以算出prio
== 10了,其实这些都可以自己举个例子,试一下就很容易明白里面的东西原理,当有多个任务时,他们的优先级分别为10,34,15,。根据这种方法,也可以得到最高优先级是10的结果的!

其实我个人也有一些想法,如果不想以牺牲空间换时间的话,也可以用2个for循环来找最高优先级。

for(i=0;i<8;i++)

{

if(OSRdyGrp>>i & 0x01)//找到最小bit位为1的时候

{

y = i;

break;

}

}

for(i=0;i<8;i++)

{

if(OSRdyGTbl[y]>>i & 0x01)//找到最小bit位为1的时候

{

x = i;

break;

}

}

prio = (INT8U)((y << 3u) + x); 

这样时间复杂度最大的时候为O(16),也是一种查找优先级的方法,大家也可以讨论并测试一下!!
这次就先写到这了!下次再写!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: