当前位置: 首页 > news >正文

FreeRTOS 事件标志组详解:原理、用法与实战技巧

在嵌入式系统中,任务之间经常需要同步通信。FreeRTOS 提供了多种机制来实现这些需求,例如队列、信号量、消息缓冲区等。而当你需要一个任务等待多个“事件条件”同时满足或任一满足时,事件标志组(Event Group) 就是最优解。

本文将深入讲解 FreeRTOS 的事件标志组原理、用法、应用场景,并配合“大白话”解释,帮助你快速学会并灵活使用。


一、什么是事件标志组(Event Group)?

事件标志组是一个由多个二进制位(bit)组成的集合,每一位可以被设置(set)或清除(clear),用来表示一个事件是否发生。

  • 每一个 bit 是一个“标志”;
  • 多个任务可以等待一个或多个标志;
  • 标志可以由其他任务或中断服务程序(ISR)设置。

大白话解释:

想象你在一个工地上,负责启动挖掘机的总开关,但前提是:

  • 工人 A 必须戴好安全帽(事件 A);
  • 工人 B 必须穿好反光衣(事件 B);
  • 工人 C 必须签到上班(事件 C)。

你可以等待这三个条件全部满足(AND)或任意一个满足(OR)再开始工作。

这就是事件标志组的作用:多个“事件”,你可以选择等“一个”或“全都”。


二、事件标志组的原理

事件标志组本质上是一个 32 位无符号整数,每一位代表一个事件标志(bit 0 ~ 31)。FreeRTOS 提供 API 支持对这些位进行设置、清除、等待等操作。

一个 Event Group 可以被多个任务共享。任务可以阻塞地等待某些位被置位(Set),满足条件后解除阻塞。


三、事件标志组的 API 用法

1. 创建事件组

EventGroupHandle_t xEventGroupCreate(void);

返回一个事件组句柄。

EventGroupHandle_t xEventGroup;
xEventGroup = xEventGroupCreate();

2. 设置事件标志位(Set Bits)

EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, EventBits_t uxBitsToSet);
  • 将某些位设置为 1,表示事件已发生。
  • 其他任务如果在等待这些位,就可能被唤醒。

xEventGroupSetBits(xEventGroup, BIT0 | BIT2); // 设置第0和第2位

3. 清除事件标志位(Clear Bits)

EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, EventBits_t uxBitsToClear);
  • 手动清除某些位(设为0),可用于重置状态。

4. 等待事件标志位(Wait Bits)

EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup,EventBits_t uxBitsToWaitFor,BaseType_t xClearOnExit,BaseType_t xWaitForAllBits,TickType_t xTicksToWait
);
参数说明:
参数说明
uxBitsToWaitFor要等待的标志位(如 `BIT0
xClearOnExit是否在退出等待后自动清除这些位
xWaitForAllBitspdTRUE 表示等待所有位都为1,pdFALSE 表示等任一位即可
xTicksToWait最长等待时间(tick数),0为不等待
示例:

// 等待 BIT0 和 BIT1 同时被设置,超时时间为 1000 tick
xEventGroupWaitBits(xEventGroup, BIT0 | BIT1, pdTRUE, pdTRUE, 1000);

5. 在中断中设置事件(From ISR)

BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,EventBits_t uxBitsToSet,BaseType_t *pxHigherPriorityTaskWoken
);
  • 可在中断中使用,安全地设置事件位;
  • pxHigherPriorityTaskWoken 用于中断后切换任务。

四、事件标志组的大白话图解

标志位含义
BIT0 = 0x01任务 A 完成
BIT1 = 0x02任务 B 完成
BIT2 = 0x04任务 C 完成

如果主任务要等 A、B、C 全部完成:

xEventGroupWaitBits(xEventGroup, BIT0 | BIT1 | BIT2, pdTRUE, pdTRUE, portMAX_DELAY);

如果只要等任意一个完成:

xEventGroupWaitBits(xEventGroup, BIT0 | BIT1 | BIT2, pdTRUE, pdFALSE, portMAX_DELAY);

五、实战案例:任务同步应用

场景:多个传感器数据采集任务,主任务需要在全部采集完成后处理数据。

步骤:
  1. 创建事件组;
  2. 每个采集任务完成后设置对应事件位;
  3. 主任务等待所有位置位后继续执行。
示例代码:

#define SENSOR1_DONE_BIT  (1 << 0)
#define SENSOR2_DONE_BIT  (1 << 1)EventGroupHandle_t xSyncEvent;void vSensor1Task(void *pvParameters) {// 模拟采集vTaskDelay(pdMS_TO_TICKS(100));xEventGroupSetBits(xSyncEvent, SENSOR1_DONE_BIT);vTaskDelete(NULL);
}void vSensor2Task(void *pvParameters) {vTaskDelay(pdMS_TO_TICKS(200));xEventGroupSetBits(xSyncEvent, SENSOR2_DONE_BIT);vTaskDelete(NULL);
}void vMainTask(void *pvParameters) {xSyncEvent = xEventGroupCreate();xTaskCreate(vSensor1Task, "Sensor1", 128, NULL, 1, NULL);xTaskCreate(vSensor2Task, "Sensor2", 128, NULL, 1, NULL);// 等待两个任务完成xEventGroupWaitBits(xSyncEvent,SENSOR1_DONE_BIT | SENSOR2_DONE_BIT,pdTRUE,pdTRUE,portMAX_DELAY);printf("所有传感器数据采集完成,开始处理\n");vEventGroupDelete(xSyncEvent);vTaskDelete(NULL);
}

六、注意事项与最佳实践

问题原因建议
不会唤醒任务等待条件不满足或等待超时检查标志位设置是否正确
ISR 中使用不当使用普通 API 而非 FromISR 版本中断中需使用 xEventGroupSetBitsFromISR()
标志位“粘连”未启用 xClearOnExit需要在任务中手动清除或设置自动清除
http://www.xdnf.cn/news/658711.html

相关文章:

  • 网页模板素材网站 web前端网页制作模板
  • 如何清除浏览器启动hao点360
  • 【多智能体系统开发框架AutoGen解析与实践】
  • 初学ADC
  • 【四】频率域滤波(下)【830数字图像处理】
  • 华为OD机试真题——通信系统策略调度(用户调度问题)(2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • 算力服务器和GPU服务器之间的联系
  • C++中使用类的继承机制来定义和实现基类与派生类
  • 初始化硬盘时,选MBR还是GUID?—「小白教程」
  • Linux系统中为Qt项目封装一个udp客户端类
  • 在麒麟系统(Kylin OS)上安装`geckodriver`
  • 跳板问题(贪心算法+细节思考)
  • 中国工程咨询协会新型基础设施专业委员会成立
  • Open vSwitch笔记20250526
  • 基于python合成100X100的透明背景图片和图标
  • 十大排序算法
  • 单例模式,饿汉式,懒汉式,在java和spring中的体现
  • 从数据页角度理解B+树查询
  • Netty学习专栏(五):Netty高性能揭秘(Reactor模式与零拷贝的深度实践)
  • 华为OD机试真题——单词接龙(首字母接龙)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • 股指期货移仓换月技巧是什么?
  • CUDA编程笔记(1)--最简单的核函数
  • 大模型RL方向面试题90道
  • Filter和Interceptor详解(一文了解执行阶段及其流程)
  • CVE-2024-36467 Zabbix权限提升
  • java枚举和mybaits-plus结合实现映射输出和存储
  • VScode怎么运行一个c语言程序
  • ChatGPT与认知科学:人机协同的未来图景
  • STM32 IIC总线死锁问题总结
  • 洛谷——P3372 【模板】线段树 1