ucos2嵌入式实时操作系统.ppt

上传人:牧羊曲112 文档编号:5451405 上传时间:2023-07-08 格式:PPT 页数:291 大小:3.76MB
返回 下载 相关 举报
ucos2嵌入式实时操作系统.ppt_第1页
第1页 / 共291页
ucos2嵌入式实时操作系统.ppt_第2页
第2页 / 共291页
ucos2嵌入式实时操作系统.ppt_第3页
第3页 / 共291页
ucos2嵌入式实时操作系统.ppt_第4页
第4页 / 共291页
ucos2嵌入式实时操作系统.ppt_第5页
第5页 / 共291页
点击查看更多>>
资源描述

《ucos2嵌入式实时操作系统.ppt》由会员分享,可在线阅读,更多相关《ucos2嵌入式实时操作系统.ppt(291页珍藏版)》请在三一办公上搜索。

1、,嵌入式系统原理与接口技术,第六讲 嵌入式实时操作系统C/OS-,本节提要,1.1 计算机操作系统,定义OS是一种系统软件。OS是在计算机硬件与计算机应用程序之间,通过提供应用程序接口,屏蔽了计算机硬件工作的一些细节,大大提高了应用程序的开发效率。作用与功能OS为应用程序提供了一个界面友好,性能稳定、安全,效率高,操作方便的虚拟计算机。OS的主要功能:处理器的管理;存储的管理;设备的管理;文件的管理;网络和通信的管理;提供用户接口。,1.2 嵌入式操作系统,定义运行在嵌入式硬件平台上,对整个系统及其所操作的部件、装置等资源进行统一协调、指挥和控制的系统软件。嵌入式操作系统的主要特点:微型化可裁

2、剪性实时性高可靠性易移植性嵌入式操作系统按应用范围分为通用型(如Win CE,VXWorks,CLinux,C/OS-等)和专用型(Symbian,Plam OS等)两种。,1.3 实时操作系统(RTOS),定义RTOS是具有实时性能且能支持实时控制系统工作的操作系统。RTOS是一个程序,它按时序方式调度执行,管理系统资源,并为开发应用代码提供一致的基础。RTOS的首要任务是调度一切可利用的资源来完成实时控制任务,其次才着眼于提高计算机系统的使用效率,其重要特点是能满足对时间的限制和要求。在实时计算中,系统的正确性不仅依赖于计算的逻辑结果,而依赖于结果产生的时间。,RTOS与通用计算机OS的区

3、别,实时性代码尺寸小应用程序开发较难需要专用的开发工具,RTOS的组成,实时操作系统需根据实际应用环境的要求,对内核进行裁减和重配置。根据其面向实际应用领域的不同,实时操作系统组成也有所不同,一般包括以下几个重要部分:实时内核网络组件文件系统图形用户界面,RTOS的特点,支持异步事件的响应中断和调度任务的优先级机制支持抢占式调度确定的任务切换时间和中断延迟时间支持同步,1.4 前/后台系统,前/后台系统是嵌入式实时系统的主要形式,用于不复杂的小系统设计上。,前/后台行为应用程序是一个无限循环,循环中调用相应的函数完成相应的操作,这部分可看成后台行为(background)。中断服务程序处理异步

4、事件,这部分可看成前台行为(foreground)。,说明时间相关性很强的关键操作(critical operation)一定是靠中断服务来保证的。因为中断服务提供的信息一直要等到后台程序运行到该处理这个信息时,才能得到处理。该系统在处理信息的及时性上,比实际做的要差。处理信息的及时性称做任务级响应时间。最坏情况下,任务级响应时间取决于整个循环的的执行时间。(循环执行时间不是常数),1.5 代码的临界段,代码的临界段也称为临界区,指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。为确保临界段代码的执行不被中断,在进入临界段之前要关中断,而临界段代码执行完以后要立即开中断(在

5、任务切换时,地址、指令、数据等寄存器堆栈保护)。,1.6 多任务,任务 一个任务,也称作一个线程,是一个简单的程序。每个任务都是整个应用的某一部分,每个任务被赋予一定的优先级,有它自己的一套CPU寄存器和自己的栈空间。,每个任务都是一个无限的循环。每个任务都在 以下5种状态之一:休眠态休眠态相当于该任务驻留在内存中,但并不被多任务内核所调用。就绪态就绪态意味着该任务已经准备好,可以运行,但由于该任务的优先级比正在运行的任务的优先级低,还暂时不能运行。,挂起态(等待某一事件发生)挂起状态也可以叫做等待事件态WAITING,指该任务在等待,等待某一事件的发生。被中断态 发生中断时,CPU提供相应的

