《第章 嵌入式实时操作系统分析(上UCOS分析,参考资料).ppt》由会员分享,可在线阅读,更多相关《第章 嵌入式实时操作系统分析(上UCOS分析,参考资料).ppt(39页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第 八章嵌入式实时操作系统(C/OS)分析嵌入式实时操作系统C/OS嵌入式LinuxWinCE嵌入式实时操作系统C/OSC/OS简介C/OS内核结构C/OS简介C/OS即MicroC/OS,微控制器操作系统美国人Jean Labrosse 1992年完成应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等 1998年C/OS-II,目前最新的版本是C/OS-II V2.70网站www.ucos-II.comC/OS II的特点公开源码可移植性 C/OS II源码绝大部分是用移植性很强的ANSI C写的,与微处理器硬件相关的部分是用汇编语言写的,汇编语言
2、写的部分已经压到最低限度,以使C/OS II便于移植到其他微处理器上。C/OS II可以在绝大多数8位、16位、32位以至64位微处理器、微控制器及数字信号处理器(DSP)上运行。可裁减(scalable)可以只使用 C/OS-II中应用程序需要的那些系统服务。也就是说某产品可以只使用很少几个 C/OS-II调用,而另一个产品则使用了几乎所有 C/OS-II的功能,这样可以减少产品中的 C/OS-II所需的存储器空间(RAM和ROM)。这种可剪裁性是靠条件编译实现的。可剥夺性(preemptive)C/OS-II是完全可剥夺型的实时内核,即 C/OS-II总是运行就绪条件下优先级最高的任务。多
3、任务 C/OS-II可以管理64个任务;然而,目前这一版本保留8个给系统。应用程序最多可以有56个任务。可确定性绝大多数 C/OS-II的函数调用与服务的执行时间具有可确定性。任务栈每个任务有自己单独的栈,C/OS-II允许每个任务有不同的栈空间,以便压低应用程序对RAM的需求。系统服务 C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。中断管理中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。稳定性与可靠性C/OS-II内核结构C/OS-II的文件
4、结构任务管理时间管理任务间通信C/OS-II的文件结构 C/OS-II(与处理器类型无关的代码与处理器类型无关的代码)OS_CORE.COS_FLAG.COS_MBOX.COS_MEM.COS_MUTEX.COS_Q.COS_SEM.COS_TASK.COS_TIME.CuCOS_II.CuCOS_II.H C/OS-II配置文件配置文件(与应用程序有关)(与应用程序有关)OS_CFG.HINCLUDES.H移植移植 C/OS-II(与处理器类型有关的代码)与处理器类型有关的代码)OS_CPU.HOS_CPU_A.ASMOS_CPU_C.C任务管理建立任务任务格式任务状态任务调度任务切换建立任
5、务OS TaskCreate()OSTaskCreateExtended()分配任务堆栈的分配任务堆栈的栈顶指针栈顶指针分配给任务的优先级分配给任务的优先级任务参数指任务参数指针针任务代任务代码指针码指针 checkSet pointer if level is freeSet up task stackInitialize TCBOption to extend functionalityIf called from a taskAs before任务格式任务通常是一个无限循环。每个任务不能占用全部CPU的资源。需要有等待,或延时等系统调用。void task(void*pdata)for(
6、;)/*用户代码*/*调用C/OS-II 的某些功能函数*/*用户代码*/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_PRIO-0。任务状态睡眠态就绪态运行态等待状态中断服务状态任务控制块(OS_TCB)任务一旦建立,一个任务控制块OS_TCB就被赋值。任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,C/OS-II用它来保存该任务的状态。当任务重新得到CPU的使用权时,任务
7、控制块能确保任务从中断处继续执行。任务控制块 OS_TCB是一个数据结构,保存该任务的相关参数,包括任务堆栈指针,状态,优先级,任务表位置,任务链表指针等。所有的任务控制块分为两条链表,空闲链表和使用链表。任务控制块结构任务控制块结构0S_TCBStruct os_tcb OS_STK *OSTCBStkPtr;struct os_tcb*OSTCBNext;struct os_tcb*OSTCBprev;OS_EVENT *OSTCBEventPtr;void *OSTCBMsg;INT16U OSTCBDly;INT8U OSTCBStat;INT8U OSTCBPrio;INT8U OS
8、TCBX,OSTCBY,OSTCBBitX,OSTCBBitY;OS_TCB事件控制块的指针任务的状态字加速任务进入就绪态的过程空任务控制块列表空任务控制块列表系统初始化时,所有任务控制块被链接成空任务控制块的单向链表。任务调度C/OS-II是占先式实时多任务内核,优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。C/OS-II中任务级的调度是由函数OSSched()完成的,每个任务的优先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。C/OS-II任务调度所花的时间为常数,与应用程序中建立的任务数无关。检查是否中断调用和允许任务调
9、用找到优先级最高的任务该任务是否正在运行任务级的任务切换任务级的任务切换OS_TASK_SW系统调用指令完成保护当前任务的现场恢复新任务的现场执行中断返回指令开始执行新的任务中断与时钟节拍C/OS-II需要提供周期性信号源,用于实现时间延时和确认超时。C/OS-II中的时钟节拍服务是通过中断服务子程序钟调用OSTimeTick()实现的。OSTimeTick()跟踪所有任务的定时器以及超时时限。中断与时钟节拍中断与时钟节拍 当发生中断时,首先应保护现场,将CPU寄存器入栈,再处理中断函数,然后恢复现场,将CPU寄存器出栈,最后执行中断返回iret(x86)指令实现中断返回。C/OS-II中提供
10、了OSIntEnter()和OSIntExit()告诉内核进入了中断状态。时钟节拍是一种特殊的中断,操作系统的心脏。首先32位的整数OSTime加一。对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态,最后进行上下文切换。时间管理OSTimeDly()OSTimeDlyHMSM()OSTimeDlyResume()OSTimeGet()OSTimeSet()OSTimeDly()是C/OS-II提供的一个可以被任务调用而将延时一段特定时间的功能函数。调用该函数会使C/OS-II进行一次任务调度,从而去执行下一个优先级最高的就绪态任务。void OSTimeDly(INT16U tick
11、s)if(ticks 0)/确保tick大于0 OS_ENTER_CRITICAL();/进入临界段代码 if(OSRdyTblOSTCBCur-OSTCBY&=OSTCBCur-OSTCBBitX)=0)/*Delay current task */设置任务为非就绪状态 OSRdyGrp&=OSTCBCur-OSTCBBitY;OSTCBCur-OSTCBDly=ticks;/在TCB中装载延时数 OS_EXIT_CRITICAL();/退出临界段代码 OSSched();/调度下一个任务开始运行 OSTimeDlyHMSM()函数功能同OSTimeDly()一样,不同的是它是按小时、分、秒
12、及毫秒来定义延时时间的。OSTimeDlyResume()函数功能是恢复延时的任务。延时的任务可以不等待延时期满,而是通过其他任务取消延时而使自己处于就绪态。无论时钟节拍何时发生,C/OS-II 都会将一个32位的计数器加1。调用OSTimeGet()可以获得该计数器的当前值;也可以通过调用 OSTimeSet(),改变该计数器的值。任务间的通信C/OS-II中,采用多种方法保护任务之间的共享数据和提供任务之间的通信。提供OS_ENTER_CRITICAL和OS_EXIT_CRITICAL来对临界资源进行保护。OSSchedLock()禁止调度保护任务级的共享资源。提供了经典操作系统任务间通信
13、方法:信号量、邮箱、消息队列,事件标志。事件控制块(事件控制块(ECB)所有的通信信号都被看成是事件所有的通信信号都被看成是事件(event),一个称为事件控制一个称为事件控制块块(ECB,Event Control Block)的数据结构来表征每一个具体事的数据结构来表征每一个具体事件,件,ECB的结构如下:的结构如下:-typedef struct INT8U OSEventType;/*事件类型事件类型*/INT8U OSEventGrp;/*等待任务所在的组等待任务所在的组*/INT16U OSEventCnt;/*计数器(当事件是信号量时)计数器(当事件是信号量时)*/void *O
14、SEventPtr;/*指向消息或者消息队列的指针指向消息或者消息队列的指针*/INT8U OSEventTblOS_EVENT_TBL_SIZE;/*等待任务列表等待任务列表*/OS_EVENT;与与TCB类似的结构,使用两个链表,空闲链表与使用链表类似的结构,使用两个链表,空闲链表与使用链表信号量信号量信号量在多任务系统中用于:控制共享资源的使用权、标志事件的发生、使两个任务的行为同步C/OS-II中信号量由两部分组成:信号量的计数值和等待该信号任务的等待任务表。信号量的计数值可以为二进制,也可以是其他整数。系统通过OSSemPend()和OSSemPost()来支持信号量的两种原子操作P
15、()和V()。P()操作减少信号量的值,如果新的信号量的值不大于0,则操作阻塞;V()操作增加信号量的值。多任务的启动首先系统初始化OSInit()然后建立任务OSTaskcreat()最后调用OSStart()开始多任务调度void main()OSInit();.OSTaskcreat().OSStart();在调用C/OS-II的任何其他服务之前,C/OS-II首先调用系统初始化函数OSInit()。OSInit()初始化C/OS-II所有的变量和数据结构。OSInit()建立空闲任务OS_TaskIdle(),这个任务总是处于就绪态。空闲任务OS_TaskIdle()的优先级总是设成最
16、低,即OS_LOWEST_PRIO。同时OSInit()还要建立统计任务OS_TaskStat(),并且使其进入就绪态。OS_TaskStat()的优先级总是设为OS_LOWEST_PRIO-1。什么也不做的空闲任务,只是为了消耗CPU的时间片void OSTaskIdle()for(;)OS_ENTER_CRITICAL();OSIdleCtr+;OS_EXIT_CRITICAL();/end of forvoid OSStart(void)INT8U y,x;if(OSRunning=FALSE)/判断是否没有启动内核 y=OSUnMapTblOSRdyGrp;x=OSUnMapTblOSRdyTbly;OSPrioHighRdy=(INT8U)(y 3)+x);/找到优先级最高的准备就绪任务 OSPrioCur =OSPrioHighRdy;/当前运行任务优先级 OSTCBHighRdy =OSTCBPrioTblOSPrioHighRdy;/根据任务优先级找到任务 OSTCBCur=OSTCBHighRdy;OSStartHighRdy();/让优先级最高的任务运行起来