全书课件:μCOS-Ⅱ标准教程 杨宗德_第1页
全书课件:μCOS-Ⅱ标准教程 杨宗德_第2页
全书课件:μCOS-Ⅱ标准教程 杨宗德_第3页
全书课件:μCOS-Ⅱ标准教程 杨宗德_第4页
全书课件:μCOS-Ⅱ标准教程 杨宗德_第5页
已阅读5页,还剩177页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第一章C/OS-II与嵌入式实时操作系统 实时操作系统概述实时操作系统概述 C/OS-II内核源代码文档结构内核源代码文档结构 C/OS-II基本概念基本概念 2021-10-122嵌入式软件系统基本模型 硬件层板级支持包(BSP)实时操作系统内核系统(RTOS)应用程序层(Application)FS文件系统图形界面GUI系统管理接口固件2021-10-123实时操作系统设计原则 采用各种算法和策略,始终保证系统行为的可预测性。即在任何情况下,在系统运行的任何时刻,操作系统的资源配置策略都能为争夺资源(包括CPU、内存、网络带宽等)的多个实时任务合理地分配资源,使每个实时任务的实时性要求都能

2、得到满足。2021-10-124实时操作系统内核分类 不可剥夺型内核 可剥夺型内核2021-10-125不可剥夺型内核中断响应示意 2021-10-126可剥夺型内核中断响应示意 2021-10-127常见实时操作系统 Vxworks操作系统 WinCE操作系统 Symbian操作系统 RT-Linux操作系统 C/OS操作系统 第一章C/OS-II与嵌入式实时操作系统 实时操作系统概述实时操作系统概述 C/OS-II内核源代码文档结构内核源代码文档结构 C/OS-II基本概念基本概念 2021-10-129第一章C/OS-II与嵌入式实时操作系统 实时操作系统概述实时操作系统概述 C/OS-

3、II内核源代码文档结构内核源代码文档结构 C/OS-II基本概念基本概念 2021-10-1211嵌入式应用程序开发模式 单片机系统的前后台程序 基于任务(进程)的软件设计方法 2021-10-1212简单单片机系统软件设计方法 2021-10-1213C/OS-II基于任务(进程)的软件设计方法 void Task_one(void *pdata)/任务1代码void Task_two(void *pdata) /任务2代码void Task_three(void *pdata) /任务3代码void main(void)/入口OSInit();/初始化系统OsTaskCreate(task

4、_one,.);/创建任务1OsTaskCreate(task_one,.); /创建任务2OsTaskCreate(task_one,.); /创建任务3.OSStart();/启动系统,此时操作系统控制整个软件的运行2021-10-1214可重入函数与不可重入函数 可重入函数是指函数代码在运行过程中被中断,在中断返回时仍然能够恢复到原来的状态,并能准备无误的执行的函数. 不可重入函数则在运行过程中不可以被中断。 int i=10;int program_one(void)int j;if(i=10)i=20;elsei=0;return 1;2021-10-1215习题 (1)实时操作系统

5、所遵循的设计原则是什么?实时操作系统与通用操作系统之间的主要区别是什么?常见的实时操作系统有哪些,主要应用到哪些领域?(2)根据内核是否可以被抢占,实时操作系统分为哪两类,主要区别是什么?(3)基于操作系统的应用程序开发与前后台程序开发有什么区别,各有什么特点?(4)什么是临界状态,什么是可重入函数和不可重入函数?(5)临界状态处理的办法有哪些,为什么在操作系统中使用了大量的临界状态?试分析应用于ARM处理器的C/OS-II系统中临界状态的处理办法。 第2章C/OS-II任务管理 多任务管理多任务管理 案例案例C/OS-II任务基本属性任务基本属性 C/OS-II任务管理函数源码分析任务管理函

6、数源码分析 2021-10-1217多任务示例运行结果 this is App_three, prio=30,Delay 2 second and start againthis is App_two, prio=20,Delay 4 second and start againthis is App_three, prio=30,Delay 2 second and start againthis is App_three, prio=30,Delay 2 second and start againthis is App_one, prio=10,Delay 6 second and st

7、art againthis is App_two, prio=20,Delay 4 second and start againthis is App_three, prio=30,Delay 2 second and start againthis is App_three, prio=30,Delay 2 second and start again2021-10-1218源代码 #include #define TASK_STK_SIZE 128OS_STK AppStk_oneTASK_STK_SIZE; /任务one的堆栈OS_STK AppStk_twoTASK_STK_SIZE;