6、中断服务,原来正在运行的任务暂不运行,进入中断处理。,运行态 运行态的任务是指该任务掌握了CPU的控制权,正在运行中。,多任务,多任务运行的实现实际上是靠CPU(中央处理单元)在许多任务之间转换、调度。CPU只有一个,轮番服务于一系列任务中的某一个。多任务运行使CPU的利用率得到最大的发挥,并使应用程序模块化。在实时应用中,多任务化的最大特点是,开发人员可以将很复杂的应用程序层次化。使用多任务,应用程序将更容易设计与维护。,任务切换(Context Switch),当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(即CPU寄存器中的全部内容)到任务的当前状况保存区(即任务自己的栈

7、区之中)。入栈完成后,把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行,这个过程叫做任务切换。任务切换过程增加了应用程序的额外负荷。任务切换所需要的时间取决于CPU有多少寄存器要入栈。,1.7 系统内核与调度,功能 多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。内核提供的基本服务是任务切换。优点 使用实时内核可以大大简化应用系统设计,因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。,系统内核,缺点内核本身也增加了应用程序的额外负荷。代码空间增加了ROM的用量。内核本身的数据结构增加了RAM的用

8、量。内核本身对CPU的占用时间一般在2到5个百分点之间。说明实时内核为使CPU的利用更为有效,提供了必不可少的系统服务:信号量管理,邮箱、消息队列及时间延时等。单片机一般不能运行实时内核,因为单片机的RAM很有限。,调度算法基于优先级的调度法 每个任务根据其重要程度的不同赋予一定的优先级,CPU总是让处在就绪态的、优先级最高的任务先运行。时间片轮转调度法调度原则 总是进入优先级最高、就绪态的任务运行。,调度(Scheduler)调度是内核的主要职责之一,就是要决定该轮到 哪个任务运行了。,1.8 不可剥夺与可剥夺型,不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。异步事件还

9、是由中断服务来处理。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。,基于优先级的内核有两种类型:不可剥夺内核 和可剥夺型内核。不可剥夺型内核,要求每个任务主动放弃cpu的使用权。,不可剥夺型内核的优点响应中断快 使用不可剥夺型内核时,任务级响应时间比前/后台系统快得多。此时的任务级响应时间取决于最长的任务执行时间。几乎不需要使用信号量保护共享数据 运行着的任务占有CPU,而不必担心被别的任务抢占。但这也不是绝对的,在某种情况下,信号量还是用得着的。处理共享

10、I/O设备时仍需要使用互斥型信号量。,不可剥夺型内核的缺点不可剥夺型内核最大缺陷在于其响应时间,即响应高优先级的任务慢。不可剥夺型内核任务级响应时间要大大好于前/后台系统,但仍是不可知的,商业软件几乎没有不可剥夺型内核。,可剥夺型内核最高优先级的任务一旦就绪,总能得到CPU的控制权。当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。如果是中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的那个任务开始运行。,说明使用可剥夺型内核,最高优先级的任务什么时候可以执

11、行,何时可以得到CPU的控制权,这些是可知的,使得任务级响应时间得以最优化。使用可剥夺型内核时,应用程序不应直接使用不可重入型函数。调用不可重入型函数时,要满足互斥条件,这一点可以用互斥型信号量来实现。如果调用不可重入型函数时,低优先级的任务的CPU使用权被高优先级任务剥夺,不可重入型函数中的数据有可能被破坏。,可剥夺型内核总是让就绪态的高优先级的任 务先运行,中断服务程序可以抢占CPU。C/OS-以及大多数的商业的实时内核都是 可剥夺型内核。,1.9 可重入型函数,可重入型函数可以被一个以上的任务调用,而不必担心数据的破坏。可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据

