FreeRTOS 事件标志组实例


FreeRTOS 事件标志组实例

一、事件标志组概述

事件标志组是FreeRTOS中用于任务间同步与通信的一种机制。它通过一组位(bit)来表示不同的事件,每个位可以独立设置或清除,代表特定事件的发生状态。任务或中断服务例程(ISR)可以读取这些位,从而判断特定事件是否已经发生,进而采取相应的动作。
事件标志组的主要特点包括:
多事件支持:一个事件标志组可以包含多个事件位,允许同时处理多个事件。
灵活性:可以使用位掩码来一次等待或清除多个事件标志位,提供了更大的灵活性。
高效性:事件标志组的操作通常不涉及复杂的上下文切换或内存分配,因此具有较高的效率。

二、事件标志组的创建与配置

在FreeRTOS中,使用xEventGroupCreate函数来创建一个新的事件标志组对象。该函数返回一个指向该对象的句柄,供后续操作使用。如果创建失败,则返回NULL。
EventGroupHandle_t xEventGroupCreate(void);

此外,FreeRTOS还提供了静态内存分配的方式来创建事件标志组,即xEventGroupCreateStatic函数。这种方式适用于需要在静态内存池中分配资源的场景。

三、事件标志组的操作

设置事件标志位

使用xEventGroupSetBits函数来设置一个或多个事件标志位。该函数接受事件标志组句柄和要设置的事件位作为参数。
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet);

清除事件标志位

使用xEventGroupClearBits函数来清除一个或多个事件标志位。该函数同样接受事件标志组句柄和要清除的事件位作为参数。
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear);

等待事件标志位

使用xEventGroupWaitBits函数来等待一个或多个事件标志位被设置。该函数允许任务阻塞(等待)直到指定的事件位被设置,或者等待超时。
EventBits_t xEventGroupWaitBits(
EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait
);

xEventGroup:事件标志组句柄。
uxBitsToWaitFor:等待的事件标志位,可以使用逻辑或运算符等待多个事件标志位。
xClearOnExit:成功等待到事件标志位后,是否清除事件组中对应的事件标志位。
xWaitForAllBits:是否等待uxBitsToWaitFor中的所有事件标志位都被设置。
xTicksToWait:等待的阻塞时间,单位为时钟节拍周期。

四、实例分析

以下是一个简单的实例,展示了如何在FreeRTOS中使用事件标志组来实现任务间的同步与通信。

#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#define START_TASK_PRIO 1
#define START_STK_SIZE 128
TaskHandle_t StartTask_Handler;
EventGroupHandle_t FlagEventGroup;
#define BIT_0 0x01
#define BIT_1 0x02
#define BIT_2 0x04
void start_task(void *pvParameters)
{
    EventBits_t FlagVal;
    FlagEventGroup = xEventGroupCreate(); // 创建事件标志组
    if (FlagEventGroup == NULL)
    {
        // 处理创建失败的情况
    }
    // 创建其他任务(略)
   while(1)
    {
        // 设置事件标志位(模拟事件发生)
        FlagVal = xEventGroupSetBits(FlagEventGroup, BIT_0 | BIT_1);
        printf("事件标志组设置值为:%d\r\n", FlagVal);
        // 清除事件标志位(可选)
        xEventGroupClearBits(FlagEventGroup, BIT_0 | BIT_1);

        vTaskDelay(200); // 延时
    }
}
void task1(void *pvParameters)
{
    EventBits_t uxBits;
    while(1)
    {
        // 等待事件标志位BIT_0被设置
        uxBits = xEventGroupWaitBits(
            FlagEventGroup,
            BIT_0,
            pdTRUE, // 清除事件标志位
            pdFALSE, // 等待任意一位被设置
            portMAX_DELAY // 无限期等待
        );
        if (uxBits & BIT_0)
        {
            // 处理事件BIT_0
            printf("任务1:事件BIT_0发生\r\n");
        }
        vTaskDelay(500); // 延时
    }
}
void task2(void *pvParameters)
{
    EventBits_t uxBits;
   while(1)
    {
        // 等待事件标志位BIT_1被设置
        uxBits = xEventGroupWaitBits(
            FlagEventGroup,
            BIT_1,
            pdTRUE, // 清除事件标志位
            pdFALSE, // 等待任意一位被设置
            portMAX_DELAY // 无限期等待
        );
        if (uxBits & BIT_1)
        {
            // 处理事件BIT_1
            printf("任务2:事件BIT_1发生\r\n");
        }
        vTaskDelay(500); // 延时
    }
}
int main(void)
{
    // 创建启动任务
    xTaskCreate(
        start_task,       // 任务函数
        "StartTask",      // 任务名称
        START_STK_SIZE,   // 堆栈大小
        NULL,             // 任务输入参数
        START_TASK_PRIO,  // 任务优先级
        &StartTask_Handler // 任务句柄
    );
    // 创建其他任务(略)
    // 启动调度器
    vTaskStartScheduler();
    return 0;
}

在这个实例中,我们创建了一个事件标志组FlagEventGroup,并在start_task中模拟了事件的发生(设置事件标志位BIT_0和BIT_1)。task1和task2分别等待事件标志位BIT_0和BIT_1被设置,并在事件发生时进行相应的处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值