第10章 μCOS 升级到 μCOS-II
- 格式:pdf
- 大小:43.34 KB
- 文档页数:14
uC/OS-II简介u C / O S 是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。
μC/OS-II 的前身是μC/OS,最早出自于1992 年美国嵌入式系统专家Jean brosse 在《嵌入式系统编程》杂志的5 月和6 月刊上刊登的文章连载,并把μC/OS 的源码发布在该杂志的B B S 上。
μC/OS 和μC/OS-II 是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。
CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。
用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II 嵌人到开发的产品中。
μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至 2KB 。
μC/OS-II 已经移植到了几乎所有知名的CPU 上。
严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。
没有提供输入输出管理,文件系统,网络等额外的服务。
但由于uC/OS-II 良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。
uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。
任务管理uC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,改任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,改任务负责统计当前cpu的利用率。
μCOS-II 中就绪表查表算法及OSUnMapTbl 表格的由来OSUnMapTbl 的由来为什么要采用这样的一个表格呢?μC/OS-II 是一个实时系统,在操作时间上它的所有操作都必须是常量,用通俗的话来说:“系统的任何操作都必须具有时间上的承诺”,而循环程序是不能达到这个要求的,所以才采取了这样的一个查表方法。
表格中的数据是如何得到的呢?其实这些数据就是0~255数据字节从低位到高位中(即从左到右)第一个被置1的位的位置。
具体过程如下:(大家可以对照源码中OSUnMapTbl 数组)…OSUnMapTbl[0] = 0…OSUnMapTbl[1] = 0…OSUnMapTbl[2] = 1…OSUnMapTbl[3] = 0…OSUnMapTbl[4] = 2…OSUnMapTbl[5] = 0…OSUnMapTbl[6] = 1…OSUnMapTbl[7] = 0…OSUnMapTbl[8] = 3……Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 0 0 0x00 没有被置1的位,故位置为0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 0 1 0x01 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 1 0 0x02 首个被置1的位置为bit1Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 0 1 1 0x03 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 0 0 0x04 首个被置1的位置为bit2Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 0 1 0x05 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 1 0 0x06 首个被置1的位置为bit1Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 0 1 1 1 0x07 首个被置1的位置为bit0Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 0 0 0 0 1 0 0 0 0x08 首个被置1的位置为bit3…OSUnMapTbl[15] = 0…OSUnMapTbl[16] = 4…OSUnMapTbl[31] = 5…OSUnMapTbl[47] = 4…OSUnMapTbl[63] = 6………OSUnMapTbl[240] = 4………OSUnMapTbl[255] = 0快速查表过程y = OSUnMapTbl[OSRdyGrp]; // 获得优先级别的D5,D4,D3位(即先找出是哪一组) x = OSUnMapTbl[OSRdyTbl[y]]; // 获得优先级的D2,D1,D0位(再从哪一组中找出是哪一位) prio = (y<<3) + x; // 获得就绪任务的优先级别 ① 首先将就绪任务组OSRdyGrp 用来在OSUnMapTbl[]中进行查表,找出OSRdyGrp 的位中首次置1位置,确定出当前就绪表中最高优先级是哪一组任务,即优先级的D5,D4,D3位。
第八章基于μC O S-I I的程序设计实例8.1 实例介绍为了使读者对μCOS-II操作系统有更深的理解,本章将介绍一个在STM32F103 处理器平台上使用μCOS-II实时操作系统的程序设计实例。
此实例使用英倍特公司提供的STM103V100评估板来实现一个简易温度计。
该实例使用STM103V100评估板自带的高灵敏度数字温度传感器来传送温度数据,根据实际采样周期的需要,安排了四种不同的采样方式。
采样的条件和周期可以通过键盘输入进行调节,采样得到的结果可以在评估板的液晶屏上同步显示,并通过串口将采样所得的结果送到上位机。
关于STM103V100评估板的更多内容超出本书范围,请读者参阅其它相关资料。
8.2 实例分析本节主要分析如何通过基于实时操作系统编程的方法实现整个系统的所有功能。
下面的内容将从任务划分开始,详细说明任务分析的过程。
8.2.1 实例任务划分为了更合理的将整个系统划分为不同任务,首先要明确一个好的实时系统应具备那些特点,即任务划分的基本原则是什么。
一般说来,任务划分的基本原则有以下几点:∙满足系统“实时性”:一般使用μCOS-II的嵌入式应用系统,对于响应时间要求很高,如果实时性得不到满足,系统会出现错误甚至导致难以挽回的故障。
因此在任务划分时,保证系统实时性是首要原则。
∙较少资源需求:多个任务协同运转,依靠操作系统的调度策略。
任务之间的同步,任务之间的通信,内存管理都需要消耗系统资源。
所以在任务划分时,尽量将使用同类资源的应用归入同一任务中,以减少操作系统调度时所消耗的资源。
∙合理的任务数:同一系统,任务划分的数目越多,每个任务的功能越简单,实现越容易,但任务数目的增多,加大了操作系统的调度负担,资源开销也随之加大;相反,如果任务划分的数目太少,会增加每个任务的复杂性,使任务设计难度加大。
最极端的情况,当系统任务数目减少到1时,也就失去了使用多任务操作系统的意义。
对一个具体的嵌入式应用系统进行任务划分时,可以有不同的任务划分方案。
uC/OS-II简介u C / O S 是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。
μC/OS-II 的前身是μC/OS,最早出自于1992 年美国嵌入式系统专家Jean brosse 在《嵌入式系统编程》杂志的5 月和6 月刊上刊登的文章连载,并把μC/OS 的源码发布在该杂志的B B S 上。
μC/OS 和μC/OS-II 是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。
CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。
用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌人到开发的产品中。
μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至2KB 。
μC/OS-II 已经移植到了几乎所有知名的CPU 上。
严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。
没有提供输入输出管理,文件系统,网络等额外的服务。
但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。
uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。
任务管理uC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,改任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,改任务负责统计当前cpu 的利用率。
μC/OSII安装调试指南前言μC/OS是一种体积小巧而实用的实时操作系统,由于其代码的开放性,近年来普遍受到人们的关注,许多人开始从事这一操作系统的学习及应用工作,但由于其文档较少,特别是关于安装和使用方面的指导性文章不够充足,使很多初学者,特别是刚刚接触嵌入式操作系统的朋友们不知道如何进行系统的安装及调试,为此我结合自己使用的切身体会,谈一谈它的安装及调试问题,希望对大家能起到一定的帮助作用。
使用的工具文中的开发工具及开发包如下:* 开发包:μC/OS2.51* 文中开发工具:Borland C 3.1所有相关工具在此处下载/folder/fetcxypq#其中开发工具是经过剪裁过的,只适用于此项目开发。
1.开发包的安装步骤* 1.1 下载软件包μCOS_V2.52.rar* 1.2 解压缩,建议解压到C盘根目录,这样文件将安装在C:\SOFTWARE,需要空间2.12MB * 1.3 安装完毕* 1.4 以默认安装路径为例,目录结构为:C: \SOFTWARE这是根目录,是所有软件相关的文件都放在这个目录下。
+ C:\SOFTWARE\BLOCKS子程序模块目录。
笔者将例子中μC/OS-II用到的与PC相关的函数模块编译以后放在这个目录下。
+ C:\SOFTWARE\HPLISTC这个目录中存放的是与范例HPLIST相关的文件(请看附录D,HPLISTC和TO)。
HPLIST.C 存放在C:\SOFTWARE\HPLISTC \SOΜRCE目录下。
DOS下的可执行文件(HPLIST.EXE)存放在C:\SOFTWARE\TO\EXE中。
+ C:\SOFTWARE\TO这个目录中存放的是和范例TO相关的文件(请看附录D,HPLISTC和TO)。
源文件TO.C 存放在C:\SOFTWARE\TO\SOΜRCE中,DOS下的可执行文件(TO.EXE)存放在 C:\SOFTWARE\TO\EXE中。
μC\OS-Ⅱ操作系统的任务切换作者:司新生来源:《数字技术与应用》2010年第06期摘要:μC\OS-Ⅱ操作系统是一个多任务占先式实时操作系统,每一个任务由三部分组成,任务控制块,任务的私有堆栈、任务代码。
每一个任务有一个决定其重要性的任务优先级,系统通过任务就绪表来进行任务的切换,就绪的任务在任务就绪表中设置其标志位,退出就绪的任务在就绪表中撤消其标志位。
任务的切换过程就是通过任务就绪表找到优先级最高的任务,保存原来运行任务的上下文到该任务的私有堆栈中,从最高优先级的任务私有堆栈中复制断点数据到工作寄存器中,pc指针指向该任务的代码段,实现了任务的切换。
关键词:操作系统任务控制块优先级任务切换1 μC\OS-Ⅱ的任务μC\OS-Ⅱ操作系统是一个多任务系统,它最多可以管理64个任务,但两个优先级最低的任务已被系统占用,一个是统计任务,一个是空闲任务。
空闲任务的作用为当操作系统没有其它任务执行时,就转入空闲任务而不使系统没事可做。
任务的结构每一个任务都有如下结构。
它由任务控制块TCB,任务代码,任务堆栈组成,多个任务控制块形成一个任务控制块链表。
每一个任务在创建时都被分配有一个任务优先级,优先级序号从0到63,优先级数值越大则表示优先级越低,最高的优先级是优先级序号为0的任务,最低的优先级是优先级为63的任务。
操作系统可以设定管理的任务数,在OS_CFG.H文件中,可以定义OS_LOWEST_PRIO值,该值最大为63。
每一个任务都有唯一的任务优先级,μC\OS-Ⅱ操作系统任务切换的关键就是该任务的优先级,操作系统总是运行处于就绪状态的最高优先级的任务。
创建任务主要完成四项任务,一是指出任务代码存放的地址,二是指明任务参数指针,也即任务参数地址,三是指明任务堆栈栈顶指针,在进行任务切换时保存或恢复与任务相关的寄存器的值,四是确定任务的优先级,优先级的高低决定了任务的紧迫性和重要性。
任务创建的代码如下。
中文4200字移植μC/OS-II这篇文章介绍如何将μC/OS-II移植到不同的处理器上。
所谓移植,就是使一个实时内核能在其他的微处理器上运行。
为了方便移植,大部分μC/OS-II的代码是用C语言编写的:但是,仍需要用C语言和汇编语言编写一些与处理器硬件相关的代码,这是因为μC/OS-II在读/写处理器寄存器时,只能通过汇编语言来实现。
由于μC/OS-II在设计前就已经考虑了可移植性,所以它的移植相对来说是比较容易的。
要使μC/OS-II正常运行,处理器必须满足以下要求:(1)处理器的C编译器能产生可重入型代码:(2) 处理器支持中断,并且能产生定时中断(通常为10-100Hz);(3) 用C语言就可以开关中断;(4) 处理器能支持一定数量的数据存储器的硬件堆栈;(5) 处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令;如果已经了解处理器和C编译器的技术细节,那么移植的工作是非常容易的,测试一个像μC/OS-II这样的实时内核其实并不复杂,甚至可以在没有任何应用程序下测试,换句话说,就是让内核自己测试自己。
有两种原因要这样做:第一,避免使本来就复杂的事情变的更加复杂化;第二,如果出现问题可以知道问题出在内核代码中,而不是应用程序中。
刚开始时,可以运行一些简单的任务和时钟节拍中断程序。
一旦多任务调度成功运行了,再添加应用程序的任务就更加容易了。
1.1 开发工具如前所述移植μC/OS-II需要标准的C交叉编译器,并且是针对所使用的CPU 的;因为它是一个可剥夺的内核,只能通过C编译器来产生可重入型代码。
同时C编译器还要支持汇编语言程序。
绝大部分为嵌入式系统设计的C编译器都包括汇编器、链接器、定位器。
链接器用来将不同的模块(编译过或汇编过的文件)链接成目标文件;定位器则允许将代码和数据放置在目标处理器的指定内存空间中。
所用的C编译器还提供另一种机制,能在C编译器中开中断和关中断。
第10章从 µC/OS 升级到 µC/OS-II本章描述如何从µC/OS 升级到 µC/OS-II。
如果已经将µC/OS移植到了某类微处理器上,移植µC/OS-II所要做的工作应当非常有限。
在多数情况下,用户能够在1个小时之内完成这项工作。
如果用户熟悉µC/OS的移植,可隔过本章前一部分直接参阅10.05节。
10.0 目录和文件用户首先会注意到的是目录的结构,主目录不再叫\SOFTWARE\uCOS。
而是叫\SOFTWARE\uCOS-II。
所有的µC/OS-II文件都应放在用户硬盘的\SOFTWARE\uCOS-II目录下。
面向不同的微处理器或微处理器的源代码一定是在以下两个或三个文件中:OS_CPU.H,OS_CPU_C.C,或许还有OS_CPU_A.ASM.。
汇编语言文件是可有可无的,因为有些C编译程序允许使用在线汇编代码,用户可以将这些汇编代码直接写在OS_CPU_C.C.中。
与微处理器有关的特殊代码,即与移植有关的代码,在 µC/OS 中是放在用微处理器名字命名的文件中的,例如,Intel 80x86的实模式(Real Mode),在大模式下编译(Large Modle)时,文件名为Ix86L.H,Ix86L_C.C,和Ix86L_A.ASM.。
表 L10.1在μC/OS-II中重新命名的文件.\SOFTWARE\uCOS\Ix86L \SOFTWARE\uCOS-II\Ix86LIx86L.H OS_CPU.H Ix86L_A.ASM OS_CPU_A.ASMIx86L_C.C OS_CPU_C.C 升级可以从这里开始:首先将µC/OS目录下的旧文件复制到µC/OS-II 的相应目录下,并改用新的文件名,这比重新建立一些新文件要容易许多。
表10.2给出来几个与移植有关的新旧文件名命名法的例子。
表 L10.2对不同微处理器从µC/OS到µC/OS-II,要重新命名的文件.\SOFTWARE\uCOS\I80251 \SOFTWARE\uCOS-II\I80251I80251.H OS_CPU.H I80251.C OS_CPU_C.C\SOFTWARE\uCOS\M680x0 \SOFTWARE\uCOS-II\M680x0 M680x0.H OS_CPU.HM680x0.C OS_CPU_C.C \SOFTWARE\uCOS\M68HC11 \SOFTWARE\uCOS-II\M68HC11M68HC11.H OS_CPU.H M68HC11.C OS_CPU_C.C\SOFTWARE\uCOS\Z80 \SOFTWARE\uCOS-II\Z80 Z80.H OS_CPU.HZ80_A.ASM OS_CPU_A.ASM Z80_C.C OS_CPU_C.C10.1INCLUDES.H用户应用程序中的INCLUDES.H文件要修改。
以80x86 实模式,在大模式下编译为例,用户要做如下修改:• 变目录名 µC/OS 为 µC/OS-II• 变文件名IX86L.H为OS_CPU.H• 变文件名UCOS.H为uCOS_II.H新旧文件如程序清单 L10.1和 L10.2所示10.2OS_CPU.HOS_CPU.H文件中有与微处理器类型及相应硬件有关的常数定义、宏定义和类型定义。
10.2.1与编译有关的数据类型s为了实现 µC/OS-II,用户应定义6个新的数据类型:INT8U、INT8S、INT16U、NT16S、INT32U、和INT32S。
这些数据类型有分别表示有符号和无符号8位、16位、32位整数。
在µC/OS中相应的数据类型分别定义为:UBYTE、BYTE、UWORD、WORD、ULONG和LONG。
用户所要做的仅仅是复制µC/OS中数类型并修改原来的UBYTE为INT8U,将BYTE为INT8S,将UWORD修改为INT16U等等,如程序清单 L10.3所示。
程序清单 L10.1 µC/OS 中的INCLUDES.H./**************************************************************** * INCLUDES.H*************************************************************** */#include <STDIO.H>#include <STRING.H>#include <CTYPE.H>#include <STDLIB.H>#include <CONIO.H>#include <DOS.H>#include "\SOFTWARE\UCOS\IX86L\IX86L.H"#include "OS_CFG.H"#include "\SOFTWARE\UCOS\SOURCE\UCOS.H"程序清单 L10.2 µC/OS-II 中的 INCLUDES.H./**************************************************************** * INCLUDES.H*************************************************************** */#include <STDIO.H>#include <STRING.H>#include <CTYPE.H>#include <STDLIB.H>#include <CONIO.H>#include <DOS.H>#include "\SOFTWARE\uCOS-II\IX86L\OS_CPU.H"#include "OS_CFG.H"#include "\SOFTWARE\uCOS-II\SOURCE\uCOS_II.H"程序清单 L10.3µC/OS到µC/OS-II 数据类型的修改./* uC/OS data types: */typedef unsigned char UBYTE; /* Unsigned 8 bit quantity */ typedef signed char BYTE; /* Signed 8 bit quantity */ typedef unsigned int UWORD; /* Unsigned 16 bit quantity */ typedef signed int WORD; /* Signed 16 bit quantity */ typedef unsigned long ULONG; /* Unsigned 32 bit quantity */ typedef signed long LONG; /* Signed 32 bit quantity *//* uC/OS-II data types */typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ typedef signed char INT8S; /* Signed 8 bit quantity */ typedef unsigned int INT16U; /* Unsigned 16 bit quantity */ typedef signed int INT16S; /* Signed 16 bit quantity */ typedef unsigned long INT32U; /* Unsigned 32 bit quantity */ typedef signed long INT32S; /* Signed 32 bit quantity */在µC/OS中,任务栈定义为类型OS_STK_TYPE,而在µC/OS-II中任务栈要定义类型OS_STK.,为了免于修改所有应用程序的文件,可以在OS_CPU.H中建立两个数据类型,以Intel 80x86 为例,如程序清单 L10.4所示。
程序清单 L10.4 µC/OS 和 µC/OS-II任务栈的数据类型#define OS_STK_TYPE UWORD /* 在 uC/OS 中 */#define OS_STK INT16U /* 在 uC/OS-II 中 */10.2.2OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()µC/OS-II和µC/OS一样,分别定义两个宏来开中断和关中断:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。
在µC/OS向µC/OS-II升级的时候,用户不必动这两个宏。
.10.2.3OS_STK_GROWTH大多数微处理器和微处理器的栈都是由存储器高地址向低地址操作的,然而有些微处理器的工作方式正好相反。
µC/OS-II设计成通过定义一个常数OS_STK_GROWTH来处理不同微处理器栈操作的取向:对栈操作由低地址向高地址增长,设OS_STK_GROWTH 为 0对栈操作由高地址向低地址递减,设OS_STK_GROWTH 为 1有些新的常数定义(#define constants )在µC/OS中是没有的,故要加到OS_CPU.H中去。
10.2.4OS_TASK_SW()OS_TASK_SW()是一个宏,从µC/OS升级到µC/OS-II时,这个宏不需要改动。
当µC/OS-II从低优先级的任务向高优先级的任务切换时要用到这个宏,OS_TASK_SW()的调用总是出现在任务级代码中。
10.2.5OS_FAR因为Intel 80x86的结构特点,在µC/OS中使用过OS_FAR。
这个定义语句(#define)在µC/OS-II 中去掉了,因为这条定义使移植变得不方便。
结果是对于Intel 80x86,如果用户定义在大模式下编译时,所有存储器属性都将为远程(FAR).在µC/OS-II中,任务返回值类型定义如程序清单L10.5所示。