首页 > 嵌入式软件 > Uc/os II

μC/OS-II 是一个源代码公开、可移植、可裁剪的实时多任务操作系统,具有稳定可靠、实时性好等优点,是专门针对微处理器和微控制器设计的实时内核,它的内核可以做到很小,很适合在单片机系统上移植。移植了μC/OS-II 的嵌入式系统可以使各个任务独立工作,互不干涉,很容易实现准时而且无误执行,使实时应用程序的设计和扩展变得容易,使应用程序的设计过程大为减化。在这个星期内,我通过对禁用了邮箱、队列、文件系统的最简单的μCOS-ii操作系统进行了学习,现将收获分享如下。

本文引用地址: http://embed.21ic.com/software/ucos/201705/45796.html

μCOS-ii运行过程

μCOS-ii的主函数不到十行代码,但是因为其高度的结构化以及良好的函数封装,对其运行过程的了解对于学习μCOS-ii的编程思想以及设计思路具有重大的意义。

我通过将μCOS-ii代码移植到SST89V564RD单片机中,并且利用TI公司的温度传感器TMP124创建了两个任务:读TMP122数据、向串口发送读取的温度值。要求两个任务轮流执行,读TMP122的优先级高于向串口发送数据的优先级。

1 系统初始化

在μCOS-ii中,系统初始化可以分为全局变量初始化、创建空闲任务任务、堆栈初始化、任务控制块初始化等部分内容。

全局变量初始化。由于μCOS-ii操作系统中定义了众多与系统参数有关的全局变量,因此全局变量的初始化包含众多内容。这些系统参数的初始化大都被封装 在OSInit()函数中。尤其要注意的是,在OSInit函数中,OSRunning变量一定要被定义成FALSE,否则在OSStart函数中,系统 无法启动创建的任务,系统因此变成了一个有始有终的函数,创建的任务永远得不到执行。在实际运行过程中表现为主函数运行一次之后,系统不再运行。另外需要 注意的是OSTCBCur、OSTCBList等这几个变量需要定义为(OS_TCB DT_XDATA *)0的类型。因为这些变量是指向结构体TCB(Task Control Block)的指针,并不是数字〇。

创建空闲任务。创建空闲任务包括进入临界区、任务堆栈初始化、TCB初始化、退出临界区等内容,大部分是一些简单的赋值操作,比较简单,不再赘述。其中OSRdyGrp |= ptcb->OSTCBBitY; OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;这两句话要尽量看懂。因为这两句话牵扯到后面OSUnMapTbl这个矩阵的理解。其含义为一旦任务就绪队列中有"1"(即对应的任务就绪),则相应的任务组OSRdyGrp 相应的位变成1,OSRdyTbl中的相应的位也变成1.

堆栈初始化以及任务控制块初始化。比较容易理解,简单的赋值操作。不过在堆栈初始化中的ppdata = ppdata;opt = opt; 以及任务控制块初始化中的pext= pext; stk_size= stk_size;pbos=pbos;opt=opt; id= id;这些语句刚开始的时候很令人费解。其实这些是防止编译器不断的报warning,以免影响正常的调试的。

2 任务创建

同上述创建空任务大体雷同。需要注意的是此时操作系统的OSRunning变量还是处于FALSE状态,因此创建任务的过程中,操作系统并没有开始运行。 这就是为什么操作系统在开始运行的时候不是选择第一个创建的任务开始运行,而是从所有的任务里面选择优先级最高的运行的原因。

3 任务调度

任务调度是从OSStart函数开始的。具体包括OSStart、OsStartHighRdy、Task1~n、OSTimeDlyHMSM、OSSched等函数,其中任务交换是在汇编语言文件的OS_TASK_SW函数中运行的。

OsStart在整个系统运行的过程中只会运行一次。在系统创建任务之后运行。主要目的是从任务就绪表中挑选出优先级最高的任务,并开始运行优先级最高的任务。

