1、,嵌 入 式 操作 系 统 C/OS-,1. C/OS-简+介 1.1 嵌入式操作系统运行在嵌入式硬件平台上,对整个系统及其操作的部件,装置等资源进行统一协调,指挥和控制的系统软件。 主要特点: 微型化 嵌入式系统芯片内部的存储器的容量通常不大( 1MB以内),可裁减性 硬件平台多样性,对象有各种类型,要求EOS提供的功能模块可根据用户需要选择使用。 实时性 生产过程的控制,数据采集,传输通信等许多场合要求系统快速响应事件,所以要求嵌入式操作系统有较好的实时性。,高可靠性 广泛用于航天航空,交通运输,重要生产设备等,所以要求EOS可靠性好。 易移植性 为适应多种硬件平台,EOS不需要做大量的修
2、改,就可稳定的运行于不同的平台。,1.2 实时嵌入式操作系统:使系统及时响应外部事件的请求,并及时 控制所有实时设备与任务协调运行,能在一 个规定的时间内完成事件的处理,该操作系 统称为实时操作系统RTOS,对实时系统有二个基本要求: 实时系统的计算须产生正确的结果,即功能或逻辑正确。 实时系统的计算必须在规定的周期内完成,即时间正确。按时间正确的程度可分: RTOS又分为硬实时操作系统和软实时操作系统。,硬实时: 要求系统必须在极严格的时间内完成实时任务。对硬实时来说,超过截止时间计算出来的正确结果和错误的计算结果都是不能容忍的,因为事故已发生了,结果再正确也没有什么意义。,软实时 相对来说
3、,如果系统完成实时任务的截止时间要求不是十分严格,超过容许的时间得到的运算结果不会完全没有用途,只是结果的可信度有某种降低,该类系统叫做软RTS。,嵌入式系统主要是对设备进行控制,能否及时快速地响应外部事件,常常是对系统的第一要求,所以嵌入式系统选用的操作系统大多是RTOS。 一个RTOS,在现有的硬件条件下,接受输入后,要尽可能快的计算出结果,使应用程序能预先正确的确定完成任务所需要的最长时间。,RTOS应具有以下三点:RTOS必须是多任务系统。任务的切换时间应与系统中的任务数无关。中断延时的时间可预知并且尽可能短。操作系统完成任务用的时间应该是应用 程序设计时就可预知的。,多任务:多任务系
4、统把一个大的应用程序分解成相对独立的多个任务完成,给应用程序的设计和维护提供了极大的方便。现有的RTOS都是多任务系统。,EOS内核的分类EOS中只有一个CPU,所以在一个具体的时 刻只能允许多个任务中的一个任务使用CPU。 根据系统中的任务获得CPU的权利方式,多任 务RTOS的内核分为可剥夺型和不可剥夺性二种 类型。(占先式和非占先式)。,不可剥夺型内核,也叫合作型多任务内核。 该内核总是优先级别高的任务最先获得CPU的使用权。为了防止某个任务始终霸占CPU的使用权,这种内核要求每个任务必须主动放弃CPU的使用权。,可剥夺型内核 CPU总是运行多任务中优先权级别最高的那个任务,即使CPU正
5、在运行某个低优先级别的任务,当有优先级别高的任务准备就绪时 ,该高级别的任务就会剥夺正在运行任务的CPU使用权,而使自己获得CPU使用权。,可剥夺型内核实时性好,所以目前大 多数ERTOS是可剥夺型内核。不论哪一种类型的内核,每个任务须 有一个唯一的优先级别来表示它的CPU的 权力。,任务切换时间 多任务,存在任务之间的切换, 操作系统的调度器就是做此工作的。调度器切换任务需要时间,切换 时间的长短也是影响系统实时性的一 个重要因素。,为使应用程序设计时,可计算系统完成某一个任务的准确执行时间,要求进行任务切换的调度器的运行时间应该是固定的,即任务切换所用时间不能受应用程序中其他因素的影响(如
6、任务数目)。,中断延时 CPU响应中断到CPU转向中断服务程序之间的时间叫做中断延时。中断延时会影响系统的实时性。所以缩短中断延时也是RTOS要解决的课题。,嵌入式系统的任务由于嵌入式系统完成的是对一个装置或设备的控制任务,任务是相对固定的,因此在一般情况下RTOS支持的典型任务是一个无限循环结构的。 一个用C语言编写的任务结构,void mytask ( void * pdata )for ( ; ; )用户编写的代码;从任务的代码看,任务实质是一个返回类型的void 函数,并在函数的无限循环中完成用户的工作。,用户应用程序如何来响应用户的一些外部异步事件? 使用的是中断技术,并且在中断服务
7、程序中处理这些异步事件。,1.3 嵌入式实时操作系统 目前EOS主要以提供“微内核”为主,其他如窗口界面,文件管理模块,通信协议等还要有开发人员自己设计或外采购。多数EOS主要提供三项服务,辅助应用程序设计人员的设计:,1) 内存管理: 主要是动态内存管理, 使用内存时,可由OS提供的内存分配函数来获得足够的内存空间;一旦使用完毕,可调用OS提供的内存释放函数,把曾经使用的内存空间还给系统,可使内存重复应用。,2) 多任务管理: RTOS会提供丰富的多任务管理函数,使程序设计人员设计多线程的应用程序。一般EOS提供良好的任务调度机制,控制任务的启动,运行,暂停和结束等状态。通常这些调度函数会满
8、足实时性要求,即在规定的时间内完成任务的每个动作。,3) 外部资源管理: 外围设备也是系统的部分资源,所以RTOS必须对这些资源进行合理的调度和管理,才能保证每个要使用资源的任务在运行时可获得足够的资源。,1.4 C/OS简介,1、C/OSMicro Controller O S,微控制器操作系统 2、 C/OS简介 美国人Jean Labrosse 1992年完成 应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等 1998年C/OS-II,目前的版本C/OS -II V2.61,2.72 2000年,得到美国航空管理局(FAA)的认证,可以用于飞
9、行器中. 网站www.ucos-II.com(),一个真正的实时操作系统。实时操作系统在实现时通常采用的是基于优先级的任务调度策略。也就是说系统根据各个任务的优先级,动态地切换各个任务,来保证实时性。通常基于优先级的操作系统有两种:可剥夺型的和不可剥夺型的。,C/OS特点,只有基于优先级的可剥夺型的操作系统 才是真正的实时操作系统。在可剥夺型内核中,当有更高优先级的任务就绪时,总能得到CPU的控制权。C/OS-以及绝大多数商业实时内核都是可剥夺型内核。,C/OS-实际上是一个实时操作系统内核,只包含了任务调度、任务管理、时间管理、内存管理和任务间的通信与同步等基本功能。没有提供输入输出管理、文
10、件系统、网络之类的额外服务。但是由于C/OS-的可移植性和开源性,用户可以自己添加所需的各种服务。,公开源代码 代码开放,使用人员可清楚地了解该OS个方面的设计细节,通过自己修改源代码,来构造符合应用需求的操作系统环境. 可移植性(Portable)除少量与处理器有关的部分采用汇编语言,大部分代码用C语言编写,具有良好的可移植性,可裁减性 C/OS-II的系统服务函数定义了条件编译开 关量,对不需要的功能模块可以通过条件编译 进行裁减。,可固化(ROMable) C/OS-II是为嵌入式应用而设计的,这就意味着只要读者有固化手段 (C编译、连接、下载等), C/OS-II可以嵌入到读者的产品中
11、成为产品的一 部分。,占先式(Preemptive), 即C/OS-II总是运行就绪条件下优先级最高的任务. 多任务 C/OS-II可以管理64个任务,目前的版本保留8个给系统。应用程序最多可以有56个任务,每个任务必须设置不同的优先级。,可确定性 全部 C/OS-II的函数调用与服务的执行时间具有可确定性。 任务栈 每个任务有自己单独的栈, C/OS-II允许每个任务有不同的栈空间。 系统服务C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、时间相关函数等。,中断管理中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中
12、断嵌套层数可达255层。 稳定性与可靠性自1992年以来C/OS-II已经有几百个商业 应用.,2 C/OS-的结构C/OS-其实只有一个内核,提供任务管理、内存管理、时间管理和任务间的通信与同步等基本功能。虽然目前已经出现针对C/OS-应用的第三方软件如网络管理、输入输出管理、TCP/IP协议栈等。但这些功能的实现都是基于C/OS-的内核管理功能实现的,C/OS-II的文件结构,内核由三类文件构成: 与微处理无关的代码,有十一个文件; 与应用有关软件相关的代码,有二个程序文件; 与微处理器相关的代码,有三个程序文件。,内核负责管理各任务,即为每个任务分配CPU 时间,并负责任务之间的通信.内
13、核提供的基本服 务是任务的切换.通过实时内核可将应用程序分 成若干个任务,由实时内核管理它们.c/OS - 内核保护机制定义二个宏:OS_ENTER_CRITICAL(), OS_EXIT_CRITICAL()实现中断的禁止和允许,保护 临界代码.这二个宏应成对使用.,OS_ENTER_CRITICAL(),OS_EXIT_CRITICAL() 有3种实现方法.用户可以通过 ”#define OS_CRITICAL_Method”来定义: #define OS_CRITICAL_Method1 #define OS_CRITICAL_Method2 #define OS_CRITICAL_Me
14、thod3,3 c/OS - 提供的系统服务 主要有:任务管理,中断处理与时间管理,任务同步与通信,内存管理等部分。 1)任务管理 包括任务的建立、挂起、恢复、删除 、调度、任务调度的上锁与解锁、中断的打开与关闭 等。 2)中断处理与时间管理 包括中断进入与脱离、中 断级任务切换,时钟的节拍、任务延时等,3)任务同步与通信 包括信号量、信号量集、互斥信号量、消息邮箱、消息队列等 4)内存管理系统 包括建立内存分区、分配内存块、释放内存块、查询内存分区的状态等。 c/OS - 提供的服务是通过系统服务函数实现,5 c/OS - 的任务1)任务的基本概念 c/OS - 的任务是一个程序实体,由任务
15、代码,任务堆栈,任务优先级和任务控制块构成的实体。,从任务的存储结构来看,c/OS - 的任务由三部分构成:任务程序代码,任务堆栈,任务控制快任务程序代码: 是任务的功能部分,任务堆栈: 保存任务工作状态和环境,任务控制块: 保存任务属性。 任务有二种类型: 用户任务和系统任务,任务控制块(TCB),2) 任务控制块 OS_TCB: 是一个数据结构,保存该任务的相关参数,包括任务 堆栈指针,状态优先级,任务表位置,任务链表指针 等。应用程序调用任务创建函数OSTaskCreat( )创建 任务时,控制块OS_TCB将被赋与任务相关的数据. OS_TCB 全部驻留在RAM.,当任务的CPU 使用
16、权被剥夺时, C/OS II 用任务控制块保存该任务的状态,当任 务重新得到CPU使用权时,OS_TCB能确保任 务从被中断的地方继续运行。,空任务列表,所有的任务控制块都被放置在任务控制块列表数组OSTCBTbl 中,系统初始化时,所有任务控制块被链接成空任务控制块的单向链表。任务建立后,空任务控制块指针OSTCBFreeList指向的任务控制块就赋给了该任务,然后OSTCBFreeList的值调整为指向链表中的下一个空任务控制块。,任务控制块初始化函数,INT8U OS_TCBInit( INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id,
17、INT32U stk_size, void *pext, INT16U opt ) ,为管理多个任务,c/OS - 把每一个任务作为一个节点,然后将所有任务的控制块链接成任务链表。 应用程序调用c/OS - 的函数OSInit(),进行c/OS - 的初始化时,空任务控制链接表建立。当创建任务时系统会将空任务控制链接表分配给任务,再将任务控制块的各成员赋值,最后链接到任务控制块链表中。,3 ) 任务状态因为只有一个CPU ,所以在一个具体的时刻只能允许一个任务占用CPU。根据任务是否占用CPU,是否处于中断,等待等情况,c/OS - 中的任务可能处于5种状态之一。 休眠状态: 任务只是以代码形
18、式驻留在程序空间( ROM,RAM ),还没有交给OS管理是的情况,即还没有配备任务控制块。,等待状态: 正在运行的任务,需要等待一段时间或一个事件的发生再运行时,该任务会把CPU的使用权让给其他任务而使任务进入等待状态。 中断服务状态; 一个正在运行的任务响应中断申请就会中止运行而去执行中断服务程序。 这是的任务状态叫做中断服务状态。,就绪状态: 任务配备了任务控制模块并且在就绪表中进行了就绪登记,则任务具备了运行的充分条件。 运行状态: 处于就绪状态的任务经调度器判断获得了CPU的使用权,则任务就进入运行状态。就绪任务只有当优先级高于本任务的任务都转入等待状态时,才可能进入运行状态。 任务
19、状态的转换,图,任务状态,任务创建后,就处于就绪状态.一个任务可以通过调用OSTASKDEL(),使它自 己或另一个任务返回休眠状态.,4) 用户任务代码的一般结构例1: 一个用C语言编写的任务void Mytask (void * pdata )(for (; )可以被中断的用户代码;OS_ENTER_CRITICAL ( ) ; / 进入临界段( 关中断),不可以被中断的用户代码;OS_EXIT_CRITICAL ( ) ; / 退出临界段 (开中断)可以被中断的用户代码;)从程序设计的角度看,一个c/OS - 任务的代码 就是一个C语言函数。,为了有效的对中断进行控制。任务代码中使用了定
20、义的宏 OS_ENTER_CRITICAL ( ) ;OS_EXIT_CRITICAL ( ) 来控制任务何时响应中断,何时屏蔽中断。在二个运行的宏之间的代码是不会响应中断的,这种受保护的代码段叫做临界段。实际需要可在一个任务中使用这对宏,设置多个临界段。,用户应用程序结构void Mytask1 ( void * pdata ) / 定义用户任务1for ( ; ). ,void Mytask2 (void * pdata ) / 定义用户任务2for ( ; ).,void Mytask3 (void * pdata ) / 定义用户任务3for ( ; ).void main ( ),O
21、SInit ( ) ; / 初始化c/OS - OSTaskCreate ( Mytask 1,) ; /创建用户任务1OSTaskCreate ( Mytask 2,) ;/ 创建用户任务2OSTaskCreate ( Mytask 3,) ;/ 创建用户任务3,OSStart ( ) ; / 启动任务.使用OSStart ( ) 启动了一个任务后,任务 就交给了操作系统来管理和调度了。,5)系统任务c/OS - 预先定义了二个为应用程序服务的系统任务:空闲任务和统计任务。 空闲任务: OSTaskIdle ( ),系统定义的一个空闲任务,执行后并不做什么事 只对空闲任务的运行次数进行计数,
22、计数器OSdleCtr. 当就绪表中出现可执行就绪任务时,空闲任务把CPU的 使用权转交该任务。,c/OS - 规定一个用户程序必须使用这个空闲任务,并且该任务是不能用软件进行删除的。 统计任务:OSTaskStart ( ): 每秒计算一次CPU在单位时间内被使用的时间,并且把计算结果以百分比的形式存放在变量OSCPUsage 中,以便应用程序通过访问它来了解CPU的利用率。统计任务根据需要选择应用。,用户应用程序要使用该统计任务,则必须把定义在系统头文件OS_CFG.H 中的系统配置常数OS_TASK_STAT_EN 置为 1 ,并且必须在创建统计任务之前调用函数 OSStatInit (
23、 ) ,对统计任务进行初始化。,6) 任务调度 c/OS - 总是运行进入就绪态中优先级最高的任务.确定哪一个任务优先级最高,运行哪一个任务,由任务调度器,依据某种算法完成.任务级的调度是由函数OSSCHED()完成.c/OS - 中调度所花的时间是常数,与应用程序中建立的任务数无关.,任务级的任务调度-OSSched,C/OS是占先式实时多任务内核,优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。 C/OS中不支持时间片轮转法.每个任务的优先级不同且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。 C/OS任务调度所花的时间为常数,与应用程序
24、中建立的任务数无关。,任务的切换由二步完成:1. 被挂起任务的寄存器推入堆栈2. 然后将较高优先级的任务的寄存器值从堆栈中恢复到寄存器.OSSched() 的所有代码都是临界代码,7)任务的优先级别与优先权c/OS - 的每个任务必须有一个唯一的优先级,c/OS - 把任务的优先权分为64 个优先级别,每个级别用一个数字表示,数字 0 表示任务的优先级别最高。通常一个应用程序的任务数小于64。为了节省内存,用户可根据应用程序的需要,在文件OS_CFG.H 中通过给表示最低优先级别的常数OS_LOWEST_PRIO 赋值的方法,说明应用程序中的任务优先级别的数目。,该常数一旦定义,意味着系统中可
25、供使用的优先级别为 0,1,2,3,OS_LOWEST_PRIO ,共 OS_LOWEST_PRIO + 1 个。系统总是把 OS_LOWEST_PRIO 自动赋给空闲任务,如果用户任务还使用了统计任务,则系统会把OS_LOWEST_PRIO 1赋给统计任务,所以用户可用优先级别是:0,1,2,3, , OS_LO WEST_PRIO 2 ,共有 OS_LOWEST_PRIO 1个任务。,例: 如希望应用程序的任务优先级别为 28,则表示最低优先级别的常数OS_LOWEST_PRIO值是多少?如果应用程序中使用了系统提供的空闲任务和统计任务,则该应用程序最多可安排多少个任务?,解:表示最低优先
26、级别的常数OS_LOWEST_PRIO 值应该是 27,即 0,1,2,27。由于空闲任务占用27,统计任务占用 26,所以应用程序最多可以安排优先级别为0,1,2, ,25 的任务,26个任务。,对一个用户任务定义优先级别,需要在调用系统函数OSTaskCreate ( ) 来创建任务时,用该函数的第4个参数 prio来指定。,C/OS II 2.5版本支持64个任务,每个任务一个特定的优先级。优先级越高,数字越小。 系统占用了8个任务,保留优先级为0、1、2、3、OS_LOWEST_PRIO-3、 OS_LOWEST_PRIO-2、OS_LOWEST_PRIO-1、 OS_LOWEST_P
27、RIO-0。,Task Structure,Alternate Structure,8)任务就绪表 OSRdyTbl C/OS-II进行任务调度的依据是任务就绪表 就绪表确定最高优先级 优先级数分解为高三位和低三位: 0 0 Y Y Y X X X YYY OSRdyGrp XXX OSRdyTbl ,根据优先级找到任务在就绪任务表中的位置,每个就绪的任务都放入就绪表中(ready list)中,就绪表有两个变量:OSRdyGrp、OSRdyTbl,优先级最低任务,(空闲任务),优先级最高任务,任务优先级号,根据优先级确定就绪表(1),假设优先级为12的任务进入就绪状态,12=1100b,则O
28、SRdyTbl1的第4位置1,且OSRdyGrp的第1位置1,相应的数学表达式为:OSRdyGrp |=0000 0010=0x02;OSRdyTbl1 |=0001 0000=0x10;,根据优先级确定就绪表(1),优先级为21的任务就绪21=10 101b,则OSRdyTbl2的第5位置1,且OSRdyGrp的第2位置1,相应的数学表达式为:OSRdyGrp |=0000 0100=0x04;,根据优先级确定就绪表(2),若OSRdyGrp及OSRdyTbl的第n位置1,则应该把OSRdyGrp及OSRdyTbl的值与2n 相或。uC/OS中,把2n的n=0-7的8个值先计算好存在数组OS
29、MapTbl中,也就是:OSMapTbl0 =20=0x01(0000 0001)OSMapTbl1 =21=0x02(0000 0010)OSMapTbl7 =27=0x80(1000 0000),使任务进入就绪态,如果prio是任务的优先级,也是任务的识别号,则将任务放入就绪表,即使任务进入就绪态的方法是: OSRdyGrp | = OSMapTblprio3;OSRdyTblprio3|=OSMapTblprio,假设优先级为121100b OSRdyGrp |=OSMapTbl1 (0000 0010) 注:prio3= 1100b 3=1; OSRdyTbl1 |=OSMapTbl4
30、 (0001 0000); 注:prio & 0x07=0000 1100 & 0000 0111= 4,使任务脱离就绪态,将任务就绪表OSRdyTblprio3相应元素的相应位清零,而且当OSRdyTblprio3中的所有位都为零时,即全组任务中没有一个进入就绪态时,OSRdyGrp的相应位才为零。,采用查表法确定高优先级任务,查表法具有确定的时间,增加了系统的 可预测性,uC/OS设计了一个数组 OSUnMapTbl16x16 Y =OSUnMapTblOSRdyGrp; X =OSUnMapTblOSRdyTbl Y ; Prio =( Y 3)+ X ;,采用查表法确定高优先级任务,I
31、NT8U const 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,
32、 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,
33、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 ;,优先级判定表OSUnMapTbl256,举例:如OSRdyGrp的值为01101000B,即0X68,则查得OSUnMapTblOSRdyGrp的值是3,它相应于OSRdyGrp中的第3位置1;如OSRdyTbl3的值是11100100B,即0XE4,则查OSUnMapTblOSRdyTbl3的值是2,则进入就绪态的最高任务优先级Prio=3*8+2=26,任务调度: 由调度器完成.其主要工作有二项 1. 在任务就绪表中查找具有最高优先级别的就绪任务. 2. 实现任务的切换.C/OS-II有二种调度器:任务级调度器,中断级调度器. 任务级调度器由函数OSSched()实现.,Task scheduler,给调度器上锁,给调度器开锁,本节 结束,