七、嵌入式系统设计与开发_第1页
七、嵌入式系统设计与开发_第2页
七、嵌入式系统设计与开发_第3页
七、嵌入式系统设计与开发_第4页
七、嵌入式系统设计与开发_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌入式系统设计与开发

第7章C/OS-Ⅱ实时操作系统本章提要7.1C/OS-Ⅱ实时操作系统概述7.2C/OS-Ⅱ的内核结构7.3多任务同步机制7.4C/OS-Ⅱ中的根本数据类型7.5C/OS-Ⅱ在ARM上的移植7.1C/OS-Ⅱ实时操作系统概述μC/OS-II读做“microCOS2”,意为“微控制器操作系统版本2”。μC/OS-II是源码公开的著名实时内核,可用于各类8位、16位和32位单片机或DSP。从μC/OS算起,该内核已有10多年应用史,在诸多领域得到广泛应用。μC/OS-II是一个完整的、可移植、可固化、可剪裁的占先式实时多任务内核。μC/OS-II使用ANSIC语言编写,包含一小局部汇编代码,使之可以供不同架构的微处理器使用。至今,从8位到64位,μC/OS-II已在超过40种不同架构的微处理器上运行。实时系统概念1.任务任务是一个简单的程序,也称作一个线程,该程序可以认为CPU完全属于该程序占用。2.任务切换多任务系统中,任务切换是指CPU的控制权由当前运行任务转移到另外一个准备就绪任务时所发生的事件。3.操作系统内核多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通信,内核提供的根本效劳是任务切换。4.调度调度是内核的主要职责之一,就是决定该轮到哪个任务运行,多数实时内核是基于优先级调度法的。5.可重入性可重入性是指可重入型函数可以被一个以上的任务调用,而不必担忧数据被破坏。6.任务优先级每个任务都有其优先级,任务越重要,赋予的优先级应越高。8.优先级继承优先级继承可以用来解决优先级反转的问题。9.互斥互斥是用来控制多任务对共享数据进行访问的同步机制。10.中断延迟中断延迟是指从硬件中断发生的一条指令,到开始执行中断处理程序的一条指令之间的这段时间。11.时钟节拍时钟节拍是特定的周期性中断,这个中断可以看作是系统心脏的脉动。C/OS-Ⅱ的主要特点1.源代码开放购置作者撰写的《嵌入式实时操作系统μC/OS-II》一书即可获得μC/OS-IIV2.52版本的所有源代码,购置此书的其它版本可以获得相应版本的全部源代码。2.可移植性μC/OS-II的源代码绝大局部是使用移植性很强的ANSIC写的,将与微处理器硬件相关的汇编语言使用量压缩到最低的限度,以使μC/OS-II便于移植到其它微处理器上。目前,μC/OS-II已经被移植到多种不同架构的微处理器上。3.可固化性只要具备适宜的软硬件工具,就可以将μC/OS-II嵌入到产品中成为产品的一局部。4.可剪裁性μC/OS-II使用条件编译实现可剪裁,用户程序可以只编译自己需要的〔μC/OS-II的〕功能,而不编译不要需要的功能,以减少μC/OS-II对代码空间和数据空间的占用。5.抢占性μC/OS-II是抢占性的实时内核.这意味着μC/OS-II总是运行就绪条件下优先级最高任务。6.多任务μC/OS-II可以管理64个任务,然而,μC/OS-II的作者建议用户保存8个给μC/OS-II。这样,留给用户的应用程序最多可有56个任务。7.可确定性绝大多数μC/OS-II的函数调用和效劳的执行时间具有确定性,也就是说,用户总是能知道μC/OS-II的函数调用与效劳执行了多长时间。8.任务栈μC/OS-II的每个任务都有自己单独的栈,使用μC/OS-II的占空间校验函数,可确定每个任务到底需要多少栈空间。9.系统效劳μC/OS-II提供很多系统效劳,例如信号量、互斥信号量、时间标志、消息邮箱、消息队列、块大小固定的内存的申请与释放及时间管理函数等。10.中断管理中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被中断唤醒,那么高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。11.稳定性与可靠性μC/OS-II是μC/OS的升级版,μC/OS自1992年以来已经有数百个商业应用。μC/OS-II与μC/OS的内核是一样的,只是提供了更多的功能。2000年7月,μC/OS-II在一个航空工程中得到了美国联邦航空管理局对商用飞机的、符合RTCADO–178B标准的认证。这说明,该操作系统的质量得到了认证,可以在任何应用中使用。EnglishISBN1-57820-103-9美国CMPBOOKChineseISBN7-81077-290-2北京航空航天大学出版社KoreanISBN89-951540-5-57.2μC/OS-II的内核结构μC/OS-II内核保护机制在多任务与中断并存的实时操作系统中,为了保护核心区代码,μC/OS-II的内核需要在存取代码核心区时禁止中断,存取完成后再将中断重新翻开,以免出现多个任务或中断效劳程序同时进入该代码区。中断禁止时间是实时内核的一项最重要的指标,因为它影响着系统对实时事件的响应能力。μC/OS-II试图将这段中断禁止时间减至最小。但是,这在很大程度上还取决于系统的CPU结构,以及编译器生成的代码质量。μC/OS-II定义了两个宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来实现对中断的允许和禁止,关中断和开中断是为了保护临界段代码,这些代码与处理器有关,是需要移植的代码。OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()可以有3种不同的实现方法:〔1〕方法1:#defineOS_CRITICAL_METHOD1这是最简单的一种实现OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()的方法。如果用户在中断禁止的情况下调用了一个μC/OS-II函数,而在从一个μC/OS-II函数返回时,中断将被允许。但是,如果用户在调用μC/OS-II之前已禁止了中断,而一般在调用返回以后仍要求禁止中断。〔2〕方法2:#defineOS_CRITICAL_METHOD2这种实现方法在实现OS_ENTER_CRITICAL()时,是将禁止的中断状态保存在堆栈中,然后禁止中断。而OS_EXIT_CRITICAL()的实现只需简单地将中断状态从堆栈中恢复出来。无论是在中断禁止时,还是中断允许时调用μC/OS-II效劳,都可以在该调用前后保存中断状态。〔3〕方法3:#defineOS_CRITICAL_METHOD3有些编译器提供了一些功能扩展,允许用户获取CPU状态〔PSW〕,并可将它存入函数的局部变量中。于是,这一变量被重新恢复到PSW中,就可以用伪码表示。任务一个任务,也称作一个线程,是一个简单的程序,该程序可以认为CPU完全属于该程序自身。在C语言中,任务一般是指一个无限循环函数。任务函数voidmyTask(void*pdata) {for(;;){ /*用户代码*//*调用uC/OS-II效劳*/OSFlagPend();OSMboxPend();OSMutexPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/*用户代码*/}}自动删除任务voidmyTask(void*pdata){/*用户代码*/OSTaskDel(OS_PRIO_SELF);}任务状态实时应用程序的设计过程,包括如何把问题分割成多个任务,每个任务都是整个应用的某一局部,被赋予一定的优先级,有它自身的一套CPU存放器和自己的栈空间。多任务运行的实现实际上是靠CPU在许多任务之间转换和调度。CPU只有一个,轮番效劳于一系列任务中的某一个。每个任务都处在5种状态之中,这5种状态是休眠态、就绪态、运行态、挂起态和被中断态。挂起休眠准备运行ISR中断OSIntExit〔〕TaskisPreemptedOSTaskDel〔〕OSTaskDel〔〕OSTaskDel〔〕OSTaskCreate〔〕OSTaskCreateExit〔〕OSMBoxPend〔〕OSQPend〔〕OSSernPend〔〕OSTaskSuspend〔〕OSTimeDly〔〕OSTimeDlyHMSM〔〕OSMBoxPost〔〕OSQPost〔〕OSQPostFront〔〕OSSernPost〔〕OSTaskResume〔〕OSTimeDlyResume〔〕OSTimeTick〔〕OSStart〔〕OSIntExit〔〕OSTASKSW〔〕任务控制块任务控制块OS_TCB是一个数据结构,保存该任务的相关参数,包括任务堆栈指针,状态,优先级,任务表位置,任务链表指针等。所有的任务控制块分为两条链表,空闲链表和使用链表。OS_TCB控制模块定义如下:typedefstructos_tcb{OS_STK*OSTCBStkPtr;#ifOS_TASK_CREATE_EXT_EN>0void*OSTCBExtPtr;OS_STK*OSTCBStkBottom;INT32UOSTCBStkSize;INT16UOSTCBOpt;INT16UOSTCBId;#endifstructos_tcb*OSTCBNext;structos_tcb*OSTCBPrev;#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN||OS_SEM_ENOS_EVENT*OSTCBEventPtr;#endif#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_ENvoid*OSTCBMsg;#endifINT16UOSTCBDly;INT8UOSTCBStat;INT8UOSTCBPrio;INT8UOSTCBX;INT8UOSTCBY;INT8UOSTCBBitX;INT8UOSTCBBitY;#ifOS_TASK_DEL_ENBOOLEANOSTCBDelReq;#endif}OS_TCB;控制块说明:1.OSTCBStkPtr指向当前任务栈顶的指针。2.OSTCBExtPtr指向用户定义的任务控制块扩展。3.OSTCBStrBottom指向任务栈底的指针。4.OSTCBStrSizeOSTCBStrSize用来保存栈中可容纳的指针元数目而不是用字节〔Byte〕表示的栈容量总数。5.OSTCBOpt它存储了传给OSTaskCreateExt()的选择,只有在用户将OS_TASK_CREATE_EXT_EN设为1时,这个变量才有效。6.OSTCBld用于存储任务的识别码〔ID〕。7.OSTCBNext和OSTCBPrev用于任务控制块OS_TCBs的双重链接。8.OSTCBEventPtr指向事件控制块的指针。9.OSTCBMsg指向传给任务的消息的指针。10.OSTCBDly当需要把任务延时假设干个时钟节拍,或者需要把任务挂起一段时间以等待某事件的发生时要用到这个变量。11.OSTCBStat任务的状态字。12.OSTCBPrio任务优先级。13.OSTCBX、OSTCBY、OSTCBBitX和OSTCBBitY用于加速任务进入就绪态的过程或者进入等待事件发生状态的过程。14.OSTCBDelReq布尔量,用于表示该任务是否需要删除。任务调度