8、 /任务two的堆栈OS_STK AppStk_threeTASK_STK_SIZE; /任务three的堆栈static void App_one(void *p_arg); /任务one代码static void App_two(void *p_arg); /任务two代码static void App_three(void *p_arg); /任务three代码void main(int argc, char *argv) OSInit(); /初始化系统/依次创建三个任务OSTaskCreate(App_one,NULL,(OS_STK *)&AppStk_oneTASK_STK_SI

9、ZE-1,(INT8U)10);OSTaskCreate(App_two,NULL,(OS_STK *)&AppStk_twoTASK_STK_SIZE-1,(INT8U)20);OSTaskCreate(App_three,NULL,(OS_STK *)&AppStk_threeTASK_STK_SIZE-1,(INT8U)30); OSStart(); 启动多任务,将CPU控制权交给系统2021-10-1219任务代码void App_one(void *p_arg)/任务one代码内容p_arg = p_arg;/无作用,仅防止编译错误 while (TRUE) OS_Printf(th

10、is is App_one, prio=10,Delay 6 second and start againnn); /输出提示信息 OSTimeDlyHMSM(0, 0, 6, 0); /等待6秒,将在第4章介绍 第2章C/OS-II任务管理 多任务管理多任务管理 案例案例C/OS-II任务基本属性任务基本属性 C/OS-II任务管理函数源码分析任务管理函数源码分析 2021-10-1221C语言可执行代码结构 2021-10-1222C/OS-II任务结构 2021-10-1223C/OS-II任务栈 栈在创建任务时使用OSTaskCreate()函数声明如下:INT8U OSTaskCre

11、ate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)C/OS-II将任务栈空间的数据类型重新定义为OS_STK,实际上就是短整型,定义如下:/come from os_cpu.htypedef unsigned short OS_STK; /栈空间每个单元的数据类型为16位的在创建任务时需要显式的声明一段全局空间做为该任务的栈,申请一个栈空间的示例代码如下:#define TASK_STK_SIZE 128/此大小可重新定义,根据需要定义OS_STK AppStartTaskStkTASK_STK_SIZE

12、; /全局变量2021-10-1224栈增长方向 2021-10-1225C/OS-II任务控制块 TCB(Task Control Block)用来存储一个任务的当前属性。任务的主要属性包括: 任务栈空间位置,即前节所述该任务的栈空间。 任务与其它任务通信的数据空间,在C/OS-II中称为事件,见第5,6,7章说明; 任务的当前状态,标识当前任务是在运行还是在等待某个事件发生; 任务的优先级,任务的标识,全系统唯一,此值是任务调度的依据 。2021-10-1226C/OS-II任务控制块 C/OS-II采用双向链表来管理所有任务的TCB come from ucos_ii.htypedef

13、struct os_tcb OS_STK *OSTCBStkPtr; /指向该任务的栈顶指针,前节介绍#if OS_TASK_CREATE_EXT_EN 0/如果是用OSTaskCreateExt()创建的任务有以下参数 void *OSTCBExtPtr; /指向用户为该任务自定义的扩展TCB,这不是必须的 OS_STK *OSTCBStkBottom; 指向栈底指针 INT32U OSTCBStkSize; /栈的大小,单元个数 INT16U OSTCBOpt; /栈初始化时的选项,见初始化控制块函数说明 INT16U OSTCBId; /任务ID(0.65535),暂时没有使用#endi

14、f struct os_tcb *OSTCBNext; /指向双向TCB链表中的下一个TCB struct os_tcb *OSTCBPrev; /指向双向TCB链表中的前一个TCB2021-10-1227任务控制块初始化时示意图 2021-10-1228任务控制块经过任务添加和删除后示意图 2021-10-1229C/OS-II任务优先级 C/OS-II操作系统进行任务调度所采用的算法是基于优先级的调度算法(调度算法:选择哪一个处于就绪状态的任务运行的策略)。任何一个任务有唯一的一个任务优先级值,其类型为INT8U(unsigned char类型),定义如下:INT8U OSTCBPrio;

15、 /优先级值,如果为0表示优先级最高typedef unsigned char INT8U; / INT8U类型就是unsigned char 在C/OS-II操作系统中,优先级值越大,优先级越低,因此,优先级值为0的任务优先级最高。因为优先级类型为unsigned char(范围为0255),因此,定义C/OS-II操作系统优先级值最大为255,也就是说,最多允许创建256个任务(一个任务有唯一的优先级)。在目前的C/OS-II版本中,仅允许创建64个任务,最低优先级值为63 2021-10-1230C/OS-II任务状态 /come from ucos_ii.h#define OS_STA

