• 使用队列集进行传递数据或信号同步


    使用队列集进行传递数据或信号同步

    概述

    队列集适用于多个发送者、多种数据(信号)类型向同一个接收者发送数据(信号)的情况。

    队列集中可以包含队列和一些信号量。通过队列集,可以实现一个任务监听多个通信组件,从多个通信组件获取信号和数据的功能。

    如图所示,队列集可以同时等待前述 queue、Semaphores、ringbuf 上的信号和数据,当其中一个组件有信号时,通过队列集返回的句柄可以从对应的组件上获取信号。
    在这里插入图片描述

    主要的 API 包括:

    /*
    * 创建队列集
    */
    QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength // 指定一次可以排队的最大事件数。要绝对确定事件不会丢失 uxEventQueue长度应设置为添加到集合中的队列长度的总和,其中二进制信号量和互斥体的长度为 1,计数信号量的长度由其最大计数值设置(如最大计数为 5 的计数信号量,长度为5)。
                   );
    
    /*
    * 添加对象到队列集,注意将队列和信号量添加到队列集时,它们必须为空。
    */
    BaseType_t xQueueAddToSet(
                              QueueSetMemberHandle_t xQueueOrSemaphore, // 要添加到队列集的队列或信号量的句柄
                              QueueSetHandle_t xQueueSet // 队列集的句柄
                          );
    
    /*
    * 从队列集中移除对象,注意将队列和信号量移除队列集时,它们必须为空。
    */
    BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_txQueueOrSemaphore, // 要移除队列集的队列或信号量的句柄
                                   QueueSetHandle_txQueueSet)// 队列集的句柄
    
    
    /*
    * 从队列集的成员中选择一个有效的队列或信号量,没有有效的成员时,将持续等待至最长时间后返回
    */
    QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_txQueueSet, // 队列集
                                               const 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

    需求及功能解析

    通常,队列集使用的并不多,因为总是可以找到功能类似的通信组件来代替它。比如创建一个下述的结构体:

    typedef struct IP_TASK_COMMANDS
    {
        eIPEvent_t eEventType; /* 标识事件类型 */
        void *pvData; /* 指向与事件对应的数据. */
    } xIPStackEvent_t;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后通过队列来处理不同的消息。但是如果你的确有这种监听多种通信组件的需求,你仍然可以尝试使用队列集来完成这项功能。

    示例解析

    示例创建了多个队列,并将这些队列加入到队列集中。任务1、任务2 分别向不同的队列发送数据,任务3 通过队列集同时监听任务1、任务2发送的数据并打印。

    This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 294408 bytes
    TASK1: send=0
    TASK2: send=0
    TASK3: recv queue1 and value=0
    TASK3: recv queue2 and value=0
    TASK1: send=1
    TASK2: send=1
    TASK3: recv queue1 and value=1
    TASK3: recv queue2 and value=1
    TASK1: send=2
    TASK2: send=2
    TASK3: recv queue1 and value=2
    TASK3: recv queue2 and value=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    讨论

    允许将队列、信号量、ringbuf加入到队列集,但为什么没有提到将 streambuf、messagebuf 加入到队列集呢?

    答案你可以在过去讲述 streambuf、messagebuf 的章节找到答案,欢迎读者留言公布答案。

    总结

    1)允许将队列、信号量、ringbuf加入到队列集,通过队列集实现同时从多个通信组件接收信号或数据的目的。

    资源链接

    1)Learning-FreeRTOS-with-esp32 系列博客介绍
    2)对应示例的 code 链接 (点击直达代码仓库)

    3)下一篇:FreeRTOS 任务任务同步与数据传递总结

  • 相关阅读:
    linux环境下文件传输与环境命令
    ubuntu基本配置
    Linux基础指令(五)
    Mysql知识进阶
    创新实战|从5大维度成功实现传统研发向敏捷研发转型
    大佬的职场经验
    1024程序员狂欢节有好礼 | 前沿技术、人工智能、集成电路科学与芯片技术、新一代信息与通信技术、网络空间安全技术
    Unity拓展编辑器 找出未被引用的资源列表
    希望所有计算机专业学生都去这些网站刷题
    vue 2.0
  • 原文地址:https://blog.csdn.net/wangyx1234/article/details/127710306