文献标识码: A
DOI:10.16157/j.issn.0258-7998.172451
中文引用格式: 朱明辉,赵信广,尤星懿. 基于FreeRTOS和MQTT的海洋监测网络框架[J].电子技术应用,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 引言
随着海洋的不断开发、探索,以及生活垃圾等污染物的排放,海洋环境遭到严重破坏,因此保护海洋环境刻不容缓。为了加强海洋环境的保护,提高对海洋环境的合理开发利用,人们迫切地需要提高海洋监测技术,实现对海洋信息实时监测,更好地实现灾害预警、资源利用、环境保护以及各种军事活动。海洋监测基于传感器网络实现,通过多个传感器构成传感器网络采集数据并上传到控制中心实现。传统的单片机进行传感器数据的采集与传输,只能进行单任务,在较复杂的数据采集传输中就显得力不从心。而实时操作系统可以设置多个任务,每个任务执行的周期是可靠的,可以优先快速地执行对实时性要求高的事件,并且程序的设计相对简单,功能的拓展也比较容易。在数据传输上,消息队列遥测传输(Message Queuing Telemetry Transport,MQTT)协议设计之初充分考虑了网络的不确定性,协议代码量少,报文精简,可以适应不理想的网络条件,提供实时可靠的消息服务。因此对于海洋监测网络来说,在实时操作系统上利用传感器网络采集数据并通过MQTT协议进行交互成为一种可靠的选择。
1 FreeRTOS简介
FreeRTOS操作系统内核占用空间小,实时性高,源码公开、可移植,可以在资源有限的微控制器中运行。FreeRTOS在任务调度上支持抢占式、合作式和时间片式,任务数量没有限制,不同任务可以设置不同的优先级,优先级随数值的增大而提高,同一优先级也可以设置不同任务[1]。与其他嵌入式操作系统相比,FreeRTOS比较简单,上手容易,商业上免费,而且社会占有量高。
2 MQTT协议
2.1 MQTT简介
MQTT是一款发布/订阅(publish/subscribe)模式的消息传输协议。该协议构建于TCP/IP协议上,并且具有简单、规范、开销低、易于实现的特点。这些特点使得它对于一些要求低功耗、低带宽等受限的环境来说是很好的选择,因此MQTT协议被广泛应用在物-物通信以及物联网中。
2.2 MQTT特点
(1)MQTT可以实现消息一对多分发;
(2)对负载内容屏蔽;
(3)传输消息提供3种服务质量,用户可根据实际应用权衡效率与服务质量;
(4)协议报文的精简,减少对网络质量的依赖;
(5)客户端异常中断的通知机制。
2.3 MQTT结构
MQTT协议中有发布者、代理服务器、订阅者3种身份。客户端和代理服务器首先需要通过交互连接请求报文来建立连接,之后客户端向代理服务器发布消息,而订阅者可以向消息代理服务器订阅消息。在此协议模型中代理服务器相当于一个转发者,转发的消息通过主题来区分。协议模型如图1所示。MQTT协议通过这种消息模式,可以实现多对多的通信,灵活性高,并且发送设备和接收设备不直接相连,实现了发布者与订阅者解耦[1]。
2.4 MQTT数据包
MQTT数据包整体上可以分为固定头、可变头、有效载荷,其中固定头在所有报文中都存在,而可变头和有效载荷是否存在则取决于报文类型。
(1)固定头(Fixed header)
固定头在MQTT所有报文中都存在,大小为2~5 B,第一字节用来表示报文类型和标志字段,第二字节开始是剩余长度字段。固定头格式如表1。
表1中,Message Type用4个位表示14种消息类型;QoS level代表服务质量:QoS0、QoS1、QoS2,等级越高对系统的要求越高,而效率越低;Remaining Length表示剩余长度,最大4 B。
(2)可变头(Variable header)
固定报头之后是可变头,不同报文的可变头是不同的。可变报头的报文标识符字段并不是所有报文都存在,在客户端发送的报文中,如果带报文标识符,则报文标识符必须是当前未使用的。
(3)有效载荷(Payload)
有效载荷是紧跟可变头的MQTT数据包的最后一部分,存在于CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE、PUBLISH 5种报文消息中,其中PUBLISH中是要传输的数据,可根据需要选择是否带有效载荷。
3 MQTT在FreeRTOS上的应用
3.1 硬件结构
3.1.1 应用条件
首先在STM32上移植FreeRTOS,其次要支持TCP/IP协议。对于嵌入式系统来说,实现TCP/IP协议分为软件方法和硬件方法,软件上可以通过移植uIP、LwIP等协议栈实现;硬件上可以选择STM32互联型产品,或者STM32连接以太网收发芯片、WiFi模块等来实现。
3.1.2 硬件电路设计
本文采用STM32连接W5500芯片的方案,与其他方法相比更加快捷、简便。W5500芯片集成了TCP/IP协议栈,提供了SPI外设接口,方便了与MCU相连,使用全新的SPI协议,速率能达到80 MHz。利用W5500提供的官方驱动库函数与SPI接口的驱动函数,进行必要的初始化参数配置,就可以实现以太网通信。W5500的两种工作模式中,选用了可以与其他设备共享SPI接口的可变数据长度模式(VDM),由SCSn控制数据段长度,可以选择1 B~N B的任意数据段长度。硬件电路连接如图2所示。
W5500通过SPI接口连接MCU,其中PC5用于初始化以太网芯片,如果连接断开可以通过PC5及时控制W5500,PA4~PA5用于SPI通信,PB0控制W5500的中断生效。W5500的差分信号传输TXP/TXN和差分信号接收RXP/RXN,分别与网络接口RJ45中的网络变压器相连,并且连接活动状态和网络连接指示灯。选择HR911105A作为网络接口,它本身自带网络变压器,可以增强信号,保证了通信距离,同时使W5500与外部隔离,提高了抗干扰能力。整个电路设计简单,同时也保证了数据传输速度和可靠性。
3.2 报文时序
以传输服务质量QoS2为例,MQTT的报文时序如图3所示。
(1)订阅者客户端向代理服务器发送CONNECT报文请求连接,代理服务器返回CONNACK确认连接,订阅者客户端与代理服务器建立了网络连接;
(2)订阅者客户端向代理服务器发布SUBSCRIBE报文订阅主题,代理服务器返回SUBACK确认订阅;
(3)发布者客户端向代理服务器发送CONNECT报文请求连接,代理服务器返回CONNACK确认连接,发布者客户端与代理服务器建立了网络连接;之后发布者通过PUBLISH发布消息。如果传输消息的服务质量为QoS2,代理服务器和发布者之间会通过三步报文PUBREC、PUBREL、PUBCOMP来确定PUBLISH消息精确收到;
(4)订阅者客户端通过发送PINGREQ报文进行心跳连接表示自己还连接着,代理服务器回复PINGRESP报文响应心跳,确认客户端还在连接;
(5)代理服务器把从发布者客户端接收到的特定主题的信息,转发给订阅此主题的客户端;
(6)订阅者客户端向代理服务器发布取消订阅主题报文UNSUBSCRIBE,代理服务器发布UNSUBACK报文,确认收到了对方的取消订阅报文;
(7)客户端发送给代理服务器的最后一个控制报文,表示客户端正常断开连接[1]。
3.3 任务设计以及优先级
FreeRTOS的每个任务都可以分配一个0~(configMAX_PRIORITIES-1)的优先级,0的优先级最低。FreeRTOS抢占式任务调度器总是保证处于就绪态或者运行态的最高优先级的任务运行,而时间片轮转调度器则是保证处于相同优先级的任务轮转运行时间片的长度,当时间片用完或者调用阻塞式API函数时,任务切换。时间片的长度可以自己设置,时间片太短任务会频繁地切换,降低了CPU的效率;而时间片太长又会造成实时响应变差,一般选择100 ms[1]。FreeRTOS上的MQTT应用包含的任务以及优先级设计如图4所示。
3.4 应用
在海下通过海流计和水深计收集数据,并经过水密网线传输到浮标上的服务器,代理服务器选择mosquitto软件。首先通过W5500的Socket编程实现系统的网络通信功能,在此基础上进行MQTT的任务设计。在任务编写过程中为了简洁将W5500数据发送和接收封装到MQTT函数Mqtt_SendPkt、Mqtt_RecvPkt中。
(1)Receive_task:优先级设为9。调用Mqtt_InitContext函数,初始化MqttContext即MQTT运行上下文,并将设置MqttContext中的回调函数及关联参数;调用Mqtt_RecvPkt函数接收服务器消息,函数内封装了W5500的接收函数,当接收到数据会进入中断,调用函数读取。在Mqtt_RecvPkt函数中对接收到的数据进行解析,低于2 B的数据标记错误。调用Mqtt_Dispatch函数对收到的数据的第一个字节高4位控制报文类型进行解析,根据报文类型回调响应函数或者设置标志位。例如收到的是PUBREC控制报文,则调用响应函数发布PUBREL报文。任务流程如图5所示。
(2)Heart_task:优先级设为8。在网络连接的情况下通过Mqtt_PackPingReqPkt封装数据包,PINGREQ报文固定头部第一字节高4位设为12,即报文类型为心跳请求,低4位为0,剩余长度字节为0,即没有可变报头和有效载荷,通过Mqtt_SendPkt发送后挂起任务,等待响应。当接收任务收到了消息并解析为PINGRESP报文,标记收到心跳响应;若超过检测次数还没有收到心跳响应,则调用getSn_SR函数,获取Socket连接状态;如果连接失败,标记设备错误,否则标记协议错误,之后挂起任务2 min15 s。在CONNECT报文的可变报头中设置心跳时间Keep Alive,单位是s,这里设置为180。任务流程如图6所示。
(3)Fault_task:优先级为7。根据标志位,如果协议出错,则发送DISCONNECT报文,然后发送CONNECT报文进行重新连接;如果设备出错,则发送DISCONNECT报文,断开网络连接,进行W5500芯片的初始化,最后进行MQTT重新连接。
(4)Sensor_task:优先级为6。检测海流计和水深计的存在,并读取海流计或水深计的数据。
(5)Send_task:优先级为5。在网络连接的情况下,调用Mqtt_PackPublishPkt封装数据,设置报文格式为PUBLISH,服务质量为至少分发一次,retain设置为1。在水深计中报文设置如表2,设置固定报头剩余长度为13、可变报头主题名为depth、有效载荷为4 B的水深计数据;在海流计中设置固定报头剩余长度为59、可变报头主题名为current、有效载荷是海流计的数据,其中第5~8个字节为温度,第29~32字节是方位,第33~36字节是流速,第45~48字节是电压。例如:海流计数据pval,9.381,-0.311,-0.993,-0.221,0.340,0.439,197.586,
164.580,-0.423,0.117,12.132。调用Mqtt_SendPkt发送数据。最后挂起任务2 min。数据封装和发送在临界段内执行,防止被中断打断。
(6)Key_task:优先级为4。扫描按键,不同按键分别代表订阅消息、取消订阅和发布消息。
(7)Net _task:优先级设为3。首先初始化W5500以太网芯片,进行网络连接,然后Mqtt_PackConnectPkt封装连接包。固定头中报文类型设为CONNECT,在可变头中设置协议名为MQTT,协议级别的值为4,即3.1.1版本。本文不支持遗嘱,故连接标志字节设为0xC6,设置Keep_alive为180 s,根据连接标志字节的设置,在有效载荷中按顺序设置客户端标识符、用户名、密码。由Mqtt_SendPkt发送连接包,如果接收任务收到了服务器发来的CONNACK,蜂鸣器短鸣5次,提示成功;如果超时还没连接成功,蜂鸣器长叫,提示失败,并标记为硬件错误,然后初始化W5500,重新进行网络连接。任务流程如图7所示。
(8)Date_task:优先级设为2。根据按键任务设置的不同标志位执行不同的命令函数,上传数据函数、发布消息函数、订阅消息函数以及取消订阅函数。其中海流计中订阅消息函数在有效载荷中设置主题名为depth,获取水深计数据;水深计中订阅消息函数在有效载荷中设置主题名为current,获取海流计数据,设置服务质量QoS为1。
4 结论
本文应用了海流计和水深计收集数据,在此基础上可以加入更多传感器收集数据,形成海洋监测网络,实现物物相连。通过对服务器获取的信息进行分析就能获取当前海洋的信息数据,实现了对海洋的实时监测。
参考文献
[1] 刘滨.嵌入式操作系统FreeRTOS的原理与实现[J].单片机与嵌入式系统,2005(7):8-11.
[2] 马跃,孙翱,贾军营.MQTT协议在移动互联网即时通信中的应用[J].计算机系统应用,2016(3):170-176.
[3] 姚丹,谢雪松.基于MQTT协议的物联网通信系统的研究与实现[J].信息通信,2016(3):33-35.
[4] 王慧明.FreeRTOS在coldfire上的实现和应用[J].微计算机信息,2016(7):74-76.
作者信息:
朱明辉1,2,赵信广1,2,尤星懿1
1.山东科技大学 电气与自动化工程学院,山东 青岛266590;2.山东省科学院 海洋仪器仪表研究所,山东 青岛266100