12、不会丢失。可重入型函数或者只使用局部变量,即变量保存在CPU寄存器中或堆栈中。如果使用全局变量,则要对全局变量予以保护。,可重入型函数的例子,程序清单(可重入型函数)void swap(int*x,int*y)int Temp;Temp=*x;*x=*y;*y=Temp;,不可重入型函数的例子,程序清单(不可重入型函数)int Temp;void swap(int*x,int*y)Temp=*x;*x=*y;*y=Temp;,把Temp定义为局部变量;调用函数之前关中断,调用后再开中断;用信号量禁止该函数在使用过程中被再次调用。,使函数具有可重入性的方法:,1.10 任务优先级,任务优先级 每

13、个任务都有优先级。任务越重要,赋予的优先级越高,对大多数内核而言,优先级是由用户决定的。静态优先级 应用程序执行过程中诸任务优先级不变,则称之为静态优先级。在静态优先级系统中,诸任务以及它们的时间约束在程序编译时是已知的。,动态优先级 应用程序执行过程中,任务的优先级是可变的,则称之为动态优先级。实时内核应当避免出现优先级反转问题。,1.11 优先级反转,优先级反转 为防止优先级反转,内核能自动变换任务 的优先级,这叫做优先级继承,优先级反转,优先级继承,1.12 任务优先级分配,任务优先级分配实时系统大多综合了软实时和硬实时这两种需求。软实时系统只是要求任务执行得尽量快,并不要求在某一特定时

14、间内完成。硬实时系统中,任务不但要执行无误,还要准时完成。单调执行率调度法RMS(Rate Monotonic Scheduling),用于分配任务优先级。这种方法基于任务执行的次数(或称任务的执行率),执行最频繁的任务优先级最高。,单调执行率调度法,RMS做了一系列假设:所有任务都是周期性的;任务间不需要同步,没有共享资源,没有任务间数据交换等问题;CPU必须总是执行那个优先级最高且处于就绪态的任务。换句话说,须使用优先级调度法。RMS定理(Ei/Ti)n(21/n-1),i,RMS认为:最高执行率的任务具有最高的优先级;但在某些条件下,最高执行率的任务并非是最重要的任务。,基于任务的CPU

15、最高允许使用率,1.13 互斥条件,实现任务间通讯最简便的办法是使用共享数据结构。虽然共享数据区法简化了任务间的信息交换,但必须保证每个任务在处理共享数据时的排它性,以避免竞争和数据的破坏。与共享资源打交道时,使之满足互斥条件最一般的方法有:关中断;使用测试并置位指令;禁止做任务切换;利用信号量。,关中断和开中断,处理共享数据时保证互斥,最简便快捷的办法是关中断和开中断。C/OS-提供两个宏调用以完成关中断和开中断。OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()说明 在任何时候,关中断的时间都要尽量短。一般说,关中断时间最长不超过内核本身的关中断时间,这样就不会影响

16、系统中断延迟。,测试并置位操作,定义 如果不使用实时内核,当两个任务共享一个资源时,一定要约定好,先测试某一全程变量,如果该变量是0,允许该任务与共享资源打交道。为防止另一任务也要使用该资源,前者只需简单地将全程变量置为1,这就称作测试并置位TAS(Test-And-Set)操作。说明 TAS操作可能是微处理器的单独一条不会被中断的指令,否则应在程序中关中断做TAS操作再开中断。,禁止,然后允许任务切换,如果任务不与中断服务子程序共享变量或数据结构,可以使用“禁止、然后允许任务切换”操作。应该尽量避免“禁止任务切换”之类操作,因为内核最主要的功能就是做任务的调度与协调。,1.14 信号量(Se

17、maphores),信号量是60年代中期Edgser Dijkstra 发明的。信号量实际上是一种约定机制,在多任务内核中普遍使用.信号量用于:控制共享资源的使用权(满足互斥条件);标志某事件的发生;使两个任务的行为同步。信号量像是一把钥匙,任务要运行下去,得先拿到这把钥匙。如果信号量已被别的任务占用,该任务只得被挂起,直到信号量被当前使用者释放。,信号量有两种类型:二进制型:只有两个值1和0。当信号量的值为0时,该任务被挂起;当值为1时,任务得以运行。,计数型信号量 计数式信号量的值可以是0255或065535或04294967295,取决于信号量规约机制使用的是8位、16位还是32位,实际

