文獻(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ù)編寫(xiě)過(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