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

之前自己在研究 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),也是一种查找优先级的方法,大家也可以讨论并测试一下!!

这次就先写到这了!下次再写!





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值