1、uCuC/OS-II/OS-II操作系统操作系统 uC/OS-II操作系统操作系统uC/OS-II操作系统简介操作系统简介及开发过程及开发过程uCuC/OS-II/OS-II操作系统操作系统 内内 容容一、一、 uCOS-II操作系统简介操作系统简介二、二、 uCOS-II操作系统内核结构操作系统内核结构三、三、 uCOS-II操作系统任务管理操作系统任务管理四、四、 uCOS-II操作系统内存管理操作系统内存管理五、五、 uCOS-II操作系统时间管理操作系统时间管理六、六、 uCOS-II操作系统任务间的通讯操作系统任务间的通讯七、七、 uCOS-II操作系统移植操作系统移植八、八、 uC
2、OS-II操作系统实验操作系统实验uCuC/OS-II/OS-II操作系统操作系统 一、一、 uCOS-II操作系统简介操作系统简介1.1 uC/OS-II简介简介1.2 uC/OS-II特点特点1.3 C/OS-II应用应用uCuC/OS-II/OS-II操作系统操作系统 1.1 uC/OS-II简介简介1、uC/OS-II是一个简单、高效的嵌是一个简单、高效的嵌入式实时操作系统内核入式实时操作系统内核2、支持、支持 x86、ARM、PowerPC、MIPS 等众多体系结构等众多体系结构3、可从、可从www.ucos-网站上获得网站上获得全部源码及其在各种体系结构平台全部源码及其在各种体系结
3、构平台上的移植范例。上的移植范例。uCuC/OS-II/OS-II操作系统操作系统 1.2 uC/OS-II特点特点1、uC/OS-II内核具有很强的可移植性。内核具有很强的可移植性。2、具有可抢占的实时多任务调度功能。、具有可抢占的实时多任务调度功能。3、提供了许多系统服务,如信号量、消、提供了许多系统服务,如信号量、消息队列、邮箱、内存管理、时间函数等息队列、邮箱、内存管理、时间函数等4、这些功能可以根据不同的需求进行裁、这些功能可以根据不同的需求进行裁减。减。uCuC/OS-II/OS-II操作系统操作系统 1.3 C/OS-II的各种商业应用的各种商业应用全世界有数百种产品在全世界有数
4、百种产品在应用应用:v医疗器械医疗器械v移动电话移动电话v路由器路由器v工业控制工业控制vGPS 导航系统导航系统v智能仪器智能仪器v更多更多uCuC/OS-II/OS-II操作系统操作系统 二、二、 uCOS-II操作系统内核结构操作系统内核结构2.1 临界段临界段2.2 任务任务2.3 任务状态任务状态2.4 任务控制块任务控制块2.5 任务就绪表任务就绪表2.6 任务调度任务调度2.7 中断处理中断处理2.8 时钟节拍时钟节拍 2.9 C/OS-初始化初始化2.10 C/OS-启动启动 uCuC/OS-II/OS-II操作系统操作系统 目的:为了实现资源共享。目的:为了实现资源共享。实现
5、方法:进入临界段时关中断,退出临界段时实现方法:进入临界段时关中断,退出临界段时开中断。这使得开中断。这使得C/OS-能够在临界段代码时避能够在临界段代码时避免被其它任务或中断服务所中断。免被其它任务或中断服务所中断。 C/OS-定义两个宏定义两个宏(macros)来开关中断。分别来开关中断。分别是:是:v进入临界段:进入临界段:OS_ENTER_CRITICAL()v退出临界段:退出临界段:OS_EXIT_CRITICAL()。这两个宏的定义取决于所用的微处理器,每种微这两个宏的定义取决于所用的微处理器,每种微处理器都有自己的处理器都有自己的OS_CPU.H文件。文件。 2.1 临界段临界段
6、(Critical Sections)uCuC/OS-II/OS-II操作系统操作系统 2.2 任务(任务(task)一个任务通常是一个无限的循环一个任务通常是一个无限的循环:void mytask(void *pdata) do init while (1) do something; waiting; do something; uCuC/OS-II/OS-II操作系统操作系统 任务(任务(task)C/OS-可以管理多达可以管理多达64个任务。个任务。v优先级为优先级为0-63 v优先级号越低,任务的优先级越高。优先级号越低,任务的优先级越高。v每个任务的优先级不能相同。每个任务的优先级
7、不能相同。保留优先级保留优先级:v高优先级:高优先级:0、1、2、3v低优先级:低优先级:OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及以及OS_LOWEST_PRI0用户可以有多达用户可以有多达56个应用任务。个应用任务。uCuC/OS-II/OS-II操作系统操作系统 2.3 任务状态任务状态就绪就绪休眠休眠等待等待或挂或挂起起运行运行中断中断服务服务删除任务删除任务删除任务删除任务删除任务删除任务中断中断中断结束中断结束创建任务创建任务任务调度任务调度任务被抢占任务被抢占等待消息等待消息挂起挂起收到消息收到消息挂起时间到挂起时间到
8、uCuC/OS-II/OS-II操作系统操作系统 任务状态任务状态休眠态休眠态 - OSTaskCreate()或或OSTaskCreateExt() - 就绪态就绪态等待态等待态,就绪态就绪态,运行态运行态 - OSTaskDel() - 休眠态休眠态就绪态就绪态 - OSStart() - 运行态运行态运行态运行态 - OSTimeDly()或或OSTimeDlyHMSM() , OSSemPend(),OSMboxPend(),或,或OSQPend() - 等待态等待态等待态等待态 - OSTimeTick() -就绪态就绪态空闲任务空闲任务 - OSTaskIdle() uCuC/OS
9、-II/OS-II操作系统操作系统 2.4 任务控制任务控制块(块(TCB)任务控制块任务控制块 OS_TCB OS_TCB 是一个数据结构,保存是一个数据结构,保存该任务的相关参数,包括任务堆栈指针,状该任务的相关参数,包括任务堆栈指针,状态,优先级,任务表位置,和任务链表指针态,优先级,任务表位置,和任务链表指针等。等。一旦任务建立了,任务控制块一旦任务建立了,任务控制块OS_TCBsOS_TCBs将被将被赋值。赋值。所有的任务控制块分为两条链表,空闲链表所有的任务控制块分为两条链表,空闲链表和使用链表。和使用链表。uCuC/OS-II/OS-II操作系统操作系统 任务控制块结构的主要成员
10、任务控制块结构的主要成员OS_STK *OSTCBStkPtr; /*当前任务栈顶的指针当前任务栈顶的指针* */ /struct os_tcb *OSTCBNext; /*任务控制块的双重链接任务控制块的双重链接指针指针*/struct os_tcb *OSTCBPrev; /*任务控制块的双重链接任务控制块的双重链接指针指针*/void void * *OSTCBExtPtrOSTCBExtPtr; / /* *用户定义的任务控制块扩展用户定义的任务控制块扩展* */ /OS_EVENT *OSTCBEventPtr; /*事件控制块的指针事件控制块的指针* */ /void *OSTCB
11、Msg; /*消息的指针消息的指针*/INT16U OSTCBDly; /*任务延时任务延时*/INT8U OSTCBStat; /*任务的状态字任务的状态字* */ /INT8U OSTCBPrio; /*任务优先级任务优先级* */ /INT8U OSTCBX; /*用于加速进入就绪态的过程用于加速进入就绪态的过程*/ INT8U OSTCBY; /*用于加速进入就绪态的过程用于加速进入就绪态的过程*/ INT8U OSTCBBitX; /*用于加速进入就绪态的过程用于加速进入就绪态的过程*/ INT8U OSTCBBitY; /*用于加速进入就绪态的过用于加速进入就绪态的过程程*/BOO
12、LEAN OSTCBDelReq; /*用于表示该任务是否要删除用于表示该任务是否要删除*/uCuC/OS-II/OS-II操作系统操作系统 2.5 任务就绪表任务就绪表(Ready List) 每个任务的就绪态标志都放入就绪表中每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量的,就绪表中有两个变量OSRdyGrpOSRdyGrp和和OSRdyTblOSRdyTbl。 在在OSRdyGrpOSRdyGrp中,任务按优先级分组,中,任务按优先级分组,8 8个个任务为一组。任务为一组。OSRdyGrpOSRdyGrp中的每一位表示中的每一位表示8 8组任务中每一组中是否有进入就绪态的组任务
13、中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪任务。任务进入就绪态时,就绪表表OSRdyTblOSRdyTbl中的相应元素的相应位也置中的相应元素的相应位也置位。位。uCuC/OS-II/OS-II操作系统操作系统 任务就绪表(任务就绪表(Ready List) uCuC/OS-II/OS-II操作系统操作系统 根据就绪表确定最高优先级根据就绪表确定最高优先级通过通过OSRdyGrpOSRdyGrp值确定高值确定高3 3位,假设位,假设OSRdyGrpOSRdyGrp0 x080 x08,对,对应应OSRdyTbl3OSRdyTbl3,查表,查表(OSUnMapTbl)得到得到3(3
14、(八进制,八进制,二进制二进制011);011);通过通过OSRdyTbl3OSRdyTbl3的值来确定低的值来确定低3 3位,假设位,假设OSRdyTbl3OSRdyTbl30 x3a0 x3a,查表得优先级为,查表得优先级为1 1;则最高优先级的任务为;则最高优先级的任务为3 3* *8+1=258+1=25uCuC/OS-II/OS-II操作系统操作系统 2.6 任务调度任务调度 C/OSC/OS是抢占式实时多任务内核,优先级最高是抢占式实时多任务内核,优先级最高的任务一旦准备就绪,则拥有的任务一旦准备就绪,则拥有CPUCPU的所有权开的所有权开始投入运行。始投入运行。 C/OSC/OS
15、中不支持时间片轮转法,每个任务的优中不支持时间片轮转法,每个任务的优先级要求不一样且是唯一的,所以任务调度的先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。并进行上下文切换。 C/OSC/OS任务调度所花的时间为常数,与应用程任务调度所花的时间为常数,与应用程序中建立的任务数无关。序中建立的任务数无关。uCuC/OS-II/OS-II操作系统操作系统 任务调度任务调度C/OS-C/OS-总是运行进入就绪态任务中优总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先先级最高的那一个。确定哪个任务优先
16、级最高,下面该哪个任务运行了的工作级最高,下面该哪个任务运行了的工作是由调度器(是由调度器(SchedulerScheduler)完成的。)完成的。 任务级的调度是由函数任务级的调度是由函数OSSchedOSSched()()完成的。完成的。中断级的调度是由另一个函数中断级的调度是由另一个函数OSIntExtOSIntExt()()完成的,这个函数将在以后描述。完成的,这个函数将在以后描述。 uCuC/OS-II/OS-II操作系统操作系统 2.7 中断处理中断处理 用户中断服务子程序流程用户中断服务子程序流程: 1、保存全部、保存全部CPU寄存器寄存器; 2、调用、调用OSIntEnter或
17、或OSIntNesting直接加直接加1;3、执行用户代码做中断服务、执行用户代码做中断服务; 4、调用、调用OSIntExit();5、恢复所有、恢复所有CPU寄存器;寄存器;6、执行中断返回指令;、执行中断返回指令;uCuC/OS-II/OS-II操作系统操作系统 OSIntEnter() void OSIntEnter (void) OS_ENTER_CRITICAL(); OSIntNesting+; OS_EXIT_CRITICAL();uCuC/OS-II/OS-II操作系统操作系统 OSIntExit()()OS_ENTER_CRITICAL();if (-OSIntNestin
18、g | OSLockNesting) = 0) OSIntExitY = OSUnMapTblOSRdyGrp;OSPrioHighRdy = (INT8U)(OSIntExitY 3) + OSUnMapTblOSRdyTblOSIntExitY); if (OSPrioHighRdy != OSPrioCur) OSTCBHighRdy=OSTCBPrioTblOSPrioHighRdy; OSCtxSwCtr+; OSIntCtxSw(); OS_EXIT_CRITICAL();uCuC/OS-II/OS-II操作系统操作系统 中断与时钟节拍中断与时钟节拍当发生中断时,首先应保护现场,将
19、当发生中断时,首先应保护现场,将CPU寄存寄存器入栈,再处理中断函数,然后恢复现场,将器入栈,再处理中断函数,然后恢复现场,将CPU寄存器出栈,最后执行中断返回。寄存器出栈,最后执行中断返回。uC/OS中提供了中提供了OSIntEnter()和和OSIntExit()告告诉内核进入了中断状态。诉内核进入了中断状态。时钟节拍是一种特殊的中断,是操作系统的心时钟节拍是一种特殊的中断,是操作系统的心脏。可以对任务列表进行扫描,判断是否有延脏。可以对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态,最后进行上下时任务应该处于准备就绪状态,最后进行上下文切换。文切换。uCuC/OS-II/OS-
20、II操作系统操作系统 2.8 时钟节拍时钟节拍 C/OS需要用户提供周期性信号源,用于实现时需要用户提供周期性信号源,用于实现时间延时和确认超时。节拍率应在每秒间延时和确认超时。节拍率应在每秒10次到次到100次次之间之间,或者说或者说10到到100Hz。时钟节拍率越高,系统。时钟节拍率越高,系统的额外负荷就越重。的额外负荷就越重。时钟节拍的实际频率取决于用户应用程序的精度。时钟节拍的实际频率取决于用户应用程序的精度。时钟节拍源可以是专门的硬件定时器,也可以是时钟节拍源可以是专门的硬件定时器,也可以是来自来自50/60Hz交流电源的信号。交流电源的信号。 用户必须在多任务系统启动以后再开启时钟
21、节拍用户必须在多任务系统启动以后再开启时钟节拍器,也就是在调用器,也就是在调用OSStart()之后。之后。uCuC/OS-II/OS-II操作系统操作系统 时钟节拍中断服务子程时钟节拍中断服务子程 (OSTickISR)void OSTickISR(void) 保存处理器寄存器的值;保存处理器寄存器的值; 调用调用OSIntEnter()或是将或是将OSIntNesting加加1; 调用调用OSTimeTick(); 调用调用OSIntExit(); 恢复处理器寄存器的值恢复处理器寄存器的值; 执行中断返回指令执行中断返回指令;uCuC/OS-II/OS-II操作系统操作系统 2.9 C/O
22、S-初始化初始化 在调用在调用C/OS-的任何其它服务之前,的任何其它服务之前,C/OS-要求用户首先调用系统初始化函数要求用户首先调用系统初始化函数OSInit()。OSInit()建立空闲任务建立空闲任务idle task,这个任务总是处,这个任务总是处于就绪态的。空闲任务于就绪态的。空闲任务OSTaskIdle()的优先级()的优先级总是设成最低,即总是设成最低,即OS_LOWEST_PRIO。 C/OS-还初始化了还初始化了4个空数据结构缓冲区。个空数据结构缓冲区。uCuC/OS-II/OS-II操作系统操作系统 C/OS-初始化后的一些数据结构初始化后的一些数据结构uCuC/OS-I
23、I/OS-II操作系统操作系统 C/OS-初始化后的空缓冲区初始化后的空缓冲区 uCuC/OS-II/OS-II操作系统操作系统 2.10 C/OS-的启动的启动 多任务的启动是用户通过调用多任务的启动是用户通过调用OSStartOSStart()()实实现的。然而,启动现的。然而,启动C/OS-C/OS-之前,用户至之前,用户至少要建立一个应用任务。少要建立一个应用任务。 OSInit(); /* 初始化uC/OS-II*/ 调用OSTaskCreate()或OSTaskCreateExt(),创建至少一个任务 ; OSStart(); /*开始多任务调度!永不返回 */uCuC/OS-II
24、/OS-II操作系统操作系统 OSStartif (OSRunning = FALSE) y = OSUnMapTblOSRdyGrp; x = OSUnMapTblOSRdyTbly; OSPrioHighRdy = (INT8U)(y 3;3;OSRdyTblprio3 |=OSMapTblprioOSRdyTblprio3 |=OSMapTblprio & 0 x07; & 0 x07;假设优先级为假设优先级为1212 00 001 100 b (1,4) 00 001 100 b (1,4)OSRdyGrpOSRdyGrp |=0 x02 |=0 x02;(;(0000 0010 b0
25、000 0010 b)OSRdyTbl1 |=0 x10; OSRdyTbl1 |=0 x10; (0001 0000 b0001 0000 b)uCuC/OS-II/OS-II操作系统操作系统 使任务脱离就绪态使任务脱离就绪态将任务就绪表将任务就绪表OSRdyTblprioOSRdyTblprio33相应元素相应元素的相应位清零,而且的相应位清零,而且当当OSRdyTblprioOSRdyTblprio33中的所有位都为零时,即全组任务中没有中的所有位都为零时,即全组任务中没有一个进入就绪态时一个进入就绪态时,OSRdyGrpOSRdyGrp的相应位才的相应位才为零。为零。if(OSRdyT
26、blprioif(OSRdyTblprio3&=3&= OSMapTblprioOSMapTblprio & 0 x07)=0) & 0 x07)=0)OSRdyGrp&=OSMapTblprioOSRdyGrp&=OSMapTblprio3;3;uCuC/OS-II/OS-II操作系统操作系统 3.2 任务删除任务删除OSTaskDel() 删除任务删除任务,是说任务将返回并处于休眠状是说任务将返回并处于休眠状态,并不是说任务的代码被删除了态,并不是说任务的代码被删除了 .OSTaskDel()一开始应确保用户所要删除一开始应确保用户所要删除的任务并非是空闲任务的任务并非是空闲任务.用户可以
27、删除用户可以删除statistic任务任务 .确保用户不是在确保用户不是在ISR例程中去试图删除一例程中去试图删除一个任务个任务 uCuC/OS-II/OS-II操作系统操作系统 3.3 任务调度器任务调度器 void OSSched (void) INT8U y; OS_ENTER_CRITICAL(); if (OSLockNesting | OSIntNesting) = 0) y = OSUnMapTblOSRdyGrp; OSPrioHighRdy = (INT8U)(y 3) + OSUnMapTblOSRdyTbly); if (OSPrioHighRdy != OSPrioCu
28、r) OSTCBHighRdy = OSTCBPrioTblOSPrioHighRdy; OSCtxSwCtr+; OS_TASK_SW(); OS_EXIT_CRITICAL();uCuC/OS-II/OS-II操作系统操作系统 3.4 任务切换任务切换 (OS_TASK_SW)任务切换由以下两步完成任务切换由以下两步完成 :v将被挂起任务的微处理器寄存器推入堆栈将被挂起任务的微处理器寄存器推入堆栈 。v将较高优先级的任务的寄存器值从栈中恢复将较高优先级的任务的寄存器值从栈中恢复到寄存器中到寄存器中 。OSSched()的所有代码都属临界段代码。的所有代码都属临界段代码。在寻找进入就绪态的优
29、先级最高的任务在寻找进入就绪态的优先级最高的任务过程中,为防止中断服务子程序把一个过程中,为防止中断服务子程序把一个或几个任务的就绪位置位,中断是被关或几个任务的就绪位置位,中断是被关掉的。掉的。 uCuC/OS-II/OS-II操作系统操作系统 任务级的任务切换任务级的任务切换OS_TASK_SW()通过系统调用指令完成通过系统调用指令完成保护当前任务的现场保护当前任务的现场恢复新任务的现场恢复新任务的现场执行中断返回指令执行中断返回指令开始执行新的任务开始执行新的任务uCuC/OS-II/OS-II操作系统操作系统 调用调用OS_TASK_SW()前的数据结构前的数据结构低优先级任务 OS
30、_TCBOSTCBCur(1)存贮器低地址存贮器高地址堆栈方向堆栈方向SPR1R2R3R4PCPSW存贮器低地址存贮器高地址高优先级任务 OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)uCuC/OS-II/OS-II操作系统操作系统 保存当前保存当前CPU寄存器的值寄存器的值低优先级任务 OS_TCBOSTCBCurPSWPCR1R2R3R4存贮器低地址存贮器高地址堆栈方向堆栈方向SPR1R2R3R4PCPSW存贮器低地址存贮器高地址高优先级任务 OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)(1)(3)uCuC/OS-II/OS-II操作系统操作系统
31、重新装入要运行的任务重新装入要运行的任务低优先级任务 OS_TCBOSTCBCurPSWPCR1R2R3R4存贮器低地址存贮器高地址堆栈方向堆栈方向SPR1R2R3R4PCPSWPSWPCR1R2R3R4存贮器低地址存贮器高地址高优先级任务 OS_TCBOSTCBHighRdyOSTCBCur(1)(2)CPU(4)(4)(1)(3)(3)(4)uCuC/OS-II/OS-II操作系统操作系统 任务切换任务切换OSCtxSw()的代码的代码Void OSCtxSw(voidVoid OSCtxSw(void) ) 将将R1,R2,R3R1,R2,R3及及R4R4推入当前堆栈;推入当前堆栈; O
32、STCBCurOSTCBCurOSTCBStkPtrOSTCBStkPtr = SP; = SP; OSTCBCur = OSTCBHighRdy OSTCBCur = OSTCBHighRdy; ; OSPrioCur = OSPrioHighRdy OSPrioCur = OSPrioHighRdy; ; SP = OSTCBHighRdy SP = OSTCBHighRdy OSTCBSTKPtrOSTCBSTKPtr; ; 将将R4,R3,R2R4,R3,R2及及R1R1从新堆栈中弹出;从新堆栈中弹出; 执行中断返回指令;执行中断返回指令; uCuC/OS-II/OS-II操作系统操作
33、系统 四、四、 uCOS-II操作系统内存管理操作系统内存管理4.1 内存管理概述内存管理概述4.2 内存控制块内存控制块4.3 内存管理初始化内存管理初始化4.4 建立内存分区建立内存分区4.5 分配内存块分配内存块4.6 释放内存块释放内存块uCuC/OS-II/OS-II操作系统操作系统 4.1 内存管理概述内存管理概述在在ANSI CANSI C中可以用中可以用mallocmalloc()()和和free()free()两个函数动两个函数动态地分配内存和释放内存。在嵌入式实时操作系态地分配内存和释放内存。在嵌入式实时操作系统中,容易产生内存碎片。统中,容易产生内存碎片。 C/OS-II
34、C/OS-II中,操作系统把连续的大块内存按分区中,操作系统把连续的大块内存按分区来管理。每个分区中包含有整数个大小相同的内来管理。每个分区中包含有整数个大小相同的内存块。存块。在一个系统中可以有多个内存分区。这样,用户在一个系统中可以有多个内存分区。这样,用户的应用程序就可以从不同的内存分区中得到不同的应用程序就可以从不同的内存分区中得到不同大小的内存块。但是,特定的内存块在释放时必大小的内存块。但是,特定的内存块在释放时必须重新放回它以前所属于的内存分区。须重新放回它以前所属于的内存分区。uCuC/OS-II/OS-II操作系统操作系统 内存分区示意图内存分区示意图uCuC/OS-II/O
35、S-II操作系统操作系统 4.2 内存控制块内存控制块 为了便于内存的管理,在为了便于内存的管理,在C/OS-IIC/OS-II中使用内存控制块中使用内存控制块(memory control blocksmemory control blocks)的数据结构来跟踪每一个内)的数据结构来跟踪每一个内存分区,系统中的每个内存分区都有它自己的内存控制块。存分区,系统中的每个内存分区都有它自己的内存控制块。 typedef structtypedef struct void void * *OSMemAddrOSMemAddr; ; / /* *分区起始地址分区起始地址* */ / void void
36、 * *OSMemFreeListOSMemFreeList; ; / /* *下一个空闲内存下一个空闲内存块块* */ / INT32U OSMemBlkSize INT32U OSMemBlkSize; ;/ /* *内存块的大小内存块的大小* */ / INT32U OSMemNBlks INT32U OSMemNBlks; ;/ /* *内存块数量内存块数量* */ / INT32U OSMemNFree INT32U OSMemNFree; ;/ /* *空闲内存块数量空闲内存块数量 * */ / OS_MEM; OS_MEM;uCuC/OS-II/OS-II操作系统操作系统 4.3
37、 内存管理初始化内存管理初始化如果要在如果要在C/OS-IIC/OS-II中使用内存管理,需要中使用内存管理,需要在在OS_CFG.HOS_CFG.H文件中将开关量文件中将开关量OS_MEM_ENOS_MEM_EN设置设置为为1 1。这样。这样C/OS-II C/OS-II 在启动时就会对内存在启动时就会对内存管理器进行初始化。(管理器进行初始化。(由由OSInit调用调用OSMemInit实现实现 )该初始化主要建立一个内存控制块链表,该初始化主要建立一个内存控制块链表,(如下图)其中的常数(如下图)其中的常数OS_MAX_MEM_PARTOS_MAX_MEM_PART(见(见OS_CFG.
38、HOS_CFG.H)定义了最大的内存分区数,)定义了最大的内存分区数,该常数值至少应为该常数值至少应为2 2。uCuC/OS-II/OS-II操作系统操作系统 空闲内存控制块链表空闲内存控制块链表 uCuC/OS-II/OS-II操作系统操作系统 4.4 建立内存分区建立内存分区OSMemCreate() 在使用一个内存分区之前,必须使用在使用一个内存分区之前,必须使用OSMemCreateOSMemCreate()()先建立该内存分区。该函数共有先建立该内存分区。该函数共有4 4个参数:内存分区的起始地址、分区内的内存块个参数:内存分区的起始地址、分区内的内存块总块数、每个内存块的字节数和一
39、个指向错误信总块数、每个内存块的字节数和一个指向错误信息代码的指针。息代码的指针。 每个内存分区必须含有至少两个内存块,每个内每个内存分区必须含有至少两个内存块,每个内存块至少为一个指针的大小存块至少为一个指针的大小 。OS_MEM OS_MEM * *CommTxBufCommTxBuf; ;INT8U CommTxPart10032;INT8U CommTxPart10032;CommTxBuf = OSMemCreate(CommTxPartCommTxBuf = OSMemCreate(CommTxPart, 100, 32, &err); , 100, 32, &err); uCuC
40、/OS-II/OS-II操作系统操作系统 4.5 分配内存块分配内存块OSMemGet() 应用程序可以调用应用程序可以调用OSMemGetOSMemGet()()函数从已经建立的函数从已经建立的内存分区中申请一个内存块。该函数的唯一参数内存分区中申请一个内存块。该函数的唯一参数是指向特定内存分区的指针,该指针在建立内存是指向特定内存分区的指针,该指针在建立内存分区时,由分区时,由OSMemCreateOSMemCreate()()函数返回。函数返回。注意的是,用户可以在中断服务子程序中调用注意的是,用户可以在中断服务子程序中调用OSMemGetOSMemGet()(),因为在暂时没有内存块可
41、用的情况,因为在暂时没有内存块可用的情况下,下,OSMemGetOSMemGet()()不会等待,而是马上返回不会等待,而是马上返回NULLNULL指指针。针。 uCuC/OS-II/OS-II操作系统操作系统 4.6 释放内存块释放内存块OSMemPut()应用程序不再使用一个内存块时,必须及应用程序不再使用一个内存块时,必须及时地把它释放并放回到相应的内存分区中。时地把它释放并放回到相应的内存分区中。这个操作由这个操作由OSMemPutOSMemPut()()函数完成。函数完成。 必须注意的是必须注意的是,OSMemPutOSMemPut()()并不知道一个并不知道一个内存块是属于哪个内存
42、分区的。内存块是属于哪个内存分区的。 释放内存释放内存块时必须将它释放到正确的分区。块时必须将它释放到正确的分区。uCuC/OS-II/OS-II操作系统操作系统 五、五、 uCOS-II操作系统时间管理操作系统时间管理C/OS-(C/OS-(其它内核也一样其它内核也一样) )要求用户提要求用户提供定时中断来实现延时与超时控制等功供定时中断来实现延时与超时控制等功能。能。这个定时中断叫做时钟节拍,它应这个定时中断叫做时钟节拍,它应该每秒发生该每秒发生1010至至100100次。次。时钟节拍的频率时钟节拍的频率越高,系统的负荷就越重。越高,系统的负荷就越重。 与时钟管理相关的系统服务有:与时钟管
43、理相关的系统服务有:vOSTimeDLY()vOSTimeDLYHMSM()vOSTimeDlyResmue()vOStimeGet()vOSTimeSet()uCuC/OS-II/OS-II操作系统操作系统 六、六、 uCOS-II操作系统任务间的通讯操作系统任务间的通讯6.1 任务间通信手段任务间通信手段6.2 事件控制块事件控制块 ECB6.3 信号量信号量 semaphore6.4 邮箱邮箱 OSMboxuCuC/OS-II/OS-II操作系统操作系统 6.1 任务间通信手段任务间通信手段 C/OSC/OS中,采用多种方法保护任务之间的共享数中,采用多种方法保护任务之间的共享数据和提供
44、任务之间的通信。据和提供任务之间的通信。v提供提供OS_ENTER_CRITICALOS_ENTER_CRITICAL和和OS_EXIT_CRITICALOS_EXIT_CRITICAL来对临界资源进行保护来对临界资源进行保护v利用函数利用函数OSSchedLockOSSchedLock()()和和OSSchekUnlockOSSchekUnlock()()对对任务调度函数上锁和开锁来实现数据共享任务调度函数上锁和开锁来实现数据共享 。v提供了经典操作系统任务间通信方法:信号量、提供了经典操作系统任务间通信方法:信号量、邮箱、消息队列,事件标志。邮箱、消息队列,事件标志。 uCuC/OS-II
45、/OS-II操作系统操作系统 6.2 事件控制块事件控制块ECB所有的通信信号都被看成是事件所有的通信信号都被看成是事件(event), (event), 一个称为事件控一个称为事件控制块制块(ECB, Event Control Block)(ECB, Event Control Block)的数据结构来表征每一个的数据结构来表征每一个具体事件,具体事件,ECBECB的结构如下:的结构如下:typedef structtypedef struct void void * *OSEventPtrOSEventPtr; /; /* *指向消息或消息队列的指针指向消息或消息队列的指针* */ /
46、INT8U OSEventTblOS_EVENT_TBL_SIZE INT8U OSEventTblOS_EVENT_TBL_SIZE; /; /* *等待任务列表等待任务列表* */ / INT8U OSEventGrp INT8U OSEventGrp; /; /* *等待任务组等待任务组* */ / INT16U OSEventCnt INT16U OSEventCnt; /; /* *计数器(事件是信号量时)计数器(事件是信号量时)* */ / INT8U OSEventType INT8U OSEventType; /; /* *事件类型:信号量、邮箱等事件类型:信号量、邮箱等* *
47、/ / OS_EVENT; OS_EVENT;与与TCBTCB类似的结构,使用两个链表,空闲链表与使用链表类似的结构,使用两个链表,空闲链表与使用链表uCuC/OS-II/OS-II操作系统操作系统 6.3 信号量信号量 semaphore信号量在多任务系统中用于:控制共享资源的信号量在多任务系统中用于:控制共享资源的使用权、标志事件的发生、使两个任务的行为使用权、标志事件的发生、使两个任务的行为同步。同步。uCuC/OS/OS中信号量由两部分组成:信号量的计数中信号量由两部分组成:信号量的计数值和等待该信号任务的等待任务表。信号量的值和等待该信号任务的等待任务表。信号量的计数值可以为二进制计
48、数值可以为二进制, , 也可以是其他整数。也可以是其他整数。系统通过系统通过OSSemPend( )OSSemPend( )和和OSSemPostOSSemPost( )( )来支持来支持信号量的两种原子操作信号量的两种原子操作P()P()和和V()V()。P()P()操作减操作减少信号量的值,如果新的信号量的值不大于少信号量的值,如果新的信号量的值不大于0,0,则操作阻塞;则操作阻塞;V()V()操作增加信号量的值操作增加信号量的值。 uCuC/OS-II/OS-II操作系统操作系统 6.4 邮箱邮箱 OSMbox 邮箱是邮箱是C/OS-II中另一种通讯机制,它可以使中另一种通讯机制,它可以
49、使一个任务或者中断服务子程序向另一个任务发一个任务或者中断服务子程序向另一个任务发送一个指针型的变量。该指针指向一个包含了送一个指针型的变量。该指针指向一个包含了特定特定“消息消息”的数据结构。的数据结构。 通过调用通过调用OSMboxCreate()函数来建立邮箱,函数来建立邮箱,并且要指定指针的初始值。一般情况下,这个并且要指定指针的初始值。一般情况下,这个初始值是初始值是NULL,但也可以初始化一个邮箱,但也可以初始化一个邮箱,使其在最开始就包含一条消息。使其在最开始就包含一条消息。 OSMboxPend() 等待一个邮箱中的消息。等待一个邮箱中的消息。OSMboxPost() 发送一个
50、消息到邮箱中。发送一个消息到邮箱中。uCuC/OS-II/OS-II操作系统操作系统 七、七、 uCOS-II操作系统移植操作系统移植7.1 COS-II移植简介移植简介7.2 移植移植 COS-II满足的条件满足的条件7.3 C/OS-II在在S3C2410上的移植上的移植uCuC/OS-II/OS-II操作系统操作系统 7.1 COS-II移植简介移植简介所谓移植,是指使一个实时操作系统能所谓移植,是指使一个实时操作系统能够在某个微处理器平台上运行。够在某个微处理器平台上运行。 COS-II的主要代码都是由标准的的主要代码都是由标准的C语语言写成的,移植方便。言写成的,移植方便。uCuC/