FreeRTOS学习笔记-事件组
概述
事件组允许任务在“阻塞”状态下等待一个或多个事件的组合发生。当事件发生时,事件组解除阻塞所有等待同一事件或事件组合的任务。
关键函数说明
#include "freertos/event_groups.h"
//创建事件组
EventGroupHandle_t xEventGroupCreate( void );// 如果configUSE_16_BIT_TICKS==1事件组为8bit,否则为24bit
//设置事件bit
EventBits_t xEventGroupSetBits(
EventGroupHandle_t xEventGroup,//事件组句柄
const EventBits_t uxBitsToSet //要设置的事件组bit
);
//等待事件bit
EventBits_t xEventGroupWaitBits(
const EventGroupHandle_t xEventGroup,//事件组句柄
const EventBits_t uxBitsToWaitFor,//需要等待的bit
const BaseType_t xClearOnExit,//函数执行完是否清除等待bit,pdTRUE==clear ;pdFALSE==不清除
const BaseType_t xWaitForAllBits,//pdTRUE== 所有等待bit被设置时返回(AND);pdFALSE==任意1个等待bit被设置时返回(OR)
TickType_t xTicksToWait //等待时间
);
//事件同步
EventBits_t xEventGroupSync(
EventGroupHandle_t xEventGroup,//事件组句柄
const EventBits_t uxBitsToSet,//被设置的bit
const EventBits_t uxBitsToWaitFor,//等待的bit
TickType_t xTicksToWait );//等待时间
课程示例
事件组等待(Event Group Wait)
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/semphr.h"
#include "freertos/event_groups.h"
#define BIT_0 (1 << 0)
#define BIT_4 (1 << 4)
EventGroupHandle_t EventGroup1;
void mytask1(void *pvParameter)
{
EventBits_t uxBits;
while (1)
{
uxBits = xEventGroupWaitBits(
EventGroup1, /* The event group being tested. */
BIT_0 | BIT_4, /* The bits within the event group to wait for. */
pdTRUE, /* Clear */
pdFALSE, /* OR-- Don't wait for both bits, either bit will do. */
portMAX_DELAY); /* */
if ((uxBits & (BIT_0 | BIT_4)) == (BIT_0 | BIT_4))
{
/* bit 0 和 4 都被设置*/
printf("task1 bit0 and bit4 is set \n");
printf("----------------------------\n");
}
else if ((uxBits & BIT_0) != 0)
{
/* 仅BIT_0 was set. */
printf("task1 just bit0 is set \n");
printf("----------------------------\n");
}
else if ((uxBits & BIT_4) != 0)
{
/* 仅BIT_4 was set. */
printf("task1 just bit4 is set \n");
printf("----------------------------\n");
}
else
{
/*超时*/
printf("task1 wait time out \n");
printf("----------------------------\n");
}
}
}
void mytask2(void *pvParameter)
{
vTaskDelay(2000 / portTICK_PERIOD_MS);
xEventGroupSetBits(EventGroup1, BIT_0 | BIT_4);
printf("task2 set bit0 and bit4 \n");
vTaskDelay(2000 / portTICK_PERIOD_MS);
xEventGroupSetBits(EventGroup1, BIT_0);
printf("task2 set bit0 \n");
vTaskDelay(2000 / portTICK_PERIOD_MS);
xEventGroupSetBits(EventGroup1, BIT_4);
printf("task2 set bit4 \n");
vTaskDelay(2000 / portTICK_PERIOD_MS);
vTaskDelete(NULL);
}
void app_main(void)
{
EventGroup1 = xEventGroupCreate(); //创建事件组1
if (EventGroup1 != NULL)
{
xTaskCreatePinnedToCore(mytask1, "mytask1", 1024 * 5, NULL, 1, NULL, 0); //最后一个参数是Core ID
xTaskCreatePinnedToCore(mytask2, "mytask2", 1024 * 5, NULL, 1, NULL, 0);
}
}
效果
task2 set bit0 and bit4
task1 bit0 and bit4 is set
----------------------------
task2 set bit0
task1 just bit0 is set
----------------------------
task2 set bit4
task1 just bit4 is set
----------------------------
任务2每隔2s设置一次事件bit,任务1均能正常接收。
事件组同步(Event Group Sync)
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/semphr.h"
#include "freertos/event_groups.h"
#define TASK_0_BIT (1 << 0)
#define TASK_1_BIT (1 << 1)
#define TASK_2_BIT (1 << 2)
#define ALL_SYNC_BITS (TASK_0_BIT | TASK_1_BIT | TASK_2_BIT)
EventGroupHandle_t EventGroup1;
void mytask0(void *pvParameter)
{
while (1)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
xEventGroupSync(
EventGroup1, //事件组句柄
TASK_0_BIT, //被设置的bit
ALL_SYNC_BITS, //等待的bit
portMAX_DELAY); //等待时间
printf("task0 sync over \n");
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void mytask1(void *pvParameter)
{
while (1)
{
vTaskDelay(2000 / portTICK_PERIOD_MS);
xEventGroupSync(
EventGroup1, //事件组句柄
TASK_1_BIT, //被设置的bit
ALL_SYNC_BITS, //等待的bit
portMAX_DELAY); //等待时间
printf("task1 sync over \n");
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void mytask2(void *pvParameter)
{
while (1)
{
vTaskDelay(3000 / portTICK_PERIOD_MS);
xEventGroupSync(
EventGroup1, //事件组句柄
TASK_2_BIT, //被设置的bit
ALL_SYNC_BITS, //等待的bit
portMAX_DELAY); //等待时间
printf("task2 sync over \n");
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
EventGroup1 = xEventGroupCreate(); //创建事件组1
if (EventGroup1 != NULL)
{
xTaskCreatePinnedToCore(mytask0, "mytask0", 1024 * 5, NULL, 6, NULL, 0); //最后一个参数是Core ID
xTaskCreatePinnedToCore(mytask1, "mytask1", 1024 * 5, NULL, 6, NULL, 0);
xTaskCreatePinnedToCore(mytask2, "mytask2", 1024 * 5, NULL, 6, NULL, 0);
}
int i = 1;
while (1)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("%d \n", i);
i++;
}
}
效果
1
2
task2 sync over
task0 sync over
task1 sync over
3
4
5
6
7
8
9
10
task2 sync over
task0 sync over
task1 sync over
11
12
13
14
15
16
17
18
task2 sync over
task0 sync over
task1 sync over
19
20
21
22
23
24
主程序循环打印秒计数,可见任务1、2、3在第3s进行了同步,反复运行。