zA嵌入式系统设计与实例开发.ppt
《zA嵌入式系统设计与实例开发.ppt》由会员分享,可在线阅读,更多相关《zA嵌入式系统设计与实例开发.ppt(105页珍藏版)》请在三一办公上搜索。
1、嵌入式系统设计与实例开发ARM与C/OS-第四讲 实时嵌入式操作系统C/OS-,兢家亦鸥去厂气价菌曹垒绍补鹅臭骄庞或熏甚妖禁沉影喳柴竣体苦仑逆典zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,嵌入式实时操作系统C/OS1,内核结构 临界段(Critical Sections)任务任务状态任务控制块(Task Control Blocks,OS_TCBs)就绪表(Ready List)任务调度(Task Scheduling)空闲任务(Idle Task)统计任务C/OS中的中断处理时钟节拍C/OS-初始化C/OS-的启动,危绍计暖里鬃裕冤侣簿酝轴偶莹添饲稗怜注醇握候勘歉沽狞卵纸产场乃
2、磷zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,嵌入式实时操作系统C/OS1,任务管理建立任务,OSTaskCreate()建立任务,OSTaskCreateExt()任务堆栈删除任务,OSTaskDel()请求删除任务,OSTaskDelReq()改变任务的优先级,OSTaskChangePrio()挂起任务,OSTaskSuspend()恢复任务,OSTaskResume()获得有关任务的信息,OSTaskQuery(),冰荤柞钨狄讣苔蜕锦腕饶蔡眷欠船赶虏肥无权鞭曹氦本秧席味绒语砍疽茫zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,嵌入式实时操作系统C/OS1,任务之
3、间的通信与同步事件控制块ECB使一个任务进入就绪状态,OSEventTaskRdy()使一个任务进入等待状态,OSEventTaskWait()由于等待超时将一个任务置为就绪状态,OSEventTO()信号量邮箱消息队列,笺延壹梳贿邀缴房虾澜讥头窃气喝绦钉颊肝劣东营枯绞丧阔床毯渍志湾莉zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,内核结构,渭宏框轰江经劳跨陶石遍庐虫赚问森畅纤穆乱晋渣抒鼓顾壕酚琵协梯赢拄zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,临界段(Critical Sections),C/OS-为了处理临界段代码需要关中断,处理完毕后再开中断。这使得C/OS-能
4、够避免同时有其它任务或中断服务进入临界段代码。关中断的时间是实时内核开发商应提供的最重要的指标之一 就使用C/OS-而言,关中断的时间很大程度上取决于微处理器的架构以及编译器所生成的代码质量。C/OS-定义两个宏(macros)来关中断和开中断 OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()。因为这两个宏的定义取决于所用的微处理器,故在文件OS_CPU.H中可以找到相应宏定义。每种微处理器都有自己的OS_CPU.H文件。,掷霞篡椿恤荡盾银脯坏字魁渐芹怒腥刷单窑饥窄欢毕沉停蹿脸衣枕吱毕吾zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,临界段(Critical
5、 Sections),开关中断示例#define OS_ENTER_CRITICAL()EA=0;/移植到51,只使用中断方式1#define OS_EXIT_CRITICAL()EA=1,冲陌庙潮虾或及诊辗有背孜惦搐撤稚举稻左吟狰斜誉遍噎淀雀属威搬踏痴zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,任务task,典型的一个无限循环。void mytask(void*pdata)for(;)do something;waiting;do something;C/OS II 2.5版本支持64个任务,每个任务一个特定的优先级。优先级越高,数字越小系统占用了8个任务,保留优先级为0、1、
6、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRIO-2、OS_LOWEST_PRIO-1、OS_LOWEST_PRIO-0。,涕牛墒细及猩坚其魁迎形招颜冒圣咯掩航像磐额频负楞寸敢尧拥绚法舟枪zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,任务状态,下图是C/OS-控制下的任务状态转换图。在任一给定的时刻,任务的状态一定是在这五种状态之一,或勉败癣军篇快犬卫耳窗鞋展掐员个压婴睦头猾淋苏您矿彰耶镰蹦舞拆闯zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,任务控制块(TCB),任务控制块 OS_TCB是一个数据结构,保存该任务的相关参数,包括任务堆栈指针,状态,
7、优先级,任务表位置,任务链表指针等。所有的任务控制块分为两条链表,空闲链表和使用链表。,无含宰扇区省滩滥污趣癸贬墟赚讫肥锥谣荒绊挂哮蒙礼峙笆恭著茸急切奄zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,任务控制块结构,Struct os_tcb OS_STK*OSTCBStkPtr;/*指向当前任务栈顶的指针 struct os_tcb*OSTCBNext;/*用于任务控制块的双重联表,struct os_tcb*OSTCBprev;/*用于刷新各任务的延时变量.OSTCBDly OS_EVENT*OSTCBEventPtr;void*OSTCBMsg;/*指向传给任务的消息指针 IN
8、T16U OSTCBDly;/*保存任务在等待事件发生中允许挂起的最/*多时钟节拍数 INT8U OSTCBStat;INT8U OSTCBPrio;/*任务的优先级 INT8U OSTCBX,OSTCBY,OSTCBBitX,OSTCBBitY;OS_TCB,加速任务进入就绪态的过程,事件控制块的指针,任务的状态字,蔚巴济趁请袖勃纺江凡租各基零仇瑰吮泛柳抛架咽悍倚盔阉竭散皑纺漳荤zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,空任务列表,系统初始化时,所有任务控制块被链接成空任务控制块的单向链表,屁濒狰制琴恿予圣缠集祖愧暖毫桶渗僵映庚撬质义匣蹈廉肌伯坞剩介速噬zA嵌入式系统设计与实
9、例开发zA嵌入式系统设计与实例开发,就绪表,每个任务的就绪状态标志都放入就绪表中(ready list)中,就绪表有两个变量:OSRdyGrp、OSRdyTbl,助半犹雪掘氛脏购啊再逸页僵牟伸厦仙项豪军坏什殖摇惜袜甩凭稠码辙猎zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,1、使任务进入就绪态的程序编写,1、使任务进入就绪态的程序编写:OSRdyGrp|=OSMapTblprio3;OSRdyTblprio3|=OSMapTblprio,踌瓮悠邹生架邹腑秆恐勃虽彝吞幼陛汐嘲疗磁拨辨矽寂强迫候摸触热视笑zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,2、从就绪表中删除一个任务
10、的程序,If(OSRdyTblprio3,赞殷圈填馈摹产著堵以摆况醛蹦镶陀过些呈弦如肮疚毡翅杭使步机貉袄便zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,3、找出进入就绪态的优先级最高的任务程序编写,Y=OSUnMapTblOSRdyGrp;X=OSUnMapTblOSRydTblY;Prio=(Y3)+X;两个关键:(1)优先级数分解为高三位和低三位分别确定;(2)高优先级有着小的优先级号;例2:根据就绪表确定最高优先级假设OSRdyGrp的值为0 x24=00100 100b,-OSRdyTbl2 和OSRdyTbl5,高优先级为2;通过OSRdyTbl2的值来确定低3位,假设O
11、SRydTbl2的值为0 x12=00100 100b,-第2个和第5个任务,取高优先级第2个-prio=2*8+2=18,蝴围刁毅评崭乾女凋哗潦引昭鞋泛幕探着万贝颜汤届摊阔景冰活抽帝插慕zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,源代码中使用了查表法,查表法具有确定的时间,增加了系统的可预测性,uC/OS中所有的系统调用时间都是确定的High3=OSUnMapTblOSRdyGrp;Low3=OSUnMapTblOSRdyTblHigh3;Prio=(Hign33)+Low3;,艳偶喘阑楔候桃虱羞抬粤归氨贱蜕丢鼻眠喝奔泰禁巳持逮衅彼老篱葫刑排zA嵌入式系统设计与实例开发zA嵌入
12、式系统设计与实例开发,任务的调度-OSSched,C/OS是占先式实时多任务内核,优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。C/OS中不支持时间片轮转法,每个任务的优先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。C/OS中任务级的调度是由函数OSSched()完成的。中断级的调度是由另一个函数OSIntExt()完成的,这个函数将在以后描述。C/OS任务调度所花的时间为常数,与应用程序中建立的任务数无关。,抵雀情此鸿屏釜济疼崖煎障谁长元谓脆挽评侍功蹄舟雏射货权磺涩仆帅暖zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例
13、开发,任务的调度-OSSched,检查是否中断调用和允许任务调用,找到优先级最高的任务,该任务是否正在运行,OSTCBHighRdy指向优先级最高的那个任务控制块OS_TCB,统计计数器OSCtxSwCtr加1,案挂拘心帜锤岸脓杯看序摔烤妒喜媳耪蹄空钱憎斩郑狼俏猎士经瞥郸铰顷zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,任务的调度-OSSched,程序解释:为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,通过将以OSPrioHighRdy为下标的OSTCBPrioTbl数组中的元素赋给OSTCBHighRdy来实现的。接着,统计计数器OSCt
14、xSwCtr加1,以跟踪任务切换次数。最后宏调用OS_TASK_SW()来完成实际上的任务切换。任务切换由以下两步完成:(1)将被挂起任务的微处理器寄存器推入堆栈(2)然后将较高优先级的任务的寄存器值从栈中恢复到寄存器,区淌蓬送鸥霍仗裁澡医畏拇钢党劣兄疆嗓贱予宣叭碧藩佃抵眉泵列果宋薄zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,任务的调度-OSSched,在C/OS-中,就绪任务的栈结构总是看起来跟刚刚发生过中断一样,所有微处理器的寄存器都保存在栈中。C/OS-运行就绪态的任务所要做的一切,只是恢复所有的CPU寄存器并运行中断返回指令。OSSched()的所有代码都属临界段代码。在
15、寻找进入就绪态的优先级最高的任务过程中,为防止中断服务子程序把一个或几个任务的就绪位置位,中断是被关掉的。为缩短切换时间,OSSched()全部代码都可以用汇编语言写。,落旗绚产萤秒供舵睛策慷菠春褥眺尘轧挚云邯滩似戏道较芹滥鹊恃苏凉果zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,给调度器上锁和开锁(Locking and UnLocking the Scheduler),给调度器上锁函数OSSchedlock()用于禁止任务调度,直到任务完成后调用给调度器开锁函数OSSchedUnlock()为止。调用OSSchedlock()的任务保持对CPU的控制权。OSSchedlock()
16、和OSSchedUnlock()必须成对使用。变量OSLockNesting跟踪OSSchedLock()函数被调用的次数,以允许嵌套的函数包含临界段代码,这段代码其它任务不得干预。C/OS-允许嵌套深度达255层。当OSLockNesting减到零的时候,OSSchedUnlock()调用OSSched()。OSSchedUnlock()是被某任务调用的,在调度器上锁的期间,可能有什么事件发生了并使一个更高优先级的任务进入就绪态。,锰验骋缠愧孕骑沪燥屡咐节俊有纳挨嘉神俏徘嫉扣构炼莆脯乎栋炊开烧例zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,给调度器上锁和开锁(Locking an
17、d UnLocking the Scheduler),调用OSSchedLock()以后,用户的应用程序不得使用任何能将现行任务挂起的系统调用。不得调用OSMboxPend()、OSQPend()、OSSemPend()、OSTaskSuspend(OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMSM(),直到OSLockNesting回零为止。当低优先级的任务要发消息给多任务的邮箱、消息队列、信号量时,用户不希望高优先级的任务在邮箱、队列和信号量没有得到消息之前就取得了CPU的控制权,此时,用户可以使用禁止调度器函数。,榜法干蒙鸡除咒粳妻栅隔吻酵土词湘信扰猜杯半械邪
18、钙腋劈饶犀畴玩谁简zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,空闲任务,C/OS-总是建立一个空闲任务,这个任务在没有其它任务进入就绪态时投入运行。这个空闲任务OSTaskIdle()永远设为最低优先级,即OS_LOWEST_PRI0。空闲任务OSTaskIdle()什么也不做,只是在不停地给一个32位的名叫OSIdleCtr的计数器加1,统计任务使用这个计数器以确定现行应用软件实际消耗的CPU时间。空闲任务不可能被应用软件删除。代码如下:,void OSTaskIdle(void*pdata)pdata=pdata;for(;)OS_ENTER_CRITICAL();OSIdl
19、eCtr+;OS_EXIT_CRITICAL();,寨呀饼遗汕卷坠迟虫焰辱匙啊合旦路披庇请怒瞪污池卯诉药伸伟掣唬兔褂zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,统计任务,C/OS-有一个提供运行时间统计的任务。这个任务叫做OS_TaskStat(),如果用户将系统定义常数OS_TASK_STAT_EN(见文件OS_CFG.H)设为1,这个任务就会建立。一旦得到了允许,OS_TaskStat()每秒钟运行一次(见文件OS_CORE.C),计算当前的CPU利用率。如果用户应用程序打算使用统计任务,在调用系统启动函数OSStart()之前,用户初始代码必须先建立一个任务,在这个任务中调
20、用系统统计初始化函数OSStatInit(),然后再建立应用程序中的其它任务。程序略,宅氦褂盎枫炔咨萌墨形改如夫吕醚胯范墅妓赢勺喻坟钝误嫩歧贾难夷翅厢zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,C/OS-中的中断处理,C/OS-中,中断服务子程序要用汇编语言来写。然而,如果用户使用的C语言编译器支持在线汇编语言的话,用户可以直接将中断服务子程序代码放在C语言的程序文件中。,程序清单 C/OS-II中的中断服务子程序.用户中断服务子程序:保存全部CPU寄存器;(1)调用OSIntEnter或OSIntNesting直接加1;(2)执行用户代码做中断服务;(3)调用OSIntExit
21、();(4)恢复所有CPU寄存器;(5)执行中断返回指令;(6),调用脱离中断函数,中断嵌套层数计数器减1,捡卒弦肠高衍冕曝损欺伴匪元蚂纫阐洗壤惹逊纤栗葬稠止朔窗擞视厌布箩zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,C/OS-中的中断处理,当嵌套计数器减到零时,所有中断,包括嵌套的中断都已完成,此时C/OS-判定有没有优先级较高的任务被中断服务子程序唤醒。如果有,C/OS-就返回到那个高优先级的任务,OSIntExit()返回到调用点。保存的寄存器的值此时恢复,然后执行中断返回指令。如果调度被禁止了(OSlockNesting0),C/OS-将返回到被中断的任务。用户中断服务中做
22、的事要尽可能地少,要把大部分工作留给任务去做。中断服务子程序通知某任务去做事的手段是调用以下函数之一:OSMboxPost(),OSQPost(),OSQPostFront(),OSSemPost()。中断发生并由上述函数发出消息时,接收消息的任务可能是,也可能不是挂起在邮箱、队列或信号量上的任务。,求鸦扯缀袄言炯哦拜伊扬眼抹狮漂段租迹央湾浩龟江纺棕嗜莲宴贝巍砌恬zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,关于OSIntExit(),OSIntExit()看起来非常像OS_Sched()。但有三点不同。OSIntExit()使中断嵌套层数减1,而调度函数OS_Sched()的调度
23、条件是:中断嵌套层数计数器和锁定嵌套计数器(OSLockNesting)二者都必须是零。OSRdyTbl所需的检索值Y是保存在全程变量OSIntExitY中的。这是为了避免在任务栈中安排局部变量。这个变量在哪儿和中断任务切换函数OSIntCtxSw()有关。如果需要做任务切换,OSIntExit()将调用OSIntCtxSw()而不是调用OS_TASK_SW(),正像在OSSched()函数中那样。调整栈结构要保证所有挂起任务的栈结构看起来是一样的。有的微处理器,像Motorola 68HC11中断发生时CPU寄存器是自动入栈的,且要想允许中断嵌套的话,在中断服务子程序中要重新开中断。如果用户
24、中断服务子程序执行得非常快,用户不需要通知任务自身进入了中断服务,只要不在中断服务期间开中断,也不需要调用OSIntEnter()或OSIntNesting加1。一个任务和这个中断服务子程序通讯的唯一方法是通过全程变量。,堵欺盅康袁彩颧寂咏躇苗濒诱踪辨睹四赛侵课故木逼迭阅垂虚救歼腿蔫钒zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,中断与时钟节拍,我们知道:当发生中断时,首先应保护现场,将CPU寄存器入栈,再处理中断函数,然后恢复现场,将CPU寄存器出栈,最后执行中断返回iret(x86)指令实现中断返回。uC/OS中提供了OSIntEnter()和OSIntExit()告诉内核进入
25、了中断状态。时钟节拍是一种特殊的中断,是操作系统的心脏。首先32位的整数OSTime加一。对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态,最后进行上下文切换。,肘味驴锌在胎瑰盐溃剔肾捧俺述妖滞郝玖慎呢齐镜簿分迅跋币钮恶父术明zA嵌入式系统设计与实例开发zA嵌入式系统设计与实例开发,时钟节拍,C/OS需要用户提供周期性信号源,用于实现时间延时和确认超时。节拍率应在每秒10次到100次之间,或者说10到100Hz。时钟节拍率越高,系统的额外负荷就越重。时钟节拍的实际频率取决于用户应用程序的精度。时钟节拍源可以是专门的硬件定时器,也可以是来自50/60Hz交流电源的信号。用户必须在多任务
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- zA 嵌入式 系统 设计 实例 开发
链接地址:https://www.31ppt.com/p-5157214.html