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,任务就绪表的改变的更多相关文章

  1. ucos任务调度原理及任务就绪表

    之前我们说到,系统在运行的时候会直接依靠任务的优先级来找到任务的控制块从而实现任务的调用切换等功能,那么接下来的问题就是,系统是怎么找到并确定某一个特定的最高优先级任务并确定他的优先级的呢 为了解决这 ...

  2. 案例:8,64,256都是2的阶次方数(8是2的3次方),用Java编写程序来判断一个整数是不是2的阶次方数。

     如果一个数是2的阶次方数,则它的二进制数的首位一般是1,后面全为0.比如8:1000,64:1000000,如果将这个数减1后再作与&运算,则应该全为0,(x&(x-1)==0&am ...

  3. C# 32位程序在64位系统下注册表操作

    在64位的Windows操作系统中,为了兼容32位程序的运行,64位的Windows操作系统采用重定向机制.目的是为了能让32位程序在64位的操作系统不仅能操作关键文件文夹和关键的注册表并且又要避免与 ...

  4. Windows:32位程序运行在64位系统上注册表会重定向

    参考资料 微软注册表英文文档 StackOverflow社区回答 1.注册表位置 64bit系统(Windows Server 2008 R2只有64bit系统)的注册表分32 位注册表项和64位注册 ...

  5. 64位系统访问注册表SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

    public int ChecNonkWoW64() { try { ; string subKey = @"SOFTWARE\Microsoft\Windows\CurrentVersio ...

  6. 嵌入式实时操作系统μCOS原理与实践任务控制与时间的解析

    /*************************************************************************************************** ...

  7. ucos互斥信号量解决优先级反转问题

    在可剥夺性的内核中,当任务以独占方式使用共享资源的时候,会出现低优先级任务高于高优先级任务运行的情况,这种情况叫做优先级反转,对于实时操作系统而言,这是一场灾难,下面我们来说说优先级反转的典型环境. ...

  8. ucos实时操作系统学习笔记——内核结构和任务创建

    对于ucos实时操作系统,邵贝贝的那本书已经写得很详细了,我因为之前不深的研究过ucos,所以在这里做一个笔记,写一些个人对该操作系统的理解,仅仅是个人理解,如果有人看到这边随笔有不对的地方,望给我指 ...

  9. ucos 学习

    1.UCOSII 早期版本只支持 64 个任务,但是从 2.80 版本开始,支持任务数提高到 255 个,不过对我们来说一般 64 个任务都是足够多了,一般很难用到这么多个任务. UCOSII 保留了 ...

随机推荐

  1. mysql 货币字段类型的存储

    loat类型是可以存浮点数(即小数类型),但是float有个坏处,当你给定的数据是整数的时候,那么它就以整数给你处理.这样我们在存取货币值的时候自然遇到问题,我的default值为:0.00而实际存储 ...

  2. hack,不同的IE浏览器

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. java 类与对象

    class XiyoujiRenwu { float height,weight; String head, ear; void speak(String s) { System.out.printl ...

  4. 使用RPM包安装、配置和拆卸MySQL

    通过rpm包安装.配置及卸载mysql的详细过程. 以MySQL-server-4.0.14-0.i386.rpm为例,放在/usr/src目录下 cd /usr/src rpm -ivh MySQL ...

  5. Linux学习 -- Shell编程 -- 字符处理命令

    sort排序命令 sort [选项] 文件名 -f 忽略大小m写 -n 按数值型,默认字符串型 -r 反向 -t 指定分隔符 -k n[,m] 指定字段范围,默认行尾 eg. sort -n -t & ...

  6. material design 的android开源代码整理

    material design 的android开源代码整理 1 android (material design 效果的代码库) 地址请点击:MaterialDesignLibrary 效果: 2 ...

  7. android代码实现免提功能

    初始化AudioManager: private static AudioManager audioManager; 实现免提功能方法 protected void setSpeekModle() { ...

  8. php 文件夹遍历俩种对比

    configu.phpindex.php新建文件夹 D:\xampp\htdocs\1test\use\useversion/configu.phpD:\xampp\htdocs\1test\use\ ...

  9. php获取Linux网卡信息

    $data = exec("/sbin/ifconfig"); var_dump($data); 注意:有时候这种方式获取不到,应该是权限问题 在/var/rootP文件中添加ro ...

  10. elisp

    cons cell? 构建内存对象! 通过寄存器的基地址car和偏移地址cdr来--寻址内存对象,我是这样理解的. http://wiki.dourok.info/doku.php/%E5%B7%A5 ...