18、上是取决于所用内核的类型。根据信号量的值,内核跟踪那些等待信号量的任务。计数型信号量用于某资源可以同时为几个任务所用。,信号量管理缓冲区阵列,说明信号量常被用过了头。请求和释放信号量的过程是要花相当的时间的。处理简单共享变量使用信号量是多余的,使用关中断、开中断还可提高效率。,1.15 死锁,定义死锁也称作抱死,指两个任务无限期地互相等待对方控制着的资源。设任务T1正独享资源R1,任务T2在独享资源R2,而此时T1又要独享R2,T2也要独享R1,于是哪个任务都没法继续执行了,发生了死锁。防止发生死锁的方法:让每个任务都:先得到全部需要的资源再做下一步的工作;用同样的顺序去申请多个资源;释放资源

19、时使用相反的顺序。,说明内核大多允许用户在申请信号量时定义等待超时,以此化解死锁。当等待时间超过某一确定值,而信号量还是无效状态时,就会返回某种形式的出现超时错误的代码,告知任务,不是得不到资源使用权,而是系统错误。,1.16 同步,利用信号量可实现多个任务间的同步。单向同步(unilateral rendezvous)利用信号量使某个任务与中断服务同步或与另一个无数据交换的任务同步。,双向同步(bilateral rendezvous)2个任务可以用2个信号量同步它们的行为,如图:,说明,双向同步不可能在任务与ISR之间实施 因为ISR不可能等待一个信号量。,1.17 事件标志(Event

20、Flags),当某任务要与多个事件同步时,要使用事件标志。若任务需要与任何事件之一发生同步,可称为独 立型同步(OR)。任务也可以与若干事件都发生了 同步,称之为关联型同步(AND)。可以用多个事件的组合发信号给多个任务。通过任务和中断服务给每一位置位或复位,确定任 务执行与否。,1.18 任务间通信,定义任务间或中断服务与任务间的信息传递称为任务间的通信。(intertask communication)。,任务间信息传递有两个途径:全程变量或共享内存 用全程变量时,必须保证每个任务或中断服务程序独享该变量。中断服务中保证独享的唯一办法是关中断。如果两个任务共享某变量,各任务实现独享该变量的

21、办法可以是关中断再开中断,或使用信号量。,注意:任务只能通过全程变量与中断服务程序通信,而任务并不知道什么时候全程变量被中断服务程序修改了,除非中断程序以信号量方式向任务发信号或者是该任务以查询方式不断周期性地查询变量的值。要避免这种情况,用户可以考虑使用邮箱或消息队列。邮箱或消息队列,1.19 消息邮箱(Message Mail boxes),定义通过内核服务可以给任务发送消息。典型的消息邮箱也称作交换消息,即用一个指针型变量。一个任务或一个中断服务程序通过内核服务,可以把一则消息(即一个指针)放到邮箱里去。同样,一个或多个任务可以通过内核服务接收这则消息。发送消息和接收消息的任务约定,该指

22、针指向的内容就是那则消息。,下图示意把消息放入邮箱,TASK,Mailbox,TASK,POST,PEND,10,内核一般提供以下邮箱服务 邮箱内消息内容的初始化,邮箱里最初可以有,也可以没有消息。将消息放入邮箱(POST)。等待有消息进入邮箱(PEND)。从邮箱中得到消息。如果邮箱内有消息,就接收这则消息。如果邮箱里没有消息,则任务并不被挂起(ACCEPT),用返回代码表示调用结果。说明消息邮箱也可以当作只取两个值的信号量来用:邮箱里有消息,表示资源可以使用;而空邮箱表示资源已被其它任务占用。,1.20 消息队列(Message Queue),定义消息队列用于给任务发消息。消息队列实际上是邮

23、箱阵列。通过内核提供的服务,任务或中断服务子程序可以将一条消息(该消息的指针)放入消息队列。同样,一个或多个任务可以通过内核服务从消息队列中得到消息。发送和接收消息的任务约定,传递的消息实际上是传递的指针指向的内容。通常,先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即基于先进先出原则(FIFO)。每个消息队列有一张等待消息任务的等待列表(Waiting List)。,如图所示:中断服务子程序如何将消息放入消息队列。图中 表示消息队列,“10”表示消息队列最多可以放10条消息,沙漏旁边的0表示任务没有定义超时,将永远等下去,直至消息的到来。,TASK,Queu