16、T_RDY 0 x00u /准备就绪#define OS_STAT_SEM 0 x01u /信号量阻塞#define OS_STAT_MBOX 0 x02u /消息邮箱阻塞#define OS_STAT_Q 0 x04u /消息队列阻塞#define OS_STAT_SUSPEND 0 x08u /挂起,暂停运行#define OS_STAT_MUTEX 0 x10u /互斥事件阻塞#define OS_STAT_FLAG 0 x20u /事件标识阻塞#define OS_STAT_PEND_ANY (OS_STAT_SEM | OS_STAT_MBOX | OS_STAT_Q | OS_ST

17、AT_MUTEX | OS_STAT_FLAG)/任意一个事件阻塞2021-10-1231任务状态切换2021-10-1232系统任务 空闲任务在没有其它任务运行时运行,其优先级最低(如果最多允许创建64个任务,则其值为63),此函数没有任务参数的返回值,仅对全局变量空闲计数器OSIdleCtr进行自加操作。 统计任务优先级为OS_IDLE_PRIO-1,用来统计CPU的利用率,统计任务中执行的函数为OS_TaskStat() 。第2章C/OS-II任务管理 多任务管理多任务管理 案例案例C/OS-II任务基本属性任务基本属性 C/OS-II任务管理函数源码分析任务管理函数源码分析 2021-

18、10-1234函数名函数功能OSTaskCreate创建任务OSTaskCreateext扩展创建任务OSTaskDel删除任务OSTaskDelReq请求删除自己OSTaskNameGet获取任务名称OSTaskNameSet设置任务名称OSTaskSuspend()挂起任务OSTaskResume恢复挂起任务OSTaskStkChk任务堆栈检查OS_TaskStkClr清理任务堆栈OSTaskQuery查询任务状态2021-10-1235习题 (1)一段C可执行代码在存储态和运行态时分别分为哪几个段,各段存储哪些信息?试列出堆和栈的区别?(2)在C/OS-II操作系统中,一个任务包含哪些基

19、本信息?各部分是怎么管理的?(3)在C/OS-II操作系统中,任务栈的数据类型和基本功能是什么?(4)试分析任务控制块结构体中各成员变量的基本意义?(6)C/OS-II操作系统对任务控制块采用怎么样的管理方式?如何快速的查找到某个优先级值的任务控制块?(7)C/OS-II操作系统中任务有哪些状态,其中,阻塞状态亦分为哪几种,试分析各状态下任务的基本情况。(8)C/OS-II操作系统的系统任务有哪些?C/OS-II操作系统是如何获取当前CPU的利用率的?(9)试分析任务管理函数:创建、删除、等待、恢复、设置属性的源代码及基本算法。第3章C/OS-II操作系统任务调度C/OS-II任务级任务调度机

20、制任务级任务调度机制 C/OS-II任务级任务调度任务级任务调度 C/OS-II中断级任务调度中断级任务调度 2021-10-1237C/OS-II调度算法和调度方式 优先级调度算法原理为:给每一个任务分配一个惟一优先级,各优先级用一个整形数值标识,某优先级的值越大,其优先级越低;某优先级的值越小,其优先级越高。也就是说,如果当前操作系统准备进行调度,当有两个任务处于就绪状态, 系统将优先执行优先级别高的任务。 C/OS-II操作系统有两种调度方式:任务级任务调度和中断级任务调度,C/OS-II操作系统在完成中断后允许进行新的调度,因此,C/OS-II操作系统是可抢占性的,是强实时性操作系统,

21、这是C/OS-II操作系统内核的重要特性。2021-10-1238C/OS-II任务就绪表 2021-10-1239优先级二进制码分配 2021-10-1240更新就绪表时采用如下方法: 对OSRdyGrp和 OSRdyTblptcb-OSTCBY的修改算法如下:ptcb-OSTCBY = (INT8U)(prio 3); /得到优先级值前3位(二进制),行ptcb-OSTCBBitY = 1 OSTCBY;/得到影响就绪表的行号ptcb-OSTCBX = (INT8U)(prio & 0 x07); /得到优先级值低3位(二进制),列ptcb-OSTCBBitX = 1 OSTCBX; /得

22、到影响就绪表的列号OSRdyTblptcb-OSTCBY |= ptcb-OSTCBBitX;/将就绪表对应位置OSRdyGrp |= ptcb-OSTCBBitY; /将OSRdyGrp对应的位置位y = ptcb-OSTCBY;/得优先级的高3位,即修改OSRdyTbl的哪一行 OSRdyTbly &= ptcb-OSTCBBitX;/清除OSRdyTbly对应行的对应位 if (OSRdyTbly = 0) /如果整行没有事件处于就绪 OSRdyGrp &= ptcb-OSTCBBitY;/清除变量OSRdyGrp对应位删除任务时,使用如下算法清除任务就绪表和OSRdyGrp相应位。20

