zoukankan      html  css  js  c++  java
  • ucos任务优先级从64到256,任务就绪表的改变

         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.

  • 相关阅读:
    pycharm调试时出现十分缓慢,变量数据没法预览的解决办法
    gitignore设置失效的问题
    存储过程计算两个时间段的请假天数
    Vue 多层级目录拖动排序
    vue 动态插入渲染html
    Vue:eliment-ui el-tree动态加载更新
    Angular2+ iframe跨域调用父页面js
    Angular2.0+动态绑定html文本
    Angular2.0+开发 -实现部门树形结构
    Angular2.0+开发(1)-WebStorm配置及第一个Hello World
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4324919.html
Copyright © 2011-2022 走看看