一、必须遵守的 完整执行顺序

1. 定义事件组句柄

2. 创建事件组

3. 在任务/中断中 设置事件位

4. 在任务中 等待事件位

5.(可选)删除事件组

二、逐步骤代码 + 解释

1. 头文件 + 定义句柄

// 必须包含
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"

// 1. 定义事件组句柄(全局,方便多个任务访问)
static EventGroupHandle_t xl9555_event_group = NULL;

// 定义事件位(自己起名)
#define XL9555_INT_BIT  (1 << 0)  // bit0 = 中断触发
#define XL9555_INIT_BIT (1 << 1)  // bit1 = 初始化完成

2. 创建事件组(必须在调度器开始后)

位置:app_main 或初始化函数里

// 2. 创建事件组
xl9555_event_group = xEventGroupCreate();

// 判断是否创建成功
if (xl9555_event_group == NULL) {
    // 创建失败(内存不足)
    return;
}

3. 设置事件位(中断 / 任务里)

你这个项目是 XL9555 中断触发,所以放在中断服务函数里:

// 中断服务函数
static void IRAM_ATTR xl9555_int_isr_handler(void* arg)
{
    // 在中断中 设置事件位 !!!
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    xEventGroupSetBitsFromISR(
        xl9555_event_group,
        XL9555_INT_BIT,
        &xHigherPriorityTaskWoken
    );

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

4. 等待事件位(必须在 任务 里)

// 等待事件位的任务
void xl9555_task(void *arg)
{
    while (1) {
        // 4. 等待事件位
        EventBits_t bits = xEventGroupWaitBits(
            xl9555_event_group,  // 事件组
            XL9555_INT_BIT,      // 等待哪个bit
            pdTRUE,              // 等待后自动清除bit
            pdFALSE,             // 不需要全部bit都满足
            portMAX_DELAY        // 永久等待
        );

        // 判断是否是我们要的事件
        if (bits & XL9555_INT_BIT) {
            // 中断触发了!
            printf("XL9555 引脚电平变化\n");
        }
    }
}

三、最精简总结(背下来)

你现在的工程是:XL9555 中断 → 通知主程序处理

用事件组最完美,顺序如下:

  1. app_main → 创建事件组
  2. xl9555_init → 初始化 I2C + 注册中断
  3. 中断触发 → SetBitsFromISR
  4. 业务任务 → WaitBits → 处理 IO 变化

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