23、21-10-1241如果一个优先级为44(二进制码为101 100)的任务处于就绪状态 ptcb-OSTCBY = (INT8U)(prio 3)=(5)d ptcb-OSTCBBitY = 1 OSTCBY=(00100000)B ptcb-OSTCBX = (INT8U)(prio & 0 x07) =(4)d ptcb-OSTCBBitX = 1 OSTCBX=(00010000)B将该任务添加到就绪表中 OSRdyTblptcb-OSTCBY |= ptcb-OSTCBBitX; OSRdyGrp |= ptcb-OSTCBBitY; 即OSRdyTbl5 = OSRdyTbl5|(0

24、0010000)B/将OSRdyTbl5的Bit4位置位,标识优先级44任务就绪 OSRdyGrp = OSRdyGrp |(00100000)B /将OSRdyGrp的Bit5位置位,标识OSRdyTbl5组有一个及以上任务就绪2021-10-1242要清除优先级为30(011 110) ptcb-OSTCBY(3)d ptcb-OSTCBBitY = 1 OSTCBBitX=(01000000)B ptcb-OSTCBX = (6)d故 y = 3 OSRdyTbl3 = OSRdyTbl3&10111111/清除OSRdyTbl3的Bit6位if (OSRdyTbl3 = 0) /如果O

25、SRdyTbl30,即所有位为0 OSRdyGrp &= OSRdyGrp &1111 0111; /清除OSRdyGrp的Bit32021-10-1243获取最高优先级就绪任务 OS_EXT INT8U OSPrioCur; /当前任务优先级OS_EXT INT8U OSPrioHighRdy; /准备就绪任务中的最高优先级INT8U const OSUnMapTbl256 = 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x00 to 0 x0F */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,

26、0, 1, 0, /* 0 x10 to 0 x1F */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x20 to 0 x2F*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x30 to 0 x3F*/ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x40 to 0 x4F */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x50 to 0 x5F

27、*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x60 to 0 x6F*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x70 to 0 x7F*/ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x80 to 0 x8F*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 x90 to 0 x9F*/ 5, 0, 1, 0, 2, 0, 1, 0, 3

28、, 0, 1, 0, 2, 0, 1, 0, /* 0 xA0 to 0 xAF*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 xB0 to 0 xBF*/ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 xC0 to 0 xCF*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0 xD0 to 0 xDF*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0

29、xE0 to 0 xEF*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0 xF0 to 0 xFF*/;2021-10-1244OSUnMapTbl表构造方法如下:表中第n+1个成员OSUnMapTbln的值:从Bit0位开始,搜索值为n的二进制码中第1次出现1的位数。例如:OSUnMapTbl1 0 (1)d =(0000 0001)b,第0位有1,故值为0OSUnMapTbl202 (20)d =(0001 0100)b,第2位有1,故值为2OSUnMapTbl901 (90)d =(0101 1010)b,第1位有1,故值为1试

