文獻(xiàn)標(biāo)識(shí)碼: A
DOI:10.16157/j.issn.0258-7998.172451
中文引用格式: 朱明輝,,趙信廣,尤星懿. 基于FreeRTOS和MQTT的海洋監(jiān)測網(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 引言
隨著海洋的不斷開發(fā),、探索,以及生活垃圾等污染物的排放,,海洋環(huán)境遭到嚴(yán)重破壞,,因此保護(hù)海洋環(huán)境刻不容緩。為了加強(qiáng)海洋環(huán)境的保護(hù),,提高對(duì)海洋環(huán)境的合理開發(fā)利用,,人們迫切地需要提高海洋監(jiān)測技術(shù),實(shí)現(xiàn)對(duì)海洋信息實(shí)時(shí)監(jiān)測,,更好地實(shí)現(xiàn)災(zāi)害預(yù)警,、資源利用,、環(huán)境保護(hù)以及各種軍事活動(dòng)。海洋監(jiān)測基于傳感器網(wǎng)絡(luò)實(shí)現(xiàn),,通過多個(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ì)簡單,功能的拓展也比較容易,。在數(shù)據(jù)傳輸上,,消息隊(duì)列遙測傳輸(Message Queuing Telemetry Transport,MQTT)協(xié)議設(shè)計(jì)之初充分考慮了網(wǎng)絡(luò)的不確定性,,協(xié)議代碼量少,,報(bào)文精簡,可以適應(yīng)不理想的網(wǎng)絡(luò)條件,,提供實(shí)時(shí)可靠的消息服務(wù),。因此對(duì)于海洋監(jiān)測網(wǎng)絡(luò)來說,在實(shí)時(shí)操作系統(tǒng)上利用傳感器網(wǎng)絡(luò)采集數(shù)據(jù)并通過MQTT協(xié)議進(jìn)行交互成為一種可靠的選擇,。
1 FreeRTOS簡介
FreeRTOS操作系統(tǒng)內(nèi)核占用空間小,,實(shí)時(shí)性高,源碼公開,、可移植,,可以在資源有限的微控制器中運(yùn)行。FreeRTOS在任務(wù)調(diào)度上支持搶占式,、合作式和時(shí)間片式,,任務(wù)數(shù)量沒有限制,不同任務(wù)可以設(shè)置不同的優(yōu)先級(jí),,優(yōu)先級(jí)隨數(shù)值的增大而提高,,同一優(yōu)先級(jí)也可以設(shè)置不同任務(wù)[1]。與其他嵌入式操作系統(tǒng)相比,,F(xiàn)reeRTOS比較簡單,,上手容易,商業(yè)上免費(fèi),,而且社會(huì)占有量高,。
2 MQTT協(xié)議
2.1 MQTT簡介
MQTT是一款發(fā)布/訂閱(publish/subscribe)模式的消息傳輸協(xié)議。該協(xié)議構(gòu)建于TCP/IP協(xié)議上,,并且具有簡單,、規(guī)范,、開銷低、易于實(shí)現(xiàn)的特點(diǎn),。這些特點(diǎn)使得它對(duì)于一些要求低功耗,、低帶寬等受限的環(huán)境來說是很好的選擇,因此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)文的精簡,減少對(duì)網(wǎng)絡(luò)質(zhì)量的依賴,;
(5)客戶端異常中斷的通知機(jī)制,。
2.3 MQTT結(jié)構(gòu)
MQTT協(xié)議中有發(fā)布者、代理服務(wù)器,、訂閱者3種身份,。客戶端和代理服務(wù)器首先需要通過交互連接請(qǐng)求報(bào)文來建立連接,,之后客戶端向代理服務(wù)器發(fā)布消息,,而訂閱者可以向消息代理服務(wù)器訂閱消息。在此協(xié)議模型中代理服務(wù)器相當(dāng)于一個(gè)轉(zhuǎn)發(fā)者,,轉(zhuǎn)發(fā)的消息通過主題來區(qū)分,。協(xié)議模型如圖1所示。MQTT協(xié)議通過這種消息模式,,可以實(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é)用來表示報(bào)文類型和標(biāo)志字段,,第二字節(jié)開始是剩余長度字段。固定頭格式如表1,。
表1中,,Message Type用4個(gè)位表示14種消息類型,;QoS level代表服務(wù)質(zhì)量:QoS0、QoS1,、QoS2,,等級(jí)越高對(duì)系統(tǒng)的要求越高,而效率越低,;Remaining Length表示剩余長度,,最大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)來說,實(shí)現(xiàn)TCP/IP協(xié)議分為軟件方法和硬件方法,,軟件上可以通過移植uIP,、LwIP等協(xié)議棧實(shí)現(xiàn);硬件上可以選擇STM32互聯(lián)型產(chǎn)品,,或者STM32連接以太網(wǎng)收發(fā)芯片,、WiFi模塊等來實(shí)現(xiàn)。
3.1.2 硬件電路設(shè)計(jì)
本文采用STM32連接W5500芯片的方案,,與其他方法相比更加快捷,、簡便。W5500芯片集成了TCP/IP協(xié)議棧,,提供了SPI外設(shè)接口,,方便了與MCU相連,使用全新的SPI協(xié)議,,速率能達(dá)到80 MHz,。利用W5500提供的官方驅(qū)動(dòng)庫函數(shù)與SPI接口的驅(qū)動(dòng)函數(shù),,進(jìn)行必要的初始化參數(shù)配置,就可以實(shí)現(xiàn)以太網(wǎng)通信,。W5500的兩種工作模式中,,選用了可以與其他設(shè)備共享SPI接口的可變數(shù)據(jù)長度模式(VDM),由SCSn控制數(shù)據(jù)段長度,,可以選擇1 B~N B的任意數(shù)據(jù)段長度,。硬件電路連接如圖2所示。
W5500通過SPI接口連接MCU,,其中PC5用于初始化以太網(wǎng)芯片,,如果連接斷開可以通過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ì)簡單,同時(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ā)布者通過PUBLISH發(fā)布消息,。如果傳輸消息的服務(wù)質(zhì)量為QoS2,,代理服務(wù)器和發(fā)布者之間會(huì)通過三步報(bào)文PUBREC、PUBREL,、PUBCOMP來確定PUBLISH消息精確收到,;
(4)訂閱者客戶端通過發(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)文,,表示客戶端正常斷開連接[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í)間片的長度,當(dāng)時(shí)間片用完或者調(diào)用阻塞式API函數(shù)時(shí),,任務(wù)切換,。時(shí)間片的長度可以自己設(shè)置,時(shí)間片太短任務(wù)會(huì)頻繁地切換,,降低了CPU的效率,;而時(shí)間片太長又會(huì)造成實(shí)時(shí)響應(yīng)變差,一般選擇100 ms[1],。FreeRTOS上的MQTT應(yīng)用包含的任務(wù)以及優(yōu)先級(jí)設(shè)計(jì)如圖4所示,。
3.4 應(yīng)用
在海下通過海流計(jì)和水深計(jì)收集數(shù)據(jù),并經(jīng)過水密網(wǎng)線傳輸?shù)礁?biāo)上的服務(wù)器,,代理服務(wù)器選擇mosquitto軟件,。首先通過W5500的Socket編程實(shí)現(xiàn)系統(tǒng)的網(wǎng)絡(luò)通信功能,在此基礎(chǔ)上進(jìn)行MQTT的任務(wù)設(shè)計(jì),。在任務(wù)編寫過程中為了簡潔將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ò)連接的情況下通過Mqtt_PackPingReqPkt封裝數(shù)據(jù)包,,PINGREQ報(bào)文固定頭部第一字節(jié)高4位設(shè)為12,,即報(bào)文類型為心跳請(qǐng)求,低4位為0,,剩余長度字節(jié)為0,,即沒有可變報(bào)頭和有效載荷,通過Mqtt_SendPkt發(fā)送后掛起任務(wù),,等待響應(yīng),。當(dāng)接收任務(wù)收到了消息并解析為PINGRESP報(bào)文,標(biāo)記收到心跳響應(yīng),;若超過檢測次數(shù)還沒有收到心跳響應(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)文,,斷開網(wǎng)絡(luò)連接,,進(jìn)行W5500芯片的初始化,最后進(jìn)行MQTT重新連接,。
(4)Sensor_task:優(yōu)先級(jí)為6,。檢測海流計(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)頭剩余長度為13、可變報(bào)頭主題名為depth,、有效載荷為4 B的水深計(jì)數(shù)據(jù),;在海流計(jì)中設(shè)置固定報(bào)頭剩余長度為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ā)來的CONNACK,蜂鳴器短鳴5次,,提示成功,;如果超時(shí)還沒連接成功,蜂鳴器長叫,,提示失敗,,并標(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)測網(wǎng)絡(luò),,實(shí)現(xiàn)物物相連,。通過對(duì)服務(wù)器獲取的信息進(jìn)行分析就能獲取當(dāng)前海洋的信息數(shù)據(jù),,實(shí)現(xiàn)了對(duì)海洋的實(shí)時(shí)監(jiān)測。
參考文獻(xiàn)
[1] 劉濱.嵌入式操作系統(tǒng)FreeRTOS的原理與實(shí)現(xiàn)[J].單片機(jī)與嵌入式系統(tǒng),,2005(7):8-11.
[2] 馬躍,,孫翱,賈軍營.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