【家中宝】 esp32s2 freertos任务之间的通信 Event Groups
用操作系统,就会发现,任务与任务之间,线程与线程之间,中断和任务之间都不能直接的用全局变量来整。那样会出问题的。
那怎么办?freertos就给了写方法。这里就esp32s2来简单的聊一下这个问题。虽然我也不是那么的懂。
本章中只讨论一下事件组 Event Groups的使用。因为wifi的例子里面就用到了这个。其实每个程序中可以用很多个事件组的。这里就用两个。
事件组的用途很广可以从中断中设置,从任务中判断接收。从任务中设置,从任务中判断接收。只是函数不一样。每个事件组有8位或24位事件位(可以设置)。
这个很适合于为信号传递,比如按键的按下就是一个很好的例子:按键任务中有24个按键,每个按键按下对于一个事件标记发送,其他任务中就可以监测使用它。
还有可以使用这个进行任务的同步。
更多资料可以参考:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/system/freertos.html?highlight=event%20groups#_CPPv418xEventGroupSetBits18EventGroupHandle_tK11EventBits_t
具体使用如下代码
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"//这个头文件是一定要的
#include "esp_system.h"
#include "esp_spi_flash.h"
EventGroupHandle_t xEventGroup1;//定义事件组句柄
EventGroupHandle_t xEventGroup2;
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
//下面函数判断时间是否发生和处理
void aFunction( EventGroupHandle_t xEventGroup )
{
EventBits_t uxBits;
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
uxBits = xEventGroupWaitBits(
xEventGroup, // 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.
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{
printf("xEventGroup xEventGroupWaitBits() returned because both bits were set.\n");
}
else if( ( uxBits & BIT_0 ) != 0 )
{
printf("xEventGroup xEventGroupWaitBits() returned because just BIT_0 was set.\n");
}
else if( ( uxBits & BIT_4 ) != 0 )
{
printf("xEventGroup xEventGroupWaitBits() returned because just BIT_4 was set.\n");
}
else
{
}
uxBits = xEventGroupWaitBits(
xEventGroup2, // 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.
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{
printf("xEventGroup2 xEventGroupWaitBits() returned because both bits were set.\n");
}
else if( ( uxBits & BIT_0 ) != 0 )
{
printf("xEventGroup2 xEventGroupWaitBits() returned because just BIT_0 was set.\n");
}
else if( ( uxBits & BIT_4 ) != 0 )
{
printf("xEventGroup2 xEventGroupWaitBits() returned because just BIT_4 was set.\n");
}
else { }
}
// Task to create a queue and post a value.
void vATask( void *pvParameters )
{
while(1)
{ //这里定期的设置和清除事件标志位 以便任务vADifferentTask能收到事件标记
xEventGroupSetBits(
xEventGroup1, // The event group being updated.
BIT_0 | BIT_4 );// The bits being set.
printf("xEventGroupSetBits xEventGroup1 BIT_0 | BIT_4\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
xEventGroupClearBits(
xEventGroup1, // The event group being updated.
BIT_0 | BIT_4 );// The bits being cleared.
printf("xEventGroupClearBits xEventGroup1 BIT_0 | BIT_4\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
xEventGroupSetBits(
xEventGroup2, // The event group being updated.
BIT_0 | BIT_4 );// The bits being set.
printf("xEventGroupSetBits xEventGroup2 BIT_0 | BIT_4\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
xEventGroupClearBits(
xEventGroup2, // The event group being updated.
BIT_0 | BIT_4 );// The bits being cleared.
printf("xEventGroupClearBits xEventGroup2 BIT_0 | BIT_4\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
// Task to receive from the queue.
void vADifferentTask( void *pvParameters )
{
while(1)
{
printf("xEventGroup1 。。。。。。。。。。。。。。。。。\n");
aFunction( xEventGroup1 );//定期调用aFunction( xEventGroup1 )判断是否有事件产生
printf("xEventGroup2 。。。。。。。。。。。。。。。。。\n");
aFunction( xEventGroup2 );//定期调用aFunction( xEventGroup2 )判断是否有事件产生
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
printf("Hello world!\n");
/* Print chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
//这里创建两个任务,创建两个事件组, 之所以创建两个事件组是为了说明程序中能创建多个事件组。
xTaskCreate(vATask, "vATask", 1024*2, NULL, configMAX_PRIORITIES-3, NULL);
xTaskCreate(vADifferentTask, "vADifferentTask", 1024*2, NULL, configMAX_PRIORITIES-4, NULL);
xEventGroup1 =xEventGroupCreate();
xEventGroup2 =xEventGroupCreate();
while(1){
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
本帖最后由 damiaa 于 2022-9-14 11:12 编辑
FreeRTOS的事件组就和RTThread的事件集一样。这个功能用途确实多。