龙芯技术社区
直播中

ALSET

3年用户 269经验值
擅长:可编程逻辑,电源/新能源,嵌入式技术,处理器/DSP
私信 关注

【广东龙芯2K500先锋板试用体验】4.移植开发MQTT服务与MQTT通讯测试

W801通过2K500上发wifi信号强度数据

【广东龙芯2K500先锋板试用体验】4.移植开发MQTT服务与MQTT通讯测试

大信(QQ:8125036)

       龙芯2K500先锋板采用龙芯2K0500芯片,龙芯2K500片内集成64位LA264处理器核、32位DDR3控制器、2D GPU、DVO显示接口、两路PCIe2.0、两路SATA2.0、四路USB2.0、一路USB3.0、两路GMAC、PCI总线、HDA及其他常用接口,可用于工业物联网的数据采集,消息收发等应用场景。
      本次测试以在LS-2K500上实现嵌入式的消息代理服务为目标,并测试物联通讯功能。常用的物联消息协议是MQTT协议,它是现在智能设备硬件广泛支持的一种消息协议。本次基于该硬件平台尝试开发测试MQTT服务,做相关的消息收发测试,验证其作为MQTT消息代理服务的实现。
1.png

一、MQTT简介

       MQTT 协议由 AndyStanford-Clark (IBM) 和 Arlen Nipper(Arcom,现为 Cirrus Link)于 1999 年发明。 他们需要一种通过卫星连接石油管道的协议,以最大限度地减少电池损耗和带宽。所以他们为这个协议规定了几种要求:
