西安电子科技大学嵌入式实时操作系统课件-第8章.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《西安电子科技大学嵌入式实时操作系统课件-第8章.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 西安电子科技大学 嵌入式 实时 操作系统 课件
- 资源描述:
-
1、第8章 事件标志组第8章 事件标志组8.1 概述概述 8.2 建立事件标志组建立事件标志组OSFlagCreate()8.3 等待事件标志组中的事件标志位等待事件标志组中的事件标志位OSFlagPend()8.4 置位或者清零事件标志组中的事件标志置位或者清零事件标志组中的事件标志OSFlagPost()8.5 删除事件标志组删除事件标志组OSFlagDel()8.6 无等待地获得事件标志组中的事件标志无等待地获得事件标志组中的事件标志OSFlagAccept()8.7 查询事件标志组的状态查询事件标志组的状态OSFlagQuery()习题习题 第8章 事件标志组8.1 概概 述述8.1.1
2、事件标志组的组成及管理函数事件标志组的组成及管理函数C/OS-的事件标志组由两部分组成:一是用于保存当前事件组中各种状态的各种标志位;二是等待标志位或者清零的任务列表。如表8.1所示,C/OS-提供了六种对事件标志组进行管理的函数,函数所属文件是OS_FLAG.C。第8章 事件标志组表表8.1 事件标志组管理函数一览表事件标志组管理函数一览表第8章 事件标志组8.1.2 事件标志组管理函数的配置常量事件标志组管理函数的配置常量在使用事件标志组管理函数之前,必须设置OS_CFG.H文件中相应的配置常量,以确定是编译还是裁剪该函数,其配置常量如表8.2所示。第8章 事件标志组表表8.2 事件标志组
3、管理函数的配置常量一览表事件标志组管理函数的配置常量一览表第8章 事件标志组8.1.3 实现事件标志组所需要的数据结构实现事件标志组所需要的数据结构实现一个事件标志组除了需要任务控制块OS_TCB以外,还需要两个新的数据结构,即事件标志组数据结构OS_FLAG_GRP和事件标志节点OS_FLAG_NODE。如程序清单8.1所示,OS_FLAG_GRP包括如下三个成员:(1).OSFlagType:用来检验指针的类型是否为指向事件标志组的指针。(2).OSFlagWaitList:事件标志组的等待任务列表。(3).OSFlagFlags:一系列表明当前事件标志状态的位,它可以是8、16或32位的
4、,具体大小由OS_CFG.H文件中的OS_FLAGS常量决定。第8章 事件标志组程序清单程序清单8.1 OS_FLAG_GRP数据结构数据结构typedef struct INT8U OSFlagType;void *OSFlagWaitList;OS_FLAGS OSFlagFlags;OS_FLAG_GRP第8章 事件标志组OS_FLAG_NODE数据结构用来记录任务在等待哪些事件标志位以及等待的方式(“与”或者“或”)。当任务需要等待事件标志位时,就会建立一个OS_FLAG_NODE数据结构;当这些等待事件的标志位发生后,这个数据结构就会被删除。OS_FLAG_NODE数据结构如程序清单
5、8.2所示,具体说明如下:(1).OSFlagNodeNext和.OSFlagNodePrev:用于链接OS_FLAG_NODE的双向链表指针。(2).OSFlagNodeTCB:指向一个等待事件标志组中事件标志的任务控制块。通过这个指针可以确定哪一个任务在等待事件标志组中的事件。第8章 事件标志组(3).OSFlagNodeFlagGrp:反向指向事件标志组的指针。(4).OSFlagNodeFlags:指明任务在等待事件标志组中的哪几位事件标志。例如,如果任务调用OSFlagPend(),并等待事件标志组中的0、2、4、6位事件标志,那么OSFlag NodeFlags的值为0 x55。O
6、SFlagNodeFlags的位数可能是8、16或32位,其大小由OS_FLAGS指定。(5).OSFlagNodeWaitType:指明等待事件标志组中的事件标志的类型是AND(“与”)还是OR(“或”),AND表示所有事件标志都发生,OR表示任何一个事件标志发生。其可能值如下:第8章 事件标志组OS_FLAG_WAIT_CLR_ALL 所有指定的事件标志位清零OS_FLAG_WAIT_CLR_ANDOS_FLAG_WAIT_CLR_ANY 任意指定的事件标志位清零OS_FLAG_WAIT_CLR_OROS_FLAG_WAIT_SET_ALL 所有指定的事件标志位置位OS_FLAG_WAIT
7、_SET_AND第8章 事件标志组OS_FLAG_WAIT_SET_ANY 任意指定的事件标志位置位OS_FLAG_WAIT_SET_OR其中,AND和ALL意义相同,OR和ANY意义也是相同的,意义相同的可以互换使用。第8章 事件标志组程序清单程序清单8.2 OS_FLAG_NODE数据结构数据结构type structvoid *OSFlagNodeNext;void *OSFlagNodePrev;void *OSFlagNodeTCB;void *OSFlagNodeFlagGrp;OS_FLAGS OSFlagNodeFlags;INT8U OSFlagNodeWaitType;OS
8、_FLAG_NODE;事件标志组、事件标志节点和任务控制块之间的关系如图8.1所示。第8章 事件标志组图8.1 事件标志组、事件标志节点和任务控制块之间的关系第8章 事件标志组8.2 建立事件标志组建立事件标志组OSFlagCreate()8.2.1 函数原型函数原型函数原型如下:OS_FALG_GRP*OSFlagCreate(OS_FLAGS flags,INT8U*err)OSFlagCreate()函数用于建立事件标志组。其开关量是OS_FLAG_EN,调用者可以是任务或者启动代码。它有如下两个参数:(1)flags:事件标志组的事件标志初值。第8章 事件标志组(2)err:指向错误代
9、码的指针。其值为如下内容之一:OS_NO_ERR:事件标志组建立成功。OS_ERR_CREATE_ISR:在中断中调用。OS_FLAG_GRP_DEPLETED:系统中空闲事件标志组已用完,OS_CFG.H文件中事件标志组的数量需要更改。第8章 事件标志组8.2.2 返回值返回值如果建立成功,则返回事件标志组的指针;如果系统没有多余的空闲事件标志组,则返回空指针。8.2.3 源代码源代码OSFlagCreate()函数的源代码如程序清单8.3所示。第8章 事件标志组程序清单程序清单8.3 OSFlagCreate()函数的源代码函数的源代码OS_FLAG_GRP *OSFlagCreate(O
10、S_FLAGS flags,INT8U*err)#if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#endif OS_FLAG_GRP*pgrp;if(OSIntNesting 0)/*确保中断不能调用*/*err=OS_ERR_CREATE_ISR;/*若在中断中调用,则返回错误代码和空指针*/第8章 事件标志组 return(OS_FLAG_GRP*)0);OS_ENTER_CRITICAL();pgrp=OSFlagFreeList;/*在空闲事件标志组链表中取一个空闲事件标志组*/if(pgrp!=(OS_FLAG_GRP*)0)/*检查所取的空闲事件
11、标志组是否有效*/*若有效,则调整空闲事件标志组链表指针*/OSFlagFreeList =(OS_FLAG_GRP*)OSFlagFreeList-OSFlagWaitList;第8章 事件标志组 pgrp-OSFlagType =OS_EVENT_TYPE_FLAG;/*设置事件标志组类型*/pgrp-OSFlagFlags =flags;/*设置初始值 */pgrp-OSFlagWaitList=(void*)0;/*事件标志组的等待任务列表清零*/OS_EXIT_CRITICAL();*err =OS_NO_ERR;/*返回调用成功代码*/else /*若没有多余的空闲事件标志组,则返
12、回相应的错误代码*/第8章 事件标志组 OS_EXIT_CRITICAL();*err =OS_FLAG_GRP_DEPLETED;return(pgrp);/*返回事件标志组指针 */第8章 事件标志组8.3 等待事件标志组中的事件标志位等待事件标志组中的事件标志位OSFlagPend()8.3.1 函数原型函数原型函数原型如下:OS_FLAGS OSFlagPend(OS_FLAG_GRP*pgrp,OS_FLAGS flags,INT8U wait_type,INT16U timeout,INT8U*err)第8章 事件标志组OSFlagPend()函数用于等待事件标志组中的事件标志,可
13、以是多个事件标志的不同组合,可以等待任一指定事件标志位置位或者清零,也可以等待全部指定事件标志位置位或者清零。如果所等待的事件标志位条件不能满足,则会挂起调用者,直到指定的事件标志组合发生或者等待超时期满。该函数的调用者只能是任务,开关量是OS_FLAG_EN。该函数有如下五个参数:(1)pgrp:指向事件标志组的指针。其值可以在事件标志组建立时得到。(2)flags:指定需要检查的事件标志位。若置1,则检查对应位;若置0,则忽略对应位。第8章 事件标志组(3)wait_type:定义等待事件标志位的方式。其方式为如下四种之一:OS_FLAG_WAIT_CLR_ALL:所有指定的事件标志位都清
14、零。OS_FLAG_WAIT_CLR_ANY:任意指定的事件标志位清零。OS_FLAG_WAIT_SET_ALL:所有指定的事件标志位都置位。OS_FLAG_WAIT_SET_ANY:任意指定的事件标志位置位。(4)timeout:超时定义。第8章 事件标志组(5)err:指向错误代码的指针。其内容为如下几种之一:OS_NO_ERR:调用成功。OS_ERR_PEND_ISR:在中断中调用。OS_FLAG_INVALID_PGRP:pgrp为空指针。OS_ERR_EVENT_TYPE:pgrp不是指向事件标志组的指针。OS_TIMEOUT:等待超时。OS_FLAG_ERR_WAIT_TYPE:w
15、ait_type不是指定的参数之一。第8章 事件标志组如果一个任务在得到所需要的事件标志后想恢复这个事件标志,则可以在wait_type参数上加一个常量OS_FLAG_ CONSUME,即OS_FLAG_WAIT_?_?+OS_FLAG_ CONSUME。8.3.2 返回值返回值如果调用该函数时使用了OS_FLAG_CONSUME选项,则返回恢复后的事件标志组事件标志状态;否则,返回OSFlagPend()调用后的事件标志组事件标志状态;如果超时,则返回0。8.3.3 源代码源代码OSFlagPend()函数的源代码如程序清单8.4所示。第8章 事件标志组程序清单程序清单8.4 OSFlagP
16、end()函数的源代码函数的源代码OS_FLAGS OSFlagPend(OS_FLAG_GRP*pgrp,OS_FLAGS flags,INT8U wait_type,INT16U timeout,INT8U*err)#if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#endif OS_FLAG_NODE node;OS_FLAGS flags_cur;OS_FLAGS flags_rdy;BOOLEAN consume;第8章 事件标志组 if(OSIntNesting 0)/*确保中断不能调用*/*err=OS_ERR_PEND_ISR;/*若在中断中调
17、用,则返回错误代码*/return(OS_FLAGS)0);/*返回空指针 */#if OS_ARG_CHK_EN 0 if(pgrp=(OS_FLAG_GRP*)0)/*确保pgrp指针有效 */第8章 事件标志组*err=OS_FLAG_INVALID_PGRP;return(OS_FLAGS)0);#endif if(pgrp-OSFlagType!=OS_EVENT_TYPE_FLAG)/*确保事件类型正确 */*err=OS_ERR_EVENT_TYPE;return(OS_FLAGS)0);第8章 事件标志组 if(wait_type&OS_FLAG_CONSUME)/*检查是否使
18、用了consume选项*/wait_type&=OS_FLAG_CONSUME;consume =TRUE;/*设置consume选用状态标志*/else/*若未使用*/consume =FALSE;/*将consume选用状态标志设置为“FALSE”*/第8章 事件标志组 OS_ENTER_CRITICAL();switch(wait_type)/*以四种方式处理等待事件标志组*/case OS_FLAG_WAIT_SET_ALL:/*所有指定的事件标志位都置位*/flags_rdy=pgrp-OSFlagFlags&flags;/*提取flags指定的事件标志位*/if(flags_rdy
19、=flags)/*检查是否有可用的事件标志组*/if(consume=TRUE)/*若可用,则检查是否设置了consume 选项*/第8章 事件标志组 pgrp-OSFlagFlags&=flags_rdy;/*对指定的事件标志位清零*/flags_cur=pgrp-OSFlagFlags;/*保存需要返回的事件标志位状态*/OS_EXIT_CRITICAL();*err =OS_NO_ERR;return(flags_cur);/*返回调用者*/else /*若没有可用的事件标志组,则需等到事件发生或超时期满*/第8章 事件标志组 OS_FlagBlock(pgrp,&node,flags,
20、wait_type,timeout);/*将调用者加到事件标志组的等待任务列表中去,挂起任务*/OS_EXIT_CRITICAL();break;case OS_FLAG_WAIT_SET_ANY:/*任意指定的事件标志位置位*/flags_rdy=pgrp-OSFlagFlags&flags;/*提取flags指定的事件标志位*/if(flags_rdy!=(OS_FLAGS)0)/*检查是否有可用的事件标志组*/第8章 事件标志组 if(consume=TRUE)/*若可用,则检查是否设置了consume 选项*/pgrp-OSFlagFlags&=flags_rdy;/*对指定的事件标志
21、位清零*/flags_cur=pgrp-OSFlagFlags;/*保存需要返回的事件标志位状态*/OS_EXIT_CRITICAL();*err =OS_NO_ERR;return(flags_cur);/*返回调用者*/第8章 事件标志组 else /*若没有可用的事件标志组,则需等到事件发生或超时期满*/OS_FlagBlock(pgrp,&node,flags,wait_type,timeout);OS_EXIT_CRITICAL();break;#if OS_FLAG_WAIT_CLR_EN 0 case OS_FLAG_WAIT_CLR_ALL:/*所有指定的事件标志位都清零 */
22、第8章 事件标志组 flags_rdy=pgrp-OSFlagFlags&flags;/*提取flags指定的事件标志位*/if(flags_rdy=flags)/*检查是否有可用的事件标志组*/if(consume=TRUE)/*若有,则检查是否设置了consume 选项*/pgrp-OSFlagFlags|=flags_rdy;/*对指定的事件标志位置位*/flags_cur=pgrp-OSFlagFlags;/*保存需要返回的事件标志位状态*/第8章 事件标志组 OS_EXIT_CRITICAL();*err =OS_NO_ERR;return(flags_cur);/*返回调用者*/e
23、lse /*若没有可用的事件标志组,则需等到事件发生或超时期满*/OS_FlagBlock(pgrp,&node,flags,wait_type,timeout);OS_EXIT_CRITICAL();break;第8章 事件标志组 case OS_FLAG_WAIT_CLR_ANY:/*任意指定的事件标志位清零*/flags_rdy=pgrp-OSFlagFlags&flags;/*提取flags指定的事件标志位*/if(flags_rdy!=(OS_FLAGS)0)/*检查是否有可用的事件标志组*/if(consume=TRUE)/*若有,则检查是否设置了consume 选项*/pgrp-
24、OSFlagFlags|=flags_rdy;/*对指定的事件标志位置位*/第8章 事件标志组 flags_cur=pgrp-OSFlagFlags;/*保存需要返回的事件标志位状态*/OS_EXIT_CRITICAL();*err =OS_NO_ERR;return(flags_cur);else /*若没有可用的事件标志组,则需等到事件发生或超时期满*/OS_FlagBlock(pgrp,&node,flags,wait_type,timeout);OS_EXIT_CRITICAL();第8章 事件标志组 break;#endif default:/*如果wait_type参数不是指定的四
25、种之一*/OS_EXIT_CRITICAL();flags_cur=(OS_FLAGS)0;*err =OS_FLAG_ERR_WAIT_TYPE;return(flags_cur);第8章 事件标志组 OS_Sched();/*调用者被挂起,需要运行准备就绪的最高优先级任务*/OS_ENTER_CRITICAL();/*当再次返回时,需要检查本函数是因超时期满还是因事件发生而恢复运行的*/if(OSTCBCur-OSTCBStat&OS_STAT_FLAG)/*是因超时期满而恢复运行的吗*/OS_FlagUnlink(&node);/*若是,则将OS_FLAG_NODE从等待任务列表链表中删
展开阅读全文