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

在FreeRTOS 中多事件组的用法详解

在 FreeRTOS 中,可以创建多个事件组,且这是常见的设计模式。事件组的数量仅受限于系统内存资源(每个事件组占用约 12-16 字节 RAM)。以下是关键细节和最佳实践:


1. 创建多个事件组的实现方法

1.1 动态创建(推荐)
#include "FreeRTOS.h"
#include "event_groups.h"

// 创建两个独立的事件组
EventGroupHandle_t xEventGroup1 = xEventGroupCreate();
EventGroupHandle_t xEventGroup2 = xEventGroupCreate();
1.2 静态创建(需预先分配内存)
StaticEventGroup_t xEventGroupBuffer1, xEventGroupBuffer2;
EventGroupHandle_t xEventGroup1 = xEventGroupCreateStatic(&xEventGroupBuffer1);
EventGroupHandle_t xEventGroup2 = xEventGroupCreateStatic(&xEventGroupBuffer2);

2. 多事件组的典型应用场景

2.1 模块化设计
  • 场景:不同功能模块使用独立的事件组,避免事件位冲突。
    // 传感器模块专用事件组
    #define SENSOR_DATA_READY_BIT (1 << 0)
    EventGroupHandle_t xSensorEventGroup = xEventGroupCreate();
    
    // 通信模块专用事件组
    #define NETWORK_CONNECTED_BIT (1 << 0)
    EventGroupHandle_t xNetworkEventGroup = xEventGroupCreate();
    
2.2 多任务独立同步
  • 场景:每个任务等待自己专属的事件组,减少耦合。
    void vTaskA(void *pvParameters) {
        while (1) {
            // 等待事件组1的 BIT_0
            xEventGroupWaitBits(xEventGroup1, BIT_0, pdTRUE, pdTRUE, portMAX_DELAY);
            // 处理事件...
        }
    }
    
    void vTaskB(void *pvParameters) {
        while (1) {
            // 等待事件组2的 BIT_1
            xEventGroupWaitBits(xEventGroup2, BIT_1, pdTRUE, pdTRUE, portMAX_DELAY);
            // 处理事件...
        }
    }
    

3. 多事件组的资源管理与优化

3.1 内存占用
  • 每个事件组占用约 12-16 字节 RAM(具体取决于硬件架构)。
  • 建议:在资源受限的系统中,避免过度创建事件组。可通过复用事件位或合并逻辑减少数量。
3.2 事件位规划
  • 独立分配:为每个事件组单独定义事件位,避免跨组混淆:
    // 事件组1的事件位
    #define GROUP1_BIT0 (1 << 0)
    #define GROUP1_BIT1 (1 << 1)
    
    // 事件组2的事件位
    #define GROUP2_BIT0 (1 << 0)
    
3.3 错误处理
  • 检查事件组创建是否成功:
    if (xEventGroup1 == NULL) {
        // 内存不足,处理错误
    }
    

4. 多事件组 vs 单一事件组

场景多事件组单一事件组
事件位冲突风险低(事件位独立)高(需全局管理事件位)
代码可维护性高(模块化设计)低(逻辑集中)
内存消耗较高(每个组占用独立内存)低(仅一个组)
适用场景复杂系统、多模块协作简单系统、少量事件

5. 完整示例:多事件组控制

// 定义两个事件组和各自的事件位
EventGroupHandle_t xMotorEventGroup, xSensorEventGroup;
#define MOTOR_START_BIT (1 << 0)
#define SENSOR_DATA_READY_BIT (1 << 0)

void vMotorTask(void *pvParameters) {
    while (1) {
        // 等待电机启动事件
        xEventGroupWaitBits(xMotorEventGroup, MOTOR_START_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
        // 启动电机...
    }
}

void vSensorTask(void *pvParameters) {
    while (1) {
        // 等待传感器数据就绪
        xEventGroupWaitBits(xSensorEventGroup, SENSOR_DATA_READY_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
        // 处理数据...
    }
}

void vControlTask(void *pvParameters) {
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(1000));
        // 触发电机启动
        xEventGroupSetBits(xMotorEventGroup, MOTOR_START_BIT);
        // 触发传感器数据就绪
        xEventGroupSetBits(xSensorEventGroup, SENSOR_DATA_READY_BIT);
    }
}

int main() {
    // 创建事件组
    xMotorEventGroup = xEventGroupCreate();
    xSensorEventGroup = xEventGroupCreate();

    // 创建任务
    xTaskCreate(vMotorTask, "Motor", 1024, NULL, 2, NULL);
    xTaskCreate(vSensorTask, "Sensor", 1024, NULL, 2, NULL);
    xTaskCreate(vControlTask, "Control", 1024, NULL, 1, NULL);

    vTaskStartScheduler();
    return 0;
}

结论

在 FreeRTOS 中,创建多个事件组是完全可行的,且是管理复杂系统事件的有效手段。合理使用多事件组可以:

  1. 降低模块间耦合度
  2. 避免事件位冲突
  3. 提升代码可维护性

唯一需要注意的是:在资源受限的嵌入式系统中,需平衡事件组数量和内存消耗

http://www.dtcms.com/a/95950.html

相关文章:

  • 2025.3.27-2025.3.30
  • C语言基础—构造类型
  • ubuntu 安装 g++
  • QT6使用Mysql全流程
  • StarRocks 证书SRCA和SRCP
  • 内容中台的数字化管理价值是什么?
  • UniApp开发多端应用——流式语音交互场景优化
  • uvm configuration
  • 线程同步——条件变量
  • supabase新增用户的完整流程和注册
  • Pycharm(七):几个简单案例
  • 从排泄危机到数字免疫:解码餐饮业“全息食安大脑“的进化逻辑
  • SQL 链接服务器的查询提示“不允许使用远程表值函数调用”(NOLOCK)
  • 【Deepseek】Deepseek学习
  • vscode连接服务器失败问题解决
  • JavaScript中闭包的使用
  • 【vLLM 学习】快速入门
  • React19源码系列之Hooks(useRef)
  • SQL中累计求和与滑动求和函数sum() over()的用法
  • WebRTC简介及应用
  • 惠购供应链 SAAS 系统正式上线,构建数字商业生态版图
  • InfluxDB OSS v2的数据写入与查询——以C#为例操作
  • uvm基本知识
  • react 封装无缝滚动组件
  • get_seed协议
  • 躺平生产力
  • 如何一键安装所有Python项目的依赖!
  • 5.1 WPF路由事件以及文本样式
  • C笔记20250325
  • Golang使用 ip2region 查询IP的地区信息