概述
消息隊列是一種任務間傳遞數據的有效方式。消息隊列使用環形緩沖池(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。