文獻(xiàn)標(biāo)識(shí)碼: A
DOI:10.16157/j.issn.0258-7998.172451
中文引用格式: 朱明輝,趙信廣,尤星懿. 基于FreeRTOS和MQTT的海洋監(jiān)測(cè)網(wǎng)絡(luò)框架[J].電子技術(shù)應(yīng)用,2018,44(1):41-44.
英文引用格式: Zhu Minghui,Zhao Xinguang,You Xingyi. Marine monitoring network framework based on FreeRTOS and MQTT[J]. Application of Electronic Technique,2018,44(1):41-44.
0 引言
隨著海洋的不斷開(kāi)發(fā)、探索,以及生活垃圾等污染物的排放,海洋環(huán)境遭到嚴(yán)重破壞,因此保護(hù)海洋環(huán)境刻不容緩。為了加強(qiáng)海洋環(huán)境的保護(hù),提高對(duì)海洋環(huán)境的合理開(kāi)發(fā)利用,人們迫切地需要提高海洋監(jiān)測(cè)技術(shù),實(shí)現(xiàn)對(duì)海洋信息實(shí)時(shí)監(jiān)測(cè),更好地實(shí)現(xiàn)災(zāi)害預(yù)警、資源利用、環(huán)境保護(hù)以及各種軍事活動(dòng)。海洋監(jiān)測(cè)基于傳感器網(wǎng)絡(luò)實(shí)現(xiàn),通過(guò)多個(gè)傳感器構(gòu)成傳感器網(wǎng)絡(luò)采集數(shù)據(jù)并上傳到控制中心實(shí)現(xiàn)。傳統(tǒng)的單片機(jī)進(jìn)行傳感器數(shù)據(jù)的采集與傳輸,只能進(jìn)行單任務(wù),在較復(fù)雜的數(shù)據(jù)采集傳輸中就顯得力不從心。而實(shí)時(shí)操作系統(tǒng)可以設(shè)置多個(gè)任務(wù),每個(gè)任務(wù)執(zhí)行的周期是可靠的,可以優(yōu)先快速地執(zhí)行對(duì)實(shí)時(shí)性要求高的事件,并且程序的設(shè)計(jì)相對(duì)簡(jiǎn)單,功能的拓展也比較容易。在數(shù)據(jù)傳輸上,消息隊(duì)列遙測(cè)傳輸(Message Queuing Telemetry Transport,MQTT)協(xié)議設(shè)計(jì)之初充分考慮了網(wǎng)絡(luò)的不確定性,協(xié)議代碼量少,報(bào)文精簡(jiǎn),可以適應(yīng)不理想的網(wǎng)絡(luò)條件,提供實(shí)時(shí)可靠的消息服務(wù)。因此對(duì)于海洋監(jiān)測(cè)網(wǎng)絡(luò)來(lái)說(shuō),在實(shí)時(shí)操作系統(tǒng)上利用傳感器網(wǎng)絡(luò)采集數(shù)據(jù)并通過(guò)MQTT協(xié)議進(jìn)行交互成為一種可靠的選擇。
1 FreeRTOS簡(jiǎn)介
FreeRTOS操作系統(tǒng)內(nèi)核占用空間小,實(shí)時(shí)性高,源碼公開(kāi)、可移植,可以在資源有限的微控制器中運(yùn)行。FreeRTOS在任務(wù)調(diào)度上支持搶占式、合作式和時(shí)間片式,任務(wù)數(shù)量沒(méi)有限制,不同任務(wù)可以設(shè)置不同的優(yōu)先級(jí),優(yōu)先級(jí)隨數(shù)值的增大而提高,同一優(yōu)先級(jí)也可以設(shè)置不同任務(wù)[1]。與其他嵌入式操作系統(tǒng)相比,F(xiàn)reeRTOS比較簡(jiǎn)單,上手容易,商業(yè)上免費(fèi),而且社會(huì)占有量高。
2 MQTT協(xié)議
2.1 MQTT簡(jiǎn)介
MQTT是一款發(fā)布/訂閱(publish/subscribe)模式的消息傳輸協(xié)議。該協(xié)議構(gòu)建于TCP/IP協(xié)議上,并且具有簡(jiǎn)單、規(guī)范、開(kāi)銷低、易于實(shí)現(xiàn)的特點(diǎn)。這些特點(diǎn)使得它對(duì)于一些要求低功耗、低帶寬等受限的環(huán)境來(lái)說(shuō)是很好的選擇,因此MQTT協(xié)議被廣泛應(yīng)用在物-物通信以及物聯(lián)網(wǎng)中。
2.2 MQTT特點(diǎn)
(1)MQTT可以實(shí)現(xiàn)消息一對(duì)多分發(fā);
(2)對(duì)負(fù)載內(nèi)容屏蔽;
(3)傳輸消息提供3種服務(wù)質(zhì)量,用戶可根據(jù)實(shí)際應(yīng)用權(quán)衡效率與服務(wù)質(zhì)量;
(4)協(xié)議報(bào)文的精簡(jiǎn),減少對(duì)網(wǎng)絡(luò)質(zhì)量的依賴;
(5)客戶端異常中斷的通知機(jī)制。
2.3 MQTT結(jié)構(gòu)
MQTT協(xié)議中有發(fā)布者、代理服務(wù)器、訂閱者3種身份??蛻舳撕痛矸?wù)器首先需要通過(guò)交互連接請(qǐng)求報(bào)文來(lái)建立連接,之后客戶端向代理服務(wù)器發(fā)布消息,而訂閱者可以向消息代理服務(wù)器訂閱消息。在此協(xié)議模型中代理服務(wù)器相當(dāng)于一個(gè)轉(zhuǎn)發(fā)者,轉(zhuǎn)發(fā)的消息通過(guò)主題來(lái)區(qū)分。協(xié)議模型如圖1所示。MQTT協(xié)議通過(guò)這種消息模式,可以實(shí)現(xiàn)多對(duì)多的通信,靈活性高,并且發(fā)送設(shè)備和接收設(shè)備不直接相連,實(shí)現(xiàn)了發(fā)布者與訂閱者解耦[1]。
2.4 MQTT數(shù)據(jù)包
MQTT數(shù)據(jù)包整體上可以分為固定頭、可變頭、有效載荷,其中固定頭在所有報(bào)文中都存在,而可變頭和有效載荷是否存在則取決于報(bào)文類型。
(1)固定頭(Fixed header)
固定頭在MQTT所有報(bào)文中都存在,大小為2~5 B,第一字節(jié)用來(lái)表示報(bào)文類型和標(biāo)志字段,第二字節(jié)開(kāi)始是剩余長(zhǎng)度字段。固定頭格式如表1。
表1中,Message Type用4個(gè)位表示14種消息類型;QoS level代表服務(wù)質(zhì)量:QoS0、QoS1、QoS2,等級(jí)越高對(duì)系統(tǒng)的要求越高,而效率越低;Remaining Length表示剩余長(zhǎng)度,最大4 B。
(2)可變頭(Variable header)
固定報(bào)頭之后是可變頭,不同報(bào)文的可變頭是不同的。可變報(bào)頭的報(bào)文標(biāo)識(shí)符字段并不是所有報(bào)文都存在,在客戶端發(fā)送的報(bào)文中,如果帶報(bào)文標(biāo)識(shí)符,則報(bào)文標(biāo)識(shí)符必須是當(dāng)前未使用的。
(3)有效載荷(Payload)
有效載荷是緊跟可變頭的MQTT數(shù)據(jù)包的最后一部分,存在于CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE、PUBLISH 5種報(bào)文消息中,其中PUBLISH中是要傳輸?shù)臄?shù)據(jù),可根據(jù)需要選擇是否帶有效載荷。
3 MQTT在FreeRTOS上的應(yīng)用
3.1 硬件結(jié)構(gòu)
3.1.1 應(yīng)用條件
首先在STM32上移植FreeRTOS,其次要支持TCP/IP協(xié)議。對(duì)于嵌入式系統(tǒng)來(lái)說(shuō),實(shí)現(xiàn)TCP/IP協(xié)議分為軟件方法和硬件方法,軟件上可以通過(guò)移植uIP、LwIP等協(xié)議棧實(shí)現(xiàn);硬件上可以選擇STM32互聯(lián)型產(chǎn)品,或者STM32連接以太網(wǎng)收發(fā)芯片、WiFi模塊等來(lái)實(shí)現(xiàn)。
3.1.2 硬件電路設(shè)計(jì)
本文采用STM32連接W5500芯片的方案,與其他方法相比更加快捷、簡(jiǎn)便。W5500芯片集成了TCP/IP協(xié)議棧,提供了SPI外設(shè)接口,方便了與MCU相連,使用全新的SPI協(xié)議,速率能達(dá)到80 MHz。利用W5500提供的官方驅(qū)動(dòng)庫(kù)函數(shù)與SPI接口的驅(qū)動(dòng)函數(shù),進(jìn)行必要的初始化參數(shù)配置,就可以實(shí)現(xiàn)以太網(wǎng)通信。W5500的兩種工作模式中,選用了可以與其他設(shè)備共享SPI接口的可變數(shù)據(jù)長(zhǎng)度模式(VDM),由SCSn控制數(shù)據(jù)段長(zhǎng)度,可以選擇1 B~N B的任意數(shù)據(jù)段長(zhǎng)度。硬件電路連接如圖2所示。
W5500通過(guò)SPI接口連接MCU,其中PC5用于初始化以太網(wǎng)芯片,如果連接斷開(kāi)可以通過(guò)PC5及時(shí)控制W5500,PA4~PA5用于SPI通信,PB0控制W5500的中斷生效。W5500的差分信號(hào)傳輸TXP/TXN和差分信號(hào)接收RXP/RXN,分別與網(wǎng)絡(luò)接口RJ45中的網(wǎng)絡(luò)變壓器相連,并且連接活動(dòng)狀態(tài)和網(wǎng)絡(luò)連接指示燈。選擇HR911105A作為網(wǎng)絡(luò)接口,它本身自帶網(wǎng)絡(luò)變壓器,可以增強(qiáng)信號(hào),保證了通信距離,同時(shí)使W5500與外部隔離,提高了抗干擾能力。整個(gè)電路設(shè)計(jì)簡(jiǎn)單,同時(shí)也保證了數(shù)據(jù)傳輸速度和可靠性。
3.2 報(bào)文時(shí)序
以傳輸服務(wù)質(zhì)量QoS2為例,MQTT的報(bào)文時(shí)序如圖3所示。
(1)訂閱者客戶端向代理服務(wù)器發(fā)送CONNECT報(bào)文請(qǐng)求連接,代理服務(wù)器返回CONNACK確認(rèn)連接,訂閱者客戶端與代理服務(wù)器建立了網(wǎng)絡(luò)連接;
(2)訂閱者客戶端向代理服務(wù)器發(fā)布SUBSCRIBE報(bào)文訂閱主題,代理服務(wù)器返回SUBACK確認(rèn)訂閱;
(3)發(fā)布者客戶端向代理服務(wù)器發(fā)送CONNECT報(bào)文請(qǐng)求連接,代理服務(wù)器返回CONNACK確認(rèn)連接,發(fā)布者客戶端與代理服務(wù)器建立了網(wǎng)絡(luò)連接;之后發(fā)布者通過(guò)PUBLISH發(fā)布消息。如果傳輸消息的服務(wù)質(zhì)量為QoS2,代理服務(wù)器和發(fā)布者之間會(huì)通過(guò)三步報(bào)文PUBREC、PUBREL、PUBCOMP來(lái)確定PUBLISH消息精確收到;
(4)訂閱者客戶端通過(guò)發(fā)送PINGREQ報(bào)文進(jìn)行心跳連接表示自己還連接著,代理服務(wù)器回復(fù)PINGRESP報(bào)文響應(yīng)心跳,確認(rèn)客戶端還在連接;
(5)代理服務(wù)器把從發(fā)布者客戶端接收到的特定主題的信息,轉(zhuǎn)發(fā)給訂閱此主題的客戶端;
(6)訂閱者客戶端向代理服務(wù)器發(fā)布取消訂閱主題報(bào)文UNSUBSCRIBE,代理服務(wù)器發(fā)布UNSUBACK報(bào)文,確認(rèn)收到了對(duì)方的取消訂閱報(bào)文;
(7)客戶端發(fā)送給代理服務(wù)器的最后一個(gè)控制報(bào)文,表示客戶端正常斷開(kāi)連接[1]。
3.3 任務(wù)設(shè)計(jì)以及優(yōu)先級(jí)
FreeRTOS的每個(gè)任務(wù)都可以分配一個(gè)0~(configMAX_PRIORITIES-1)的優(yōu)先級(jí),0的優(yōu)先級(jí)最低。FreeRTOS搶占式任務(wù)調(diào)度器總是保證處于就緒態(tài)或者運(yùn)行態(tài)的最高優(yōu)先級(jí)的任務(wù)運(yùn)行,而時(shí)間片輪轉(zhuǎn)調(diào)度器則是保證處于相同優(yōu)先級(jí)的任務(wù)輪轉(zhuǎn)運(yùn)行時(shí)間片的長(zhǎng)度,當(dāng)時(shí)間片用完或者調(diào)用阻塞式API函數(shù)時(shí),任務(wù)切換。時(shí)間片的長(zhǎng)度可以自己設(shè)置,時(shí)間片太短任務(wù)會(huì)頻繁地切換,降低了CPU的效率;而時(shí)間片太長(zhǎng)又會(huì)造成實(shí)時(shí)響應(yīng)變差,一般選擇100 ms[1]。FreeRTOS上的MQTT應(yīng)用包含的任務(wù)以及優(yōu)先級(jí)設(shè)計(jì)如圖4所示。
3.4 應(yīng)用
在海下通過(guò)海流計(jì)和水深計(jì)收集數(shù)據(jù),并經(jīng)過(guò)水密網(wǎng)線傳輸?shù)礁?biāo)上的服務(wù)器,代理服務(wù)器選擇mosquitto軟件。首先通過(guò)W5500的Socket編程實(shí)現(xiàn)系統(tǒng)的網(wǎng)絡(luò)通信功能,在此基礎(chǔ)上進(jìn)行MQTT的任務(wù)設(shè)計(jì)。在任務(wù)編寫過(guò)程中為了簡(jiǎn)潔將W5500數(shù)據(jù)發(fā)送和接收封裝到MQTT函數(shù)Mqtt_SendPkt、Mqtt_RecvPkt中。
(1)Receive_task:優(yōu)先級(jí)設(shè)為9。調(diào)用Mqtt_InitContext函數(shù),初始化MqttContext即MQTT運(yùn)行上下文,并將設(shè)置MqttContext中的回調(diào)函數(shù)及關(guān)聯(lián)參數(shù);調(diào)用Mqtt_RecvPkt函數(shù)接收服務(wù)器消息,函數(shù)內(nèi)封裝了W5500的接收函數(shù),當(dāng)接收到數(shù)據(jù)會(huì)進(jìn)入中斷,調(diào)用函數(shù)讀取。在Mqtt_RecvPkt函數(shù)中對(duì)接收到的數(shù)據(jù)進(jìn)行解析,低于2 B的數(shù)據(jù)標(biāo)記錯(cuò)誤。調(diào)用Mqtt_Dispatch函數(shù)對(duì)收到的數(shù)據(jù)的第一個(gè)字節(jié)高4位控制報(bào)文類型進(jìn)行解析,根據(jù)報(bào)文類型回調(diào)響應(yīng)函數(shù)或者設(shè)置標(biāo)志位。例如收到的是PUBREC控制報(bào)文,則調(diào)用響應(yīng)函數(shù)發(fā)布PUBREL報(bào)文。任務(wù)流程如圖5所示。
(2)Heart_task:優(yōu)先級(jí)設(shè)為8。在網(wǎng)絡(luò)連接的情況下通過(guò)Mqtt_PackPingReqPkt封裝數(shù)據(jù)包,PINGREQ報(bào)文固定頭部第一字節(jié)高4位設(shè)為12,即報(bào)文類型為心跳請(qǐng)求,低4位為0,剩余長(zhǎng)度字節(jié)為0,即沒(méi)有可變報(bào)頭和有效載荷,通過(guò)Mqtt_SendPkt發(fā)送后掛起任務(wù),等待響應(yīng)。當(dāng)接收任務(wù)收到了消息并解析為PINGRESP報(bào)文,標(biāo)記收到心跳響應(yīng);若超過(guò)檢測(cè)次數(shù)還沒(méi)有收到心跳響應(yīng),則調(diào)用getSn_SR函數(shù),獲取Socket連接狀態(tài);如果連接失敗,標(biāo)記設(shè)備錯(cuò)誤,否則標(biāo)記協(xié)議錯(cuò)誤,之后掛起任務(wù)2 min15 s。在CONNECT報(bào)文的可變報(bào)頭中設(shè)置心跳時(shí)間Keep Alive,單位是s,這里設(shè)置為180。任務(wù)流程如圖6所示。
(3)Fault_task:優(yōu)先級(jí)為7。根據(jù)標(biāo)志位,如果協(xié)議出錯(cuò),則發(fā)送DISCONNECT報(bào)文,然后發(fā)送CONNECT報(bào)文進(jìn)行重新連接;如果設(shè)備出錯(cuò),則發(fā)送DISCONNECT報(bào)文,斷開(kāi)網(wǎng)絡(luò)連接,進(jìn)行W5500芯片的初始化,最后進(jìn)行MQTT重新連接。
(4)Sensor_task:優(yōu)先級(jí)為6。檢測(cè)海流計(jì)和水深計(jì)的存在,并讀取海流計(jì)或水深計(jì)的數(shù)據(jù)。
(5)Send_task:優(yōu)先級(jí)為5。在網(wǎng)絡(luò)連接的情況下,調(diào)用Mqtt_PackPublishPkt封裝數(shù)據(jù),設(shè)置報(bào)文格式為PUBLISH,服務(wù)質(zhì)量為至少分發(fā)一次,retain設(shè)置為1。在水深計(jì)中報(bào)文設(shè)置如表2,設(shè)置固定報(bào)頭剩余長(zhǎng)度為13、可變報(bào)頭主題名為depth、有效載荷為4 B的水深計(jì)數(shù)據(jù);在海流計(jì)中設(shè)置固定報(bào)頭剩余長(zhǎng)度為59、可變報(bào)頭主題名為current、有效載荷是海流計(jì)的數(shù)據(jù),其中第5~8個(gè)字節(jié)為溫度,第29~32字節(jié)是方位,第33~36字節(jié)是流速,第45~48字節(jié)是電壓。例如:海流計(jì)數(shù)據(jù)pval,9.381,-0.311,-0.993,-0.221,0.340,0.439,197.586,
164.580,-0.423,0.117,12.132。調(diào)用Mqtt_SendPkt發(fā)送數(shù)據(jù)。最后掛起任務(wù)2 min。數(shù)據(jù)封裝和發(fā)送在臨界段內(nèi)執(zhí)行,防止被中斷打斷。
(6)Key_task:優(yōu)先級(jí)為4。掃描按鍵,不同按鍵分別代表訂閱消息、取消訂閱和發(fā)布消息。
(7)Net _task:優(yōu)先級(jí)設(shè)為3。首先初始化W5500以太網(wǎng)芯片,進(jìn)行網(wǎng)絡(luò)連接,然后Mqtt_PackConnectPkt封裝連接包。固定頭中報(bào)文類型設(shè)為CONNECT,在可變頭中設(shè)置協(xié)議名為MQTT,協(xié)議級(jí)別的值為4,即3.1.1版本。本文不支持遺囑,故連接標(biāo)志字節(jié)設(shè)為0xC6,設(shè)置Keep_alive為180 s,根據(jù)連接標(biāo)志字節(jié)的設(shè)置,在有效載荷中按順序設(shè)置客戶端標(biāo)識(shí)符、用戶名、密碼。由Mqtt_SendPkt發(fā)送連接包,如果接收任務(wù)收到了服務(wù)器發(fā)來(lái)的CONNACK,蜂鳴器短鳴5次,提示成功;如果超時(shí)還沒(méi)連接成功,蜂鳴器長(zhǎng)叫,提示失敗,并標(biāo)記為硬件錯(cuò)誤,然后初始化W5500,重新進(jìn)行網(wǎng)絡(luò)連接。任務(wù)流程如圖7所示。
(8)Date_task:優(yōu)先級(jí)設(shè)為2。根據(jù)按鍵任務(wù)設(shè)置的不同標(biāo)志位執(zhí)行不同的命令函數(shù),上傳數(shù)據(jù)函數(shù)、發(fā)布消息函數(shù)、訂閱消息函數(shù)以及取消訂閱函數(shù)。其中海流計(jì)中訂閱消息函數(shù)在有效載荷中設(shè)置主題名為depth,獲取水深計(jì)數(shù)據(jù);水深計(jì)中訂閱消息函數(shù)在有效載荷中設(shè)置主題名為current,獲取海流計(jì)數(shù)據(jù),設(shè)置服務(wù)質(zhì)量QoS為1。
4 結(jié)論
本文應(yīng)用了海流計(jì)和水深計(jì)收集數(shù)據(jù),在此基礎(chǔ)上可以加入更多傳感器收集數(shù)據(jù),形成海洋監(jiān)測(cè)網(wǎng)絡(luò),實(shí)現(xiàn)物物相連。通過(guò)對(duì)服務(wù)器獲取的信息進(jìn)行分析就能獲取當(dāng)前海洋的信息數(shù)據(jù),實(shí)現(xiàn)了對(duì)海洋的實(shí)時(shí)監(jiān)測(cè)。
參考文獻(xiàn)
[1] 劉濱.嵌入式操作系統(tǒng)FreeRTOS的原理與實(shí)現(xiàn)[J].單片機(jī)與嵌入式系統(tǒng),2005(7):8-11.
[2] 馬躍,孫翱,賈軍營(yíng).MQTT協(xié)議在移動(dòng)互聯(lián)網(wǎng)即時(shí)通信中的應(yīng)用[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2016(3):170-176.
[3] 姚丹,謝雪松.基于MQTT協(xié)議的物聯(lián)網(wǎng)通信系統(tǒng)的研究與實(shí)現(xiàn)[J].信息通信,2016(3):33-35.
[4] 王慧明.FreeRTOS在coldfire上的實(shí)現(xiàn)和應(yīng)用[J].微計(jì)算機(jī)信息,2016(7):74-76.
作者信息:
朱明輝1,2,趙信廣1,2,尤星懿1
1.山東科技大學(xué) 電氣與自動(dòng)化工程學(xué)院,山東 青島266590;2.山東省科學(xué)院 海洋儀器儀表研究所,山東 青島266100