30、想如果当前只有优先级1,9,23三个任务处于就绪状态, OSRdyGrp的值应该为(0000 0111)B,OSRdyTbl0=(XXXX XX10)B,因此通过该算法: y = OSUnMapTbl OSRdyGrp=OSUnMapTbl70OSUnMapTblOSRdyTbl0)OSUnMapTbl21 OSPrioHighRdy = (INT8U)(0 = 204 OSInitHookBegin(); /调用特殊初始化代码,根据不同的处理器有不同的代码#endif OS_InitMisc(); /初始化部分全局变量,见后结小节此函数说明 OS_InitRdyList(); 初始化任务就绪

31、表,见后续小节说明 OS_InitTCBList(); /见第2章,初始化空闲TCB链表 OS_InitEventList(); /初始化事件控制块链表,见后续事件管理章节#if (OS_VERSION = 251) & (OS_FLAG_EN 0) & (OS_MAX_FLAGS 0)/如果在这些条件下 OS_FlagInit(); /初始化事件组标志结构,见事件组标识管理章节#endif#if (OS_MEM_EN 0) & (OS_MAX_MEM_PART 0) OS_MemInit(); /初始化内存管理,见内存管理章节#endif2021-10-1259#if (OS_Q_EN 0)

32、 & (OS_MAX_QS 0) OS_QInit(); /初始化消息队列,见消息队列章节#endif OS_InitTaskIdle(); /创建空闲任务#if OS_TASK_STAT_EN 0/如果允许使用统计任务 OS_InitTaskStat(); /创建统计任务#endif#if OS_VERSION = 204 OSInitHookEnd(); /调用特殊初始化代码,不同的处理器有不同的代码#endif#if OS_VERSION = 270 & OS_DEBUG_EN 0 OSDebugInit();/ #endif2021-10-1260全局变量 初始化变量说明初始化值OST

33、ime32位系统时钟变量,标识系统运行时间0OSIntNesting 中断嵌套次数0OSLockNesting调度器嵌套上锁次数0OSTaskCtr任务计数器,标识系统创建了多少个任务0OSRunning标识系统内核是否运行,为TURE标识正在运行FALSEOSCtxSwCtr系统上下文切换次数0OSIdleCtr空闲时间计数器0OSIdleCtrRun1秒前空闲任务计数器值0OSIdleCtrMax1秒内空闲任务计数器可达的最大值0OSStatRdy统计任务标识,即是否执行统计任务FALSE2021-10-1261运行最高优先级任务 OSStartHighRdy()函数用来运行最高优先级任务

34、,由于涉及到寄存器,因此,此函数多用汇编语言来实现,以下列出ARM7/9处理器下此函数的汇编实现。此函数基本过程如下: (1)设置当前任务TCB指针OSTCBCur为就绪表中最高优先级任务的TCB(OSTCBHighRdy); (2)从该任务的任务栈中读取SPSR寄存器的值修改当前的CPSR寄存器,从任务栈中读取R0-R12能用寄存器的值、LR寄存器的值; (3)从该任务的入口开始执行。第4章C/OS-II系统启动与时钟任务C/OS-II系统启动过程系统启动过程 时钟任务与时钟管理时钟任务与时钟管理 2021-10-1263时钟概念任何实时系统的时钟硬件设备每隔一段时间(即一个系统tick)产

35、生的一个硬件中断,操作系统接收到该硬件中断后,更新时间计数器,更新所有对时钟依赖的程序代码,从而维持系统有序而稳定的运行。C/OS-II定义了宏OS_TICKS_PER_SEC来标识来当前系统时钟中断产生的时间间隔,如果该值定义为100,即标识0.01秒产生一个时钟中断。#define OS_TICKS_PER_SEC 100 /* Set the number of ticks in one second */另外,系统定义了全局时钟变量来记录系统运行的时间值,该变量定义如下:OSTime为32位系统时钟变量,标识系统运行时间:OS_EXT volatile INT32U OSTime; /

36、* Current value of system time (in ticks) */2021-10-1264创建系统时钟任务 (1)在系统启动前,创建系统时钟任务,使其处于最高优先级执行,因为时钟任务比所有任务更重要,其函数调用如下: (2)因时钟任务是因产生中断而执行,因此,其为中断服务子程序内容,在timer_Task()函数中安装时钟中断服务程序,定义如下 在安装时钟中断处理程序中启动系统时钟,即系统硬件时钟中断到来时就执行该中断服务程序,uHALr_InstallSystemTimer()函数定义如下:OSTaskCreate(timer_Task, 0); /此处略去其它参数,S

37、YS_Task为执行代码位置static void timer_Task(void *Id)uHALr_InstallSystemTimer();/安装时钟处理中断程序void uHALr_InstallSystemTimer(void)rTCON |=TCON_4_ONOFF; /此句的功能是启动时钟中断定时器SetISR_Interrupt(IRQ_TIMER4, TimerTickHandle, NULL); /安装中断处理程序/ IRQ_TIMER4为中断向量,TimerTickHandle为处理函数2021-10-1265习题 (1)C/OS-II操作系统启动时将执行哪些信息的初始化

38、? (2)C/OS-II操作系统在初始化时创建了空闲任务和统计任务,这两个任务是必须的吗,两者的优先级怎么设置,为什么? (3)是否可以在C/OS-II操作系统启动前创建任务? (4)为什么说时钟任务是C/OS-II操作系统中最为重要的任务,试分析创建时钟任务的过程。 (5)C/OS-II操作系统时钟管理函数OSTimeDly()可以设置任意时间延迟吗?为什么?第5章 C/OS-II任务间通信机制 COS-II事件管理机制事件管理机制 单消息传递事件:消息邮箱单消息传递事件:消息邮箱 多消息传递事件:消息队列多消息传递事件:消息队列 2021-10-1267事件控制块示意图 2021-10-1

39、268事件控制块 #if OS_EVENT_EN & (OS_MAX_EVENTS 0)typedef struct os_event INT8U OSEventType/(1)事件的类型 void *OSEventPtr; /(2)指向邮箱或消息队列的指针,如果是同步机制,不使用 INT16U OSEventCnt; /(3)信号量计数器,如果是其它事件,不使用此参数#if OS_LOWEST_PRIO 1/如果允许设置事件名称 INT8U OSEventNameOS_EVENT_NAME_SIZE;/事件名称#endif OS_EVENT;#endif2021-10-1269事件类型 #d

40、efine OS_EVENT_TYPE_UNUSED 0u/未使用任何事件#define OS_EVENT_TYPE_MBOX 1u/消息邮箱#define OS_EVENT_TYPE_Q 2u/消息队列#define OS_EVENT_TYPE_SEM 3u/信号量#define OS_EVENT_TYPE_MUTEX 4u/互斥锁#define OS_EVENT_TYPE_FLAG 5u/事件组标志(第5章介绍)第5章 C/OS-II任务间通信机制 COS-II事件管理机制事件管理机制 单消息传递事件:消息邮箱单消息传递事件:消息邮箱 多消息传递事件:消息队列多消息传递事件:消息队列 20

41、21-10-1271消息邮箱基本原理 2021-10-1272消息邮箱创建OS_EVENT *OSMboxCreate (void *msg)事件的创建是由具体的事件管理程序来实现的,例如,创建一个消息邮箱事件由消息邮箱创建函数OSMboxCreate()来实现,创建消息队列事件则由消息队列创建函数来实现。创始消息邮箱函数声明如下:2021-10-1273从消息邮箱中读取消息的方式 (1)非阻塞式读取是指无论消息邮箱中是否有数据,读取操作也不阻塞,直接返回,显然,如果有数据,将读取出来,如果没有数据,将读取为NULL。 (2)阻塞式读取是指在消息邮箱中有数据时,直接读取出来;如果没有数据,则使

42、当前任务进入等待状态,系统执行调度程序执行新的任务,当下一次消息到来时将激活等待表中的最高优先级任务,从而使该任务进入就绪状态。为了避免任务一直处于等待状态(所等待的资源一直未分配),可以设置一个等待的时间范围,当超过该延迟时,则直接返回。2021-10-1274阻塞式方式从某消息邮箱中获取数据 void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)非阻塞接收消息 void *OSMboxAccept (OS_EVENT *pevent)2021-10-1275按指定方式发送数据到消息邮箱INT8U OSMboxPost

