# 事件标志
***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.***
---
# 功能概述
事件标志组(Event Flag Group)是UniRTOS提供的一种轻量级同步机制,用于在任务间传递“某个事件或条件是否已发生”的状态。它主要用于任务同步、状态通知和多事件协同,不用于业务数据传输,因此适合与消息队列等数据传输机制配合使用。
在UniRTOS中,一个事件标志(Flag)对象由一组按位管理的标志位组成,每一位表示一种独立事件。任务创建Flag对象后,可由一个或多个任务对指定标志位进行设置、等待、清除和查询。通过这种方式,系统可以便捷地表达“某个条件已满足”、“某个异步事件已到达”或“多个前置条件已就绪”等同步关系。
需要注意的是,Flag表示的是事件状态,而非事件次数。当某一位被置位时,表示对应事件已发生;在该标志位被清除前,即使再次对同一位重复置位,其状态仍然保持为“已发生”,不会累计次数。因此,Flag更适合用于条件同步和状态协同。如果业务场景需要逐次处理每一个事件或同时传递附加数据,建议使用更适合的数据通信机制。
在函数使用上,Flag采用32位位图表示事件状态,其中bit 31(0x80000000)保留为错误指示位,业务侧不应将其作为普通事件位使用。等待函数同时支持超时控制,因此既可用于阻塞等待,也可用于带超时参数的同步等待。总体而言,Flag是一种开销小、逻辑直观、适合多事件协同的同步机制。
# Flag API
## 头文件
*qosa_sys.h*
## 函数概览
| **函数名** | **功能描述** |
| --- | --- |
| *qosa_flag_create()* | 创建Flag对象 |
| *qosa_flag_delete()* | 删除Flag对象 |
| *qosa_flag_set()* | 设置指定的Flag |
| *qosa_flag_wait()* | 等待接收指定的Flag |
| *qosa_flag_clear()* | 手动清除指定的Flag |
## 函数定义
### qosa_flag_create
- **功能描述**
创建Flag对象,并执行初始化操作。
- **函数原型**
```c
qosa_errcode_os_e qosa_flag_create(qosa_flag_t *flag_ref)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *flag_ref* | 输出 | qosa_flag_t * | 指向Flag句柄指针的地址,用于接收创建的Flag句柄 |
- **返回值说明**
*QOSA_ERROR_OK*:函数执行成功
*QOSA_ERROR_FLAG_INVALID_ERR*:Flag参数无效
*QOSA_ERROR_FLAG_CREATE_ERR*:Flag创建失败
```{note}
当创建的Flag不再使用时,应调用 ***qosa_flag_delete()*** 释放资源。
```
### qosa_flag_delete
- **功能描述**
删除Flag对象,并释放相关资源。
- **函数原型**
```c
qosa_errcode_os_e qosa_flag_delete(qosa_flag_t flag_ref)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *flag_ref* | 输入 | qosa_flag_t | Flag句柄 |
- **返回值说明**
*QOSA_ERROR_OK*:函数执行成功
*QOSA_ERROR_FLAG_INVALID_ERR*:Flag参数无效
*QOSA_ERROR_FLAG_DELETE_ERR*:Flag删除失败
### qosa_flag_set
- **功能描述**
设置指定的Flag。
- **函数原型**
```c
qosa_errcode_os_e qosa_flag_set(qosa_flag_t flag_ref, qosa_uint32_t flag)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *flag_ref* | 输入 | qosa_flag_t | Flag句柄 |
| *flag* | 输入 | qosa_uint32_t | 需要设置的Flag值
限制:Flag的最高bit位(bit 31,0x80000000)为系统保留位,不允许设置 |
- **返回值说明**
*QOSA_ERROR_OK*:函数执行成功
*QOSA_ERROR_FLAG_INVALID_ERR*:Flag参数无效
*QOSA_ERROR_FLAG_SET_ERR*:Flag设置失败
### qosa_flag_wait
- **功能描述**
等待接收指定的Flag。
- **函数原型**
```c
qosa_uint32_t qosa_flag_wait(qosa_flag_t flag_ref, qosa_uint32_t flag, qosa_uint32_t clear_exit, qosa_uint32_t wait_all, qosa_uint32_t timeout)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *flag_ref* | 输入 | qosa_flag_t | Flag句柄 |
| *flag* | 输入 | qosa_uint32_t | 需要等待的Flag值
限制:Flag的最高bit位(bit 31,0x80000000)为系统保留位,不允许设置 |
| *clear_exit* | 输入 | qosa_uint32_t | 成功获取Flag后,是否自动清除已触发的标志位
*QOSA_FLAG_CLEAR_ENABLE(0)*:自动清除
*QOSA_FLAG_CLEAR_DISABLE(1)*:不自动清除 |
| *wait_all* | 输入 | qosa_uint32_t | 等待模式
*QOSA_FLAG_WAIT_ALL(0)*:等待所有指定的Flag置位
*QOSA_FLAG_WAIT_ANY(1)*:等待任意指定的Flag置位 |
| *timeout* | 输入 | qosa_uint32_t | 超时时间。单位:毫秒
*QOSA_WAIT_FOREVER* 表示无限等待 |
- **返回值说明**
成功时,返回实际收到的Flag值。
*QOSA_ERROR_FLAG_INVALID_ERR*:Flag参数无效
*QOSA_ERROR_FLAG_WAIT_ERR*:等待Flag失败或超时
```{note}
*qosa_flag_wait()* 支持两种常见的等待方式:一种是等待任意一个目标标志位置位后返回,适用于多个事件中任意一个发生即可继续处理的场景;另一种是等待全部目标标志位都置位后返回,适用于多个条件均满足后才能继续执行的场景。此外,等待成功后,还可以根据参数选择是否自动清除本次命中的标志位。
```
### qosa_flag_clear
- **功能描述**
手动清除指定的Flag。
- **函数原型**
```c
qosa_errcode_os_e qosa_flag_clear(qosa_flag_t flag_ref, qosa_uint32_t flag)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *flag_ref* | 输入 | qosa_flag_t | Flag句柄 |
| *flag* | 输入 | qosa_uint32_t | 需要清除的Flag值 |
- **返回值说明**
*QOSA_ERROR_OK*:函数执行成功
*QOSA_ERROR_FLAG_INVALID_ERR*:Flag参数无效
*QOSA_ERROR_FLAG_CLEAR_ERR*:Flag清除失败
## 枚举定义
#### qosa_errcode_os_e
错误码枚举定义如下:
```c
typedef enum
{
QOSA_ERROR_OK = 0,
...
QOSA_ERROR_FLAG_INVALID_ERR = 600 | QOSA_ERRCODE_OS_BASE,
QOSA_ERROR_FLAG_CREATE_ERR,
QOSA_ERROR_FLAG_DELETE_ERR,
QOSA_ERROR_FLAG_SET_ERR,
QOSA_ERROR_FLAG_WAIT_ERR,
QOSA_ERROR_FLAG_CLEAR_ERR,
QOSA_ERROR_FLAG_GET_ERR,
...
}qosa_errcode_os_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_ERROR_OK* | 函数执行成功 |
| *QOSA_ERROR_FLAG_INVALID_ERR* | Flag参数无效 |
| *QOSA_ERROR_FLAG_CREATE_ERR* | Flag创建失败 |
| *QOSA_ERROR_FLAG_DELETE_ERR* | Flag删除失败 |
| *QOSA_ERROR_FLAG_SET_ERR* | Flag设置失败 |
| *QOSA_ERROR_FLAG_WAIT_ERR* | 等待Flag失败或超时 |
| *QOSA_ERROR_FLAG_CLEAR_ERR* | Flag清除失败 |
| *QOSA_ERROR_FLAG_GET_ERR* | 获取Flag失败 |
# 应用逻辑流程图
```{figure} images/board_ZDSEwEeknhg5QIbqLBZckTvJnDb.jpg
:align: center
:alt: image
```
# 示例代码
完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/system/sync_comm/event_flag/event_demo.c 。
# 常见问题
## Q1: Flag的值有什么限制?
- bit 31 不可使用:最高bit位(bit 31,0x80000000)为系统保留位,业务侧不允许设置或等待该位。
- 有效位范围:实际可用的标志位为bit 0 ~bit 30(共31个)。
- 不支持累积计数:Flag表示事件状态而非事件次数,同一标志位重复置位不会累积。
建议使用位掩码方式定义标志位,如:
```c
#define FLAG_EVENT_A (1 << 0) // 第0位
#define FLAG_EVENT_B (1 << 1) // 第1位
#define FLAG_EVENT_C (1 << 2) // 第2位
```
## Q2: qosa_flag_wait()中clear_exit参数的作用是什么?
该参数控制成功获取Flag后,是否自动清除已触发的标志位:
- *QOSA_FLAG_CLEAR_ENABLE*:自动清除已触发的标志位,适合一次性事件。
- *QOSA_FLAG_CLEAR_DISABLE*:不清除。保持标志位不变,适合多次触发或状态标志。
## Q3: 多任务同时等待同一个Flag会发生什么?
多个任务可以同时等待同一个Flag。当Flag被设置时:
- 如果使用 *QOSA_FLAG_WAIT_ANY* 模式,所有等待该位掩码的任务都会被唤醒。
- 如果使用 *QOSA_FLAG_WAIT_ALL* 模式,只有当所有请求的标志位都被设置时才会唤醒任务。
## Q4: 超时时间设置为0有什么特殊含义?
超时时间设置为0表示不阻塞等待,立即返回结果。如果此时Flag已满足条件,则返回实际Flag值;否则返回 *QOSA_ERROR_FLAG_WAIT_ERR*。
## Q5: Flag对象在任务间如何共享?
Flag句柄(qosa_flag_t)本质上是一个指针,可以直接作为参数传递给不同的任务以进行共享访问。请确保在最后一个使用该Flag的任务中调用 *qosa_flag_delete()* 释放底层资源,避免内存泄漏或悬空指针问题。
## Q6: 如何避免Flag资源泄漏?
遵循以下原则:
1. 每个 *qosa_flag_create()* 必须对应一个 *qosa_flag_delete()*。
2. Flag不再被任何任务使用时方可删除。
3. 可以使用引用计数机制管理Flag生命周期。
## Q7: Flag操作是否线程安全?
是的,所有Flag API都是线程安全,可以在多个任务中同时调用。