在資源受限的嵌入式環(huán)境中,LuatOS采用消息機(jī)制實(shí)現(xiàn)模塊間解耦與高效通信。通過預(yù)定義消息名稱(如“new_msg”),開發(fā)者可輕松構(gòu)建響應(yīng)式程序結(jié)構(gòu)。接下來(lái)我們將深入剖析其實(shí)現(xiàn)原理與典型使用方法。
LuatOS 的消息機(jī)制是其多任務(wù)協(xié)作和事件驅(qū)動(dòng)編程的核心部分,主要通過sys核心庫(kù)實(shí)現(xiàn)。
消息機(jī)制包括消息的發(fā)送、接收、訂閱,以及系統(tǒng)消息的定義和使用,下面分別詳細(xì)描述其原理和使用方法。
一、LuatOS 消息機(jī)制的原理
1.1 消息機(jī)制的基本原理描述
LuatOS 基于消息隊(duì)列實(shí)現(xiàn)任務(wù)間通信,消息隊(duì)列遵循先進(jìn)先出(FIFO)原則。
消息機(jī)制配合 Lua 的協(xié)程(coroutine),可以非常絲滑的實(shí)現(xiàn)協(xié)作式多任務(wù)。
每一個(gè)協(xié)程的運(yùn)行,是相互邏輯獨(dú)立的;
在協(xié)程之間收發(fā)消息,可以實(shí)現(xiàn)不同協(xié)程間的通信。
消息發(fā)布者調(diào)用 LuatOS 的 API 發(fā)送全局消息或者定向消息。
訂閱者通過回調(diào)函數(shù)或協(xié)程等待消息并處理,實(shí)現(xiàn)異步事件驅(qū)動(dòng)。
消息調(diào)度流程大致如下:
(1)發(fā)布消息時(shí),將消息及參數(shù)插入消息隊(duì)列。
(2)消息分發(fā)函數(shù)從隊(duì)列取出消息,根據(jù)消息 ID 查找訂閱者列表。
(3)調(diào)用訂閱者的回調(diào)函數(shù)或恢復(fù)協(xié)程,傳遞消息參數(shù)。
(4)訂閱者處理消息,實(shí)現(xiàn)任務(wù)間通信和事件響應(yīng)。
這種設(shè)計(jì)使得任務(wù)間解耦,消息驅(qū)動(dòng)程序結(jié)構(gòu)清晰,適合物聯(lián)網(wǎng)設(shè)備的異步事件處理需求。
1.2 LuatOS 的消息隊(duì)列
LuatOS 的消息隊(duì)列有兩個(gè): 用戶消息隊(duì)列和系統(tǒng)消息隊(duì)列。
1.2.1 用戶消息隊(duì)列:
用戶消息隊(duì)列的接收接口有三個(gè): sys.waitUntil(),sys.waitMsg(),sys.subscribe()。
1.2.2 系統(tǒng)消息隊(duì)列:
系統(tǒng)消息隊(duì)列,存儲(chǔ)在RTOS層,是RTOS操作系統(tǒng)的基本單元。
系統(tǒng)消息只能是使用 RTOS 的接口發(fā)送該消息,并且該發(fā)送消息接口是不開放給用戶的。
系統(tǒng)消息隊(duì)列的消息, 由 sys 核心庫(kù)收取,并傳送給對(duì)應(yīng)的協(xié)程或者回調(diào)函數(shù)進(jìn)行處理。
系統(tǒng)消息隊(duì)列用于硬件事件,網(wǎng)絡(luò)事件和定時(shí)器事件的傳遞。
比如說,當(dāng) Lua 腳本的某個(gè)協(xié)程運(yùn)行了這行代碼:
1.3 topic 和消息的差異
1.3.1 topic 和消息的差異
LuatOS 的消息,分為兩類: topic 和消息。
topic 跟事件的概念是類似的,在 LuatOS 語(yǔ)境里面,topic 往往就是指事件。
topic 是全局消息,是廣播消息。
而消息跟 topic 的不同,消息是有特定接收方的,而 topic 沒有特定接收方。
LuatOS 的 sys.publish 接口是發(fā)布一個(gè)全局消息,也就是發(fā)布了一個(gè) topic,也是發(fā)布了一個(gè)事件。
sys.subscribe 接口訂閱了一個(gè) topic,也就是訂閱了一個(gè)事件。
sys.sendMsg, 是發(fā)送的消息, sys.waitMsg, 是等待和處理一個(gè)消息,是有特定的協(xié)程名字作為接收方的。
為了簡(jiǎn)化描述,在下文的其余部分,如果沒有特別的說明,我們不再區(qū)分 topic 和消息的差異,統(tǒng)一把 topic 和消息稱為消息。
1.3.2 mqtt 和 LuatOS 的 topic 的差異
mqtt 的 topic 與 sys 的 topic 有如下差異:
mqtt 的 topic 的訂閱關(guān)系是服務(wù)器側(cè)(borker)維護(hù)的,支持嚴(yán)格匹配和通配符匹配;
sys 的 topic 的訂閱關(guān)系是 LuatOS 嵌入式系統(tǒng)內(nèi)部維護(hù)的,只支持嚴(yán)格匹配。
1.4 LuatOS 消息的使用
盡管有用戶消息隊(duì)列和系統(tǒng)消息隊(duì)列兩種差異,但是在使用消息的時(shí)候,可以不關(guān)注這種差異。
用戶只需要調(diào)用 sys.publish()接口和 sys.sendMsg()接口,按照自己的需要發(fā)送消息。
在接收和處理消息的時(shí)候,用 sys.subscribe()接口,指定某個(gè)消息的回調(diào)函數(shù),這時(shí)候的消息,也不需要區(qū)分用戶隊(duì)列的消息還是系統(tǒng)消息,只要知道消息的名字,都可以指定消息的回調(diào)處理函數(shù)。
使用 sys.waitUtil()接口,sys.waitMsg 接口的時(shí)候,也不需要關(guān)心是用戶隊(duì)列的消息還是系統(tǒng)隊(duì)列的消息,只要知道消息名字,都可以處理。
所有的發(fā)送消息,和接收處理消息的接口的使用,接下來(lái)都會(huì)做消息的介紹。
二、消息的發(fā)送
2.1 全局消息(sys 庫(kù))
全局消息,也可以理解為廣播消息,所有的協(xié)程都是可以監(jiān)聽和處理的。
例如:
該消息發(fā)布后,會(huì)放入用戶的消息隊(duì)列,等待被訂閱者處理。
2.2 定向消息(sys 庫(kù))
使用sys.sendMsg(taskName, target, arg2, arg3, arg4)向指定任務(wù)發(fā)送消息,可以指定接收消息的協(xié)程的名字,也可以同時(shí)給出消息攜帶的參數(shù)。
這種消息很適用于協(xié)程間的點(diǎn)對(duì)點(diǎn)通信。 例如:
該消息直接發(fā)送給指定任務(wù),很適合請(qǐng)求-響應(yīng)模型。
三、消息的接收處理
LuatOS 消息的接收處理有三種方式: 訂閱消息,取消訂閱息,等待消息。
3.1 訂閱消息
通過sys.subscribe(id, callback)訂閱指定消息的 ID,注冊(cè)回調(diào)函數(shù),當(dāng)消息到達(dá)時(shí)調(diào)用回調(diào)函數(shù)進(jìn)行處理。 例如:
3.2 取消訂閱
3.3 等待消息
3.3.1 sys.waitUntil 接口
接口原型為:
使用示例:
該機(jī)制基于協(xié)程掛起和恢復(fù)實(shí)現(xiàn),方便同步等待異步事件。
3.3.2 sys.waitMsg 接口
waitMsg 接口用于定向接收協(xié)程間的消息,用于協(xié)程間的通信,比較適合請(qǐng)求-響應(yīng)的多協(xié)程合作的工作模式。
接口原型:
使用示例:
waitMsg 有如下幾個(gè)特點(diǎn):
(1)精準(zhǔn)定向:可以通過taskName和target指定發(fā)送方與消息名稱;
(2)參數(shù)傳遞:sendMsg 可以支持最多 3 個(gè)參數(shù)(通過arg2~arg4字段);
(3)適用協(xié)程之間的通信(如 HTTP 請(qǐng)求響應(yīng)、任務(wù)間數(shù)據(jù)同步)。
四、sys 系統(tǒng)消息
4.1 系統(tǒng)消息是什么
LuatOS 框架預(yù)定義了一些系統(tǒng)消息,開發(fā)者可以直接訂閱這些消息實(shí)現(xiàn)對(duì)硬件和系統(tǒng)事件的響應(yīng)。
系統(tǒng)消息是由 LuatOS 內(nèi)核或底層驅(qū)動(dòng)自動(dòng)發(fā)布的全局事件,面向所有訂閱者廣播,適用于硬件狀態(tài)、網(wǎng)絡(luò)事件等。
LuatOS 的系統(tǒng)消息,跟普通的消息并沒有區(qū)別,但是由于是 LuatOS 底層發(fā)布的消息,并沒有指定明確的接收協(xié)程名稱,所以系統(tǒng)消息只能是當(dāng)做全局的廣播消息來(lái)處理。
用戶可以使用 sys.WaitUntil 和 sys.subscibe 接口來(lái)處理系統(tǒng)消息,不能用 susplus.waitMsg 接口處理系統(tǒng)消息。
以下按功能模塊分類詳細(xì)說明所有系統(tǒng)消息及其觸發(fā)條件和參數(shù):
4.2 系統(tǒng)消息詳解
詳細(xì)的系統(tǒng)消息的定義和解讀,參見如下鏈接:
LuatOS 系統(tǒng)消息詳細(xì)定義:https://docs.openluat.com/osapi/sys_pub/
4.3 補(bǔ)充說明
1, 這些系統(tǒng)消息均為系統(tǒng)自動(dòng)發(fā)布,不能由用戶主動(dòng)發(fā)布。
2, 可結(jié)合 LuatOS 庫(kù)的 API(如mobile.getCellInfo()、mobile.scell())獲取詳細(xì)數(shù)據(jù)。
五、LuatOS 的定時(shí)器機(jī)制
LuatOS 定時(shí)器機(jī)制基于消息驅(qū)動(dòng),常用的軟件定時(shí)器接口集中在sys庫(kù)中。
定時(shí)器到時(shí)后,會(huì)由 sys 庫(kù)接收到定時(shí)器超時(shí)消息,并觸發(fā)注冊(cè)的回調(diào)函數(shù)或喚醒掛起的任務(wù)。
下面詳細(xì)介紹其用法和原理。
5.1 LuatOS 定時(shí)器的基本原理
5.2 常用定時(shí)器 API 及用法
5.2.1 單次定時(shí)器
1,創(chuàng)建方式:
2,代碼示例:
5.2.2 循環(huán)定時(shí)器
1, 創(chuàng)建方式:
2, 代碼示例
5.2.3 停止定時(shí)器
1, 創(chuàng)建方式:
(1)停止指定定時(shí)器:
(2)停止所有綁定到某個(gè)回調(diào)的定時(shí)器:
2,代碼示例
5.2.4 在任務(wù)中延時(shí)/等待消息
1, 函數(shù)說明
(1)sys.wait(ms):在 task 協(xié)程中掛起指定毫秒數(shù),底層用定時(shí)器實(shí)現(xiàn)
(2)sys.waitUntil("MSG_ID", timeout_ms):等待某個(gè)消息或超時(shí)
代碼示例:
5.2.5 判斷定時(shí)器狀態(tài)
1,使用方式
2, 代碼示例
5.3 總結(jié)
1,sys.waitsys.waitUntilsys.waitMsg只能在 task 協(xié)程中使用。
2, 定時(shí)器到時(shí)后,底層會(huì)向消息隊(duì)列推送rtos.MSG_TIMER消息,并附帶定時(shí)器 ID。
3, 系統(tǒng)主循環(huán) sys.run() 檢測(cè)到該消息后,會(huì)查找定時(shí)器池,將參數(shù)傳遞給注冊(cè)的回調(diào)或喚醒掛起的協(xié)程
4, 定時(shí)器總結(jié)表
序號(hào) |
功能 |
API 示例 |
說明 |
1 |
單次定時(shí)器 |
sys.timerStart(func, 2000, arg) |
2 秒后執(zhí)行一次 |
2 |
循環(huán)定時(shí)器 |
sys.timerLoopStart(func, 5000, arg) |
每 5 秒執(zhí)行一次 |
3 |
停止定時(shí)器 |
sys.timerStop(timer_id) |
停止指定定時(shí)器 |
4 |
停止所有定時(shí)器 |
sys.timerStopAll(func) |
停止所有同回調(diào)定時(shí)器 |
5 |
延時(shí) |
sys.wait(1000) |
協(xié)程中延時(shí) 1 秒 |
6 |
等待消息 |
sys.waitUntil("MSG_ID", 5000) |
等待消息或超時(shí) |
7 |
等待消息 |
sys.waitMsg("TASK_NAME", "MSG_ID", 5000) |
等待發(fā)送給"TASK_NAME"的消息或超時(shí) |
8 |
判斷狀態(tài) |
sys.timerIsActive(timer_id) |
查詢定時(shí)器是否激活 |
六、消息機(jī)制的使用流程示例
如下的示例,展示了如何訂閱消息、發(fā)布消息和在任務(wù)中等待消息,幫助理解 LuatOS 消息機(jī)制的核心用法。
該示例完整展示了 LuatOS 消息機(jī)制的核心用法,建議在真實(shí)設(shè)備運(yùn)行時(shí)結(jié)合串口日志觀察執(zhí)行流程。
實(shí)際項(xiàng)目中可根據(jù)需要調(diào)整消息類型和定時(shí)器間隔。
6.1 代碼示例
6.2 代碼的執(zhí)行流程說明
1, 初始化階段:
2, 消息傳遞流程:
3, 定時(shí)器生命周期:
6.3 執(zhí)行日志
6.4 關(guān)鍵 API 對(duì)照表
功能 |
API |
全局消息訂閱 |
sys.subscribe |
定時(shí)器管理 |
sys.timerStart/Stop |
定向消息發(fā)送 |
sys.sendMsg |
定向消息接收 |
sys.waitMsg |
任務(wù)間延時(shí) |
sys.wait |
具名任務(wù)創(chuàng)建 |
sys.taskInitEx |
七、總結(jié)
消息機(jī)制原理:基于消息隊(duì)列和協(xié)程,發(fā)布者將消息放入隊(duì)列,訂閱者通過回調(diào)或協(xié)程等待并處理,支持異步事件驅(qū)動(dòng)。
發(fā)送消息:sys.publish()廣播消息,sys.sendMsg()定向發(fā)送消息。
接收消息:sys.subscribe()訂閱消息,sys.waitUntil()和sys.waitMsg()阻塞等待消息,sys.unsubscribe()取消訂閱。
系統(tǒng)消息:框架預(yù)定義多種系統(tǒng)事件消息,直接訂閱即可響應(yīng)硬件和系統(tǒng)事件。
應(yīng)用場(chǎng)景:網(wǎng)絡(luò)模塊通信、傳感器數(shù)據(jù)廣播、定時(shí)器事件處理等。
通過合理使用 LuatOS 的消息機(jī)制,可以實(shí)現(xiàn)高效、解耦的物聯(lián)網(wǎng)應(yīng)用架構(gòu),支持復(fù)雜的事件驅(qū)動(dòng)和多任務(wù)協(xié)作。
今天的內(nèi)容就分享到這里了~
審核編輯 黃宇
-
LuatOS
+關(guān)注
關(guān)注
0文章
118瀏覽量
2474
發(fā)布評(píng)論請(qǐng)先 登錄
揭秘LuatOS Task:多任務(wù)管理的“智能中樞”

解碼LuatOS:短信功能的底層運(yùn)作機(jī)制

評(píng)論