uC/OS-II 中的事件标志组相当于一群互斥型信号量,通过这些信号量占用情况的逻辑函数求值确定任务的执行与挂起。事件标志组在一些中文参考资料中又称信号量集,以下采用前一种名称。本文使用的是 uC/OS-II V2.91 的源码。
OS_FLAG_GRP
与事件 OS_EVENT 不同的是,uC/OS 使用另一种数据结构 OS_FLAG_GRP 来表示事件标志组。
结构体中的 OSFlagFlags 成员可以是一个 8 位、16 位、32 位的变量,变量的每个位代表一个事件标志(又称信号量,对应于信号量集),变量的大小根据 os_cfg.h 中的 OS_FLAGS_NBITS 条件编译而得
OSFlagWaitList 指向等待任务列表的首地址,等待任务列表是一个双向链表,节点名为 OS_FLAG_NODE ,每个节点对应一个等待任务。
对等待任务列表的操作 OS_FlagBlock(), OS_FlagInit(), OS_FlagTaskRdy(), OS_FlagUnlink() 作为底层函数被事件标志组函数封装。
OSFlagCreate()
使用事件标志组之前需要调用 OSFlagCreate()函数从空标志组链表中取出一个元素。
flags 原样赋值给 OSFlagFlags,由于后者是无符号整型数,以防万一传递参数时可用强制类型转换。这里是要给所有事件标志初始化,赋值 0 即可。
perr 照旧是存储输出信息的地方。
这两种情况都会返回空指针,OS_ERR_NONE 表示创建成功,返回事件标志组指针。
OSFlagDel()
删除事件标志组的方式与其他事件相同。
perr, opt 行为一致,删除成功后返回空指针
OSFlagPend() & OSFlagAccept()
任务请求一个事件标志组事件的某些标志位,在触发或超时后继续执行。
flags 是即将写入等待任务列表节点的掩码 OSFlagNodeFlags。wait_type 是触发条件设置,写入等待任务列表节点的 OSFlagNodeWaitType。
需要不挂起请求的,使用 OSFlagAccept(),用法基本相同
需要注意的是,如果对应的事件标志没有发生,函数返回值为 0;如果对应事件标志发生,函数返回事件标志组结构中的 OSFlagFlags 成员,即当前事件标志组的所有事件标志。因此在判断时还需参考 perr 的值。
OSFlagPost()
用于发送事件标志。
flags 仍是用于掩码,判断哪些位被操作;opt 则描述对有效位的操作。
OSFlagQuery()
OSFlagQuery() 可以直接返回事件标志组结构中的 OSFlagFlags 成员。
OS_FLAGS OSFlagQuery(OS_FLAG_GRP *pgrp, INT8U *perr) 与其他 OS_EVENT 不同的是,访问事件标志组不会对内部的事件标志造成影响。一旦有任务就绪,等待任务列表里只会移除对应任务的节点。