24、e,0,POST,ISR,Interrupt,PEND,内核提供的消息队列服务如下:消息队列初始化,队列初始化时总是清为空。放一则消息到队列中去(Post)。等待一则消息的到来(Pend)。如果队列中有消息,则任务可以得到消息,但如果此时队列为空,内核并不将该任务挂起(Accept),则用特别的返回代码通知调用者。,1.21 中断,在实时系统中,中断用于通知CPU“有异常事件发生了”。中断一旦被识别,CPU保存部分(或全部)现场(Context),即部分或全部寄存器的值,跳转到中断服务子程序(ISR)。中断服务子程序进行事件处理,处理完成后,程序回到:在前/后台系统中,程序回到后台程序;对不可

25、剥夺型内核而言,程序回到被中断了的任务;对可剥夺型内核而言,让进入就绪态的优先级最高的任务开始运行。,通过两条特殊指令:关中断(Disable interrupt)和开中断(Enable interrupt),可以让微处理器不响应或响应中断。微处理器一般允许中断嵌套。,中断延迟,实时系统最重要的指标就是关中断的时间长短。所有实时系统在进入临界区代码段之前都要关中断;执行完临界代码段之后再开中断。关中断的时间越长,中断延迟就越长。中断延迟由表达式给出:中断延迟=关中断的最长时间+开始执行中 断服务子程序的第1条指令的时间,中断响应,中断响应为从中断发生到开始执行用户的中断服务子程序代码来处理这个

26、中断的时间。对前/后台系统,保存寄存器以后立即执行用户代码,中断响应时间=中断延迟+保存CPU内部 寄存器的时间 对于不可剥夺型内核,微处理器保存内部寄存器以后,立即执行中断服务子程序代码:中断响应时间=中断延迟+保存CPU内部 寄存器的时间,对于可剥夺型内核,则要先调用一个特定的函数,该函数通知内核即将进行中断服务,使得内核可以跟踪中断的嵌套。中断响应 中断延迟+保存CPU内部寄存 器的时间+内核进入中断服 务函数的执行时间,中断恢复时间(Interrupt Recovery),中断恢复时间定义为微处理器返回到被中断了的程序代码所需要的时间。在前/后台系统中,中断恢复时间=恢复CPU内部寄存

27、器值的时间+执行中断返回指令的时间不可剥夺型内核的中断恢复时间与前/后台系统一样。中断恢复时间=恢复CPU内部寄存器值的时间+执行中断返回指令的时间,对于可剥夺型内核,在中断服务子程序的末尾要调用一个由实时内核提供的函数。该函数用于判断中断是否脱离了所有的中断嵌套。如果脱离了嵌套,内核要判断是否使得一个优先级更高得任务进入就绪态。如果是,则让优先级更高的任务开始运行。中断恢复时间=判定是否有优先级更高的任 务进入了就绪态的时间+恢 复优先级更高任务的CPU内部 寄存器的时间+执行中断返 回指令的时间,中断处理,虽然中断服务的处理时间应该尽可能的短,但是对处理时间并没有绝对的限制,根据实际应用要

28、求时间而定。,1.22 时钟节拍(Clock Tick),定义时钟节拍是特定的周期性中断。这个中断可以看作是系统心脏的脉动。中断之间的时间间隔取决于不同的应用,一般在10ms200ms之间。说明时钟的节拍式中断使得内核可以将任务延时若干个整数时钟节拍,以及当任务等待事件发生时,提供等待超时的依据。时钟节拍率越快,系统的额外开销就越大。各种实时内核都有将任务延时若干个时钟节拍的功能。一般来说,延时精度是1个时钟节拍。,1.23 对存储器的要求,对于前/后台系统,对存储器容量的需求仅仅取决于应用程序代码;而使用多任务内核时,内核本身就需要额外的代码空间(ROM)。内核的大小取决于多种因素,取决于内

29、核的特性,从1K100K字节都是可能的。总代码量=应用程序代码+内核代码,因为每个任务都是独立运行的,必须给每个任务提供单独的栈空间(RAM)。决定栈空间的大小,不仅须计算任务本身的需求(局部变量、函数调用等等),还需要计算最多中断嵌套层数。若内核不支持单独的中断用栈 RAM总需求=应用程序的RAM需求+(任务 栈需求+最多中断嵌套栈需 求)*任务数若内核支持中断用栈分离RAM总需求=应用程序的RAM需求+内核数 据区的RAM需求+各任务栈需 求之总和+最多中断嵌套栈 需求,说明为减少应用程序需要的RAM空间,对每个任务栈空间的使用都要非常小心,特别要注意以下几点:定义函数和中断服务子程序中的