43、(OS_EVENT *pevent, void *msg) 发送消息到消息邮箱 INT8U OSMboxPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)删除消息邮箱OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *err)第5章 C/OS-II任务间通信机制 COS-II事件管理机制事件管理机制 单消息传递事件:消息邮箱单消息传递事件:消息邮箱 多消息传递事件:消息队列多消息传递事件:消息队列 2021-10-1277消息队列事件示意图 2021-10-1278队列控制块数据类型 t

44、ypedef struct os_q /消息队列控制块 struct os_q *OSQPtr; /用于构建空闲消息队列控制块链表,指向下一个消息队列控制块 void *OSQStart; /指向消息队列指针数组的起始位置 void *OSQEnd; /指向消息队列指针数组的结束位置 void *OSQIn; /指向消息队列指针数组中下一个可以插入消息的位置 void *OSQOut; /指向消息队列指针数组中下一个读出消息的位置 INT16U OSQSize;/指针数组的大小 INT16U OSQEntries;/当前可以读取的消息个数 OS_Q;2021-10-1279习题 (1)什么是事

45、件?在COS-II中,有哪些类型的事件,哪些是任务间通信的机制,哪些是任务间同步机制? (2)试分析事件控制块结构体成员变量意义?事件的任务等待表如何标识某个任务等待它,将某个任务添加到等待表的算法是什么,从等待表中删除某个任务的算法是什么,查找等待表中等待的最高优先级任务是什么? (3)消息邮箱主要原理是什么?试总结消息邮箱管理函数功能、参数及返回值,并分析其源代码。 (4)消息队列主要原理是什么?试总结消息队列管理函数功能、参数及返回值,并分析其源代码。 第6章 COS-II任务间单事件同步任务同步机制:信号量任务同步机制:信号量 互斥事件管理机制:互斥锁互斥事件管理机制:互斥锁 2021