OsStartHighRdy为asm文件中的一部分。主要是堆栈的操作。目的是要把高优先级任务的任务堆栈复制到寄存器中,为即将开始的运行最高优先级的任务做好准备。

Task1~n。Task为一个无限循环函数。虽然是无限循环函数,但是与平常前后台系统中的无限循环具有区别。因为μCOS-ii操作系统并不是一个像 Linux那样的时间片轮流处理的操作系统,它仅仅是一个处理完一部分内容之后再去处理另一部分内容的实时操作系统。这就要求在每一个任务的每一个无限循 环中都要加一个调用OSSched函数的函数。

OSTimeDlyHMSM主要是为用户提供一个良好的借口,将用户输入的时、分、秒、毫秒这四个数据转换成系统的滴答数,然后调用OSTimeDly实 现。在OSTimeDly中调用OSSched,确保系统的实时性。OSSched函数结构也类似于OSStart,主要是计算出任务就绪表中最高优先级 的任务,通过OS_TASK_SW中的堆栈的操作实现任务的交换。

μCOS-ii查找最高优先级算法的实现

指导思想:以空间换时间。

在查看源代码的过程中,最令人费解的或许就是OSUnMapTbl这个矩阵了。现将此矩阵复制如下:

INT8U const DT_XDATA OSUnMapTbl[] = {

0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0

};

在了解这个矩阵的工作原理之前,我们有必要了解一下几个变量的含义:

OSRdyGrp 是一个8位的unsigned char型数。由于该μCOS-ii系统最多允许prio为63,也就是说最多允许有64个优先级。64个优先级被分成了八组,每组有八个优先级。如果有 任何一组中的任务进入了就绪状态,则该组所对应的位变为1。比如优先级为4,23,56的任务同时进入了就绪态,则对应第0,2,7组中有任务进入了就绪 态,则此时OSRdyGrp 应为 10000101。

OSRdyTbl为一个有8个元素的8位数的数组,分别为OSRdyTbl[0]...OSRdyTbl[7]。从OSRdyTbl[0]到 OSRdyTbl[7]的每一位数对应相应优先级的任务是不是进入了就绪态。还是上面的例子,假如优先级为4,23,56的任务进入了就绪态,则 OSRdyTbl[0]的第4位,OSRdyTbl[2]的第7位,OSRdyTbl[7]的第0位变成1,其他的位仍然保持零。

介绍完两个变量之后,就可以很容易理解这个矩阵的作用了。矩阵的第i个数字表示用二进制表示的i中1所出现的最小位数。比如对于矩阵的第48个数字,48用二进制表示为00110000,在第4位以及第5位中出现了1,故去最小值,则OSUnMapTbl[48]=4 。也就是说,通过查这个矩阵得到的是最小的出现1的位数。假如对于OSRdyGrp 来说,在OSRdyGrp 等于48的情况下,意味着第四组与第五组中有任务处于就绪状态,则通过此表可以得出最高优先级的任务在第四组中。假如对于OSRdyTbl来 说,OSRdyTbl[4]表示第四组中每一个元素是不是处于就绪态。还是拿48来打比方,假如OSRdyTbl[4]等于48,有48用二进制表示为 00110000可得第四位与第五位中有两个任务处于就绪态,此时查询OSUnMapTbl[48]=4可得优先级最高的任务处于第四位上。由此很容易理 解这两行代码:

y= OSUnMapTbl[OSRdyGrp];

x = OSUnMapTbl[OSRdyTbl[y]];

因此得到的y为最高优先级所在的组号。X为最高优先级所在的组中最高优先级所在的组的组号。由于每组有8个成员,对于y组第x个来说,优先级自然是 8*y+x 。由此得到了最高优先级。下面的代码不难理解。

OSPrioHighRdy = (INT8U)((y << 3) + x);