30、局部变量,特别是定义大型数组和数据结构;函数(子程序)的嵌套;中断嵌套;库函数需要的栈空间;多变元的函数调用。,综上所述,多任务系统比前/后台系统需要更多的代码空间(ROM)和数据空间(RAM)。额外的代码空间取决于内核的大小,而RAM的用量取决于系统中的任务数。,2.1 C/OS简介,C/OS-Micro Controller OS,微控制器操作系统。C/OS简介美国人Jean Labrosse 1992年完成;1998年出版C/OS-V2.0版;2002年出版C/OS-第2版本;目前的版本C/OS-V2.72;2000年,得到美国航空管理局(FAA)的安全认证,可以用于飞行器中。应用面覆盖

31、了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等。网站),2.2 C/OS-的性能特点,公开源代码 提供C/OS-的V2.52全部源代码(约5500行),并进行详细的注解。可移植性(Portable)绝大部分是用移植性很强的ANSI C写的,与微处理器硬件相关的部分是用汇编语言写的。汇编语言写的部分已经压到最低限度,使得C/OS-便于移植到其他微处理器上。C/OS-可以在绝大多数8位、16位、32位以至64位微处理器、微控制器、数字信号处理器(DSP)上运行。,可固化(ROMable)C/OS-是为嵌入式应用而设计的,这就意味着,只要具备合适的系列软件工具(

32、C编译、连接、下载和固化),C/OS-可以嵌入到产品中成为产品的一部分。,可裁剪(Scalable)可以只使用C/OS-中应用程序需要的系统服务。也就是说某产品可以只使用很少几个 C/OS-调用,而另一个产品则使用了几乎所有 C/OS-的功能,这样可以减少产品中的C/OS-所需的存储器空间(RAM和ROM)。可剪裁性是靠条件编译实现的。可剥夺性(preemptive)C/OS-是完全可剥夺型的实时内核,即C/OS-总是运行就绪条件下优先级最高的任务。,多任务 C/OS-可以管理64个任务,然而,目前这一版本保留8个给系统。应用程序最多可以有56个任务。可确定性 全部C/OS-的函数调用与服务的

33、执行时间具有可确定性。任务栈 每个任务有自己单独的栈。C/OS-允许每个任务有不同的栈空间,以便压低应用程序对RAM的需求。,系统服务 C/OS-提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。中断管理 中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。稳定性与可靠性 C/OS-在2000年7月得到美国航空管理局(FAA)的认证,可以用于飞行器中。,2.3 C/OS-提供的系统服务,信号量带互斥机制的信号量减少优先级反转的问题事件标志消息信箱消息队列内存管理时钟

34、管理任务管理,C/GUI 嵌入式用户界面用ANSI C书写;支持任何8、16、32-bits CPU;彩色,灰度,等级或黑白显示;代码尺寸小。C/FS 嵌入式文件系统用ANSI C书写;支持任何8、16、32-bits CPU;支持SMC,MMC,SD,CF,IDE,Flash,RAM其他介质。,提供的软件产品:,2.4 C/OS-的各种商业应用,C/OS-的文件结构,3.1 临界段(Critical Sections),C/OS-为了处理临界段代码须关中断,处理完毕后再开中断。关中断使得C/OS-能够避免同时有其他任务或中断服务进入临界代码段。关中断的时间是实时内核开发商应提供的最重要的指标

35、之一,因为这个指标影响用户系统对实时事件的响应性。C/OS-努力使关中断时间降至最短,但就使用C/OS-而言,关中断的时间很大程度上取决于微处理器的架构以及编译器所生成的代码质量。,C/OS-定义两个宏(macros)来关中断和开中 断。C/OS-中的这两个宏调用分别是:OS_ENTER_CRITICAL()OS_EXIT_CRITICAL(),OS_CRITICAL_METHOD1 用处理器指令关中断,完成OS_ENTER_CRITICAL();开中断完成OS_EXIT_CRITICAL()。OS_CRITICAL_METHOD2 在堆栈中保存中断的开/关状态,然后再关中断。在实现开中断时,

