博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ucos任务优先级从64到256,任务就绪表的改变
阅读量:5079 次
发布时间:2019-06-12

本文共 2182 字,大约阅读时间需要 7 分钟。

     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.

转载于:https://www.cnblogs.com/dengxiaojun/p/4324919.html

你可能感兴趣的文章
jQuery应用 代码片段
查看>>
MVC+Servlet+mysql+jsp读取数据库信息
查看>>
黑马程序员——2 注释
查看>>
用OGRE1.74搭建游戏框架(三)--加入人物控制和场景
查看>>
转化课-计算机基础及上网过程
查看>>
android dialog使用自定义布局 设置窗体大小位置
查看>>
ionic2+ 基础
查看>>
互联网模式下我们更加应该“专注”
查看>>
myeclipse集成jdk、tomcat8、maven、svn
查看>>
查询消除重复行
查看>>
Win 10 文件浏览器无法打开
查看>>
HDU 1212 Big Number(C++ 大数取模)(java 大数类运用)
查看>>
-bash: xx: command not found 在有yum源情况下处理
查看>>
[leetcode]Minimum Path Sum
查看>>
内存管理 浅析 内存管理/内存优化技巧
查看>>
hiho1079 线段树区间改动离散化
查看>>
【BZOJ 5222】[Lydsy2017省队十连测]怪题
查看>>
第二次作业
查看>>
【input】 失去焦点时 显示默认值 focus blur ★★★★★
查看>>
Java跟Javac,package与import
查看>>