《西安电子科技大学嵌入式实时操作系统课件-第8章》由会员分享,可在线阅读,更多相关《西安电子科技大学嵌入式实时操作系统课件-第8章(104页珍藏版)》请在金锄头文库上搜索。
1、第8章 事件标志组,8.1 概述 8.2 建立事件标志组OSFlagCreate() 8.3 等待事件标志组中的事件标志位OSFlagPend() 8.4 置位或者清零事件标志组中的事件标志OSFlagPost() 8.5 删除事件标志组OSFlagDel() 8.6 无等待地获得事件标志组中的事件标志OSFlagAccept() 8.7 查询事件标志组的状态OSFlagQuery() 习题,8.1 概 述 8.1.1 事件标志组的组成及管理函数 C/OS-的事件标志组由两部分组成:一是用于保存当前事件组中各种状态的各种标志位;二是等待标志位或者清零的任务列表。如表8.1所示,C/OS-提供了
2、六种对事件标志组进行管理的函数,函数所属文件是OS_FLAG .C。,表8.1 事件标志组管理函数一览表,8.1.2 事件标志组管理函数的配置常量 在使用事件标志组管理函数之前,必须设置OS_CFG .H文件中相应的配置常量,以确定是编译还是裁剪该函数,其配置常量如表8.2所示。,表8.2 事件标志组管理函数的配置常量一览表,8.1.3 实现事件标志组所需要的数据结构 实现一个事件标志组除了需要任务控制块OS_TCB以外,还需要两个新的数据结构,即事件标志组数据结构OS_FLAG_GRP和事件标志节点OS_FLAG_NODE。如程序清单8.1所示,OS_FLAG_GRP包括如下三个成员: (1
3、) .OSFlagType:用来检验指针的类型是否为指向事件标志组的指针。 (2) .OSFlagWaitList:事件标志组的等待任务列表。 (3) .OSFlagFlags:一系列表明当前事件标志状态的位,它可以是8、16或32位的,具体大小由OS_CFG .H文件中的OS_FLAGS常量决定。,程序清单8.1 OS_FLAG_GRP数据结构 typedef struct INT8U OSFlagType; void *OSFlagWaitList; OS_FLAGS OSFlagFlags; OS_FLAG_GRP,OS_FLAG_NODE数据结构用来记录任务在等待哪些事件标志位以及等待
4、的方式( “与”或者“或”)。当任务需要等待事件标志位时,就会建立一个OS_FLAG_NODE数据结构;当这些等待事件的标志位发生后,这个数据结构就会被删除。OS_FLAG_NODE数据结构如程序清单8.2所示,具体说明如下: (1) .OSFlagNodeNext和.OSFlagNodePrev:用于链接OS_FLAG_NODE的双向链表指针。 (2) .OSFlagNodeTCB:指向一个等待事件标志组中事件标志的任务控制块。通过这个指针可以确定哪一个任务在等待事件标志组中的事件。,(3) .OSFlagNodeFlagGrp:反向指向事件标志组的指针。 (4) .OSFlagNodeFl
5、ags:指明任务在等待事件标志组中的哪几位事件标志。例如,如果任务调用OSFlagPend(),并等待事件标志组中的0、2、4、6位事件标志,那么OSFlag NodeFlags的值为0x55。OSFlagNodeFlags的位数可能是8、16或32位,其大小由OS_FLAGS指定。 (5) .OSFlagNodeWaitType:指明等待事件标志组中的事件标志的类型是AND(“与”)还是OR(“或”),AND表示所有事件标志都发生,OR表示任何一个事件标志发生。其可能值如下:,OS_FLAG_WAIT_CLR_ALL 所有指定的事件标志位清零 OS_FLAG_WAIT_CLR_AND OS_
6、FLAG_WAIT_CLR_ANY 任意指定的事件标志位清零 OS_FLAG_WAIT_CLR_OR OS_FLAG_WAIT_SET_ALL 所有指定的事件标志位置位 OS_FLAG_WAIT_SET_AND,OS_FLAG_WAIT_SET_ANY 任意指定的事件标志位置位 OS_FLAG_WAIT_SET_OR 其中,AND和ALL意义相同,OR和ANY意义也是相同的,意义相同的可以互换使用。,程序清单8.2 OS_FLAG_NODE数据结构 type struct void *OSFlagNodeNext; void *OSFlagNodePrev; void *OSFlagNodeT
7、CB; void *OSFlagNodeFlagGrp; OS_FLAGS OSFlagNodeFlags; INT8U OSFlagNodeWaitType; OS_FLAG_NODE; 事件标志组、事件标志节点和任务控制块之间的关系如图8.1所示。,图8.1 事件标志组、事件标志节点和任务控制块之间的关系,8.2 建立事件标志组OSFlagCreate() 8.2.1 函数原型 函数原型如下: OS_FALG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U *err) OSFlagCreate()函数用于建立事件标志组。其开关量是OS_FLAG_EN,调用者
8、可以是任务或者启动代码。它有如下两个参数: (1) flags:事件标志组的事件标志初值。,(2) err:指向错误代码的指针。其值为如下内容之一: OS_NO_ERR:事件标志组建立成功。 OS_ERR_CREATE_ISR:在中断中调用。 OS_FLAG_GRP_DEPLETED:系统中空闲事件标志组已用完,OS_CFG .H文件中事件标志组的数量需要更改。,8.2.2 返回值 如果建立成功,则返回事件标志组的指针;如果系统没有多余的空闲事件标志组,则返回空指针。 8.2.3 源代码 OSFlagCreate()函数的源代码如程序清单8.3所示。,程序清单8.3 OSFlagCreate(
9、)函数的源代码 OS_FLAG_GRP *OSFlagCreate (OS_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; /*若在中断中调用,则返回错误代码和空指针 */,return (OS_FLAG_GRP *)0); OS_ENTER_CRITICAL(); pgrp = OSFlagFreeList; /*在空闲事件标志组链
10、表中取一个空闲事件标志组 */ if (pgrp != (OS_FLAG_GRP *)0) /*检查所取的空闲事件标志组是否有效 */ /*若有效,则调整空闲事件标志组链表指针 */ OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList-OSFlagWaitList;,pgrp-OSFlagType = OS_EVENT_TYPE_FLAG; /*设置事件标志组类型 */ pgrp-OSFlagFlags = flags; /*设置初始值 */ pgrp-OSFlagWaitList = (void *)0; /*事件标志组的等待任务列表清零*/ OS_
11、EXIT_CRITICAL(); *err = OS_NO_ERR; /*返回调用成功代码 */ else /*若没有多余的空闲事件标志组,则返回相应的错误代码 */,OS_EXIT_CRITICAL(); *err = OS_FLAG_GRP_DEPLETED; return (pgrp); /*返回事件标志组指针 */ ,8.3 等待事件标志组中的事件标志位 OSFlagPend() 8.3.1 函数原型 函数原型如下: OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type,INT16U timeout
12、, INT8U *err),OSFlagPend()函数用于等待事件标志组中的事件标志,可以是多个事件标志的不同组合,可以等待任一指定事件标志位置位或者清零,也可以等待全部指定事件标志位置位或者清零。如果所等待的事件标志位条件不能满足,则会挂起调用者,直到指定的事件标志组合发生或者等待超时期满。该函数的调用者只能是任务,开关量是OS_FLAG_EN。 该函数有如下五个参数: (1) pgrp:指向事件标志组的指针。其值可以在事件标志组建立时得到。 (2) flags:指定需要检查的事件标志位。若置1,则检查对应位;若置0,则忽略对应位。,(3) wait_type:定义等待事件标志位的方式。其
13、方式为如下四种之一: OS_FLAG_WAIT_CLR_ALL:所有指定的事件标志位都清零。 OS_FLAG_WAIT_CLR_ANY:任意指定的事件标志位清零。 OS_FLAG_WAIT_SET_ALL:所有指定的事件标志位都置位。 OS_FLAG_WAIT_SET_ANY:任意指定的事件标志位置位。 (4) timeout:超时定义。,(5) err:指向错误代码的指针。其内容为如下几种之一: OS_NO_ERR:调用成功。 OS_ERR_PEND_ISR:在中断中调用。 OS_FLAG_INVALID_PGRP:pgrp为空指针。 OS_ERR_EVENT_TYPE:pgrp不是指向事件
14、标志组的指针。 OS_TIMEOUT:等待超时。 OS_FLAG_ERR_WAIT_TYPE:wait_type不是指定的参数之一。,如果一个任务在得到所需要的事件标志后想恢复这个事件标志,则可以在wait_type参数上加一个常量OS_FLAG_ CONSUME,即OS_FLAG_WAIT_?_? + OS_FLAG_ CONSUME。 8.3.2 返回值 如果调用该函数时使用了OS_FLAG_CONSUME选项,则返回恢复后的事件标志组事件标志状态;否则,返回OSFlagPend()调用后的事件标志组事件标志状态;如果超时,则返回0。 8.3.3 源代码 OSFlagPend()函数的源代
15、码如程序清单8.4所示。,程序清单8.4 OSFlagPend()函数的源代码 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;,if (OSIntNesting 0) /*确保中断不能调用 */ *err = OS_ERR_PEND_ISR; /*若在中断中调用,则返回错误代码 */ return (OS_FLAGS)0); /*返回空指针 */ #if OS_ARG_CHK_EN 0 if (pgrp = (OS_FLAG_GRP *)0)