FreeRTOS 中的事件组(Event Group)是一种轻量级的同步原语,用于在多个任务之间同步事件。时间组由一个 32 位的二进制数表示,每个二进制位表示一个事件位。可以使用时间组 API 操作事件组,包括设置事件位、清除事件位、等待事件位被设置等。

下面是一些时间组的常用 API:

  1. ​xEventGroupCreate()​​:创建一个事件组,返回一个 EventGroupHandle_t​​ 类型的句柄。

  2. xEventGroupSetBits()​​:设置事件组中的一个或多个事件位。

  3. xEventGroupClearBits()​​:清除事件组中的一个或多个事件位。

  4. xEventGroupWaitBits()​​:等待一个或多个事件位被设置。

  5. ​xEventGroupGetBits()​​:获取事件组中所有事件位的当前值。

  6. ​xEventGroupSync()​​:同步多个任务之间的事件,即等待多个事件组中的事件位均被设置。

下面是一个使用时间组的示例,该示例创建了两个任务,一个任务设置事件位,另一个任务等待事件位被设置:

#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"

#define EXAMPLE_EVENT_BIT (1 << 0)

static EventGroupHandle_t event_group;

static void set_event_task(void *pvParameters)
{
    while (1) {
        // 设置事件位
        xEventGroupSetBits(event_group, EXAMPLE_EVENT_BIT);

        // 等待一段时间
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

static void wait_event_task(void *pvParameters)
{
    while (1) {
        // 等待事件位被设置
        EventBits_t bits = xEventGroupWaitBits(event_group, EXAMPLE_EVENT_BIT, pdTRUE, pdFALSE, portMAX_DELAY);

        // 执行任务
        if (bits & EXAMPLE_EVENT_BIT) {
            // 事件位已被设置
            // TODO: 执行任务
        }
    }
}

void app_main()
{
    // 创建事件组
    event_group = xEventGroupCreate();

    // 创建设置事件位的任务
    xTaskCreate(set_event_task, "set_event_task", 2048, NULL, 10, NULL);

    // 创建等待事件位的任务
    xTaskCreate(wait_event_task, "wait_event_task", 2048, NULL, 10, NULL);
}

在上述示例中,创建了两个任务:set_event_task​​ 和 wait_event_task​​。set_event_task​​ 任务每隔 1 秒设置一次事件位。wait_event_task​​ 任务等待事件位被设置后执行任务。在 wait_event_task​​ 任务中,调用 xEventGroupWaitBits()​​ 函数等待事件位被设置,如果事件位已被设置,则执行任务。

需要注意的是,事件组中的事件位是共享的,因此需要谨慎使用。如果多个任务同时操作同一个事件位,可能会导致竞争条件。为了避免竞争条件,可以使用二进制信号量(Binary Semaphore)或互斥锁(Mutex)等其他同步原语来保护共享资源。