您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 其它办公文档 > 第4章 基于ARM9和μCOS-II嵌入式系统设计
第4章基于ARM9和µC/OS-II嵌入式系统设计第4章基于ARM9和µC/OS-II嵌入式系统设计4.1µC/OS-II的内核4.2µC/OS-II的API函数4.3µC/OS-II的应用程序开发4.4µC/OS-II在S3C2410X上的移植4.5µC/OS-II的API应用4.6基于µC/OS-II操作系统的开发案例第4章基于ARM9和µC/OS-II嵌入式系统设计4.1µC/OS-II的内核多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。内核提供的基本服务是任务切换。之所以使用实时内核可以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。内核本身也增加了应用程序的额外负荷,代码空间增加ROM的用量,内核本身的数据结构增加了RAM的用量。但更主要的是,每个任务要有自己的栈空间,占用相当部分的内存空间。内核本身对CPU的占用时间一般在2到5个百分点之间。UC/OS-II有一个精巧的内核调度算法,实时内核精小,执行效率高,算法巧妙,代码空间很少。第4章基于ARM9和µC/OS-II嵌入式系统设计4.1.1µC/OS-II内核调度特点µC/OS-II内核调度主要有如下特点:●只支持基于优先级的抢占式调度算法,不支持时间片轮训。●64个优先级,只能创建64个任务,用户只能创建56个任务。●每个任务优先级都不相同。●不支持优先级逆转。●READY队列通过内存映射表实现快速查询。效率非常高。●支持时钟节拍。●支持信号量,消息队列,事件控制块,事件标志组,消息邮箱任务通讯机制。第4章基于ARM9和µC/OS-II嵌入式系统设计●支持中断嵌套,中断嵌套层数可达255层,中断使用当前任务的堆栈保存上下文。●每个任务有自己的堆栈,堆栈大小用户自己设定。●支持动态修改任务优先级。●任务TCB为静态数组,建立任务只是从中获得一个TCB,不用动态分配,释放内存。●任务堆栈为用户静态或者动态创建,在任务创建外完成,任务创建本身不进行动态内存分配。●任务的总个数(OS_MAX_TASKS)由用户决定。●0优先级最高,63优先级最低;●有一个优先级最低的空闲任务,在没有用户任务运行时运行。第4章基于ARM9和µC/OS-II嵌入式系统设计4.1.2任务控制块OS_TCB描述UC/OS-II的TCB数据结构简单,内容容易理解,保存最基本的任务信息,同时还支持裁减来减小内存消耗,TCB是事先根据用户配置,静态分配内存的结构数组,通过优先级序号进行添加,查找,删除等功能。减少动态内存分配和释放。因为依靠优先级进行TCB分配,每个任务必须有自己的优先级,不能和其他任务具有相同的优先级。第4章基于ARM9和µC/OS-II嵌入式系统设计typedefstructos_tcb{OS_STK*OSTCBStkPtr;#ifOS_TASK_CREATE_EXT_EN0void*OSTCBExtPtr;OS_STK*OSTCBStkBottom;INT32UOSTCBStkSize;INT16UOSTCBOpt;INT16UOSTCBId;#endifstructos_tcb*OSTCBNext;structos_tcb*OSTCBPrev;第4章基于ARM9和µC/OS-II嵌入式系统设计#if((OS_Q_EN&&(OS_MAX_QS=2))||OS_MBOX_EN||OS_SEM_EN)OS_EVENT*OSTCBEventPtr;#endif#if((OS_Q_EN&&(OS_MAX_QS=2))||OS_MBOX_EN)void*OSTCBMsg;#endifINT16UOSTCBDly;INT8UOSTCBStat;INT8UOSTCBPrio;INT8UOSTCBX;第4章基于ARM9和µC/OS-II嵌入式系统设计INT8UOSTCBY;INT8UOSTCBBitX;INT8UOSTCBBitY;#ifOS_TASK_DEL_ENBOOLEANOSTCBDelReq;#endif}OS_TCB;第4章基于ARM9和µC/OS-II嵌入式系统设计其中:OSTCBStkPtr是指向当前任务栈顶的指针。*OSTCBExtPtr是任务扩展模块使用;*OSTCBStkBottom指向任务堆栈栈底的指针;OSTCBStkSize存有栈中可容纳的指针元数目;OSTCBOpt把“选择项”传给函数OSTashCreaktExt()。只有当用户将OS_CFG.H文件中的OS_TASK_CREATE_EXT设为1时,这个变量才有效;OSTCBId用于存储任务的识别码(ID)。这个变量现在没有用,保留给将来扩展用;第4章基于ARM9和µC/OS-II嵌入式系统设计OSTCBNext和OSTCBPrev用于任务控制块OS_TCBs的双向链表的前后链接,该链表在时钟节拍函数OSTimerTick()中使用;OSTCBEventPtr是指向事件控制块的指针;OSTCBMsg是指向传给任务的消息的指针;OSTCBDly当需要把任务延时若干时钟节拍时要用到这个变量,或者需要把任务挂起一段时间以等待某事件的发生;OSTCBStat是任务的状态字;OSTCBPrio是任务优先级,高优先级任务的OSTCBPrio值小;第4章基于ARM9和µC/OS-II嵌入式系统设计OSTCBDelReq是一个布尔量,用于表示该任务是否需要删除;OSTCBX,OSTCBY,OSTCBBitX和OSTCBBitY用于加速任务进入就绪态的过程或进入等待事件发生状态的过程。这些值是在任务建立时算好的,或者是在改变任务优先级时算出的。这些值的算法可由下面程序实现。OSTCBY=priority3;OSTCBBitY=OSMapTbl[priority3];OSTCBX=priority&0x07;OSTCBBitX=OSMapTbl[priority&0x07];第4章基于ARM9和µC/OS-II嵌入式系统设计4.1.3就绪表(ReadyList)UC/OS-II采用内存映射的方式来实现READY队列的加入,查找,删除功能,效率非常高。但是也因此只能支持64个任务,每个任务都有自己的优先级,不能和其他任务优先级相同。每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置为1。就绪表OSRdyTbl[]数组的大小取决于OS_LOWEST_PRIO(见文件OS_CFG..H)。第4章基于ARM9和µC/OS-II嵌入式系统设计就绪表第4章基于ARM9和µC/OS-II嵌入式系统设计为确定下次该哪个优先级的任务运行了,UC/OS-II中的内核调度器总是将最低优先级的任务在就绪表中相应字节的相应位置1,即OS_LOWEST_PRIO=1。OSRdyGrp和OSRdyTbl[]的关系是按以下规则给出的:当OSRdyTbl[i]中的任何一位是1时,OSRdyGrp的第i位置1。i从0到7。可用下面句使任务进入就绪态:OSRdyGrp|=OSMapTbl[prio3];OSRdyTbl[prio3]|=OSMapTbl[prio&0x07];第4章基于ARM9和µC/OS-II嵌入式系统设计表8-1OSMapTbl[]的值下标位掩码(二进制)000000001100000010200000100300001000400010000500100000601000000710000000第4章基于ARM9和µC/OS-II嵌入式系统设计任务优先级的低三位用于确定任务在总就绪表OSRdyTbl[]中的所在位。接下去的三位用于确定是在OSRdyTbl[]数组的第几个元素。OSMapTbl[]是在ROM中的(见文件OS_CORE.C)屏蔽字,用于限制OSRdyTbl[]数组的元素下标在0到7之间。下面程序从就绪表中删除一个任务。if((OSRdyTbl[prio3]&=~OSMapTbl[prio&0x07])==0)OSRdyGrp&=~OSMapTbl[prio3];第4章基于ARM9和µC/OS-II嵌入式系统设计以上代码将就绪任务表数组OSRdyTbl[]中相应元素的相应位清0,而对于OSRdyGrp,只有当被删除任务所在任务组中全组任务一个都没有进入就绪态时,才将相应位清零。也就是说OSRdyTbl[prio3]所有的位都是0时,OSRdyGrp的相应位才清零。为了找到那个进入就绪态的优先级最高的任务,并不需要从OSRdyTbl[0]开始扫描整个就绪任务表,只需要查另外一张表,即优先级判定表OSUnMapTbl([256])(见文件OS_CORE.C)。第4章基于ARM9和µC/OS-II嵌入式系统设计OSRdyTbl[]中每个字节的8位代表这一组的8个任务哪些进入就绪态了,低位的优先级高于高位。利用这个字节为下标来查OSUnMapTbl这张表,返回的字节就是该组任务中就绪态任务中优先级最高的那个任务所在的位置。这个返回值在0到7之间。确定进入就绪态的优先级最高的任务是用以下代码完成的。y=OSUnMapTbl[OSRdyGrp];x=OSUnMapTbl[OSRdyTbl[y]];prio=(y3)+x;第4章基于ARM9和µC/OS-II嵌入式系统设计4.1.4任务状态UC/OS-II主要有五种任务状态睡眠态等待状态运行态中断状态就绪态(taskready)第4章基于ARM9和µC/OS-II嵌入式系统设计睡眠态(taskdormant)指任务驻留在程序空间之中,还没有交给μC/OS-Ⅱ管理。▲把任务交给μC/OS-Ⅱ是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt()。当任务一旦建立,这个任务就进入就绪态准备运行。▲一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。第4章基于ARM9和µC/OS-II嵌入式系统设计就绪态(taskready)指任务一量建立,这个任务就进入了就绪态,准备运行。▲任务的建立可以是在多任务开始之前也可以动态地由一个运行着的任务建立。▲如果多个任务已经启动,且一个任务是被另一个任务建立的,而新建立的任务的优先级高于建立它的任务的优先级,则这个刚刚建立的任务将立即得到CPU的使用权。第4章基于ARM9和µC/OS-II嵌入式系统设计运行态调用OSStart()可以启动多任务。OSStart()函数只能在启动时调用一次,该函数运行用户初始化代码中已经建立的、进入就绪态的优先级最高的任务。▲OSStart()函数运行进入就绪态的优先级最高的任务。▲就绪的任务只有当所有优先级高于这个任务的任务转为等待状态(taskwaiting),或者是被删除了,才能进入运行态。第4章基于ARM9和µC/OS-II嵌入式系统设计等待状态(taskwaiting)正在运行的任务可通过调用两个函数之一将自身延迟一段时间,即OSTimeDly()或OSTimeDlyHMSM(),这个任务于是进入等待状态。▲等待这段时间过去,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了CPU的控制权。▲等待的时间过去以后,系统服务函数OSTimeTick()使延迟了的任务进入就绪态(详见时钟节拍)。▲正在运行的任务期待某一事件的发生时也要等待,可通过调用以下函数之一实现:OSFlagPend(),OSSemPend(),OSMutexPend,OSMboxPend(),或OSQPend()。调用后任务进入了等待状态(WAITING)。第4章基于ARM9和µC/OS-II嵌入式系统设计中断服务态(ISRrunning)正在运行的任务是可以被中断的,除非该任务或μC/OS-Ⅱ将中
本文标题:第4章 基于ARM9和μCOS-II嵌入式系统设计
链接地址:https://www.777doc.com/doc-3329162 .html