304 6.3 xEventGroupCreate()
[[FreeRTOS_Reference_Manual_V10.0.0.pdf#page=304&selection=0,3,4,19|FreeRTOS_Reference_Manual_V10.0.0, page 304]]
FreeRTOS中的事件组时一种用于任务间同步和通信的机制,它允许多个任务通过设置和等待特定的事件来协调它们的行为。
现在有三个任务,它们分别是:
事件组的功能:
EventGroupHandle_t eventGroup = xEventGroupCreate();
#define EVENT_BIT_BREAKFAST_READY (1 << 0)
#define EVENT_BIT_CHILD_READY (1 << 1)
xEventGroupSetBits(eventGroup, EVENT_BIT_BREAKFAST_READY);
xEventGroupSetBits(eventGroup, EVENT_BIT_CHILD_READY);
xEventGroupWaitBits(eventGroup,
EVENT_BIT_BREAKFAST_READY | EVENT_BIT_CHILD_READY,
pdTRUE,
pdTRUE,
portMAX_DELAY);
xEventGroupCreate()#include "FreeRTOS.h"
#include "event_groups.h"
EventGroupHandle_t xEventGroupCreate( void );
函数说明:
EventGroupHandle_t中。设置configUSE_16_BIT_TICKS为1则事件组有8位,设置为0则有24位。参数:
None返回值:
NULL:堆内存不足,创建事件组失败。Any other value:返回一个事件组句柄。xEventGroupSetBits()#include "FreeRTOS.h"
#include "event_groups.h"
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
函数说明:
参数:
xEventGroup:事件组句柄。uxBitsToSet:要设置的事件位。返回值:
NonexEventGroupWaitBits()#include "FreeRTOS.h"
#include "event_groups.h"
EventBits_t xEventGroupWaitBits( const EventGroupHandle_t xEventGroup,
const Eventbits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait );
函数说明:
参数:
xEventGroup:事件组句柄。uxBitsToWaitFor:设置这个值可以检查多个Bit是否被置位。
0x05则意味着检查 bit 0,并且/或者 bit 2。因为 0x05 --> 0101。0x07则意味着检查 bit 0 并且/或者 bit 1 并且/或者 bit 3。因为 0x07 --> 0111。xClearOnExit:如果此形参被设置为pdTRUE,是否在退出时清零对应的位。xWaitAllBits:要求同时满足还是某一个条件满足。设置为pdTRUE,则意味着要满足所有位是否符合;设置为pdFALSE则意味着只要要有一个 Bit 被触发。xTicksToWait:阻塞时间。返回值:
Any Value:等待的事件位被设置或阻塞时间到期时事件组的值。如果在调用任务离开阻塞状态和退出此函数之间,优先级更高的任务或者中断更改了事件位的值,则此函数的返回值将不同于事件组的返回值。#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
static EventGroupHandle_t event_group; // 事件组句柄
static SemaphoreHandle_t recursive_mutex; // 递归互斥锁句柄
#define EVENT_BIT_BREAKFAST_READY (1 << 0) // 早餐准备好事件信号
#define EVENT_BIT_CHILD_READY (1 << 1) // 孩子准备好事件信号
void mom_task(void *pvPara)
{
xSemaphoreTakeRecursive(recursive_mutex, portMAX_DELAY); // 获取递归互斥锁
printf("[MOM TASK]: Begin.\n");
xEventGroupSetBits(event_group, EVENT_BIT_BREAKFAST_READY); // 向事件组发送事件信号,即“早餐准备好了”
vTaskDelay(pdMS_TO_TICKS(2000));
printf("[MOM TASK]: Breakfast ready.\n");
vTaskDelay(pdMS_TO_TICKS(1000));
xSemaphoreGiveRecursive(recursive_mutex); // 释放递归互斥锁
vTaskDelete(NULL);
}
void child_task(void *pvPara)
{
xSemaphoreTakeRecursive(recursive_mutex, portMAX_DELAY); // 获取递归互斥锁
printf("[CHILD TASK]: Begin.\n");
xEventGroupSetBits(event_group, EVENT_BIT_CHILD_READY); // 向事件组发送事件信号,即“孩子准备好了”
vTaskDelay(pdMS_TO_TICKS(2000));
printf("[CHILD TASK]: Child ready.\n");
vTaskDelay(pdMS_TO_TICKS(2000));
xSemaphoreGiveRecursive(recursive_mutex); // 释放递归互斥锁
vTaskDelete(NULL);
}
void father_task(void *pvPara)
{
xSemaphoreTakeRecursive(recursive_mutex, portMAX_DELAY); // 获取递归互斥锁
printf("[FATHER TASK]: Begin.\n");
xEventGroupWaitBits(event_group, 0x03, pdTRUE, pdTRUE, portMAX_DELAY); // 向事件组发送信号,即“可以去学校了”
vTaskDelay(pdMS_TO_TICKS(2000));
printf("[FATHER TASK]: All ready, go to school.\n");
vTaskDelay(pdMS_TO_TICKS(2000));
xSemaphoreGiveRecursive(recursive_mutex); // 释放递归互斥锁
vTaskDelete(NULL);
}
void app_main(void)
{
event_group = xEventGroupCreate();
recursive_mutex = xSemaphoreCreateRecursiveMutex();
vTaskSuspendAll();
xTaskCreate(mom_task, "Mon task", 2048, NULL, 2, NULL);
xTaskCreate(child_task, "Child task", 2048, NULL, 2, NULL);
xTaskCreate(father_task, "Father task", 2048, NULL, 1, NULL);
xTaskResumeAll();
}
代码中同时应用了递归互斥锁来对任务非阻塞。