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

  • 相关阅读:
    LabVIEW以编程方式查找系统中DAQ设备的设备名称
    【UV打印机】理光喷头组合说明(16H)
    Oracle实现主键字段自增
    HTML期末大作业——游戏介绍(HTML+CSS+JavaScript) web前端开发技术 web课程设计网页规划与设计 Web大学生网页成品
    计算机毕设 大数据二手房数据爬取与分析可视化 -python 数据分析 可视化
    C Primer Plus(6) 中文版 第10章 数组和指针 10.8 变长数组(VLA)
    计算机毕业设计Java银行招聘系统设计(系统+程序+mysql数据库+Lw文档)
    centos 端口被占用的快速排查方式
    JVM常见面试题
    axios——get、post
  • 原文地址:https://blog.csdn.net/ai_ljh/article/details/126806627