uCOS-II系统中的任务就绪表
多任务操作系统的主要工作是为系统中处于就绪状态的任务分配CPU资源,其中涉及的两个关键是:判断哪些任务处于就绪状态、确定哪个任务应该马上得到执行,即任务调度。
1. 任务就绪表
任务就绪表记录了系统中所有处于就绪状态的任务,从代码上来看它就是一个类型为INT8U的数组OSRdyTbl[]。。系统中的任务为32个时,OSRdyTbl[]就有4个成员。每个成员占据8位,所以OSRdyTbl[]的每一个数据元素对应8个任务,这8个任务称为一个任务组。在就绪表中,以任务优先二进制位,当该位为1时表示对应的任务处于就绪状态,反之为非就绪状态。
考虑到查找效率,uCOS-II定义了一个INT8U的变量OSRdyGrp,该变量的每一位都对应OSRdyTbl[]的一个任务组(即数据的一个成员)。若某任务任务所对应的位置置为1,否则为0。
举例:OSRdyGrp=00001011,那么就意味着OSRdyTbl[0]、OSRdyTbl[1]、OSRdyTbl[3]中有就绪的任务。由图可知,uCOS-II最多可以管理8 * 8 = 64个任务。
任务就绪表是以任务的优先级从低到高排序的,那么想要根据任务的优先级来找到该任务所处于就绪表中位置就轻而易举了:
由于系统至多支持64个任务,所以优先级至多也就到63,即二进制的00111111,只占据低6位,每一个OSRdyTbl[]元素只是占据8,所以只需要用3个二进制位即可表示这8位中的哪一位为1,同理,高3位用于表示至多8个OSRdyTbl[]元素的哪一个元素。即:优先级的高3位二进制位(D5、D4、D3)指明O即:优先级的高3位二进制位(D5、D4、D3)指明OSRdyTbl[]的数组下标n,低3位(D2、D1、D0)指明OSRdyTbl[n]的哪一位数据位。另外,确定OSRdyTbl[]的下标n,也就意味着OSRdyGrp的具体数据位了。
举例:某任务的优先级prio=24,问该任务落在就绪表中的哪一位?
24的二进制位为00011000,D5、D4、D3位011,即OSRdyTbl[]的下标为3,D2、D1、D0为0,即优先级prio=24的任务在OSRdyTbl[0]的第0位。
2. 操作任务就绪表
uCOS-II系统对任务就绪表的操作无非:登记就绪,注销就绪和从就绪表中的所有就绪任务取出最高优先级的任务的任务控制块(TCB)。
2.1 登记就绪
当系统中的某个任务处于就绪状态时,系统会将该任务登记在任务就绪表中,即在该任务的优先级的在就绪表的对应位置1,uCOS-II的实现代码为:
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[y] |= ptcb->OSTCBBitX;
ptcb->OSTCBY的值为:
#if OS_LOWEST_PRIO <= 63
ptcb->OSTCBY = (INT8U)(prio >> 3);
ptcb->OSTCBX = (INT8U)(prio & 0x07);
ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);
//...
如上4个变量是任务与就绪表关联的关键,它们被保存在任务的控制块中(TCB),其中ptcb->OSTCBY等于任务优先级的高3位(D5、D4、D3),即为OSRdyGrp、OSRdyTbl[]的数组下标。ptcb->OSTCBX等于任务优先级的低3位(D2、D1、D0)。(ptcb->OSTCBBitY和ptcb->OSTCBBitX也是为查询就绪表高效而设置的)
所以”OSRdyGrp |= ptcb->OSTCBBitY”是置一OSRdyGrp对应OSRdyTbl[]下标值的位,”OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX”是置一OSRdyTbl[]对应成员的位。
2.2 注销就绪
注销就绪即在该任务的优先级的在就绪表的对应位清零,uCOS-II的实现代码为:
INT8U y;
y = OSTCBCur->OSTCBY;
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; //清零OSRdyTbl[y]对应的位
if (OSRdyTbl[y] == 0x00) //若此时OSRdyTbl[y]已经为0,即所在就绪组已经没有任务就绪
{OSRdyGrp &= ~OSTCBCur->OSTCBBitY; //将OSRdyGrp对应的位清零
}
2.3 从就绪表中查找优先级最高的任务
找出优先级最高的任务,要实现不是很简单?只要一个循环遍历接可以了。但是uCOS-II是一个RTOS,对于RTOS来说,系统上的每一个操作所耗费的时间必须是一个常量,如果是去遍历就绪表找出目标任务,也是意味着整个操作所耗时间不一。
uCOS-II系统对目标的查找操作,基本都是采用哈希算法实现的(前面写了一篇哈希表的示例http://blog.csdn.net/qq_29344757/article/details/69855658,感兴趣者可以阅读,粗略了解哈希思想)。
INT8U y;
y = OSUnMapTbl[OSRdyGrp]; //最高优先级所在的任务组
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); //最高优先级任务所在的任务组的位INT8U const OSUnMapTbl[256] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
};
找出目标任务,即找出目标任务的优先级(uCOS-II中每一个优先级对应一个任务)。
任务的优先级prio = (任务组Y) << 3 | 任务组的上哪一位X
所以要找出优先级最高的任务,分两步:
(1) 确定任务组(OSRdyTbl[]的下标)Y:找出OSRedyGrp中为1的最低位Y
(2) 确定任务组中的位X:找出任务组中OSRdyTbl[x]中为1的最低位X
综上,找出目标任务的核心算法在于确定某数值为1的最低位,uCOS-II的具体实现是,借助OSUnMapTbl[]数组:
例如0x06(00000110),为1的最低位是Bit[1],那么OSUnMapTbl[0x06]=1;0x20(00100000),为1的最低位是Bit[5],即OSUnMapTbl[0x20]=5。
直接通过数组的下标取值就可以取得目标值,这就是哈希算法。哈希算法虽然消耗多了点空间,但是效率大大提高,在uCOS-II中多处使用这种思想。
uCOS-II系统中的任务就绪表相关推荐
- μCOS-II中的任务就绪表及任务调度
μCOS-II中任务就绪表及任务调度的操作以及OSUnMapTbl[]优先级的计算 在整理这个学期老师发的ppt中想起来了这个知识点,感觉很重要,当时也是迷糊了很久才搞懂: 主要写一些任务就绪表的结构 ...
- IAR中移植UCOS II系统以及sourceInsight 使用
ucos 学习笔记 1 sourceInsight 使用 CSDN参考链接 新建工程 第一步:project中new project 第二步:在高亮部分输入工程的地址,工程文件夹与IAR工程文件夹放在 ...
- ucosiii系统中的任务管理
前言: 多任务操作系统最重要的就是对任务进行管理,包括任务的创建,挂起,删除和调度等,因此对于ucosiii操作系统中任务管理的理解就显得尤为重要了. 分几个部分介绍: 1:任务状态 ...
- ucos II任务管理之一:挂起任务
Ucos II 任务管理之一 创建好了任务之后,就已经初步跨进了ucos II 的编程了.随着进一步的编程,发现学会创建了任务还是不够的. 在我的项目里,需要实现485通信功能,我创建了任务1用于串口 ...
- 基于STM32的简易示波器的UCOS II嵌入式实时操作系统实现
基于STM32的简易示波器的UCOS II嵌入式实时操作系统实现 在基于STM32的示波器的实现的基础上,在STM32上移植UCOS II嵌入式实时操作系统. 在UCOS II操作系统中将各个功能分发 ...
- UCOSIII---任务就绪表及任务调度和切换
多任务操作系统的主要工作是为系统中处于就绪状态的任务分配CPU资源,其中涉及的两个关键是:判断哪些任务处于就绪状态.确定哪个任务应该马上得到执行,即任务调度. 任务就绪表 在UCOSIII中,所有已经 ...
- 51单片机中使用ucos ii的优缺点(好文)
摘要:近年来,在单片机系统中嵌入操作系统已经成为人们越来越关心的一个话题.本文通过对一种源码公开的嵌入式实时操作系统ucos ii的分析,以51系列单片机为例,阐述了在单片机中使用该嵌入式操作系统的优 ...
- BI 系统中为什么会有很多冗余的快照表?
前言 观察一些大型用户的BI系统,经常会发现数据仓库中有很多快照表.如某交易业务的BI系统,交易明细表很大,被按月存储成多个分段表.还有一些相对不太大的表,计算时要和交易明细表关联,比如客户表.雇员表 ...
- BI 系统中为什么会有很多快照表?
观察一些大型用户的BI系统,经常会发现数据仓库中有很多快照表.如某交易业务的BI系统,交易明细表很大,被按月存储成多个分段表.还有一些相对不太大的表,计算时要和交易明细表关联,比如客户表.雇员表.商品 ...
最新文章
- 皮一皮:碰上一个说倒装句的直男怎么办...
- 19 个 JavaScript 常用的简写技术
- -bash: jps: command not found
- 查看系统是否安装了ftp服务器上,linux查看是否安装了ftp服务器上
- 家里wifi网速越来越慢_家里WIFI越用越卡?教你3个小方法,彻底解决网速慢、不稳定等问题...
- Ubuntu16.04装机2:安装CUDA10.2+cuDNN7.6.5
- 两个正数相乘为什么结果是负数
- java+ssh实现级联下拉列表(以行业大类和详细类为例)
- SVN 分支合并到主干
- 模块七:mixer模块
- 谷歌浏览器无法安装扩展程序 – chrome无法添加crx插件的解决方法
- 虚拟贝司拓展音源-Toontrack Acoustic EBX
- HTML5排序罗马数字,HTML5 罗马数字时钟
- 云原生是什么?细数云原生的5大特征
- 联发科、联芯TD合作后期走势分析
- NeuroSLAM 论文解析
- 前端禁用中文半角输入法
- H3C交换机密码加密解密
- str.indexOf()的用法
- 使用 Office 365 PowerShell 管理用户帐户和许可证(六)