概述
消息队列是一种任务间传递数据的有效方式。消息队列使用环形缓冲池(ring buffer)来管理消息的队列缓冲区,并使用类似信号量的机制进行任务间的同步。任务通过消息队列可以发送消息,也可以通过它接收消息,从而实现数据的同步及通信。任务发送的消息会暂存在消息队列中,当接收任务来读时,将暂存的数据传递给接收任务;若接收任务在接收数据时,消息队列中无可读数据,则任务会阻塞,直到有消息到来解除阻塞而进入就绪状态。
超时时间
消息接收可设置超时时间,如果任务在超时时间到期后仍未收到消息,则任务解除阻塞进入就绪状态。
消息队列功能函数
函数名 | 描述 |
aos_queue_create() | 消息队列创建函数(推荐) |
aos_queue_new() | 消息队列创建函数(兼容3.1) |
aos_queue_free() | 消息队列删除函数 |
aos_queue_send() | 向消息队列发送消息函数 |
aos_queue_recv() | 从消息队列读取消息函数 |
aos_queue_is_valid() | 判断消息队列具柄是否合法 |
aos_queue_buf_ptr() | 获取消息队列消息数据区地址 |
aos_queue_get_count() | 获取消息队列当前消息数 |
常用配置
消息队列功能:默认使能,如需修改,在YAML中修改RHINO_CONFIG_BUF_QUEUE配置
def_config:
RHINO_CONFIG_BUF_QUEUE: 0
API说明
使用示例
示例代码参考example/queue_example.c,该示例使用消息队列实现任务间数据同步,具体场景为创建任务A和认为B,以及一消息队列。任务A作为生产者循环向消息队列发送消息,任务B作为消费者循环从消息队列接收消息,一般情况下,消费者处理数据是要花费很长时间,所以会导致消息产生的速度大于消息处理的速度,使得消息队列溢出。所以可以通过调整任务B优先级大于任务A来避免这种情况,或者使用信号量来控制数据收发同步。
示例说明如下:
t0时刻,任务T调用aos_queue_new()创建一互斥量。任务T然后调用aos_task_create()创建任务A和任务B,任务A优先级设置为31,任务B优先级设置为30。任务B因消息队列无消息而阻塞,任务A得到运行向消息队列发送消息。
t1时刻,任务B因从消息队列读取到消息而解除阻塞,任务B对消息进行处理后继续等待新的消息到来。
t2时刻,任务A向消息队列发送消息。
t3时刻,重复t1时刻的操作。
该示例可配置到helloworld_demo中运行,相关代码的下载、编译和固件烧录均依赖AliOS Things配套的开发工具 ,所以首先需要参考《AliOS Things集成开发环境使用说明之搭建开发环境》,下载安装 。 待开发环境搭建完成后,可以按照以下步骤进行示例的测试。
步骤1 创建或打开工程
打开已有工程
如果用于测试的案例工程已存在,可参考《AliOS Things集成开发环境使用说明之打开工程》打开已有工程。
创建新的工程
组件的示例代码可以通过编译链接到AliOS Things的任意案例(solution)来运行,这里选择helloworld_demo案例。helloworld_demo案例相关的源代码下载可参考《AliOS Things集成开发环境使用说明之创建工程》。
步骤2 添加组件
案例下载完成后,需要在helloworld_demo组件的package.yaml中添加对组件的依赖:
depends:
- osal_aos: dev_aos # helloworld_demo中引入osal_aos组件
步骤3 下载组件
在已安装了的开发环境工具栏中,选择Terminal -> New Terminal启动终端,并且默认工作路径为当前工程的workspace,此时在终端命令行中输入:
aos install osal_aos
上述命令执行成功后,组件源码则被下载到了./components/osal_aos路径中。
步骤4 添加示例
osal_aos组件的package.yaml中添加example示例代码:
depends:
- rhino: dev_aos
- cli: dev_aos # 添加cli依赖
source_file:
- "*.c"
- "example/queue_example.c" # 添加 queue_example.c
步骤5 编译固件
在示例代码已经添加至组件的配置文件,并且helloworld_demo已添加了对该组件的依赖后,就可以编译helloworld_demo案例来生成固件了,具体编译方法可参考《AliOS Things集成开发环境使用说明之编译固件》。
步骤6 烧录固件
helloworld_demo案例的固件生成后,可参考《AliOS Things集成开发环境使用说明之烧录固件》来烧录固件。
步骤7 打开串口
固件烧录完成后,可以通过串口查看示例的运行结果,打开串口的具体方法可参考《AliOS Things集成开发环境使用说明之查看日志》。
当串口终端打开成功后,可在串口中输入help来查看已添加的测试命令。
步骤8 测试示例
CLI命令行输入:
queue_example
关键日志:
[aos_queue_example]10 recv message : 3456789012
[aos_queue_example]10 recv message : 4567890123
[aos_queue_example]10 recv message : 5678901234
[aos_queue_example]10 recv message : 6789012345
[aos_queue_example]10 recv message : 7890123456
[aos_queue_example]10 recv message : 8901234567
[aos_queue_example]10 recv message : 9012345678
注意事项
发送消息时,如果没有任务在等待接收消息,则此消息会暂时保存在环形缓冲区中,如果有任务在等待数据接收,则将消息直接传递给任务。
FAQ
Q1: 调用aos_queue_recv()接口无限期的等待消息,ms参数怎么设置? 答:将ms赋值为AOS_WAIT_FOREVER。