在資源受限的嵌入式環境中,LuatOS采用消息機制實現模塊間解耦與高效通信。通過預定義消息名稱(如“new_msg”),開發者可輕松構建響應式程序結構。接下來我們將深入剖析其實現原理與典型使用方法。
LuatOS 的消息機制是其多任務協作和事件驅動編程的核心部分,主要通過sys核心庫實現。
消息機制包括消息的發送、接收、訂閱,以及系統消息的定義和使用,下面分別詳細描述其原理和使用方法。
一、LuatOS 消息機制的原理
1.1 消息機制的基本原理描述
LuatOS 基于消息隊列實現任務間通信,消息隊列遵循先進先出(FIFO)原則。
消息機制配合 Lua 的協程(coroutine),可以非常絲滑的實現協作式多任務。
每一個協程的運行,是相互邏輯獨立的;
在協程之間收發消息,可以實現不同協程間的通信。
消息發布者調用 LuatOS 的 API 發送全局消息或者定向消息。
訂閱者通過回調函數或協程等待消息并處理,實現異步事件驅動。
消息調度流程大致如下:
(1)發布消息時,將消息及參數插入消息隊列。
(2)消息分發函數從隊列取出消息,根據消息 ID 查找訂閱者列表。
(3)調用訂閱者的回調函數或恢復協程,傳遞消息參數。
(4)訂閱者處理消息,實現任務間通信和事件響應。
這種設計使得任務間解耦,消息驅動程序結構清晰,適合物聯網設備的異步事件處理需求。
1.2 LuatOS 的消息隊列
LuatOS 的消息隊列有兩個: 用戶消息隊列和系統消息隊列。
1.2.1 用戶消息隊列:

用戶消息隊列的接收接口有三個: sys.waitUntil(),sys.waitMsg(),sys.subscribe()。
1.2.2 系統消息隊列:
系統消息隊列,存儲在RTOS層,是RTOS操作系統的基本單元。
系統消息只能是使用 RTOS 的接口發送該消息,并且該發送消息接口是不開放給用戶的。
系統消息隊列的消息, 由 sys 核心庫收取,并傳送給對應的協程或者回調函數進行處理。
系統消息隊列用于硬件事件,網絡事件和定時器事件的傳遞。
比如說,當 Lua 腳本的某個協程運行了這行代碼:


1.3 topic 和消息的差異
1.3.1 topic 和消息的差異
LuatOS 的消息,分為兩類: topic 和消息。
topic 跟事件的概念是類似的,在 LuatOS 語境里面,topic 往往就是指事件。
topic 是全局消息,是廣播消息。
而消息跟 topic 的不同,消息是有特定接收方的,而 topic 沒有特定接收方。
LuatOS 的 sys.publish 接口是發布一個全局消息,也就是發布了一個 topic,也是發布了一個事件。
sys.subscribe 接口訂閱了一個 topic,也就是訂閱了一個事件。
sys.sendMsg, 是發送的消息, sys.waitMsg, 是等待和處理一個消息,是有特定的協程名字作為接收方的。
為了簡化描述,在下文的其余部分,如果沒有特別的說明,我們不再區分 topic 和消息的差異,統一把 topic 和消息稱為消息。
1.3.2 mqtt 和 LuatOS 的 topic 的差異
mqtt 的 topic 與 sys 的 topic 有如下差異:
mqtt 的 topic 的訂閱關系是服務器側(borker)維護的,支持嚴格匹配和通配符匹配;
sys 的 topic 的訂閱關系是 LuatOS 嵌入式系統內部維護的,只支持嚴格匹配。
1.4 LuatOS 消息的使用
盡管有用戶消息隊列和系統消息隊列兩種差異,但是在使用消息的時候,可以不關注這種差異。
用戶只需要調用 sys.publish()接口和 sys.sendMsg()接口,按照自己的需要發送消息。
在接收和處理消息的時候,用 sys.subscribe()接口,指定某個消息的回調函數,這時候的消息,也不需要區分用戶隊列的消息還是系統消息,只要知道消息的名字,都可以指定消息的回調處理函數。
使用 sys.waitUtil()接口,sys.waitMsg 接口的時候,也不需要關心是用戶隊列的消息還是系統隊列的消息,只要知道消息名字,都可以處理。
所有的發送消息,和接收處理消息的接口的使用,接下來都會做消息的介紹。
二、消息的發送
2.1 全局消息(sys 庫)
全局消息,也可以理解為廣播消息,所有的協程都是可以監聽和處理的。

