ucos-ii核心算法分析(转)
μC/OS-Ⅱ是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。其 内核提供任务调度与管理、时间管理、任务间同步与通信、内存管理和中断服务等功能。适合小型控制系统,具有执行效率高、占用空间小、实时性能优良和可扩展 性强等特点,最小内核可编译至2KB。μC/OS-Ⅱ为何如此高效呢?我们从它的核心算法——任务调度算法开始分析。
2.1任务调度算法分析
操作系统的实时性主要体现在:当优先级高的任务要求工作时,操作系统要以尽快的时间将此任务调度到CPU执行。这里所花费的时间主要包括两部分:查找最高 优先级任务和任务上下文切换。其中,任务上下文切换时间是和处理器相关的,操作系统无法控制。我们主要分析uC/OS-ii如何查找最高优先级任务的。
因为任务较少,uC/OS-II采用单一优先级,这为算法的实现提供了很大的方便在uC/OS-II中,优先级可以作为任务的标识(当然要在任务存在的情况下,是通过一个指针数组实现的)来用。
调度算法主要基于分级查询。考虑到任务数目<64,可以用6bit来表示,分为高3位和低三位。uC/OS-II将优先级进行分组,按高三位进行 分组,可得8个(最多)优先级数组(000-111);每个优先级的在数组中的位置由其低三位表示。在源码中,高三位用带Y后缀的变量表示,而低三位用带 X后缀的变量表示。这样建立了1个变量OSRdyGrp(INT8U,8bit,每个bit代表一组)和1个数组OSRdyTbl[8](INT8U,每 组8bit,每个bit代表一个优先级)。这样形成了的二级查询,先选组,再选组内偏移。
其中,OSRdyGrp每一bit置1,表示该组有任务就绪。(第0~7组)。其示意图见下图:
我们举一个例子,看一下如果优先级为22的任务就绪,我们如何对优先级数组进行操作。用二进制表示为0b00010110,其高3位为010,为2,则将 第2组,也就是OSRdyGrp的第2位置1。其低3位为110,为6,则将其OSRdyTbl[2]的第6位置1。编程实现时,可以通过对1进行移位, 再进行 或 操作来实现。但考虑到移位时间不确定,uC/OS-II选择建立了一个表OSMapTbl[8],
如下。
表 T3.1 OSMapTbl[]的值
Index Bit Mask (Binary)
0 00000001
1 00000010
2 00000100
3 00001000
4 00010000
5 00100000
6 01000000
7 10000000
这样,当一个任务就绪时,我们这样处理。其中Prio是任务的优先级。
程序清单 L3.5 使任务进入就绪态
OSRdyGrp |= OSMapTbl[prio >> 3];
OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];
而当任务被挂起或删除时,我们这样处理:
程序清单 L3.6 从就绪表中删除一个任务
if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)
OSRdyGrp &= ~OSMapTbl[prio >> 3];
表建立了,如何查询最高优先级呢?这是很关键的。因为优先级的值越小,优先级越高,我们只需从OSRdyGrp中找到最低位置1的的那一组,再从该组中,查找最低位置1的位置,组合一下,就得到了最高的优先级。
同样,这可以通过一个while循环进行判断,但是,时间也是不确定的。所以,uC/OS-II又建立了一张表OSUnMapTbl,这张表有点大,其下标值范围为0x00-0xff,值域为0-7。
这样,其查询流程为:
程序清单 L3.7 找出进入就绪态的优先级最高的任务
y = OSUnMapTbl[OSRdyGrp];
x = OSUnMapTbl[OSRdyTbl[y]];
prio = (y << 3) + x;
2.2事件处理算法分析
在uC/OS-II中,事件可以是信号量、邮箱或者消息队列等,并用统一的结构体OS_EVENT表示。
我们先看一下OS_EVENT的组成:
typedef struct {
INT8U OSEventType;
INT8U OSEventGrp;
INT16U OSEventCnt;
void *OSEventPtr;
INT8U OSEventTbl[OS_EVENT_TBL_SIZE];
} OS_EVENT;
注意其中两个变量:OSEventGrp和OSEventTbl[],是不是觉得有点象OSRdyGrp和OSRdyTbl[]。那它们的处理算法是不是 也一样呢?你猜对了,这里关于事件的各种操作(如pend、post、timeout、wait等)的算法和任务调度算法如出一辙。当然也用到了 OSUnMapTb[]和OSMapTbl[]。只是任务就绪时(等待CPU时)插入就绪表,而当任务需要等待事件时要插入EVENT等待列表,反之亦 同。
2.3 小结
这两个算法(1种算法)是os_core.c中最主要的算法。此算法执行时间恒定,不随任务数目的多少变化(但不能超过64个任务),保证了其实时性。这 里,顺便对uC/OS-ii的设计哲学进行臆测:那就是“以空间换时间”,也就是表格table (array)。这可以从uC/OS-II中存在众多的全局变量,如OSEventTabl[],OSRdyTbl[],OSTCBTbl[](这样避免 了动态初始化)看出,也可以从上面介绍的任务调度算法中看出(核心数据结构为数组,并建立了两张表OSUnMapTbl和OSMapTbl)。
来自http://www.yuanma.org/data/2007/0207/article_2249.htm
ucos-ii核心算法分析(转)的更多相关文章
- DE1-SOC开发板上搭建NIOS II处理器运行UCOS II
DE1-SOC开发板上搭建NIOS II处理器运行UCOS II 今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...
- ucos ii 46个系统API函数解析
源: ucos ii 46个系统API函数解析
- FreeRTOS 和uCOS II的简单比较
转载:http://www.viewtool.com/bbs/forum.php?mod=viewthread&tid=114 这是两种RTOS, 现在粗略比较一下. freeRTOS比uCO ...
- ucos ii 百度官方介绍
μC/OS II(Micro-Controller Operating System Two)是一个可以基于ROM运行的.可裁剪的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处 ...
- 嵌入式无操作系统下管理内存和队列(类UCOS II思想)
例子:存储日志,最多存128条,每条最大1MB. 内存方面 因为嵌入式不适合用动态内存,会产生碎片.这里我们用 u8 data[LOG_SIZE];开辟固定128MB的内存区,再对其分为128个1MB ...
- 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II
SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...
- DES加密:8051实现(C语言) & FPGA实现(VHDL+NIOS II)
本文将利用C语言和VHDL语言分别实现DES加密,并在8051和FPGA上测试. 终于有机会阅读<深入浅出密码学一书>,趁此机会深入研究了DES加密的思想与实现.本文将分为两部分,第一部分 ...
- 【原创】uC/OS II 任务切换原理
今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引 ...
- ucos串口通讯模块设计
在嵌入式应用中,使用RTOS的主要原因是为了提高系统的可靠性,其次是提高开发效率.缩短开发周期.uCOS-II是一个占先式实时多任务内核,使用对象是嵌入式系统,对源代码适当裁减,很容易移植到8~32位 ...
随机推荐
- UVa 11552 Fewest Flops (DP)
题意:给一个字符串,把它分为k块,每一块里面的字母可以任意的排序.最终字符串, 连续的一样的字母算作一个chunk,问总chunks最少是多少? 析:dp[i][j] 表示第 i 个块,第 j 位在末 ...
- GridView 中RowDataBound 获取绑定后的各个字段的值
protected void GridView_dept_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType ...
- LeetCode: 383 Ransom Note(easy)
题目: Given an arbitrary ransom note string and another string containing letters from all the magazin ...
- 30个Python物联网小实验5:光线感应灯
30个Python物联网小实验5:光线感应灯 光线传感器 光线变化执行函数 光线状态执行函数 30个Python物联网小实验5:光线感应灯 光线传感器 可以检测周围环境的亮度: 方向性较好,感知特定方 ...
- ue4 修改3dui内容
修改text内容1 修改text内容2 上面的方法是对外公开某个控件,然后再蓝图中直接改控件内容 另一种更好的方法时,在控件上新建public变量,控件绑定到这个变量上,由蓝图直接改变这个public ...
- Jmeter接口自动化参数化 (转自软件测试部落)
测试场景: 有个查询城市(大概一百个 )天气预报的接口(需求参考第一课),需要根据不同的citycode,去查询对应城市的天气预报,这种接口该如何去测试呢? 分析需求: 不管是功能测试需求,还是接口测 ...
- 剑指Offer的学习笔记(C#篇)-- 求1+2+3+...+n
题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 一 . 直接解题吧 芽儿呦,突然觉得,我不说! ...
- linux grep (转)
常用用法 [root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename 选项与参数: -a :将 binary 文件以 text 文件的方式搜 ...
- 长春理工大学第十四届程序设计竞赛(重现赛)L.Homework Stream
链接:https://ac.nowcoder.com/acm/contest/912/L 题意: 作为大珩班尖子生,小r每天有很多作业要完成,例如工图.工图和工图. 很显然,做作业是要有顺序的.作业之 ...
- Uva11134
#include<bits/stdc++.h> #define inf 0x3f3f3f3f ; using namespace std; int n; struct rook{ int ...