36、只需要从堆栈中弹出原来中断的开/关状态即可。,OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()可用 三种不同的方法来实现。,具体使用哪种方法取决于用户打算移植到的处理 器的性能以及所用的C编译器。用定义(define)常数OS_CRITICAL_METHOD可 以选择具体使用那种方法。该常数是在用户程序(即产品)的移植文件OS_CPU.H中定义的。,OS_CRITICAL_METHOD3 将能得到的当前处理器的状态字的值(一些编译器)保存在C的局部变量中。该变量可恢复PSW。开、关中断各需一个局部变量。,C/OS-中的这两个宏定义:.OS_ENTER_CRITICA

37、L();/*C/OS-临界代码段*/OS_EXIT_CRITICAL();.,说明 使用时特别小心,如果调用一些如OSTimeDel()之类的功能函数之前关中断,应用程序将会崩 溃。普通使用规则,调用C/OS-功能函数时,中 断总应是开着的。,3.2 任务,任务通常是一个无限的循环。任务看起来像其它C的函数一样,有函数返回类型,有形式参数变量,但是任务是绝不会返回的。故返回参数必须定义成void。任务的两种结构第一种形式:执行无限循环的任务第二种形式:任务完成后就自我删除,void YourTask(void*pdata)(1)for(;)(2)/*用户代码*/*调用uC/OS-II的某种系统

38、服务:*/OSFlagPend();OSMboxPend();OSMutexPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/*用户代码*/,第一种形式:执行无限循环的任务,第二种形式:任务完成后就自我删除 void YourTask(void*pdata)/*用户代码*/OSTaskDel(OS_PRIO_SELF);,两者的共同点:都有一个C/OS-的系统调用,以保证函数不返回和让出CPU的资源。不同点:对于第二种形式,当

39、任务完成后,任务可以自我删除。,说明任务代码并非真的删除了,C/OS-只是简单地不再理会这个任务了,这个任务的代码也不会再运行,即使任务调用了OSTaskDel(),这个任务绝不会返回。形式参数变量是由用户代码在第一次执行的时候带入的。该变量的类型是一个指向void的指针。这是为了允许用户应用程序传递任何类型的数据给任务。,3.3 任务的状态,C/OS-中每个任务5种状态,下图为C/OS-的任务状态转换图:,睡眠态(Dormant)指任务驻留在程序空间中,还没有交给C/OS-管理,把任务交给C/OS-是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt()。

40、就绪态(Ready)当任务一旦建立,这个任务就进入就绪态准备运行。任务的建立可以是在多任务运行开始之前,也可以是动态地被一个运行着的任务建立。,运行态(Running)准备就绪的最高优先级的任务获得CPU的控制权,从而处在运行态。(调用OSStart()可以启动多任务)。任何时候只有一个任务处于运行态。指针OSTCBCur指向正在运行的任务。等待或挂起态(Pending)正在运行的任务由于调用延时函数OSTimeDly()或等待事件信号量的来临而将自身挂起,因而处于等待或挂起态。因等待某事件而被挂起的任务放在该事件的等待列表中。,中断态(Interrupt)正在运行的任务可以被中断。除非是该任

41、务将中断关闭。被中断了任务进入中断服务态(ISR)。如果中断服务程序使一个更高优先级的任务准备就绪,在中断服务程序结束后,最高优先级的任务开始运行。,3.4 任务控制块(OS_TCB),任务控制块 OS_TCB是一个数据结构,保存该任务的相关参数,包括任务堆栈指针、状态、优先级、任务表位置、任务链表指针等。当任务重新获得CPU使用权时,任务控制块能确保任务从当时被中断的那一点继续执行。,一旦任务建立,一个任务控制块OS_TCB就被赋值,程序清单如下:,typedef struct os_tcb OS_STK*OSTCBStkPtr;#if OS_TASK_CREATE_EXT_EN0 void

42、*OSTCBExtPtr;OS_STK*OSTCBStkBottom;INT32U OSTCBStkSize;INT16U OSTCBOpt;INT16U OSTCBId;#endif struct os_tcb*OSTCBNext;struct os_tcb*OSTCBPrev;#if(OS_Q_EN 0#endif,#if(OS_Q_EN 0#endif,INT16U OSTCBDly;INT8U OSTCBStat;INT8U OSTCBPrio;INT8U OSTCBX;INT8U OSTCBY;INT8U OSTCBBitX;INT8U OSTCBBitY;#if OS_TASK_D