例如:

該消息發布后,會放入用戶的消息隊列,等待被訂閱者處理。
2.2 定向消息(sys 庫)
使用sys.sendMsg(taskName, target, arg2, arg3, arg4)向指定任務發送消息,可以指定接收消息的協程的名字,也可以同時給出消息攜帶的參數。
這種消息很適用于協程間的點對點通信。 例如:

該消息直接發送給指定任務,很適合請求-響應模型。
三、消息的接收處理
LuatOS 消息的接收處理有三種方式: 訂閱消息,取消訂閱息,等待消息。
3.1 訂閱消息
通過sys.subscribe(id, callback)訂閱指定消息的 ID,注冊回調函數,當消息到達時調用回調函數進行處理。 例如:

3.2 取消訂閱

3.3 等待消息

3.3.1 sys.waitUntil 接口

接口原型為:

使用示例:

該機制基于協程掛起和恢復實現,方便同步等待異步事件。
3.3.2 sys.waitMsg 接口
waitMsg 接口用于定向接收協程間的消息,用于協程間的通信,比較適合請求-響應的多協程合作的工作模式。
接口原型:

使用示例:

waitMsg 有如下幾個特點:
(1)精準定向:可以通過taskName和target指定發送方與消息名稱;
(2)參數傳遞:sendMsg 可以支持最多 3 個參數(通過arg2~arg4字段);
(3)適用協程之間的通信(如 HTTP 請求響應、任務間數據同步)。
四、sys 系統消息
4.1 系統消息是什么
LuatOS 框架預定義了一些系統消息,開發者可以直接訂閱這些消息實現對硬件和系統事件的響應。
系統消息是由 LuatOS 內核或底層驅動自動發布的全局事件,面向所有訂閱者廣播,適用于硬件狀態、網絡事件等。
LuatOS 的系統消息,跟普通的消息并沒有區別,但是由于是 LuatOS 底層發布的消息,并沒有指定明確的接收協程名稱,所以系統消息只能是當做全局的廣播消息來處理。
用戶可以使用 sys.WaitUntil 和 sys.subscibe 接口來處理系統消息,不能用 susplus.waitMsg 接口處理系統消息。
以下按功能模塊分類詳細說明所有系統消息及其觸發條件和參數:
4.2 系統消息詳解
詳細的系統消息的定義和解讀,參見如下鏈接:
LuatOS 系統消息詳細定義:https://docs.openluat.com/osapi/sys_pub/
4.3 補充說明
1, 這些系統消息均為系統自動發布,不能由用戶主動發布。
2, 可結合 LuatOS 庫的 API(如mobile.getCellInfo()、mobile.scell())獲取詳細數據。
五、LuatOS 的定時器機制
LuatOS 定時器機制基于消息驅動,常用的軟件定時器接口集中在sys庫中。
定時器到時后,會由 sys 庫接收到定時器超時消息,并觸發注冊的回調函數或喚醒掛起的任務。
下面詳細介紹其用法和原理。
5.1 LuatOS 定時器的基本原理

5.2 常用定時器 API 及用法
5.2.1 單次定時器
1,創建方式:

2,代碼示例:

5.2.2 循環定時器
1, 創建方式:

2, 代碼示例

5.2.3 停止定時器
1, 創建方式:
(1)停止指定定時器:

(2)停止所有綁定到某個回調的定時器:

2,代碼示例

5.2.4 在任務中延時/等待消息
1, 函數說明
(1)sys.wait(ms):在 task 協程中掛起指定毫秒數,底層用定時器實現
(2)sys.waitUntil("MSG_ID", timeout_ms):等待某個消息或超時
代碼示例:


