# 事件标志 ***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都是线程安全,可以在多个任务中同时调用。