zoukankan      html  css  js  c++  java
  • 【LiteOS】LiteOS消息队列


    前言

    链接

    参考

    • 野火
    • 上面链接

    笔录草稿

    • 最近工作有点忙,远吗阅读推迟了哈哈

    基本概念

    • 队列又称消息队列

      • 是一种常用于任务间通信的数据结构
      • 能接收来自任务或中断的不固定长度的消息
      • 根据不同的 API 选择传递消息是否存放在自己空间
        • 即是 传数据 还是 传地址
      • 任务能够从队列里面读取消息
        • 当队列中的消息是空时
          • 挂起读取任务
        • 当队列中有新消息时
          • 挂起的读取任务被唤醒
          • 并处理新消息。
    • LiteOS 队列特性

      • 消息以先进先出方式排队(FIFO),支持异步读写工作方式
      • 读队列和写队列都支持超时机制
      • 发送消息类型由通信双方约定,可以允许不同长度(不超过队列节点最大值)消息
      • 一个任务能够从任意一个消息队列接收和发送消息
      • 多个任务能够从同一个消息队列接收和发送消息
      • 当队列使用结束后,如果是动态申请的内存,需要通过释放内存函数回收。

    队列运作机制

    • 队列控制块
      • usReadWriteableCnt : 可读或可写的消息数量
      • stReadWriteList : 可读或可写的消息任务等待链表
      • usQueueState : 两种状态
        • OS_QUEUE_UNUSED : 未被使用
        • OS_QUEUE_INUSED : 已被使用
    /**
      * @ingroup los_queue
      * Queue information block structure
      */
    typedef struct tagQueueCB
    {
        UINT8       *pucQueue;                              /**< Pointer to a queue handle */
        UINT16      usQueueState;                           /**< Queue state */
        UINT16      usQueueLen;                             /**< Queue length */
        UINT16      usQueueSize;                            /**< Node size     */
        UINT16      usQueueID;                              /**< usQueueID         */
        UINT16      usQueueHead;                            /**< Node head       */
        UINT16      usQueueTail;                            /**< Node tail       */
        UINT16      usReadWriteableCnt[2];       /**< Count of readable or writable resources, 0:readable, 1:writable */
        LOS_DL_LIST stReadWriteList[2];          /**< Pointer to the linked list to be read or written, 0:readlist, 1:writelist  */
        LOS_DL_LIST stMemList;                              /**< Pointer to the memory linked list */
    } QUEUE_CB_S;
    /* queue state */
    /**
      *  @ingroup los_queue
      *  Message queue state: not in use.
      */
    #define OS_QUEUE_UNUSED                 0
    
    /**
      *  @ingroup los_queue
      *  Message queue state: used.
      */
    #define OS_QUEUE_INUSED     1
    

    队列运作原理

    • 创建队列

      • 传入队列长度消息节点大小
      • 开辟相应的内存空间
      • 返回队列ID
    • 队列中消息头节点 Head消息尾节点 Tail

      • Head 表示队列中被占用消息的起始位置
      • Tail 表示队列中被空闲消息的起始位置
      • 两者均采用回卷方式
    • usReadWriteableCnt[0] 判断是否可读取

    • usReadWriteableCnt[1] 判断是否可写入

    • 删除队列时

      • 根据传入的队列ID寻找到对应的队列
      • 把队列状态置为未使用
      • 释放原队列所占的空间
      • 对应的队列控制头置为初始状态。
    • 图解:

    消息队列传输方式

    • LiteOS 的消息传输方式有两种

      1. 传地址方式
        1. 优点:效率高
        2. 缺点:修改源文件,消息对应的内容也会被修改
      2. 拷贝方式
        1. 优点:数据安全,是直接拷贝内容到消息中
        2. 缺点:效率相对传地址来说较低
    • 用户可以根据需求选择不同的方式

      • 主要参考 数据大小数据重要性 来衡量

    消息队列的阻塞机制

    • 中断中不允许使用带有阻塞机制的 API,所以中断中,阻塞值均取 0
    • LiteOS 已经实现了阻塞机制,用户直接使用即可

    出队阻塞

    • 三种方式:主要参考队列里面是否有消息
      • 不等待:0
        • 读取消息时,队列里面
          • 有消息,正常读取
          • 没有消息,则不等待,直接执行后面代码
      • 限时等待:
        • 在规定时间内,消息队列里面
          • 有消息,正常读取,
          • 没有消息,则等待
        • 超时
          • 则直接执行后面代码
      • 永久等待:LOS_WAIT_FOREVER
        • 读取消息时
          • 有消息,正常读取
          • 没有消息,一直等待,直到队列里有消息

    入队阻塞

    • 三种方式:主要参考队列里面的消息是否满了
      • 不等待:0
        • 写入消息时
          • 队列未满,正常写入
          • 队列已满,则不等待,直接执行后面代码
      • 限时等待:
        • 写入消息时
          • 队列未满,正常写入
          • 队列已满,限时等待,等待队列未满后并写入
        • 超时
          • 则直接执行后面代码
      • 永久等待:LOS_WAIT_FOREVER
        • 写入消息时
          • 队列未满,正常写入
          • 队列已满,一直等待,直到队列未满

    任务相关函数

    接口名 描述
    LOS_QueueCreate 创建一个消息
    LOS_QueueRead 读取指定队列中的数据。(buff里存放的是队列节点的地址)
    LOS_QueueWrite 向指定队列写数据。(写入队列节点中的是buff的地址)
    LOS_QueueReadCopy 读取指定队列中的数据。(buff里存放的是队列节点中的数据)(预留接口)
    LOS_QueueWriteCopy 向指定队列写数据。(写入队列节点中的是buff中的数据)(预留接口)
    LOS_QueueWriteHead 向指定队列的头部写数据
    LOS_QueueDelete 删除一个指定的队列
    LOS_QueueInfoGet 获取指定队列信息

    各函数使用可以看源码或者例程

    任务开发流程

    • 非 copy 方式 ( copy 方式类同 )
      1. 创建消息队列LOS_QueueCreate。
      2. 创建成功后,可以得到消息队列的ID值。
      3. 写队列操作函数LOS_QueueWrite。
      4. 读队列操作函数LOS_QueueRead。
      5. 获取队列信息函数LOS_QueueInfoGet。
      6. 删除队列LOS_QueueDelete。

    注意事项 *

    1. 系统可配置的队列资源个数
      • 是指整个系统的队列资源总个数
      • 而非用户能使用的个数。
      • 例如:
        • 系统软件定时器多占用一个队列资源
        • 那么系统可配置的队列资源就会减少一个。
    2. 调用 LOS_QueueCreate 函数时所传入的队列名暂时未使用,作为以后的预留参数。
    3. 队列接口函数中的入参数 uwTimeOut 是指相对时间。
    4. LOS_QueueReadCopyLOS_QueueWriteCopy 是一组接口
    5. LOS_QueueReadLOS_QueueWrite 是一组接口,两组接口需要配套使用。
    6. 鉴于 LOS_QueueWriteLOS_QueueRead 这组接口实际操作的是数据地址,用户必须保证调用 LOS_QueueRead 获取到的指针所指向内存区域在读队列期间没有被异常修改或释放,否则可能会导致不可预知的后果。
    • 采用地址方式时,必须保该地址内容没有被修改,且不推荐使用局部变量
    • 采用地址方式时,必须保该地址内容没有被修改,且不推荐使用局部变量
    • 采用地址方式时,必须保该地址内容没有被修改,且不推荐使用局部变量

    实战

    实战地址

  • 相关阅读:
    rails enum用于存储数据
    single-table inheritance 单表继承
    imageable.touch
    jbuilder的set!方法重构接口
    Two Strings Are Anagrams
    java项目导入IntelliJ IDEA
    mac 下载安装 IntelliJ IDEA Tomcat
    Merge k Sorted Lists Leetcode Java
    ruby on rails validates uniqueness
    使用update!导致的更新时候的错误信息不显示 ruby on rails
  • 原文地址:https://www.cnblogs.com/lizhuming/p/13944541.html
Copyright © 2011-2022 走看看