• 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 );//等待时间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    课程示例

    事件组等待(Event Group Wait)

    #include 
    #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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    效果

    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 
    ----------------------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    任务2每隔2s设置一次事件bit,任务1均能正常接收。

    事件组同步(Event Group Sync)

    #include 
    #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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    效果

    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进行了同步,反复运行。

  • 相关阅读:
    动态规划-买卖股票系列
    全志XR806+TinyMaix,在全志XR806上实现ML推理
    Java之SpringCloud Alibaba【六】【Alibaba微服务分布式事务组件—Seata】
    Redis系列之常见数据类型应用场景
    大数据Hadoop系列之Hadoop Web控制台添加身份验证
    docker 笔记11: Docker容器监控之CAdvisor+InfluxDB+Granfana
    一套简单的机器人短途路径规划算法
    python项目如何打包成exe、踩坑总结!
    k8s基础知识扫盲及企业落地实践分享
    前端HTML5 +CSS3 3. HMTL基础 1 列表标签 && 2 表格标签
  • 原文地址:https://blog.csdn.net/ai_ljh/article/details/126806627