C/OS-Ⅱ总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高以及应该哪个任务运行了,这些工作都是由调度器完成的,任务级的调度是由函数OSSched()完成的,中断级的调度是由另一个函数OSIntExt()完成。下面分析任务级的调度函数OSSched()的代码voidOSSched(void){INT8Uy;OS_ENTER_CRITICAL();if((OSLockNesting|OSIntNesting){ y=OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]])if(OSPrioHighRdy!=OSPrioCur){ OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; OS_TASK_SW(); }}OS_EXIT_CRITICAL();}7.3同步任务间信息的传递有两个途径:通过全局变量或发消息给另一个任务。用全局变量时,必须保证每个任务或中断效劳程序独享该变量。中断效劳中保证独享的唯一方法是关中断。如果两个任务共享某变量,各任务实现独享该变量的方法可以是先关中断再开中断,或使用信号量。消息邮箱典型的消息邮箱也称作交换消息,是用一个指针型变量,通过内核效劳,一个任务或一个中断效劳程序可以把一那么消息放到邮箱里去。邮箱是µC/OS-II中另一种通讯机制,它可以使一个任务或者中断效劳子程序向另一个任务发送一个指针型的变量。该指针指向一个包含了特定“消息”的数据结构。为了在µC/OS-II中使用邮箱,必须将OS_CFG.H中的OS_MBOX_EN常数置为1。使用邮箱之前,必须先建立该邮箱。该操作可以通过调用OSMboxCreate()函数来完成,并且要指定指针的初始值。µC/OS-II提供了5种对邮箱的操作:OSMboxCreate(),OSMboxPend(),OSMboxPost(),OSMboxAccept()和OSMboxQuery()函数1.等待邮箱消息使用OSMboxPend()函数等待邮箱消息。2.发送消息使用OSMboxPost()函数发送消息。通过消息邮箱进行通信voidmyTask1(void*pdata){char*Msg;INT8Uerr;for(;;){/*等待邮箱消息*/Msg=(char*)OSMboxPend(Mbox1,0,&err);用户程序/*将接受到的邮箱信息发送到Mbox2*/OSMboxPost(Mbox,Msg);}}voidmyTask2(void*pdata){char*Msg;INT8Uerr;for(;;){/*等待邮箱消息*/Msg=(char*)OSMboxPend(Mbox2,0,&err);用户程序/*将接收到的邮箱信息发送到Mbox1*/OSMboxPost(Mbox1,Msg);}}任务、中断效劳子程序和邮箱之间的关系7.4C/OS-Ⅱ中的根本数据类型整数数据类型类型名称类型含义数据长度(位)BOOLEAN布尔类型8INT8U8位无符号整数8INT8S8位有符号整数8INT16U16位无符号整数16INT16S16位有符号整数16INT32U32位无符号整数32INT32S32位有符号整数32FP32单精度浮点数32FP64双精度浮点数647.5C/OS-Ⅱ在ARM上的移植所谓移植,是指使一个实时内核能在某个微处理器或微控制器上运行。

