基于队列(Queue)机制改进或构建而来的通信方法介绍

在FreeRTOS中,以下模块是基于队列(Queue)机制改进或构建而来的:


1. 信号量(Semaphore)

  • 实现基础:直接基于队列实现
  • 技术细节
    • 二进制信号量:使用长度为1的队列,数据项大小为0(仅传递空令牌)
    • 计数信号量:使用长度>1的队列,通过队列剩余空间表示可用资源数
    • 互斥锁(Mutex):基于优先级继承机制的特殊信号量,底层仍使用队列
  • 代码示例
    // 信号量创建本质是队列创建
    SemaphoreHandle_t xSemaphoreCreateBinary(void) {
        return xQueueGenericCreate(1, 0, queueQUEUE_TYPE_BINARY_SEMAPHORE);
    }
    

2. 消息队列(Message Queue)

  • 实现基础:队列的直接应用
  • 技术细节
    • 标准队列的具象化应用,用于传输实际数据块
    • 通过xQueueSend()/xQueueReceive()操作数据实体
    • 数据拷贝机制与队列完全一致
  • 架构特点
    // 消息队列创建就是普通队列
    QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
    

3. 队列集(Queue Set)

  • 实现基础:多队列的监控封装
  • 技术细节
    • 通过内部队列监听多个队列/信号量的事件
    • 使用一个中央队列记录所有被监控队列的事件状态
    • 任务可阻塞在队列集上等待多个通信对象
  • 工作流程
    // 队列集监听多个队列
    void vAddToQueueSet(QueueSetMemberHandle_t xQueueOrSemaphore, 
                       QueueSetHandle_t xQueueSet) {
        // 将队列加入监控列表
    }
    

非队列基础的模块

事件标志组(Event Group)
  • 独立实现:基于位操作和任务阻塞列表
  • 特点
    • 使用32位变量存储事件标志(EventBits_t
    • 通过位掩码操作实现事件设置/等待
    • 无队列结构参与,直接操作任务控制块(TCB)
任务通知(Task Notification)
  • 实现机制:直接操作任务控制块中的状态字段
  • 特点
    • 每个任务自带一个32位通知值和一个状态标志
    • 通过xTaskNotify()直接修改目标任务的TCB
    • 无队列参与,通信延迟降低83%(官方数据)

架构对比图

模块依赖队列数据存储位置同步机制
队列自身独立队列缓冲区数据拷贝阻塞
信号量队列结构令牌计数阻塞
队列集被监控队列的联合多队列事件聚合
事件标志组独立32位变量位操作阻塞
任务通知任务控制块内直接状态修改

性能影响分析

  1. 队列派生模块的代价

    • 信号量操作耗时:约60 cycles(队列操作的基础开销)
    • 原生任务通知耗时:约8 cycles(直接内存操作)
  2. 内存占用对比

    • 每个队列实例占用:12字节头 + (项数×项大小)
    • 事件标志组占用:4字节 + 任务阻塞列表头

设计选择建议

  • 优先使用任务通知:当需要轻量级单接收者通信时
  • 选择队列/信号量:当需要多任务访问或数据持久化存储时
  • 使用事件标志组:当需要多条件位模式触发时

通过这种层级化的设计,FreeRTOS在保持队列核心机制的同时,为不同场景提供了最优的通信抽象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九层指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值