首页 > 其他 > 详细

ucos任务优先级从64到256,任务就绪表的改变

时间:2015-03-10 01:26:03      阅读:1680      评论:0      收藏:0      [点我收藏+]

     Ucos在任务调度中经常使用的技术为任务就绪表,在之前的文章中使用的例子是低于64个优先级的任务就绪表查找方法,现在ucos将任务扩展到256优先级之后,任务就绪表的查找也做了一定的修改,今天来讲讲

      首先我们看任务就绪表的设置过程,当任务创建的时候需要设置一次任务就绪表,所以我们先看oscreatetask,在里面查找到这句代码

err = OS_TCBInit(prio, psp, (OS_STK *)0, 0u, 0u, (void *)0, 0u);//然后初始化tcb任务区

    还记得tcb中有四个变量是用于快速查找任务就绪表的,分别是

ptcb->OSTCBY           

ptcb->OSTCBX            

ptcb->OSTCBBitY         

ptcb->OSTCBBitX      

    在OS_TCBInit中处理流程如下

#if OS_LOWEST_PRIO <= 63u                                         

        ptcb->OSTCBY             = (INT8U)(prio >> 3u);

        ptcb->OSTCBX             = (INT8U)(prio & 0x07u);

#else                                                            

        ptcb->OSTCBY             = (INT8U)((INT8U)(prio >> 4u) & 0xFFu);

        ptcb->OSTCBX             = (INT8U) (prio & 0x0Fu);

#endif

                                                                 

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

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

    可以看到,现在当系统定义的优先级大于63之后OSTCBY和OSTCBX的赋值方式发生了改变,之前是将345三位用于存放任务就绪分组,012存放就绪任务状态,这样就有了8个分组和每组八个任务,一共64个任务,而现在

    将0123四个位存放就绪任务状态值,4567四个位存放就绪任务分组的值,这样就有16个分组和16个位来存放,一共就能有256个任务了.

    这样改变之后就需要重新设置OSRdyGrp和OSRdyTbl[]的位宽,查看代码有以下内容

OS_EXT  OS_PRIO           OSRdyGrp;                       

OS_EXT  OS_PRIO           OSRdyTbl[OS_RDY_TBL_SIZE];

    位宽由OS_PRIO指定,再看OS_PRIO的定义,如下

#if OS_LOWEST_PRIO <= 63u

typedef  INT8U    OS_PRIO;

#else

typedef  INT16U   OS_PRIO;

#endif       

#define  OS_RDY_TBL_SIZE   ((OS_LOWEST_PRIO) / 16u + 1u)

    当优先级变化的时候,分组的宽度变成了16位,同时,数组长度变成了优先级/16+1,也就是说最多有16个元素,和我们所料不差,同样,当我们从任务就绪表中找出当前最高优先级的就绪任务的时候,查找方式也发生了变化,如下

INT8U     y;

OS_PRIO  *ptbl;

 

if ((OSRdyGrp & 0xFFu) != 0u) {

    y = OSUnMapTbl[OSRdyGrp & 0xFFu];

} else {

    y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u;

}

ptbl = &OSRdyTbl[y];

if ((*ptbl & 0xFFu) != 0u) {

    OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]);

} else {

    OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u);

}

    而之前的查找方式就颇为简单了

y             = OSUnMapTbl[OSRdyGrp];

OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);

    这两种方式有什么区别?

      首先, OSUnMapTbl这个数组是没有变化的,但是OSRdyGrp变成16位了,不能直接去表里面去查找了,这里面就做了一个调整,当低八位有任何一个不为0的时候,说明此时优先级最高的就绪任务的优先级在前八个OSRdyTbl元素中,0-7这是可以直接查表的,那当为0的时候,说明此时最高优先级的元素至少是第八个元素,那么将高八位代表的数值标出来,加上8,就能得到大于8的分组优先级.

      好,此时分组优先级得到了,要去找子优先级,可以直接在数组中找到,但是得到的数据时16进制的bcd码,还需要转换一次到hex,并且找出最高优先级,那就再用OSUnMapTbl过一次,处理的原理还是低八位有效直接通过低八位查找,高八位有效通过高八位查找并加上8,两个都得到之后

      Y左移四位加上子分组四位,就能得到当前最高优先级的任务的优先级了

   

    总结:ucos扩展任务优先级的方法就是将OSTCBY和OSTCBX原先三位标识优先级转为四位,将优先级从64转为256.

ucos任务优先级从64到256,任务就绪表的改变

原文:http://www.cnblogs.com/dengxiaojun/p/4324919.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!