收藏 分销(赏)

嵌入式系统教学课件:ucos-ii代码总结分析(医学PPT课件).ppt

上传人:人****来 文档编号:12777485 上传时间:2025-12-05 格式:PPT 页数:159 大小:1.85MB 下载积分:8 金币
下载 相关 举报
嵌入式系统教学课件:ucos-ii代码总结分析(医学PPT课件).ppt_第1页
第1页 / 共159页
嵌入式系统教学课件:ucos-ii代码总结分析(医学PPT课件).ppt_第2页
第2页 / 共159页


点击查看更多>>
资源描述
单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,第四章 实时操作系统C/OS-分析,实时操作系统,C/OS-II,1,3,2,4,C/OS-II概述,任务管理,中断和时间,管理,任务之间的通信与,同步,5,存储管理,通用操作系统和嵌入式(实时)操作系统,通用操作系统:Windows/NT/XP、Linux、UNIX等,用于PC机、服务器,,嵌入式(实时)操作系统:用于嵌入式设备的操作系统,具有通用操作系统的基本特点,又具有系统实时性、硬件的相关依赖性、软件固态化以及应用的专用性等特点;,嵌入式(实时)操作系统通常包括与硬件相关的底层驱动软件、系统内核、设备驱动接口、通信协议、图形界面、标准化浏览器Browser等;,嵌入式(实时)操作系统的重要指标:实时性(中断响应时间、任务切换时间等)、尺寸(可裁剪性)、可扩展性(内核、中间件);,嵌入式操作系统的发展,操作系统内核,应用程序,驱动程序和固件,操作系统内核,文件系统,驱动程序和固件,API,GUI,应用程序,操作系统内核,文件系统,驱动程序和固件,API,GUI,应用程序,通信协议,库函数,80年代初期,80年代中期-90年代中期,90年代末期-21世纪,常见的嵌入式操作系统,实时嵌入式操作系统的种类繁多,大体上可分为两种,商用型和免费型。,商用型的实操作系统功能稳定、可靠,有完善的技术支持和售后服务,但往往价格昂贵,如Vxworks、QNX、WinCE、Palm OS等。,免费型的实时操作系统在价格方面具有优势,目前主要有Linux,C/OS是一种源码开放的商业RTOS;,RTOS在嵌入式系统中的位置,嵌入式硬件平台,BSP,KERNEL,FS,TCP/IP,设备驱动,设备I/O,调试工具,其它组件,应用,RTOS,C/C+,C/OS,简介,1、C/OS,Micro Controller O S,微控制器操作系统,2,、,C/OS,简介,美国人Jean Labrosse 1992年完成,应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等,2019年,C/OS,-II,目前的版本,C/OS,-II V2.61,2.72,2000年,得到美国航空管理局(FAA)的认证,可以用于飞行器中,网站ucos-II(micrium),公开源代码,可移植性(,Portable,),绝大部分,C/OS-II,的源码是用移植性很强的,ANSI C,写的。和微处理器硬件相关的那部分是用汇编语言写的。汇编语言写的部分已经压到最低限度,使得,C/OS-II,便于移植到其他微处理器上。,C/OS-II,可以在绝大多数,8,位、,16,位、,32,位以至,64,位微处理器、微控制器、数字信号处理器(,DSP,),上运行。,可固化(,ROMable,),C/OS-II,是为嵌入式应用而设计的,这就意味着,只要读者有固化手段(,C,编译、连接、下载和固化),,C/OS-II,可以嵌入到读者的产品中成为产品的一部分。,可裁剪(,Scalable,),可以只使用,C/OS-II,中应用程序需要的那些系统服务。也就是说某产品可以只使用很少几个,C/OS-II,调用,而另一个产品则使用了几乎所有,C/OS-II,的功能,这样可以减少产品中的,C/OS-II,所需的存储器空间(,RAM,和,ROM,)。,这种可剪裁性是靠条件编译实现的。,C/OS,的性能特点(一),占先式(,Preemptive,),多任务,C/OS-II,可以管理,64,个任务,然而,目前这一版本保留,8,个给系统。应用程序最多可以有,256,个任务,可确定性,全部,C/OS-II,的函数调用与服务的执行时间具有可确定性。,任务栈,每个任务有自己单独的栈,,C/OS-II,允许每个任务有不同的栈空间,以便压低应用程序对,RAM,的需求。,系统服务,C/OS-II,提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。,中断管理,中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达,255,层。,稳定性与可靠性,C/OS,的性能特点(二),C/OS-II图书,描述了C/OS-II内部的工作原理,随书的CD中包含了源代码,工业界最清晰的源代码,除英文版外,有中文和韩文版,Chinese,Korean,English,ISBN 1-57820-103-9,美国CMP BOOK,ISBN 7-81077-290-2,北京航空航天大学出版社,ISBN 89-951540-5-5,C/OS-II的各种商业应用,全世界有数百种产品在应用:,Avionics,Medical,Cell phones,Routers and switches,High-end audio equipment,Washing machines and dryers,UPS,(Uninterruptible Power Supplies),Industrial controllers,GPS Navigation Systems,Microwave Radios,Instrumentation,Point-of-sale terminals,更多,C/OS-II提供的系统服务,信号量,带互斥机制的信号量,减少优先级倒置的问题,事件标志,消息信箱,消息队列,内存管理,时钟管理,任务管理,操作系统的概述,C/OS,-II的文件结构,1,3,2,4,C/OS-II概述,任务管理,中断和时间,管理,任务之间的通信与,同步,5,存储管理,任务的实现,创建任务的系统服务,OSTaskCreate(),INT8U OSTaskCreate(void(*task)(void*pd),/任务代码指针 void*pdata,/任务参数指针OS_STK*ptos,/任务栈的栈顶指针 INT8U prio /任务的优先级);,OSTaskCreateExt(),提问:,C/OS-II中的任务是进程还是线程?,任务主函数,一个任务通常是一个无限循环(返回值类型void),void MyTask(void*pdata),while(1),do something;,waiting;,do something;,Why?,任务也可以自我删除(并非真的删除,只是内核不再知道该任务),void MyTask(void*pdata),./*用户代码*/,OSTaskDel(OS_PRIO_SELF);,C/OS-可以管理多达64个任务;,每个任务被赋以不同的优先级,取值从0到OS_LOWEST_PRIO-2,数值越小,优先级越高;,系统保留了优先级为0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及OS_LOWEST_PRI0这8个任务以被将来使用,用户可以有56个应用任务;,任务的优先级同样也是它的标识号ID。,OS_CFG.H中定义63,空闲任务和统计任务,内核总是创建一个,空闲任务,OSTaskIdle();,总是设置为最低优先级,OS_LOWEST_PRIOR;,当所有其他任务都未在执行时,空闲任务开始执行;,应用程序不能删除该任务;,空闲任务的工作就是把32位计数器OSIdleCtr加1,该计数器被统计任务所使用;,统计任务,OSTaskStat(),提供运行时间统计。每秒钟运行一次,计算当前的CPU利用率。其优先级是OS_LOWEST_PRIOR-1,可选。,任务控制块TCB,任务控制块,OS_TCB是描述一个任务的核心数据结构,存放了它的各种管理信息,包括任务堆栈指针,任务的状态、优先级,任务链表指针等;,一旦任务建立了,任务控制块OS_TCB将被赋值。,任务控制块TCB,typedef struct os_tcb,栈指针;,INT16U OSTCBId;/*任务的ID*/,链表指针;,OS_EVENT*OSTCBEventPtr;/*事件指针*/,void *OSTCBMsg;/*消息指针*/,INT8U OSTCBStat;/*任务的状态*/,INT8U OSTCBPrio;/*任务的优先级*/,其他,OS_TCB;,栈指针,OSTCBStkPtr:,指向当前任务栈顶的指针,每个任务可以有自己的栈,栈的容量可以是任意的;,OSTCBStkBottom,:指向任务栈底的指针;,OSTCBStkSize,:栈的容量,用可容纳的指针数目而不是字节数(Byte)来表示。,链表指针,所有的任务控制块分属于两条不同的链表,单向的,空闲链表,(头指针为OSTCBFreeList)和双向的,使用链表,(头指针为OSTCBList);,OSTCBNext、OSTCBPrev:,用于将任务控制块插入到空闲链表或使用链表中。每个任务的任务控制块在任务创建的时候被链接到使用链表中,在任务删除的时候从链表中被删除。双向连接的链表使得任一成员都能快速插入或删除。,空闲TCB链表,所有的任务控制块都被放置在任务控制块列表数组,OSTCBTbl,中,系统初始化时,所有TCB被链接成空闲的单向链表,头指针为OSTCBFreeList。当创建一个任务后,就把OSTCBFreeList所指向的TCB赋给了该任务,并将它加入到使用链表中,然后把OSTCBFreeList指向空闲链表中的下一个结点。,系统初始化后,指针数组,指向相应TCB,任务的状态休眠,休眠状态,(,Dormant),:任务存在于内存空间中,但内核不可见;,可以通过以下函数通知内核,使之变为就绪状态:,OSTaskCreate()或OSTaskCreateExt(),可以通过以下函数返回到休眠状态:,OSTaskDel,(),任务的状态就绪,就绪状态,(Ready):万事具备,只欠CPU;,在所有的就绪任务当中,具有最高优先级的任务被选中去运行;,如果任务在运行的时候被抢占了CPU,则又回到就绪状态。,任务的状态运行,运行状态,(Running):任务在CPU上运行;,当一个任务在运行时,如果没有关闭中断,则有可能被中断所打断;,当一个任务在运行时,可能因为各种原因进入阻塞状态。,OSMBoxPend(),OSQPend(),OSSemPend,(),OSTaskSuspend,(),OSTimeDly,(),任务的状态ISR,中断服务状态,(ISR):该任务原来在CPU上运行,后来被中断所打断,由中断服务程序ISR接管了CPU;,当中断服务程序运行完毕后,内核要判断是否有新的、更高优先级的任务就绪,如果有,则原有的任务被抢占;如果没有,则原有的任务重新运行。,任务的状态阻塞,阻塞/等待状态,(Waiting):任务由于正在等待某个事件(信号量、邮箱或队列)而被挂起;,当任务等待的事件发生时,回到就绪状态。,OSMBoxpost,(),OSQPost,(),OSSemPost,(),OSTaskResume,(),OSTimeDlyResume,(),或,OSTimeTick,(),状态的转换,删除任务,任务就绪表,每个任务的就绪态标志放入在就绪表中,就绪表中有两个变量OSRdyGrp和OSRdyTbl。,在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl中的相应元素的相应位也置位。,任务就绪表,OSRdyGrp,1,2,0,7,6,5,4,3,0,0,X,X,X,Y,Y,Y,任务优先级,2,0,1,7,6,5,4,3,10,8,9,15,14,13,12,11,18,16,17,23,22,21,20,19,26,24,25,31,30,29,28,27,34,32,33,39,38,37,36,35,42,40,41,47,46,45,44,43,50,48,49,55,54,53,52,51,58,56,57,63,62,61,60,59,0,1,2,3,4,5,6,7,OSRdyTbl8,X,Y,优先级最低任务,(空闲任务),优先级最高任务,任务优先级号,对于整数OSRdyTbli(0,i7,),若它的某一位为1,则OSRdyGrp的第i位为1。,任务的优先级由X和Y确定,根据优先级确定就绪表(1),假设优先级为,12,的任务进入就绪状态,,12=1100b,则,OSRdyTbl1,的第,4,位置,1,,且,OSRdyGrp,的第,1,位置,1,,相应的数学表达式为,:,OSRdyGrp,|=0 x02,;,OSRdyTbl1|=0 x10;,而优先级为,21,的任务就绪,21=10 101b,,则,OSRdyTbl2,的第,5,位置,1,,且,OSRdyGrp,的第,2,位置,1,相应的数学表达式为:,OSRdyGrp,|=0 x04,;,OSRdyTbl2|=0 x20;,根据优先级确定就绪表(2),从上面的计算可知,:,若,OSRdyGrp,及,OSRdyBbl,的第,n,位置,1,,则应该把,OSRdyGrp,及,OSRdyBbl,的值与,2,n,相或。,uC,/OS,中,把,2,n,的,n=0-7,的,8,个值先计算好存在数组,OSMapTbl7,中,也就是:,OSMapTbl0=2,0,=0 x01,(,0000 0001,),OSMapTbl1=2,1,=0 x02,(,0000 0010,),OSMapTbl7=2,7,=0 x80,(,1000 0000,),使任务进入就绪态,如果,prio,是任务的优先级,即任务的标识号,则将任务放入就绪表,即使任务进入就绪态的方法是:,OSRdyGrp,|=,OSMapTblprio,3;,OSRdyTblprio,3|=OSMapTblprio,假设优先级为,121100b,OSRdyGrp,|=OSMapTbl123(0 x02),;,OSRdyTbl1|=0 x10;,使任务脱离就绪态,将任务就绪表,OSRdyTblprio,3,相应元素的相应位清零,而且当,OSRdyTblprio,3,中的所有位都为零时,即该任务所在组的所有任务中没有一个进入就绪态时,,OSRdyGrp,的相应位才为零。,if(OSRdyTblprio,3&=,OSMapTblprio&0 x07)=0),OSRdyGrp,&=,OSMapTblprio,3;,任务的调度,C/OS是可抢占实时多任务内核,它总是运行就绪任务中优先级最高的那一个。,C/OS中不支持时间片轮转法,每个任务的优先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。,C/OS任务调度所花的时间为常数,与应用程序中建立的任务数无关。,确定哪个任务的优先级最高,应该选择哪个任务去运行,这部分的工作是由调度器(Scheduler)来完成的。,任务级的调度是由函数,OSSched,(),完成的;,中断级的调度是由另一个函数,OSIntExt,(),完成的。,根据就绪表确定最高优先级,两个关键:,将优先级数分解为高三位和低三位分别确定;,高优先级有着小的优先级号;,根据就绪表确定最高优先级,通过OSRdyGrp值确定高3位,假设OSRdyGrp0 x08=0 x00001000,第,3,位为1,优先级的高3位为,011,;,通过OSRdyTbl3的值来确定低3位,假设OSRdyTbl30 x3a,第,1,位为1,优先级的低3位为,001,,3*8+1=,25,0,0,0,1,1,0,0,1,任务优先级,任务调度器,void OSSched(void),INT8U y;,OS_ENTER_CRITICAL();,if(OSLockNesting|OSIntNesting)=0),y =OSUnMapTblOSRdyGrp;,OSPrioHighRdy=(INT8U)(y 3)+OSUnMapTblOSRdyTbly);,if(OSPrioHighRdy!=OSPrioCur),OSTCBHighRdy=OSTCBPrioTblOSPrioHighRdy;,OSCtxSwCtr+;,OS_TASK_SW();,OS_EXIT_CRITICAL();,检查是否中断调用和允许任务调用,找到优先级最高的任务,该任务是否正在运行,源代码中使用了查表法,查表法具有确定的时间,增加了系统的可预测性,,uC,/OS,中所有的系统调用时间都是确定的,Y=,OSUnMapTblOSRdyGrp,;,X=,OSUnMapTblOSRdyTblY,;,Prio,=(Y3)+X;,参,见OS_CORE.C,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,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,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,;,优先级判定表OSUnMapTbl256,举例:,如OSRdyGrp的值为01101000B,即0X68,则查得OSUnMapTblOSRdyGrp的值是3,它相应于OSRdyGrp中的第3位置1;,如OSRdyTbl3的值是11100100B,即0XE4,则查OSUnMapTblOSRdyTbl3的值是2,则进入就绪态的最高任务优先级,Prio=3*8+2=26,任务切换,将被挂起任务的寄存器内容入栈;,将较高优先级任务的寄存器内容出栈,恢复到硬件寄存器中。,任务级的任务切换OS_TASK_SW(),通过sc系统调用指令完成,保护当前任务的现场,恢复新任务的现场,执行中断返回指令,开始执行新的任务,调用OS_TASK_SW()前的数据结构,低优先级任务,OS,_,TCB,OSTCBCur,(1),存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,PSW,存贮器低地址,存贮器高地址,高优先级任务,OS,_,TCB,OSTCBHighRdy,(3),(2),CPU,(4),(5),保存当前CPU寄存器的值,低优先级任务,OS,_,TCB,OSTCBCur,PSW,PC,R1,R2,R3,R4,存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,PSW,存贮器低地址,存贮器高地址,高优先级任务,OS,_,TCB,OSTCBHighRdy,(3),(2),CPU,(4),(5),(1),(3),重新装入要运行的任务,低优先级任务,OS,_,TCB,OSTCBCur,PSW,PC,R1,R2,R3,R4,存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,PSW,PSW,PC,R1,R2,R3,R4,存贮器低地址,存贮器高地址,高优先级任务,OS,_,TCB,OSTCBHighRdy,OSTCBCur,(1),(2),CPU,(4),(4),(1),(3),(3),(4),任务切换OS_TASK_SW()的代码,Void OSCtxSw(void),将R1,R2,R3及R4推入当前堆栈;,OSTCBCur,OSTCBStkPtr=SP;,OSTCBCur =OSTCBHighRdy;,SP =OSTCBHighRdy OSTCBSTKPtr;,将R4,R3,R2及R1从新堆栈中弹出;,执行中断返回指令;,给调度器上锁,OSSchedlock(),:给调度器上锁函数,用于禁止任务调度,保持对CPU的控制权(即使有优先级更高的任务进入了就绪态);,OSSchedUnlock(),:给调度器开锁函数,当任务完成后调用此函数,调度重新得到允许;,当低优先级的任务要发消息给多任务的邮箱、消息队列、信号量时,它不希望高优先级的任务在邮箱、队列和信号量还没有得到消息之前就取得了CPU的控制权,此时,可以使用调度器上锁函数。,任务管理的系统服务,创建任务,删除任务,修改任务的优先级,挂起和恢复任务,获得一个任务的有关信息,创建任务,创建任务的函数,OSTaskCreate,();,OSTaskCreateExt,();,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能,;,任务可以在多任务调度开始,(,即调用,OSStart,(),之前创建,也可以在其它任务的执行过程中被创建。但在,OSStart,(),被调用之前,用户必须创建至少一个任务;,不能在中断服务程序,(ISR),中创建新任务。,OSTaskCreate(),INT8U,OSTaskCreate,(,void(*,task)(void,*pd),/,任务代码指针,void*,pdata,/,任务参数指针,OS_STK*,ptos,/,任务栈的栈顶指针,INT8U,prio,/,任务的优先级,);,返回值,OS_NO_ERR,:函数调用成功;,OS_PRIO_EXIT,:任务优先级已经存在;,OS_PRIO_INVALID,:任务优先级无效。,OSTaskCreate()的实现过程,任务优先级检查,该优先级是否在,0,到,OS_LOWSEST_PRIO,之间?,该优先级是否空闲?,调用,OSTaskStkInit,(),,创建任务的栈帧;,调用,OSTCBInit,(),,从空闲的,OS_TCB,池(即,OSTCBFreeList,链表)中获得一个,TCB,并初始化其内容,然后把它加入到,OSTCBList,链表的开头,并把它设定为就绪状态;,任务个数,OSTaskCtr,加,1,;,调用用户自定义的函数,OSTaskCreateHook,(),;,判断是否需要调度(调用者是正在执行的任务),OSTaskCreateExt(),INT8U,OSTaskCreateExt,(,前四个参数与,OSTaskCreate,相同,,INT16U id,/,任务的,IDOS_STK*,pbos,/,指向任务栈底的指针,INT32U,stk_size,/,栈,能容纳的成员,数目,void *pext,/,指向用户附加数据域的指针,INT16U opt /,一些选项信息,);,返回值:与,OSTaskCreate,(),相同。,任务的栈空间,每个任务都有自己的栈空间(,Stack,),栈必须声明为,OS_STK,类型,并且由连续的内存空间组成;,栈空间的分配方法,静态分配:在编译的时候分配,例如:,static OS_STK,MyTaskStackstack_size,;OS_STK,MyTaskStackstack_size,;,动态分配:在任务运行的时候使用,malloc,(),函数来动态申请内存空间;,OS_STK *pstk;,pstk=(OS_STK*)malloc(stack_size);,/*确认malloc()能得到足够的内存空间*/,if(pstk!=(OS_STK*)0),Create the task;,动态分配,内存碎片问题,在动态分配中,可能存在内存碎片问题。特别是当用户反复地建立和删除任务时,内存堆中可能会出现大量的碎片,导致没有足够大的一块连续内存区域可用作任务栈,这时,malloc,(),便无法成功地为任务分配栈空间。,3Kb,堆初始状态,A(1Kb),B(1Kb),C(1Kb),3个任务,1Kb,B(1Kb),1Kb,删除A,C,内碎片/外碎片?,栈的增长方向,栈的增长方向的设置,从低地址到高地址:在,OS_CPU.H,中,将常量,OS_STK_GROWTH,设定为,0,;,从高地址到低地址:在,OS_CPU.H,中,将常量,OS_STK_GROWTH,设定为,1,;,OS_STK,TaskStackTASK_STACK_SIZE,;,OSTaskCreate(task,pdata,&TaskStackTASK_STACK_SIZE-1,prio,);,删除任务,OSTaskDel,(),:删除一个任务,其,TCB,会从所有可能的系统数据结构中移除。任务将返回并处于休眠状态(任务的代码还在)。,如果任务正处于就绪状态,把它从就绪表中移出,这样以后就不会再被调度执行了;,如果任务正处于邮箱、消息队列或信号量的等待队列中,也把它移出;,将任务的,OS_TCB,从,OSTCBList,链表当中移动到,OSTCBFreeList,。,OSTaskChangePrio,(),:在程序运行期间,用户可以通过调用本函数来改变某个任务的优先级。,INT8U OSTaskChangePrio(INT8U,oldprio,INT8U,newprio,),OSTaskQuery,(),:获得一个任务的有关信息,获得的是对应任务的,OS_TCB,中内容的拷贝。,OSTaskSuspend,(),:挂起一个任务,如果任务处于就绪态,把它从就绪表中移出;,在任务的,TCB,中设置,OS_STAT_SUSPEND,标志,表明该任务正在被挂起。,OSTaskResume,(),:恢复一个任务,恢复被,OSTaskSuspend,(),挂起的任务;,清除,TCB,中,OSTCBStat,字段的,OS_STAT_SUSPEND,位,挂起和恢复任务,第三章、实时操作系统,C/OS-II,1,3,2,4,C/OS-II概述,任务管理,中断和时间,管理,任务之间的通信与,同步,5,存储管理,6,C/OS-II的移植,中断处理,中断:,由于某种事件的发生而导致程序流程的改变。产生中断的事件称为,中断源,。,CPU,响应中断的条件:,至少有一个中断源向,CPU,发出中断信号;,系统允许中断,且对此中断信号未予屏蔽。,中断服务程序ISR,中断一旦被识别,,CPU,会保存部分(或全部)运行上下文(,context,,即寄存器的值),然后跳转到专门的子程序去处理此次事件,称为,中断服务子程序,(ISR),。,C/OS-中,,,中断服务子程序要用汇编语言来编写,然而,如果用户使用的,C,语言编译器支持在线汇编语言的话,用户可以直接将中断服务子程序代码放在,C,语言的程序文件中。,(1)保存全部CPU寄存器的值;,(2)调用OSIntEnter(),或直接把全局变量OSIntNesting(中断嵌套层次)加1;,(3)执行用户代码做中断服务;,(4)调用OSIntExit();,(5)恢复所有CPU寄存器;,(6)执行中断返回指令。,用户ISR的框架,OSIntEnter(),/*在调用本函数之前必须先将中断关闭*/,void OSIntEnter(void),if(OSRunning=TRUE),if(OSIntNesting 255),OSIntNesting+;,OSIntExit的意义,OSIntExit(),void OSIntExit(void),OS_ENTER_CRITICAL();/关中断,if(-OSIntNesting|OSLockNesting)=0)/判断嵌套是否为零,/把高优先级任务装入,OSIntExitY=OSUnMapTblOSRdyGrp;,OSPrioHighRdy=(INT8U)(OSIntExitYOSTCBPrio!=OS_IDLE_PRIO)(3),OS_ENTER_CRITICAL();,if(ptcb-OSTCBDly!=0),if(-ptcb-OSTCBDly=0),If(!(ptcb-OSTCBStat&OS_STAT_SUSPEND)(4),OSRdyGrp|=ptcb-OSTCBBitY;(5),OSRdyTblptcb-OSTCBY|=ptcb-OSTCBBitX;,else,ptcb-OSTCBDly=1;,ptcb=ptcb-OSTCBNext;,OS_EXIT_CRITICAL();,OS_ENTER_CRITICAL();(6),OSTime+;(7),OS_EXIT_CRITICAL();,时间管理,与时间管理相关的系统服务:,OSTimeDLY(),OSTimeDLYHMSM(),OSTimeDlyResmue(),OStimeGet(),OSTimeSet(),OSTimeDLY(),OSTimeDLY,(),:任务延时函数,申请该服务的任务可以延时一段时间;,调用,OSTimeDLY,后,任务进入等待状态;,使用方法,void,OSTimeDly,(INT16U ticks);,ticks,表示需要延时的时间长度,用时钟节拍的个数来表示。,OSTimeDLY(),void OSTimeDly(INT16U ticks),if(ticks 0),OS_ENTER_CRITICAL();,if(OSRdyTblOSTCBCur-OSTCBY&=,OSTCBCur-OSTCBBitX)=0),OSRdyGrp,OSTCBCur-OSTCBDly=ticks;,OS_EXIT_CRITICAL();,OSSched();,OSTimeDLY(1)的问题,OSTimeDlyHMSM(),OSTimeDlyHMSM,(),:,OSTimeDly,(),的另一个版本,即按时分秒延时函数;,使用方法,INT8U,OSTimeDlyHMSM,(INT8U hours,/,小时,INT8U minutes,/,分钟,INT8U seconds,/,秒,INT16U,milli,/,毫秒,);,OSTimeDlyResume(),OSTimeDlyResume,(),:让处在延时期的任务提前结束延时,进入就绪状态;,使用方法,INT8U,OSTimeDlyResume,(INT8U,prio,);,prio,表示需要提前结束延时的任务的优先级,/,任务,ID,。,系统时间,每隔一个时钟节拍,发生一个时钟中断,将一个,32,位的计数器,OSTime,加,1,;,该计数器在用户调用,OSStart,(),初始化多任务和,4,294,967,295,个节拍执行完一遍的时候从,0,开始计数。若时钟节拍的频率等于,100Hz,,该计数器每隔,497,天就重新开始计数;,OSTimeGet,(),:获得该计数器的当前值;,INT32U,OSTimeGet,(void);,OSTime,S,et,(),:设置该计数器的值。,void,OSTimeSet,(INT32U ticks);,何时启动系统定时器,如果在OSStart之前启动定时器,则系统可能无法正确执行完OSStartHighRdy,OSStart函数直接调用OSStartHighRdy去执行最高优先级的任务,OSStart不返回。,系统定时器应该在系统的最高优先级任务中启动,使用OSRunning变量来控制操作系统的运行,在我们的移植版本中,使用了uCOS-II中的保留任务1作为系统任务。负责启动定时器,时钟节拍的启动,用户必须在多任务系统启动以后再开启时钟节拍器,也就是在调用OSStart()之后;,在调用OSStart()之后做的第一件事是初始化定时器中断。,void main(void),.,OSInit();/*初始化uC/OS-II*/,/*应用程序初始化代码.*/,/*调用OSTaskCreate()创建至少一个任务*/,允许时钟节拍中断;/*错误!可能crash!*/,OSStart();/*开始多任务调度*/,系统的初始化与启动,在调用,C/OS-II,的任何其它服务之前,用户必须首先调用系统初始化函数OSInit()来初始化,C/OS的所有变量和数据结构,;,OSInit()建立空闲任务OSTaskIdle(),该任务总是处于就绪状态,其优先级一般被设成最低,即OS_LOWEST_PRIO;如果需要,OSInit()还建立统计任务OSTaskStat(),并让其进入就绪状态;,OSInit()还初始化了4个空数据结构缓冲区:空闲TCB链表OSTCBFreeList、空闲事件链表OSEventFreeList、空闲队列链表OSQFreeList和空闲存储链表OSMemFreeList。,系统初始化后的状态,C/OS-II的启动,多任务的启动是用户通过调用OSStart()实现的。然而,启动C/OS-之前,用户至少要建立一个应用任务。,void main(void),OSInit();,/*初始化uC/OS-II*/,.,通过调用OSTaskCreate()或OSTaskCreateExt(),创建至少一个任务;,.,OSStart();,/*开始多任务调度!永不返回*/,OSStart(),void OSStart(void),INT8U Y;,INT8U X;,if(OSRunning=FALSE),y =OSUnMapTblOSRdyGrp;,x =OSUnMapTblOSRdyTbly;,OSPrioHighRdy=(INT8U)(YOSEventGrp|=OSMapTblprio 3;,pevent-OSEventTblprio 3|=OSMapTblprio,从等待任务列表中删除一个任务,if(pevent-OSEventTblprio 3&=OSMapTblprio&0 x07)=0),pevent-OSEventGrp,在等待事件的任务列表中查找优先级最高的任务,在等待任务列表中查找最高优先级的任务,y =OSUnMapTblpevent-OSEventGrp;,x =OSUnMapTblpevent-OSEventTbly;,prio=(y 3)+x;,空闲ECB的管理,ECB的总数由用户所需要的信号量、邮箱和消息队列的总数决定,由OS_CFG.H中的#define OS_MAX_EVENTS定义。,在调用OSInit()初始化系统时,所有的ECB被链接成一个单向链表空闲事件控制块链表;,每当建立一个信号量、邮箱或消息队列时,就从该链表中取出一个空闲事件控制块,并对它进行初始化。,0,OS_MAX_EVENTS,OSEventFreeList,OS_EVENT,ECB的基本操作,OSEventWaitListInit,(),初始化一个事件控制块。,当创建一个信号量、邮箱或消息队列时,相应的创建函数会调用本函数对,ECB,的内容进行初始化,将,OSEventGrp,和,OSEventTbl,数组清零;,OSEventWaitListInit,(OS_EVENT*,pevent,),;,prevent,:指向需要初始化的事件控制块的指针。,OSEventTaskRdy,(),。,使一个任务进入就绪态,。,当,一个,事件,发生时,,,需要将其,等待任务列表中的最高优先级任务置,为,就绪态,;,OSEventTaskRdy,(OS_EVENT*,pevent,void*,msg,INT8U,msk,),;,msg,:指向消息的指针;,msk,:用于设置,TCB,的状态。,ECB的基本操作(续),OSEventTaskWait,(),使一个任务进入等待状态,。,当某个任务要等待一个事件的发生时,,需要调用本函数,将,该,任务从就绪任务表中删除,并放到相应事件的等待任务表中,;,O
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服