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


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

    概述

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

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

    如图所示,队列集可以同时等待前述 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 任务任务同步与数据传递总结

  • 相关阅读:
    【重温设计模式】迭代器模式及其Java示例
    J2EE从入门到入土01.MySQL安装
    上海亚商投顾:沪指高开低走 钠离子电池、储能概念崛起
    【前段基础入门之】=> 吃透CSS元素盒模型
    新点面试题
    Codesys 数据结构:1.2.4 扩展数据类型之联合体(UNION) 类型详解
    使用 Vue 官方脚手架初始化 Vue3 项目
    试错好多次(启动发生系统错误拒绝访问、服务名无效等问题),终于找到mysql 8.0的启动方法(附寻找mysql的bin目录)
    [附源码]java毕业设计在线二手车交易信息管理系统
    openpnp - 手工修改配置文件(元件高度,size,吸嘴)
  • 原文地址:https://blog.csdn.net/wangyx1234/article/details/127710306