1、这个协议必须易于实现;
2、这个协议中的数据必须易于传输,消耗成本小;
3、这个协议必须提供服务质量管理;
4、这个协议必须支持连续的会话控制;
5、假设数据不可知,不强求传输数据的类型与格式,保持灵活性。
      MQTT(MessageQueuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议, 该协议构建于TCP/IP协议上,是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
      MQTT 协议可以为大量的低功率、工作网络环境不可靠的物联网设备提供通讯保障。而它的应用范围也不仅如此,在移动互联网领域也大有作为:很多 Android App 的推送功能,都是基于 MQTT 实现的,也有一些 IM的实现也是基于 MQTT 的。
2.png

二、MQTT典型架构
      MQTT服务器一般也叫做MQTTBroker,MQTT消息代理服务器。MQTT Broker可以非常简单地在Raspberry Pi或NAS等单板计算机上实现,也可以在大型机或 Internet 服务器上实现。服务器分发消息,因此必须是发布者,客户端可以发布消息(发送方)、订阅消息(接收方)或两者兼而有之。
     客户端(也称为节点)是一种智能设备,如微控制器或具有 TCP/IP 堆栈和实现 MQTT 协议的软件的计算机。消息在允许过滤的主题下发布。主题是分层划分的 UTF-8 字符串。不同的主题级别用斜杠/作为分隔符号。
这些设计也是MQTT 的精髓所在,MQTT 经过不断的发展,已经成为了物联网 IoT 所必备的一种消息探测协议,官方强烈推荐使用的版本是 MQTT 5。
     在pub/sub 的架构模式中,broker能够对消息进行过滤,使每个订阅者只接收自己感兴趣的消息。broker 有主题的过滤、内容的过滤、类型的过滤几种方式。MQTT 具有三个服务质量级别,可以指定消息从客户端传到 broker 或者从 broker 传到客户端的服务质量,在 topic 的订阅中,会存在 topic 没有 subscriber 订阅的情况。
三、MQTT的几个开源工程
    MQTT的软件开源资料比较多,有各种各样的实现。本次以在龙芯2K500开发板上实现MQTT服务为目标,主要研究c/c++的MQTT消息服务器即broker和其它相关消息收发工具的实现。这有一个MQTT服务Broker技术选型的资料可参考。
    https://www.jianshu.com/p/3e33adcb0ed5


   通过调查,找到了几个常用的c/c++的MQTT开源工程:
1.mqttclient一个MQTT 消息客户端c/c++工程,使用了paho mqtt库
    https://github.com/jiejieTop/mqttclient
2.paho mqtt 库,网上很多MQTT工具使用的库,该库在很多系统上有了实现,如linux,win,RTos,TencentOS等,使用普遍
    https://github.com/eclipse/paho.mqtt.c.git
3. Mosquitto 是一个完整的MQTT服务和客户端开源工程,具有brocker消息转发服和发布、订阅客户端以及各测试工具
经过分析后,本次测试目标就以Mosquitto 工程在龙芯2K500开发板上的移植和实现为主。Mosquitto的各个release版本:
3.png

四、移植编译mosquitto工程
    看mosquitto的readme介绍,可见支持协议比较全,还包含了库和客户端工具和示例应用。
Mosquitto is an open sourceimplementation of a server for version 5.0, 3.1.1, and 3.1 of the MQTTprotocol. It also includes a C and C++ client library, and the `mosquitto_pub`and `mosquitto_sub` utilities for publishing and subscribing.
    经过探索和研究编译后,这里回头总结了记录在LS_2K500上编译mosquitto工程步骤和方法。为了更好的进行交叉测试MQTT,分别在目标板上和Ubuntu主机上两个平台上分别进行编译该工程以及所有的工具,方便交叉测试与验证。
    编译mosquitto中发现,该工程依赖这几个工程zlib, cJson 和openssl,而ubuntu和2K500的交叉编译SDK中都没有这几个库,因此需要分别从源码编译它们了。

1.编译2K500下的cJSON
1.1从github上拉取cJSON稳定板的源码
sudo git clone https://github.com/DaveGamble/cJSON.git
4.png
1.2修改makefile
5.png
1.3编译cJSON
切换交叉编译环境后,直接make进行编译即可。
6.png
1.4修改工程目录
因为mosquitto工程中引用cJSON的头文件的路径问题,经过研究发现需要移动一下cJSON的目录。
在当前工程下建立 cjson (注意大小写),然后把工程所有资料移入该目录下,即深入一级,这样后面才不用改代码而直接编译。
2.编译Ubuntu下的cJSON
重新进入shell后,不切换交叉编译环境,直接编译即可。
7.png
这样就编译成功得到了2K500和Ubuntu Linux两个版本的cJSON库,可以在根目录下建 bin目录,目录下建立 x86,loongson目录,分别存放编译出的不同平台的libcjson.so 库文件。
3.编译2K500下的openssl  
3.1拉取openssl最近的稳定版本代码
https://github.com/openssl/openssl.git
8.png
3.2编译配置脚本
在工程目录下编写一个执行开发板下的配置的命令行脚本,内容如下:
9.png
3.3执行编译配置命令
执行上面编写的编译配置命令:
10.png
3.4修改make脚本文件
执行配置编译后,生成了makefile等文件,因为工程是放在虚机的共享目录中,无法适用ln –s创建链接, 因此需要修改makefile.in 文件1862行,修改为以下内容:
11.png
3.5执行make编译
修改完后,再执行切换交叉环境命令
source~/cross_LA64.txt   
然后再执行
Make –j4
12.png
大约5~6分钟后,编译完成。把编译出的lib下的lib库文件和client,samples ,test下的可执行文件放到 bin/loognarch64目录下。
4 编译x86-linux 版本的openssl
4.1清空上次编译结果
重新进入shell 后,首先执行清空工程编译。
makedistclean
4.2 配置x86-linux编译脚本
13.png
4.3执行编译配置脚本
14.png
4.3修改makefile相关文件
修改 Makefile.in:1862 行为以下内容
cp -R$full $simple
4.4 执行编译
15.png
同样将编译得道的 libopenssl.so 和 libcrypto.so 文件复制到 bin/lib/x86目录下。
5. 编译2K500下的zlib
由于loongarch64 的SDK里没有zlib这个库,因此需要单独编译一个zlib的LS-2K500的版本
5.1拉取zlib源码代码
执行命令
Sudo git clone https://github.com/madler/zlib.git
16.png
5.2执行配置编译
执行
. ~/cross_LA64.txt
./configure
17.png
5.3编译
18.png
6编译LS-2K500目标板的mosquitto工程
6.1拉取mosquitto最近的稳定版本2.0.9  
执行命令:
sudo git clonehttps://github.com/eclipse/mosquitto.git  -b debian
19.png
6.2 配置交叉编译环境
先切换交叉环境,执行
source ~/cross_LA64.txt
然后在命令行修改编译环境变量,加入前面编译出的cJSON,zLib和openssl的头文件和库文件位置,命令如下:
export CPPFLAGS="-I/mnt/hgfs/LS_2K500/proj/openssl/include-I/mnt/hgfs/LS_2K500/proj/cJSON"
exportLDFLAGS="-L/mnt/hgfs/LS_2K500/proj/openssl-L/mnt/hgfs/LS_2K500/proj/cJSON/longarch64 –lssl –l crypto"
export CC=gcc
export CXX=g++
20.png
执行完简单检查完相关编译环境是否正确,如上图,显示各编译选项变量设置正确。
6.3 make编译
执行 make 进行编译
21.png
22.png
完全编译大概需要5分钟,最后编译完成。把编译出的库文件,服务端文件和客户端工具软件复制到开发板上/root/mosquitto目录下。
7.编译x86下的mosquitto工程
同样重新进入shell,再进入mosquitto下,清空上一次编译的生成文件。准备进行编译x86版本
7.1 配置x86编译环境变量
export CPPFLAGS="-I/mnt/hgfs/LS_2K500/proj/cJSON"
exportLDFLAGS="-L/mnt/hgfs/LS_2K500/proj/openssl/bin/x86/lib  -L/mnt/hgfs/LS_2K500/proj/cJSON/x86 -lssl-lcrypto"
export CC=gcc
export CXX=g++
7.2编译x86下的版本
make -j4
23.png
编译完成,编译出ubuntu的x86下服务端可执行文件与客户端工具文件。
8把不同版本放到相应目录下
把上面编译得到了x86版本与loongarch64版本的执行文件与动态库文件归档存放好,避免版本错乱。放置到工程bin目录下,如图:
24.png

五、测试mosquitto 客户端发布与订阅功能
    因为mosquitto有服务端也有客户端,为了便于测试验证MQTT协议的通讯,首先测试客户端。使用mosquitto客户端连接其它平台的服务端来验证客户端的功能。
    选择第三方的MQTT平台作为服务端,这里选用emqx 平台,它有开源版本,可以自己部署也可以使用云服务,可以申请免费测试试用,不用自己部署了。
首先申请成功 EMQX云服务:
进入云平台,创建一个免费的MQTT服务项目:
25.png
进入项目,创建该项目的用户访问认证和权限即可。
26.png
记下服务对外服务的IP地址和端口,图中信息:
27.png
    再进入 LS-2K500开发板,把编译好的mosquitto可执行文件复制到root/mosquitto目录下。把依赖的zlib,cJson,openssl库复制到开发板/lib目录下.
    在开发板环境下,运行mosquitto客户端来连接EMQX云服务,客户端分为消息发布端盒消息订阅端:
首先在2K500一个终端启动一个订阅客户端:
./mosquitto_sub-h 112.124.68.65 -t "test" -u user1 -P 123 -i "client001"
然后再2k500另一个终端窗口启动消息发布端:
./mosquitto_pub-h 112.124.68.65 -t "test" -u user1 -P 123 -i"client1"  -m "Are youOK?"
测试结果:订阅端成功收到了发布端发布的相同topic的消息。
28.png
29.png
同时在EMQX平台里的监控里看到连接的信息:
30.png
在消息指标看到连接、报文和消息的统计数据:
31.png
打开EMQX的在线测试页面,创建页面测试:
32.png
可见也收到了2K500发布的消息。同样在页面端发布消息,2K500的订阅客户端也收到了页面上发布的消息。
33.png
    在测试中需要注意订阅和发布的主题,不同主题是不通的,订阅使用“#”支持通配的消息,这样就可以对不同终端类型的节点发布不同的消息,达到数据分类上报的功能。
六、测试mosquitto 消息转发服务(Broker)功能
     测试完mosquitto客户端的使用后,可以测试mosquitto作为服务端,作为broker进行消息转发服务的功能了。
Mosquitto服务端程序名就叫 mosquitto ,不过作为服务端运行需要一番设置和操作:
1.创建工作用户
    在2K500主板系统下添加新用户 mosquitto 和用户组mosquitto
adduser mosquitto
2.创建工作目录
    这里在/root/mosquitto分别创建了log,conf,lib,目录,
/root/mosquitto/conf存放服务配置文件
/root/mosquitto/conf/conf.d存放服务插件配置文件
/root/mosquitt/lib存放消息转存的数据
/root/mosquitto/log存在服务日志
3.创建用户账号文件 pwfile  
    使用编译的apps下的mosquitto_password工具即可创建用户访问账号文件
./mosquitto_passwdconf/pwfile  user1 添加用户,密码
4.编写服务配置文件 mosquitto.conf
  1. pid_file /root/mosquitto/mosquitto.pid
  2. # 消息持久存储
  3. persistence true
  4. persistence_location /root/mosquitto/lib
  5. persistence_file mosquitto.db

  6. # 日志文件
  7. log_dest file /root/mosquitto/log/mosquitto.log

  8. # 其他配置
  9. include_dir /root/mosquitto/conf/conf.d

  10. # 禁止匿名访问
  11. allow_anonymous true

  12. # 认证配置
  13. password_file /root/mosquitto/conf/pwfile

  14. # 权限配置
  15. acl_file /root/mosquitto/conf/aclfile
5.编写消息服务权限文件 aclfile
  1. # user1能发布以test为前缀的主题, 订阅以$SYS开头的主题即系统主题
  2. user user1
  3. topic test/#
  4. topic read $SYS/#

  5. # user2能订阅以test为前缀的主题
  6. user user2
  7. topic test/#

6.修改文件所有者
    修改 /root/mosquitto 目录下所有子目录和文件的所有者为mosquitto: mosquitto所有,不然 mosquitto服务程序无法访问这些文件。
7.启动mosquitto服务
    启动mosquitto服务很简单,命令:
./mosquitto -c./mosquitto1.conf  #使用配置文件启动主服务
34.png

     此时,在另外两个2K500终端窗口,同样分别启动消息订阅端盒发布端,此时只需要把主机地址改为 127.0.0.1即连接本地这个mosquitto服务,即可进行测试mosquitto作为消息服务器的转发等功能了。
35.png
36.png
    在对mosquitto发布消息与订阅消息,服务端会记录所有连接和访问过程,通过查看日志可见服务工作:
37.png
    消息收发也可以通过上面编译的主机版本客户端来进行,只需要把连接MQTT主机地址改为开发板的地址 192.168.50.210即可。
    需要注意的是,默认mosquitto服务的TCP监听地址是绑定在127.0.0.1地址,监听端口为1883,因为外部客户端是无法访问通,修改的方式,一种方法是,修改源码,把默认监听绑定地址从127.0.0.1修改为0.0.0.0 ,修改代码内容如下:
38.png
    另一种方式是,在配置文件mosquitto.conf 中加入一行指定监听端口和绑定地址,如下:
listener1883 0.0.0.0


七、测试W801通过MQTT向LS-2K500 服务器发布消息功能
    通过上面两个测试试验,测试验证了mosquitto客户端的发布和订阅功能,以及作为服务端Broker的功能。这里更近一步,模拟使用应用环境,使用一个单片机作为下位机,将采集到的数据通过MQTT发布到2K500打开板上来。
这里使用联盛德威的W801的单片机开发板,它是一个基于平头哥的一款低功耗的32位,功能强大的单片机,具有ADC转换,WIFI,蓝牙的单芯片的一款可运行rtos系统的单片机。
39.png
   该单片机测评介绍见下面一文;
      https://bbs.elecfans.com/jishu_2201066_1_1.html
    该单片机的开发商发布了多种物联网络协议的源码,其中就有MQTT的代码与例程,该例程已经能够成功的对接阿里物联网平台,这里就在该例程的基础上进行修改,使它能够连上这块龙芯2K500的MQTT消息服务端,并进行消息的发布与订阅。
     在W801上主要修改代码如下部分:
1.修改服务接入地址,端口,发布订阅主题,用户名和密码
40.png
2.修改网w801工程里mqtt库的连接协议
    W801中MQTT例程协议使用的是MQTT V3版本,其中头部标识是 MQIsp,头部是12字节,而mosquitto连接的头部标识为MQTT,头部长度是10字节,因此做如下修改(注释掉原来的连接头部协议,增加修改后的头部)
41.png
     然后编译,烧录到W801板子上,再进行对W801配网,使w801连接到和2K500所在同一路由器网络下,开始发布消息。
     W801这里测试的是,采集板上wifi连接ap的信号强度,每隔10秒使用MQTT协议发布到服务端去。
同时在ubuntu主机环境下,使用mosquitto订阅W801单片机发布的相同的订阅主题,即可收到单片机的wifi信号强度信息了。
    下图是W801单片机运行时,串口输出的信息,分别显示了,连接wifi成功,连接LS-2K500的MQTT 服务成功,启动了wifi信号强度采集和发布任务。
42.png
    下图为2k500开发板上mosquitto的日志内容;
43.png
   下图为Ubuntu主机上,启动mosquitto的x86订阅客户端收到LS-2K500板上转发过来的消息:
44.png
    在测试中需要注意,订阅端和发布端的client ID 不能相同,即在MQTT中每个终端在服务端必须有唯一的标识,而用户名密码验证身份可以使用相同的。
   测试现场如图(W801运行发布数据,Ubuntu客户端订阅到数据):
45.png
八、MQTT开发测试总结
     通过在龙芯2K500开发板上开发测试MQTT协议的mosquitto工程,测试通了使用2K500作为客户端场景时,实现了向EMQX公有MQTT云服务发布消息和订阅接收消息的功能。 测试了在2K500板上运行mosquitto 服务,使之成为broker服务,在测试本机连接,Ubuntu主机连接和下位机单片机连接方式,进行发布数据和订阅数据的功能。这些测试验证均成功完成。
     LS-2K500 龙芯开发板在开发MQTT以上连通测试时,均使用开源开放的软件通过龙芯开班的SDK经过简单的移植和修改即可完成。总体移植难度较低,在移植过程中也发先,SDK里一些基础的组件库确实,如zip库,ssl库等。需要应用开饭者自行去实现,不过好在经过开发测试,龙芯2K500编译器兼容性较好,对测试中所有的开源工具编译均顺利通过,并且开发移植还是比较容易。
     在经W801 MCU向2K500长时间(>24小时)发送MQTT数据测试时,整体系统运行稳定,没有出现死机或者中断的状况,可见该方案稳定性较高。
    在经过模拟MQTT压力测试后,2K500运行mosquitto服务也能达到较好的性能指标,作为前端数据转发和预处理嵌入式处理服务已能够完全可以达到行业应用需求。


W801配网到发布MQTT消息

更多回帖

发帖
×
20
完善资料,
赚取积分