1、 嵌入式技术与应嵌入式技术与应用用 智能电器与智能系统省重点实验室智能电器与智能系统省重点实验室 嵌入式操作系统C/OS-II6C H A P T E R主要内容主要内容 嵌入式操作系统嵌入式操作系统 C/OS-C/OS-简介简介 C/OS-C/OS-内核结构内核结构 C/OS-C/OS-任务管理任务管理 C/OS-C/OS-时间管理时间管理 C/OS-C/OS-任务通信与同步任务通信与同步 C/OS-C/OS-的的移植规划移植规划 C/OS-C/OS-的移植的移植 移植代码应用到移植代码应用到LPC2000LPC2000为什么需要操作系统为什么需要操作系统嵌嵌 入入 式式微微 处处 理理 器
2、器S S D D R R A A M MR R O O M MI I/O OA A/D DD D/A A人人 机机 交交 互互 接接 口口通通 用用 接接 口口实实 时时 操操 作作 系系 统统(R R T T O O S S)图图 形形 用用 户户接接 口口B B S S P P/H H A A L L 硬硬 件件 抽抽 象象 层层/板板 极极 支支 持持 包包任任 务务 管管 理理文文 件件 系系 统统应应 用用 程程 序序嵌嵌 入入 式式 计计 算算 机机 系系 统统硬硬 件件 层层软软 件件 层层中中 间间 层层功功 能能 层层硬件抽象层的引入硬件抽象层的引入 嵌入式实时系统自底向上包
3、含三个部分嵌入式实时系统自底向上包含三个部分 硬件环境硬件环境 嵌入式实时操作系统嵌入式实时操作系统RTOSRTOS 嵌入式实时应用程序嵌入式实时应用程序 嵌入式系统应用的硬件环境差异大嵌入式系统应用的硬件环境差异大 中间层中间层位于操作系统和硬件之间,包含系位于操作系统和硬件之间,包含系统中与硬件相关的大部分功能统中与硬件相关的大部分功能 嵌入式系统的体系结构嵌入式系统的体系结构嵌嵌 入入 式式微微 处处 理理 器器S S D D R R A A M MR R O O M MI I/O OA A/D DD D/A A人人 机机 交交 互互 接接 口口通通 用用 接接 口口实实 时时 操操 作
4、作 系系 统统(R R T T O O S S)图图 形形 用用 户户接接 口口B B S S P P/H H A A L L 硬硬 件件 抽抽 象象 层层/板板 极极 支支 持持 包包任任 务务 管管 理理文文 件件 系系 统统应应 用用 程程 序序嵌嵌 入入 式式 计计 算算 机机 系系 统统硬硬 件件 层层软软 件件 层层中中 间间 层层功功 能能 层层嵌入式操作系统的发展嵌入式操作系统的发展操作系统内核操作系统内核应用程序应用程序驱动程序和固件驱动程序和固件操作系统内核操作系统内核文件系统文件系统驱动程序和固件驱动程序和固件APIAPIGUIGUI应用程序应用程序操作系统内核操作系统内
5、核文件系统文件系统驱动程序和固件驱动程序和固件APIAPIGUIGUI应用程序应用程序通信协议通信协议库函数库函数8080年代初期年代初期8080年代中期年代中期-90-90年代中期年代中期9090年代末期年代末期-21-21世纪世纪RTOSRTOS在嵌入式系统中的位置在嵌入式系统中的位置嵌入式硬件平台BSPKERNELFSTCP/IP设备驱动设备驱动设备设备I/O调试工具调试工具其它组件其它组件应用RTOSC/C+主要内容主要内容 嵌入式操作系统嵌入式操作系统 C/OS-C/OS-简介简介 C/OS-C/OS-内核结构内核结构 C/OS-C/OS-任务管理任务管理 C/OS-C/OS-时间管
6、理时间管理 C/OS-C/OS-任务通信与同步任务通信与同步 C/OS-C/OS-的的移植规划移植规划 C/OS-C/OS-的移植的移植 移植代码应用到移植代码应用到LPC2000LPC2000 C/OS-IIC/OS-II简介简介 概述概述 C/OS-II C/OS-II是源码公开的著名实时内核,可用是源码公开的著名实时内核,可用于各类于各类8 8位、位、1616位和位和3232位单片机或位单片机或DSPDSP。C/OS-II C/OS-II是一个完整的、可移植、可固化、是一个完整的、可移植、可固化、可剪裁的占先式实时多任务内核。可剪裁的占先式实时多任务内核。C/OS-IIC/OS-II使用
7、使用ANSI CANSI C语言编写,包含一小部分汇编代码,使之语言编写,包含一小部分汇编代码,使之可以供不同架构的微处理器使用可以供不同架构的微处理器使用 C/OS-IIC/OS-II特点特点提供源代码提供源代码:源代码全部开放。:源代码全部开放。可移植性(可移植性(portableportable):源代码绝大部分使用:源代码绝大部分使用ANSI CANSI C编写,将与微编写,将与微处理器硬件相关的汇编语言使用量压缩到最低的限度,方便移植。处理器硬件相关的汇编语言使用量压缩到最低的限度,方便移植。可固化可固化(ROMmableROMmable):具备合适的软硬件工具,就可以将:具备合适的
8、软硬件工具,就可以将CC/OS-II/OS-II嵌入到产品中成为产品的一部分。嵌入到产品中成为产品的一部分。可剪裁可剪裁(scalable)(scalable):使用条件编译实现可剪裁,减少:使用条件编译实现可剪裁,减少CC/OS-II/OS-II对对代码空间和数据空间的占用。代码空间和数据空间的占用。可剥夺可剥夺(preemptive)(preemptive):完全可剥夺型的实时内核,:完全可剥夺型的实时内核,CC/OS-II/OS-II总是总是运行就绪条件下优先级最高的任务。运行就绪条件下优先级最高的任务。C/OS-IIC/OS-II的各种商业应用的各种商业应用 全世界有数百种产品在应用全
9、世界有数百种产品在应用: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-C/OS-简介简介 C/OS-C
10、/OS-内核结构内核结构 C/OS-C/OS-任务管理任务管理 C/OS-C/OS-时间管理时间管理 C/OS-C/OS-任务通信与同步任务通信与同步 C/OS-C/OS-的的移植规划移植规划 C/OS-C/OS-的移植的移植 移植代码应用到移植代码应用到LPC2000LPC2000 C/OS-IIC/OS-II的文件结构的文件结构应用程序应用程序(用户代码)(用户代码)C/OS-IIC/OS-II(与处理器无关代码)(与处理器无关代码)OS_CORE.cOS_CORE.cOS_FLAG.cOS_FLAG.c.C/OS-IIC/OS-II配置配置(与应用无关)(与应用无关)OS_CFG.HOS
11、_CFG.HINCLUDES.HINCLUDES.H C/OS-IIC/OS-II移植移植(与处理器相关代码)(与处理器相关代码)CPUCPU定时器定时器 硬件硬件软件软件 当处理临界段代码时,须关中断,处理完毕后,当处理临界段代码时,须关中断,处理完毕后,再开中断再开中断 关中断时间关中断时间是实时内核最重要的指标之一。它影是实时内核最重要的指标之一。它影响用户系统对实时事件的相应特性。响用户系统对实时事件的相应特性。在实际应用中,关中断的时间很大程度上取决于在实际应用中,关中断的时间很大程度上取决于微处理器的结构和编译器生成的代码质量微处理器的结构和编译器生成的代码质量 微处理器通常具有关
12、中断微处理器通常具有关中断/开中断操作。开中断操作。C C源代码中插入汇编语言语句,实现关中断源代码中插入汇编语言语句,实现关中断/开中断操作开中断操作 关中断关中断/开中断操作作为语言的扩展部分,直接从开中断操作作为语言的扩展部分,直接从C C语言语言中可以关中断中可以关中断/开中断开中断 C/OS-IIC/OS-II开关中断的方法开关中断的方法 C/OS-IIC/OS-II开关中断的方法开关中断的方法 C/OS-IIC/OS-II定义了两个宏调用来开关中断定义了两个宏调用来开关中断:OS_ENTER_CRITICAL()OS_ENTER_CRITICAL()(禁止中断的宏(禁止中断的宏)O
13、S_EXIT_CRITICAL()(OS_EXIT_CRITICAL()(启用中断的宏)启用中断的宏).OS_ENTER_CRITICAL();OS_ENTER_CRITICAL();/*C/OS-IIC/OS-II临界段代码临界段代码*/OS_EXIT_CRITICAL();OS_EXIT_CRITICAL();.宏定义取决于使用的微处理器。在文件宏定义取决于使用的微处理器。在文件OS_CPU.HOS_CPU.H有相应的宏定义有相应的宏定义 C/OS-IIC/OS-II中,每种微处理器都有自己的中,每种微处理器都有自己的OS_CPU.HOS_CPU.H文件文件任务(任务(tasktask)典
14、型的任务:一个无限循环典型的任务:一个无限循环void mytask(void*pdata)for(;)do something;waiting;do something;Task StructureTask Structure void YourTask(void*pdata)(1)for(;)(2)/*用户代码用户代码*/调用调用uC/OS-II的某种系统服务的某种系统服务:OSMboxPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyH
15、MSM();/*用户代码用户代码*/任务完成后的自我删除任务完成后的自我删除 当任务完成后,任务可以自我删除当任务完成后,任务可以自我删除 任务代码并非真的删除了,系统只是简单地任务代码并非真的删除了,系统只是简单地不再理会这个任务不再理会这个任务 这个任务的代码也不会再运行了,即使任务这个任务的代码也不会再运行了,即使任务调用调用OSTaskDelOSTaskDel(),这个任务也绝不会返回(),这个任务也绝不会返回 void YourTask(void*pdata)/*用户代码用户代码*/OSTaskDel(OS_PRIO_SELF);C/OS IIC/OS II中的任务中的任务 C/OS
16、 C/OS II 2.5II 2.5版本支持版本支持6464个任务,每个任务一个特定个任务,每个任务一个特定的优先级。数字越小,优先级越高的优先级。数字越小,优先级越高 系统总是运行进入就绪态优先级最高的任务系统总是运行进入就绪态优先级最高的任务 任务优先级号就是任务编号(任务优先级号就是任务编号(IDID).优先级号也被一些优先级号也被一些内核功能函数调用。如内核功能函数调用。如OsTaskChangePrio()OsTaskChangePrio()及及OsTaskDel().OsTaskDel().系统占用了系统占用了8 8个任务,保留优先级为个任务,保留优先级为0 0、1 1、2 2、3
17、 3、OS_LOWEST_PRIO-3OS_LOWEST_PRIO-3、OS_LOWEST_PRIO-2 OS_LOWEST_PRIO-2、OS_LOWEST_PRIO-1OS_LOWEST_PRIO-1、OS_LOWEST_PRIO-0 OS_LOWEST_PRIO-0 即:建议不使用上述最高即:建议不使用上述最高4 4个和最低个和最低4 4个优先级,用户个优先级,用户任务仍可达任务仍可达5656个个任务状态任务状态 在任一给定的时刻,任务的状态一定是在任一给定的时刻,任务的状态一定是以下五种状态之一:以下五种状态之一:睡眠态(睡眠态(task dormanttask dormant)就绪态
18、(就绪态(task readytask ready)运行态(运行态(task runningtask running)等待状态(等待状态(task waitingtask waiting)中断服务态(中断服务态(ISR running)ISR running)睡眠态(睡眠态(task dormanttask dormant)指任务驻留在程序空间(指任务驻留在程序空间(ROMROM或或RAMRAM),还没有),还没有交给系统来管理的状态交给系统来管理的状态 任务交给系统通过调用以下函数之一来实现:任务交给系统通过调用以下函数之一来实现:OSTaskCreateOSTaskCreate()()OS
19、TaskCreateExtOSTaskCreateExt()()告知系统:告知系统:任务的起始地址任务的起始地址 任务建立时,用户给任务赋予的优先级任务建立时,用户给任务赋予的优先级 任务要使用的栈空间大小等任务要使用的栈空间大小等就绪态(就绪态(task readytask ready)任务一旦创建就进入就绪态,准备运行任务一旦创建就进入就绪态,准备运行 任务的创建可以是在多任务开始之前,也可以任务的创建可以是在多任务开始之前,也可以动态地由一个运行着的任务创建动态地由一个运行着的任务创建 若刚创建任务的优先级高于创建它的任务的优若刚创建任务的优先级高于创建它的任务的优先级,它将立即获得先级
20、,它将立即获得cpucpu的使用权的使用权 任务可通过任务可通过OSTaskDelOSTaskDel()返回睡眠态;或调()返回睡眠态;或调用该函数让另一个任务进入睡眠态用该函数让另一个任务进入睡眠态运行态(运行态(task runningtask running)就绪的任务只有当所有优先级高于它的任务都就绪的任务只有当所有优先级高于它的任务都转为等待状态,或被删除后,才能进入运行态转为等待状态,或被删除后,才能进入运行态 任何时刻只有一个任务处于运行态任何时刻只有一个任务处于运行态 调用调用OSStartOSStart()可以启动多任务。该函数只()可以启动多任务。该函数只能在启动时调用一次
21、能在启动时调用一次 OSStartOSStart()运行用户初始化代码中已经建立()运行用户初始化代码中已经建立的、进入就绪态的优先级最高的任务的、进入就绪态的优先级最高的任务等待状态(等待状态(task waitingtask waiting)正在运行的任务可以通过下面的调用进入等待状正在运行的任务可以通过下面的调用进入等待状态。延迟时间到,立即强制执行任务切换,让下态。延迟时间到,立即强制执行任务切换,让下一个优先级最高、并进入就绪态的任务执行。一个优先级最高、并进入就绪态的任务执行。OSTimeDlyOSTimeDly()()OSTimeDlyHMSMOSTimeDlyHMSM()()等
22、待时间过去后,系统服务(内部)函数等待时间过去后,系统服务(内部)函数OSTimeTickOSTimeTick()使延迟了的任务进入就绪态()使延迟了的任务进入就绪态 用户无需在应用程序代码中调用这个函数用户无需在应用程序代码中调用这个函数等待状态(续)等待状态(续)正在运行的任务可能需要通过调用函数等待某正在运行的任务可能需要通过调用函数等待某一事件发生。如果该事件并未发生,任务就进一事件发生。如果该事件并未发生,任务就进入等待状态入等待状态 OSFlagPendOSFlagPend();();OSMutexPendOSMutexPend()()OSSemPendOSSemPend();()
23、;OSMboxPendOSMboxPend()()当事件发生或等待超时,被挂起的任务就进入当事件发生或等待超时,被挂起的任务就进入就绪态就绪态中断服务态(中断服务态(ISR running)ISR running)正在执行的任务是可以被中断的正在执行的任务是可以被中断的,除非该,除非该任务将中断关闭,或系统将中断关闭。被任务将中断关闭,或系统将中断关闭。被中断的任务便进入了中断服务态中断的任务便进入了中断服务态 响应中断后,正在运行的任务被挂起,中响应中断后,正在运行的任务被挂起,中断服务子程序控制了断服务子程序控制了CPUCPU的使用权的使用权中断服务态(中断服务态(ISR running)
24、ISR running)中断服务子程序可能会报告一个或多个事件的发生,中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态而使一个或多个任务进入就绪态 上述情况下,从中断服务子程序返回之前,上述情况下,从中断服务子程序返回之前,C/OS C/OS IIII 要判定:要判定:被中断的任务是否还是就绪态任务中优先级最高的被中断的任务是否还是就绪态任务中优先级最高的如果中断服务子程序使另一个优先级更高的任务进入了如果中断服务子程序使另一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得就绪态,则新进入就绪态的这个优先级更高的任务将得以运行;否则,原来被中断
25、了的任务将继续运行。以运行;否则,原来被中断了的任务将继续运行。任务状态任务状态 当所有的任务都在等待时间发生或等待延迟时当所有的任务都在等待时间发生或等待延迟时间结束时,间结束时,C/OS C/OS II II 执行空闲任务(执行空闲任务(Idle Idle TaskTask)的内部函数,即:)的内部函数,即:OSTaskIdleOSTaskIdle()()任务状态任务状态任务的任务的CPU使用权使用权被剥夺被剥夺中断中断恢复恢复任务任务任务控制块(任务控制块(TCBTCB)任务控制块任务控制块 OS_TCB OS_TCB是一个数据结构,保存该任务是一个数据结构,保存该任务的相关参数,包括任
26、务堆栈指针、状态、优先级、的相关参数,包括任务堆栈指针、状态、优先级、任务表位置、任务链表指针等任务表位置、任务链表指针等 所有的任务控制块分为两条链表:所有的任务控制块分为两条链表:空闲链表空闲链表 使用链表使用链表 当任务的当任务的CPUCPU使用权被剥夺时,系统用它来保存该使用权被剥夺时,系统用它来保存该任务的状态任务的状态 全部驻留在全部驻留在RAMRAM中中 C/OS-IIC/OS-II任务控制块任务控制块typedef struct os_tcb OS_STK *OSTCBStkPtr(当前任务堆栈栈顶指针)(当前任务堆栈栈顶指针);#if OS_TASK_CREATE_EXT_E
27、N0 void *OSTCBExtPtr;(指向用户定义的任务控制块扩展)(指向用户定义的任务控制块扩展)OS_STK *OSTCBStkBottom;(指向任务堆栈栈底指针)指向任务堆栈栈底指针)INT32U OSTCBStkSize;(存有栈中可容纳的指针元数目)(存有栈中可容纳的指针元数目)INT16U OSTCBOpt;INT16U OSTCBId;(存储任务的识别码(存储任务的识别码ID,备用),备用)#endif struct os_tcb*OSTCBNext;(任务控制块(任务控制块OS-TCB双向链表的后链接)双向链表的后链接)struct os_tcb*OSTCBPrev;(
28、任务控制块(任务控制块OS-TCB双向链表的前链接)双向链表的前链接)#if(OS_Q_EN&(OS_MAX_QS=2)|OS_MBOX_EN|OS_SEM_EN OS_EVENT *OSTCBEventPtr;(指向事件控制块的指针指向事件控制块的指针)#endif空任务列表空任务列表n所有的任务控制块都被放置在任务控制块列表数组所有的任务控制块都被放置在任务控制块列表数组OSTCBTbl 中中n系统初始化时,所有任务控制块被链接成空任务控制块的单向链表系统初始化时,所有任务控制块被链接成空任务控制块的单向链表n任务建立后,空任务控制块指针任务建立后,空任务控制块指针OSTCBFreeLis
29、t指向的任务控制块就指向的任务控制块就赋给了该任务,然后赋给了该任务,然后OSTCBFreeList的值调整为指向链表中的下一个空的值调整为指向链表中的下一个空任务控制块任务控制块n任务一旦被删除,任务控制块就还给空任务链表任务一旦被删除,任务控制块就还给空任务链表任务级的任务调度任务级的任务调度-OSSched-OSSched C/OSC/OS是是占先式实时多任务内核占先式实时多任务内核,优先级最高的任务一,优先级最高的任务一旦准备就绪,则拥有旦准备就绪,则拥有CPUCPU的所有权即开始投入运行。的所有权即开始投入运行。C/OSC/OS中中不支持时间片轮转法不支持时间片轮转法,每个任务的优先
30、级要求,每个任务的优先级要求不一样且是唯一的。因此,任务调度就是:查找准备不一样且是唯一的。因此,任务调度就是:查找准备就绪的最高优先级的任务并进行上下文切换。就绪的最高优先级的任务并进行上下文切换。C/OSC/OS任务调度所花的时间为常数任务调度所花的时间为常数,与应用程序中建立,与应用程序中建立的任务数无关。的任务数无关。就绪表就绪表根据就绪表确定最高优先级根据就绪表确定最高优先级两个关键:优先级数分解为高三位和低三位分别确定 高优先级有着小的优先级号着小的优先级号 根据优先级找到任务在就绪任务表中的位置根据优先级找到任务在就绪任务表中的位置每个就绪的任务都放入就绪表中(每个就绪的任务都放
31、入就绪表中(ready listready list)中,就绪表用两个变)中,就绪表用两个变量表示:量表示:OSRdyGrpOSRdyGrp、OSRdyTblOSRdyTblOSRdyGrpOSRdyGrp1207 6 5 4 300X XX XX XY YY Y Y Y任务优先级20 0176543108915 14 13 1212 1118161723 22 2121 20 1926242531 30 29 28 2734323339 38 37 36 3542404147 46 45 44 4350484955 54 53 52 515856576363 62 61 60 5901234
32、567OSRdyTbl7OSRdyTbl7X XY优先级最低任务优先级最低任务(空闲任务)优先级最高任务优先级最高任务任务优先级号任务优先级号000 00 01 10 0 0 0001 10 01 10 00 0 1 11221采用查表法确定高优先级任务采用查表法确定高优先级任务 查表法具有确定的时间,增加了系统的可预测性,查表法具有确定的时间,增加了系统的可预测性,C/OS C/OS IIII中中所有的系统调用时间都是确定的所有的系统调用时间都是确定的High3=OSUnMapTblOSRdyGrp;High3=OSUnMapTblOSRdyGrp;Low3 =OSUnMapTblOSRdy
33、TblHigh3;Low3 =OSUnMapTblOSRdyTblHigh3;Prio =(High33)+Low3;Prio =(High3OSTCBStkPtr=SP;OSTCBCur-OSTCBStkPtr=SP;清中断源;清中断源;重新开中断;重新开中断;执行用户代码做中断服务;执行用户代码做中断服务;调用调用OSIntExit();OSIntExit();恢复所有恢复所有CPUCPU寄存器;寄存器;执行中断返回指令;执行中断返回指令;中断服务中断服务中断与时钟节拍中断与时钟节拍 时钟节拍(时钟滴答)时钟节拍(时钟滴答)TickTick,是一种定时,是一种定时器中断,可通过编程方式实现
34、器中断,可通过编程方式实现 时钟节拍是一种特殊的中断,操作系统的时钟节拍是一种特殊的中断,操作系统的心脏。首先心脏。首先3232位的整数位的整数OSTimeOSTime加一。对任加一。对任务列表进行扫描,判断是否有延时任务应务列表进行扫描,判断是否有延时任务应该处于准备就绪状态,最后进行上下文切该处于准备就绪状态,最后进行上下文切换换。时钟节拍中断服务子程序时钟节拍中断服务子程序Void OSTickISR(void)Void OSTickISR(void)保存处理器寄存器的值;保存处理器寄存器的值;调用调用OSIntEnter(),OSIntEnter(),或是将或是将OSIntNestin
35、gOSIntNesting加加1 1 if(OSIntNesting=1)if(OSIntNesting=1)OSTCBCur-OSTCBStkPtr=SP;OSTCBCur-OSTCBStkPtr=SP;调用调用OSTimeTick();OSTimeTick();发出中断设备的中断;发出中断设备的中断;重新允许中断(可选用)重新允许中断(可选用)调用调用OSIntExit();OSIntExit();恢复处理器寄存器的值;恢复处理器寄存器的值;执行中断返回指令;执行中断返回指令;系统总要建立一个空闲任务,该任务在没有其它任务进入就绪状系统总要建立一个空闲任务,该任务在没有其它任务进入就绪状态
36、时投入运行态时投入运行 空闲任务永远设为最低优先级空闲任务永远设为最低优先级 空闲任务不可能被应用软件删除空闲任务不可能被应用软件删除void OSTaskIdle(void*pdata)pdata=pdata;for(;)OS_ENTER_CRITICAL();OSIdleCtr+;OS_EXIT_CRITICAL();空闲任务空闲任务OSTaskIdle()OSTaskIdle()C/OS-IIC/OS-II初始化初始化l首先调用系统初始化函数首先调用系统初始化函数OSIint()。OSIint()初始化初始化C/OS-所有的变量和数据结构(见所有的变量和数据结构(见OS_CORE.C)。
37、)。lOSInit()建立空闲任务建立空闲任务idle task,这个任务总是处于就绪,这个任务总是处于就绪态的。空闲任务态的。空闲任务OSTaskIdle()的优先级总是设成最低,()的优先级总是设成最低,即即OS_LOWEST_PRIO。l如果统计任务允许如果统计任务允许OS_TASK_STAT_EN和任务建立扩展和任务建立扩展允许都设为允许都设为1,则,则OSInit()还得建立统计任务还得建立统计任务OSTaskStat()并且让其进入就绪态。并且让其进入就绪态。OSTaskStat的优先级总是设为的优先级总是设为OS_LOWEST_PRIO-1 l空闲和统计任务的任务控制块(空闲和统
38、计任务的任务控制块(OS_TCBs)是用双向链)是用双向链表链接在一起。表链接在一起。OSTCBList指向这个链表的起始处。当建指向这个链表的起始处。当建立一个任务时,这个任务总是被放在这个链表的起始处。立一个任务时,这个任务总是被放在这个链表的起始处。调用调用OSInit()OSInit()之后的数据结构之后的数据结构 C/OS-C/OS-的启动的启动void main(void)OSInit()/*初始化初始化uC/OS-II*/.通过调用通过调用OSTaskCreate()或或OSTaskCreateExt()创建至少一个任务创建至少一个任务;.OSStart();/*开始多任务调度开
39、始多任务调度!OSStart()永远不会返回永远不会返回*/调用调用OSStart()OSStart()之后的数据结构之后的数据结构 主要内容主要内容 嵌入式操作系统嵌入式操作系统 C/OS-简介简介 C/OS-内核结构内核结构 C/OS-任务管理任务管理 C/OS-时间管理时间管理 C/OS-任务通信与同步任务通信与同步建立任务建立任务Use one of two servicesOS TaskCreate()OSTaskCreateExt()堆栈检验,堆栈检验,OSTaskStkChkOSTaskStkChk()()删除任务,删除任务,OSTaskDelOSTaskDel()()请求删除任
40、务,请求删除任务,OSTaskDelReqOSTaskDelReq()()改变任务的优先级,改变任务的优先级,OSTaskChangePrioOSTaskChangePrio()()挂起任务,挂起任务,OSTaskSuspendOSTaskSuspend()()恢复任务,恢复任务,OSTaskResumeOSTaskResume()()其它相关函数其它相关函数主要内容主要内容 嵌入式操作系统嵌入式操作系统 C/OS-简介简介 C/OS-内核结构内核结构 C/OS-任务管理任务管理 C/OS-时间管理时间管理 C/OS-任务通信与同步任务通信与同步任务间通信手段任务间通信手段 C/OSC/OS中
41、,采用多种方法保护任务之间的共中,采用多种方法保护任务之间的共享数据和提供任务之间的通信。享数据和提供任务之间的通信。u提供提供OS_ENTER_CRITICALOS_ENTER_CRITICAL和和OS_EXIT_CRITICALOS_EXIT_CRITICAL来来对临界资源进行保护对临界资源进行保护uOSSchedLockOSSchedLock()()禁止调度保护任务级的共享资源。禁止调度保护任务级的共享资源。u提供了经典操作系统任务间通信方法:信号量、提供了经典操作系统任务间通信方法:信号量、邮箱、消息队列,事件标志。邮箱、消息队列,事件标志。事件控制块事件控制块ECBECB ECB的结
42、构如下的结构如下 -typedef struct void *OSEventPtr;/*指向消息或消息队列的指针指向消息或消息队列的指针*/INT8U OSEventTblOS_EVENT_TBL_SIZE;/*等待任务列表等待任务列表*/INT16U OSEventCnt;/*计数器(当事件是信号量时)计数器(当事件是信号量时)*/INT8U OSEventType;/*事件类型:信号量、邮箱等事件类型:信号量、邮箱等*/INT8U OSEventGrp;/*等待任务组等待任务组*/OS_EVENT;与与TCB类似的结构,使用两个链表,空闲链表与使用链表类似的结构,使用两个链表,空闲链表与使
43、用链表所有的通信信号都被看成是事件所有的通信信号都被看成是事件(event),(event),一个称为事件控一个称为事件控制块制块(ECB,Event Control Block)(ECB,Event Control Block)的数据结构来表征每一的数据结构来表征每一个具体事件,个具体事件,ECBECB的结构如下的结构如下事件的等待任务列表事件的等待任务列表空闲事件控制块链表空闲事件控制块链表事件控制块事件控制块TCBTCB的操作的操作对事件控制块进行的操作包括:对事件控制块进行的操作包括:初始化一个事件控制块初始化一个事件控制块OS_EventWaitListInit()OS_EventW
44、aitListInit();使一个任务进入就绪态使一个任务进入就绪态OS_EventTaskRdy()OS_EventTaskRdy();使一个任务进入等待某事件的状态使一个任务进入等待某事件的状态OS_EventTaskWait()OS_EventTaskWait();因为等待超时而使一个任务进入就绪态因为等待超时而使一个任务进入就绪态OS_EventTO()OS_EventTO()。信号量信号量semaphoresemaphore 信号量在多任务系统中用于:控制共享资源的使信号量在多任务系统中用于:控制共享资源的使用权、标志事件的发生、使两个任务的行为同步。用权、标志事件的发生、使两个任务
45、的行为同步。uC/OSuC/OS中信号量由两部分组成:信号量的计数值中信号量由两部分组成:信号量的计数值和等待该信号任务的等待任务表。信号量的计数和等待该信号任务的等待任务表。信号量的计数值可以为二进制值可以为二进制,也可以是其他整数。也可以是其他整数。系统通过系统通过OSSemPend()OSSemPend()和和OSSemPost()OSSemPost()来支持信来支持信号量的两种原子操作号量的两种原子操作P()P()和和V()V()。P()P()操作减少信操作减少信号量的值,如果新的信号量的值不大于号量的值,如果新的信号量的值不大于0,0,则操作则操作阻塞;阻塞;V()V()操作增加信号
46、量的值。操作增加信号量的值。任务、中断服务子程序和信号量之间的关系任务、中断服务子程序和信号量之间的关系 T Ta as sk kI IS SR RT Ta as sk kO OS SS Se em mP Pe en nd d()O OS SS Se em mA Ac cc ce ep pt t()O OS SS Se em mQ Qu ue er ry y()O OS SS Se em mP Po os st t()O OS SS Se em mP Po os st t()O OS SS Se em mA Ac cc ce ep pt t()O OR RO OS SS Se em mC Cr
47、 re ea at te e()N NN NOSSemDel()()信号量操作信号量操作 C/OS-IIC/OS-II提供提供6 6个对信号量进行操作的函数:个对信号量进行操作的函数:OSSemCreate()OSSemCreate():建立一个信号量:建立一个信号量OSSemDel():OSSemDel():删除一个信号量删除一个信号量OSSemPend()OSSemPend():等待一个信号量:等待一个信号量OSSemPost()OSSemPost():发出一个信号量:发出一个信号量OSSemAccept()OSSemAccept():无等待地请求一个信号量:无等待地请求一个信号量 当一个
48、任务请求一个信号量时,如果该信号量暂时无效,当一个任务请求一个信号量时,如果该信号量暂时无效,可以让该任务简单返回,而不是进入睡眠等待状态可以让该任务简单返回,而不是进入睡眠等待状态OSSemQuery()OSSemQuery()函数:查询一个信号量的当前状态函数:查询一个信号量的当前状态 邮邮 箱箱 邮箱是邮箱是C/OS-IIC/OS-II中另一种通讯机制,它可以使中另一种通讯机制,它可以使一个任务或者中断服务子程序向另一个任务发一个任务或者中断服务子程序向另一个任务发送一个指针型的变量。送一个指针型的变量。该指针指向一个包含了特定该指针指向一个包含了特定“消息消息”的数据结的数据结构。为了
49、在构。为了在C/OS-IIC/OS-II中使用邮箱,必须将中使用邮箱,必须将OS_CFG.HOS_CFG.H中的中的OS_MBOX_ENOS_MBOX_EN常数置为常数置为1 1。使用邮箱之前,必须先建立该邮箱。该操作可使用邮箱之前,必须先建立该邮箱。该操作可以通过调用以通过调用OSMboxCreate()OSMboxCreate()函数来完成,并且函数来完成,并且要指定指针的初始值。要指定指针的初始值。邮邮 箱箱C/OS-IIC/OS-II提供了提供了7 7种对邮箱的操作:种对邮箱的操作:OSMboxCreate()OSMboxCreate():建立一个邮箱:建立一个邮箱 OSMboxDel
50、OSMboxDel():):删除一个邮箱删除一个邮箱 OSMboxPend(OSMboxPend():等待邮箱中的消息):等待邮箱中的消息 OSMboxPost()OSMboxPost():向邮箱发送一则消息:向邮箱发送一则消息 OSMboxPostOpt()OSMboxPostOpt():向邮箱发送一则消息:向邮箱发送一则消息 OSMboxAccept()OSMboxAccept():无等待地从邮箱中得到一则消息:无等待地从邮箱中得到一则消息 OSMboxQuery()OSMboxQuery():查询一个邮箱的状态:查询一个邮箱的状态 任务、中断服务子程序和邮箱之间的关系任务、中断服务子程序