文章目录
- 事件标志组
- 创建事件标志组 xEventGroupCreate
- 将指定的事件位清零 xEventGroupClearBits
- 将指定的事件位置 1 xEventGroupSetBits
- 获取事件标志组值 xEventGroupGetBits
- 等待指定的事件位 xEventGroupWaitBits
- 代码示例
事件标志组
事件标志位
事件位用来表明某个事件是否发生,事件位通常用作事件标志,比如下面的几个例子:
- 当收到一条消息并且把这条消息处理掉以后就可以将某个位(标志)置 1,当队列中没有消息需要处理的时候就可以将这个位(标志)置 0。
- 当把队列中的消息通过网络发送输出以后就可以将某个位(标志)置 1,当没有数据需要从网络发送出去的话就将这个位(标志)置 0。
- 现在需要向网络中发送一个心跳信息,将某个位(标志)置 1。现在不需要向网络中发送心跳信息,这个位(标志)置 0。
事件组
一个事件组就是一组的事件位,事件组中的事件位通过位编号来访问,同样,以上面列出的三个例子为例:
- 事件标志组的 bit0 表示队列中的消息是否处理掉。
- 事件标志组的 bit1 表示是否有消息需要从网络中发送出去。
- 事件标志组的 bit2 表示现在是否需要向网络发送心跳信息。
事件标志组的数据类型为 EventGroupHandle_t
,当 configUSE_16_BIT_TICKS
为 1 的时候事件标志组可以存储 8 个事件位,当 configUSE_16_BIT_TICKS
为 0 的时候事件标志组存储 24个事件位。
创建事件标志组 xEventGroupCreate
创建一个事件标志组
EventGroupHandle_t xEventGroupCreate( void )
参数:
无
返回值:
NULL: 事件标志组创建失败。
其他值: 创建成功的事件标志组句柄。
将指定的事件位清零 xEventGroupClearBits
将事件标志组中的指定事件位清零
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear );
参数:
xEventGroup:要操作的事件标志组的句柄。
uxBitsToClear :要清零的事件位,比如要清除 bit3 的话就设置为 0X08。可以同时清除多个bit,如设置为 0X09 的话就是同时清除 bit3 和 bit0。
返回值:
任何值:将指定事件位清零之前的事件组值。
将指定的事件位置 1 xEventGroupSetBits
设置指定的事件位为 1
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet );
参数:
xEventGroup:要操作的事件标志组的句柄。
uxBitsToClear:指定要置 1 的事件位,比如要将 bit3 值 1 的话就设置为 0X08。可以同时将多个 bit 置 1,如设置为 0X09 的话就是同时将 bit3 和 bit0 置 1。
返回值:
任何值:在将指定事件位置 1 后的事件组值。
获取事件标志组值 xEventGroupGetBits
获取当前事件标志组的值,也就是各个事件位的值。
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
参数:
xEventGroup:要获取的事件标志组的句柄。
返回值:
任何值:当前事件标志组的值。
等待指定的事件位 xEventGroupWaitBits
调用函数以后如果任务要等待的事件位还没有准备好(置 1 或清零)的话任务就会进入阻塞态,直到阻塞时间到达或者所等待的事件位准备好。
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
const TickType_t xTicksToWait );
参数:
xEventGroup:指定要等待的事件标志组。
uxBitsToWaitFord:指定要等待的事件位,比如要等待bit0和(或)bit2的时候此参数就是0X05,如果要等待 bit0 和(或)bit1 和(或)bit2 的时候此参数就是 0X07。
xClearOnExit:此参数要是为pdTRUE的话,那么在退出此函数之前由参数uxBitsToWaitFor所设置的这些事件位就会清零。如果设置位 pdFALSE 的话这些事件位就不会改变。
xWaitForAllBits:此参数如果设置为 pdTRUE 的话,当 uxBitsToWaitFor 所设置的这些事件位都置 1,或者指定的阻塞时间到的时候函数 xEventGroupWaitBits()才会返回。当此函数为 pdFALSE 的话,只要 uxBitsToWaitFor 所设置的这些事件 位 其 中 的 任 意 一 个 置 1 , 或 者 指 定 的 阻 塞 时 间 到 的 话 函 数xEventGroupWaitBits()就会返回。
xTicksToWait:设置阻塞时间,单位为节拍数。
返回值:
任何值: 返回当所等待的事件位置 1 以后的事件标志组的值,或者阻塞时间到。根据这个值我们就知道哪些事件位置 1 了。如果函数因为阻塞时间到而返回的话那么这个返回值就不代表任何的含义。
代码示例
#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/event_groups.h"
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
/* Declare a variable to hold the created event group. */
EventGroupHandle_t xCreatedEventGroup;
void Task1(void *pvParam)
{
while(1)
{
printf("----------------!\n");
printf("task1 begin to wait!\n");
/* Wait a maximum of 100ms for either bit 0 or bit 4 to be set within the event group. Clear the bits before exiting. */
xEventGroupWaitBits(xCreatedEventGroup, /* The event group being tested. */
BIT_0 | BIT_4, /* The bits within the event group to wait for. */
pdTRUE, /* BIT_0 and BIT_4 should be cleared before returning. */
pdFALSE, /* Don't wait for both bits, either bit will do. */
portMAX_DELAY ); /* Wait a maximum of 100ms for either bit to be set. */
printf("----------------!\n");
printf("in task1, BIT_0 or BIT_4 is set!\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void Task2(void *pvParam)
{
vTaskDelay(pdMS_TO_TICKS(1000));
while(1)
{
printf("----------------!\n");
printf("task2 begin to set bit0!\n");
xEventGroupSetBits(xCreatedEventGroup, BIT_0);
vTaskDelay(pdMS_TO_TICKS(5000));
printf("----------------!\n");
printf("task2 begin to set bit4!\n");
xEventGroupSetBits(xCreatedEventGroup, BIT_4);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
void app_main(void)
{
/* Attempt to create the event group. */
xCreatedEventGroup = xEventGroupCreate();
/* Was the event group created successfully? */
if (xCreatedEventGroup == NULL)
{
/* The event group was not created because there was insufficient FreeRTOS heap available. */
printf("Event group create fail!\n");
}
else
{
/* The event group was created. */
vTaskSuspendAll();
xTaskCreate(Task1, "Task1", 1024 * 5, NULL, 1, NULL);
xTaskCreate(Task2, "Task2", 1024 * 5, NULL, 1, NULL);
xTaskResumeAll();
}
}