5.2.5 判斷定時器狀態
1,使用方式

2, 代碼示例

5.3 總結
1,sys.waitsys.waitUntilsys.waitMsg只能在 task 協程中使用。
2, 定時器到時后,底層會向消息隊列推送rtos.MSG_TIMER消息,并附帶定時器 ID。
3, 系統主循環 sys.run() 檢測到該消息后,會查找定時器池,將參數傳遞給注冊的回調或喚醒掛起的協程
4, 定時器總結表
|
序號 |
功能 |
API 示例 |
說明 |
|
1 |
單次定時器 |
sys.timerStart(func, 2000, arg) |
2 秒后執行一次 |
|
2 |
循環定時器 |
sys.timerLoopStart(func, 5000, arg) |
每 5 秒執行一次 |
|
3 |
停止定時器 |
sys.timerStop(timer_id) |
停止指定定時器 |
|
4 |
停止所有定時器 |
sys.timerStopAll(func) |
停止所有同回調定時器 |
|
5 |
延時 |
sys.wait(1000) |
協程中延時 1 秒 |
|
6 |
等待消息 |
sys.waitUntil("MSG_ID", 5000) |
等待消息或超時 |
|
7 |
等待消息 |
sys.waitMsg("TASK_NAME", "MSG_ID", 5000) |
等待發送給"TASK_NAME"的消息或超時 |
|
8 |
判斷狀態 |
sys.timerIsActive(timer_id) |
查詢定時器是否激活 |
六、消息機制的使用流程示例
如下的示例,展示了如何訂閱消息、發布消息和在任務中等待消息,幫助理解 LuatOS 消息機制的核心用法。
該示例完整展示了 LuatOS 消息機制的核心用法,建議在真實設備運行時結合串口日志觀察執行流程。
實際項目中可根據需要調整消息類型和定時器間隔。
6.1 代碼示例

6.2 代碼的執行流程說明
1, 初始化階段:

2, 消息傳遞流程:

3, 定時器生命周期:

6.3 執行日志

6.4 關鍵 API 對照表
|
功能 |
API |
|
全局消息訂閱 |
sys.subscribe |
|
定時器管理 |
sys.timerStart/Stop |
|
定向消息發送 |
sys.sendMsg |
|
定向消息接收 |
sys.waitMsg |
|
任務間延時 |
sys.wait |
|
具名任務創建 |
sys.taskInitEx |
七、總結
消息機制原理:基于消息隊列和協程,發布者將消息放入隊列,訂閱者通過回調或協程等待并處理,支持異步事件驅動。
發送消息:sys.publish()廣播消息,sys.sendMsg()定向發送消息。
接收消息:sys.subscribe()訂閱消息,sys.waitUntil()和sys.waitMsg()阻塞等待消息,sys.unsubscribe()取消訂閱。
系統消息:框架預定義多種系統事件消息,直接訂閱即可響應硬件和系統事件。
應用場景:網絡模塊通信、傳感器數據廣播、定時器事件處理等。
通過合理使用 LuatOS 的消息機制,可以實現高效、解耦的物聯網應用架構,支持復雜的事件驅動和多任務協作。
今天的內容就分享到這里了~
審核編輯 黃宇
-
LuatOS
+關注
關注
0文章
156瀏覽量
2699
發布評論請先 登錄
LuatOS 系統框架的模塊化設計原理
基于LuatOS的MQTT物聯網通信全解
LuatOS框架的使用(上)
Neway電機方案在電機控制的應用場景
Switch的應用場景
藍牙網關是什么?都有哪些功能?應用場景有哪些?
LuatOS中PWM實現LED亮度調節與呼吸燈的實戰教程
有線通信技術和無線通信技術在電能質量在線監測裝置中的應用場景有何不同?
Task任務:LuatOS實現“任務級并發”的核心引擎
揭秘LuatOS Task:多任務管理的“智能中樞”
解碼LuatOS:短信功能的底層運作機制
教程來啦!LuatOS中的消息通信機制詳解及其應用場景
評論