COS-II的主要代码都是由标准的C语言写成的,移植方便。在移植前针对所使用的微处理器进行规划,主要有以下几个方面的考虑:编译器的选择、任务模式的选择和支持的指令集。要使C/OS-Ⅱ正常运行,处理器必须满足以下要求:处理器的C编译器能产生可重入代码用C语言就可以翻开或关闭中断处理器支持中断,并且能产生定时中断〔通常在10—100Hz之间〕处理器支持能够容纳一定量数据的硬件堆栈处理器有将堆栈指针和其他CPU存放器读出并存储到堆栈或内存中的指令移植步骤C/OS-Ⅱ体系结构移植工作包括以下几个内容:用#define设置一个常量的值〔OS_CPU.h文件中〕声明10个数据类型〔OS_CPU.h文件中〕用#define声明3个宏〔OS_CPU.h文件中〕用C语言编写6个简单的函数〔OS_CPU_C.c文件中〕编写4个汇编语言函数〔OS_CPU_A.asm文件中〕1.OS_CPU.h文件OS_CPU.h包括了用#define定义的与处理器相关的常量、宏和类型定义。2.修改后的OS_CPU.h文件3.OS_CPU_A.asm文件在OS_CPU_A.asm文件中,C/OS-Ⅱ的移植要求用户编写以下4个简单的汇编语言函数:OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()和OSTickISR(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论