46、-10-1281信号量基本原理 信号量主要用来实现任务间同步,标识某类资源可用个数,或者说,对于某个特定资源,可以供多少个任务同时使用。 例如,可以使用信号量来标识一个缓冲区可用空间大小(假定缓冲区大小为256个单元,每次读写一个单元),在没有使用之前,该缓冲区没有任何内容,可用资源为256,即可以初始化信号量为256,每向缓冲区写入一个单元就将信号量的值自动减1,当信号量的值为0时即表示缓冲区满,资源暂不可用;每从缓冲区中读出一个单元,将信号量的值自动加1,如果信号量的值为256,则表示缓冲区中没有内容,不可读。2021-10-1282信号量事件控制块示意图 2021-10-1283信号量管

47、理OSSemCreate()用来创建信号量 OS_EVENT *OSSemCreate (INT16U cnt)阻塞方式获取信号量 void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)非阻塞方式获取信号量 INT16U OSSemAccept (OS_EVENT *pevent)2021-10-1284信号量管理释放信号量 INT8U OSSemPost (OS_EVENT *pevent)删除信号量 OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)查询

48、信号量信息 INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *p_sem_data)2021-10-1285信号量实现生产-消费问题应用实例 生产消费问题是一个经典的数学问题,要求生产者消费者在固定的仓库空间条件下,生产者每生产一个产品将占用一个仓库空间,生产者生产的产品库存不能越过仓库的存储量,消费者每消费一个产品将增加一个仓库空间,消费者在仓库产品为0时不能再消费。2021-10-1286信号量应用对于生产者来说,其需要申请的资源为仓库中的剩余空间,因此,生产者在生产一个产品前,申请sem_produce信号量,当此信号量的值大于0,即有可用

49、空间,将生产产品,并将sem_produce的值减去1(因为占用了一个空间);同时,当其生产一个产品后,当前仓库的产品数量增加1,需要将sem_custom信号量自动加1。对于消费者来说,其需要申请的资源为仓库中的产品,因此,消费者在消费一个产品前,将申请sem_custom信号量,当此信号量的值大于0时,即有可用产品,将消费一个产品,并将sem_custom信号量的值减去(因为消费了一个产品),同时,当消费一个产品,当前仓库的剩余空间增加1,需要将sem_produce信号量自动加1。第6章 COS-II任务间单事件同步任务同步机制:信号量任务同步机制:信号量 互斥事件管理机制:互斥锁互斥事

50、件管理机制:互斥锁 2021-10-1288互斥锁与优先级反转 2021-10-1289其基本流程如下:C任务首先被创建,并申请一个互斥锁事件,开始执行;某外部中断使任务A就绪,因A的优先级高于C,因此暂停C转而执行A;A在执行过程中需要申请互斥锁,但因互斥锁被C占用,A只能暂停转而再次执行C;C在继续执行过程中,因外部中断使任务B就绪,B因优先级高于C而得以抢占CPU,B不需要互斥锁资源;B执行完成后转而继续执行C,直到C执行完成后,才继续执行A。由以上可以看出,A较B早就绪,A优先级高于B,但A较B后执行完成,相当于B的优先级高于,此即优先级反转现象。 2021-10-1290如何避免优先

51、级反转的问题 2021-10-1291流程如下(1)C任务首先被创建,并申请一个互斥锁事件,开始执行。(2)因某个中断服务程序致使任务A得以继续执行,A在执行过程中需要申请互斥锁,但因互斥锁被任务占用也不能获得。(3)在A试图抢占互斥锁资源时,由操作系统主动将该互斥锁的拥有者(任务C)的优先级暂时提到到高于所有欲申请该互斥的任务的优先级,即使C任务的优先级暂时高于A。(4)在A继续执行过程中,因某个中断服务程序致使任务B就绪,但因B的优先级低于C提升的优先级,从而无法抢占到CPU,任务C得以继续执行;(5)任务C执行完成,A获取该互斥锁,因A的优先级高于B,故A得以继续执行直到执行完成。(6)

52、任务B得以继续执行。2021-10-1292需要说明的问题 由以上可以看出,低优先级的任务B较高优先级的任务先执行完成。另外,在占有某个互斥锁事件时,任何任务都不能阻塞的等待其它任何事件,否则会造成死锁, 例如任务A和任务B分别申请到一个互斥锁,而还将申请对方占有的互斥锁,但两者都不释放自己占有的互斥锁,从而造成死锁。2021-10-1293互斥锁事件控制块 2021-10-1294互斥锁管理 创建互斥锁对象 OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)阻塞式获取互斥锁 void OSMutexPend (OS_EVENT *pevent,

53、INT16U timeout, INT8U *err)非阻塞式获取互斥锁 INT8U OSMutexAccept (OS_EVENT *pevent, INT8U *err)2021-10-1295互斥锁管理释放互斥锁 INT8U OSMutexPost (OS_EVENT *pevent)删除互斥锁 OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err)获取互斥锁基本信息 INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *p_mutex_data)2021-10-12