此外,因为这个矩阵无论在何种情况下,都是不变的,因此个人认为原μCOS-ii系统中定义为DT_XDATA完全没有必要,只是增加了系统的开销。因此我尝试将此变量类型改成DT_CODE ,经过运行TMP124的尝试,系统运行几十分钟后仍然正常。因此得出了此处可以改进的建议。而且改进之后系统的占用xdata从600多字节减少到400多字节,系统资源占用减少很明显。

可能编写μCOS-ii的工程师为了提高可移植性,将OSUnMapTbl定义为DT_XDATA吧。仅仅猜测而已。

换一批

延伸阅读

[猎聘集] 这些技术精湛的开发工程师是如何在面试中被刷掉的...

这些技术精湛的开发工程师是如何在面试中被刷掉的...

作为一个程序员,如果没有收到心仪的工作offer,你是不是会对自己失去信心?对接创业者和程序员的网站coderfit.com 的创始人Iwan认为你无须担心。他分享了四个“恐怖故事”,告诉我们——那些厉害的工程师被拒绝的原因,很......

关键字:开发工程师 面试

[新鲜事] 矿难了显卡就会降价?你可别做梦了

矿难了显卡就会降价?你可别做梦了

此矿难非彼矿难,我们今天说的矿难是因为虚拟货币价格暴跌导致“矿业”集体崩盘的一种现象。......

关键字:显卡 矿难 比特币

[破谣言] 如果电脑技术最初是中国人发明的,那现在编程是不是就是中文的?

如果电脑技术最初是中国人发明的,那现在编程是不是就是中文的?

现在的编程代码全部都是英文,有没有可能有一天编程代码全是中文呢?而且如果当年计算机由中国人发明,编程代码是否就是以中文为主呢?......

关键字:编程 中文 英文

[疯狂史] 一位英语不及格的美国电子工程师是如何成为业界顶级技术大牛

一位英语不及格的美国电子工程师是如何成为业界顶级技术大牛

看了这个题目,大概没有人会相信我谈的是一个地地道道的美国工程师。当我们国内的年轻工程师从小学就开始的十多年,为英语耽误了大量美好的时光的时候, 就有这么一位超级工程师大牛,正宗的美国人,凭借他的智慧和“玩”法,在测试测量行业获得了令人瞩目的......

关键字:美国工程师
条评论

我 要 评 论

网友评论

大家都爱看

  • 扇出型晶圆级封装的优势和挑战!

    我们有能力创造一些能保持前代性能并且更好更小的电子设备,例如今天的可穿戴设备、智能手机或平板电脑,这是由于很多因素超过摩尔定律而快速发展,从而能够从底层的嵌入组件发展到今天把它们封…

    2018-03-29
  • Xilinx推出革命性的新型自适应计算产品

    自适应和智能计算的全球领先企业赛灵思公司(Xilinx, Inc.,(NASDAQ:XLNX)),近日宣布推出一款超越FPGA功能的突破性新型产品,名为ACAP(Adaptive Compute Acceleration Platform,自适应计算加速…

    2018-03-20
  • 赛普拉斯为树莓派3 B+ IoT单板计算机提供强大稳定的无

    先进嵌入式系统解决方案的领导者赛普拉斯(纳斯达克代码:CY)近日宣布其Wi-Fi&#174;和蓝牙&#174;combo解决方案为全新的树莓派 3 B+(Raspberry Pi 3Model B+)IoT单板计算机提供强大稳定的无线连接…

    2018-03-20
  • 观看直播领红包,SEED-A10加速卡助力人工智能

    随着云服务器、云计算的发展,大家对硬件加速的需求越来越多,但是随着设备功耗的上升、性能需求越来越高,常规加速设备以及开始不能满足需求,因此FPGA逐渐在硬件加速中找到了自己的位置,而艾…

    2018-03-19
  • 特朗普:博通不得以任何形式收购高通

    白宫周一(3月12日)晚发出声明,川普(特朗普)总统出于“国家安全”考量、禁止新加坡博通公司(Broadcom)收购美国高通公司(Qualcomm)。

    2018-03-14