43、EL_EN 0 BOOLEAN OSTCBDelReq;#endif OS_TCB;,任务控制块OS_TCB中几个成员的算法,OSTCBY=priority 3;OSTCBBitY=OSMapTblpriority 3;OSTCBX=priority,任务控制块链表 所有的任务控制块分为两条链表,空闲链表和使用链表。所有的任务控制块都被放置在任务控制块列表数组OSTCBTbl中,系统初始化时,所有任务控制块被链接成空任务控制块的单向链表,任务建立后,空任务控制块指针OSTCBFreeList指向的任务控制块就赋给了该任务,然后OSTCBFreeList的值调整为指向链表中的下一个空任务控制块。

44、一旦任务被删除,任务控制块就还给空任务链表。,任务控制块初始化,INT8U OS_TCBInit(INT8U prio,OS_STK*ptos,OS_STK*pbos,INT16U id,INT32U stk_size,void*pext,INT16U opt),OS_TCBInit接收7个参数:prio 任务优先级,保存在OSTCBPrio中。ptos 是指向栈顶的指针,保存在OSTCBStkPtr中。pbos 指向栈底的指针,保存在OSTCBStkBottom中。id 任务标识符,保存在.OSTCBId中。stk_size 栈的容量,保存在OSTCBStkSize中。pext OS_TCB

45、中的扩展指针.OSTCBExtPtr的值。opt OS_TCB中的选择项,保存在.OSTCBOpt中。,3.5 就绪表(Ready List),C/OS-是可剥夺型实时多任务内核,优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。每个任务被赋予唯一的不同的优先级,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。,就绪表(Ready List),每个任务被赋予不同的优先级等级,从0级到最低优先级OS_LOWEST_PRIO。当C/OS-初始化的时候,最低优先级OS_LOWEST_PRIO总是被赋给空闲任务idle task。高优先级有小优先级号。最多任务数目

46、OS_MAX_TASKS和最低优先级数是没有关系的。,每个就绪的任务都放入就绪表中(ready list)中,就绪表有两个变量:OSRdyGrp、OSRdyTbl。,使任务进入就绪态,根据任务的优先级确定就绪表,即把任务在就绪表中所对应的位置置1。,举例假设优先级为12的任务进入就绪状态,12=1100b,则OSRdyTbl1的第4位置1,且OSRdyGrp的第1位置1,相应的数学表达式为:OSRdyGrp|=0000 0010=0 x02;OSRdyTbl1|=0001 0000=0 x10;而优先级为21的任务就绪21=10 101b,则OSRdyTbl2的第3位置1,且OSRdyGrp的

47、第2位置1,相应的数学表达式为:OSRdyGrp|=0000 0100=0 x04;OSRdyTbl2|=0010 0000=0 x20;,OSMapTbl用于限制OSRdyTbl数组为07,是在ROM中的(见文件OS_CORE.C)屏蔽字。从上面的计算我们可以得到:若OSRdyGrp及OSRdyTbl的第n位置1,则应该把OSRdyGrp及OSRdyTbl的值与2n相或。C/OS中,把2n的n=0-7的8个值先计算好存在数组OSMapTbl中,也就是:OSMapTbl0=20=0 x01(0000 0001)OSMapTbl1=21=0 x02(0000 0010)OSMapTbl7=27=

48、0 x80(1000 0000),定义数组OSMapTbl,如果prio是任务的优先级,也是任务的识别号,则将任务放入就绪表,即使任务进入就绪态的 方法是:OSRdyGrp|=OSMapTblprio3;OSRdyTblprio3|=OSMapTblprio,将任务置为就绪态,使任务脱离就绪态,将任务就绪表OSRdyTblprio3相应元素的相应位清零,而且当OSRdyTblprio3中的所有位都为零时,即全组任务中没有一个进入就绪态时,OSRdyGrp的相应位才为零。If(OSRdyTblprio3,根据就绪表确定最高优先级的任务,进入就绪态的任务有多个,从中确定优先级高的任务。确定方法举例

49、说明:通过OSRdyGrp值确定高3位通过OSRdyTbl的值来确定低3位,任务优先级,查表法具有确定的时间,增加了系统的可预测性,C/OS中所有的系统调用时间都是确定的 High3=OSUnMapTblOSRdyGrp;Low3=OSUnMapTblOSRdyTblHigh3;Prio=(Hign33)+Low3;,优先级判定表 OSUnMapTbl256,INT8U 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,

50、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,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号