54、96习题 (1)信号量主要原理是什么?试总结信号量管理函数功能、参数及返回值,并分析其源代码。 (2)试解释信号量在生产消费问题中的应用过程。 (3)互斥锁主要原理是什么?试总结互斥锁管理函数功能、参数及返回值,并分析其源代码。 (4)什么是优先级反转,COS-II采用什么办法避免优先级反转问题?第7章 C/OS-II多事件同步机制 事件组标志同步机制基本原理事件组标志同步机制基本原理 事件组标志基本操作事件组标志基本操作 2021-10-1298事件组标志管理示意图 2021-10-1299事件组标志控制块结构体os_flag_grp typedef struct os_flag_grp /

55、事件组标志结构体 INT8U OSFlagType; /事件类型,使用时需设置为OS_EVENT_TYPE_FLAG void *OSFlagWaitList; /指向等待的任务链表 OS_FLAGS OSFlagFlags; /8, 16 or 32 bit flags,信号列表#if OS_FLAG_NAME_SIZE 1 INT8U OSFlagNameOS_FLAG_NAME_SIZE;/信号名称#endif OS_FLAG_GRP;2021-10-12100等待任务链表中结点 typedef struct os_flag_node /事件标志等待链表结点 void *OSFlagNo

56、deNext; /指向下一个等待结点 void *OSFlagNodePrev; /指向前一个等待结点 void *OSFlagNodeTCB; /指向此等待任务的任务控制块 void *OSFlagNodeFlagGrp; /指向此任务其所等待的事件组标志 OS_FLAGS OSFlagNodeFlags; /等待的事件(标识等待此标志组中哪些事件) INT8U OSFlagNodeWaitType;/等待方式(与,或,任意,所有) OS_FLAG_NODE;2021-10-12101事件组标志控制块空闲链表 第7章 C/OS-II多事件同步机制 事件组标志同步机制基本原理事件组标志同步机制

57、基本原理 事件组标志基本操作事件组标志基本操作 2021-10-12103创建事件组标志 基本流程如下: (1)参数检查。检查是否分配错误标志存储空间。 (2)条件检查。检查是否在中断服务程序中执行此程序。 (3)从空闲事件组标志控制块链表中申请一个控制块节点,如果申请失败,将返回OS_FLAG_GRP_DEPLETED错误;否则初始化申请的控制块节点成员变量。OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *err)2021-10-12104阻塞式等待事件组标志 基本流程如下:(1)参数检查。检查是否为错误标志分配空间,是否指定了等待的事件组

58、标志。(2)条件检查。检查是否在中断服务程序中执行此函数,事件类型是否为事件组标志(OS_EVENT_TYPE_FLAG)。(3)使用局部变量consume标识是否需要在当前任务等待的状态满足后,将对应的等待位位取反,即是否为宏OS_FLAG_CONSUME,如果需要,则置consume为TRUE,否则为FALSE。(4)根据等待方式选择不同的处理办法如果满足,根据consume的值选择是否需要将等待的各位(即pgrp-OSFlagFlags &= flags_rdy);如果不满足,则调用函数OS_FlagBlock()阻塞当前进程,引发新的调度,关于函数OS_FlagBlock()功能详细说

59、明见后。OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err)2021-10-12105非阻塞式等待事件组标志 基本流程如下:(1)参数检查。检查是否为错误标志分配空间,是否指定了等待的事件组标志。(2)条件检查。检查是否在中断服务程序中执行此函数,事件类型是否为事件组标志(OS_EVENT_TYPE_FLAG)。(3)使用局部变量consume标识是否需要在当前任务等待的状态满足后,将对应的等待位位取反,即是否为宏OS_FLAG_CONSUME,如

60、果需要,则置consume为TRUE,否则为FALSE。(4)根据等待方式选择不同的处理办法,如果满足,根据consume的值选择是否需要将等待的各位(即pgrp-OSFlagFlags &= flags_rdy);如果不满足直接退出,返回OS_FLAG_ERR_NOT_RDY错误。OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *err)2021-10-12106修改事件组标志状态 流程如下:(1)参数检查。检查是否为错误标志分配空间,是否指定了等待的事件组标志。(2)条件检查。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论