在ZYNQ 7020 PS端使用paho.mqtt实现设备侧开发连接华为云IoTDA服务

(2024-2025第六学期综合课程设计自主设计任务的一环)

参考资料

  1. https://blog.csdn.net/thisway_diy/article/details/125557534, 【嵌入式Linux应用】初步移植MQTT到Ubuntu和Linux开发板, 韦东山

  2. https://www.cnblogs.com/wanqieddy/archive/2011/09/21/2184257.html, Makefile 中:= ?= += =的区别, wanqi

  3. https://support.huaweicloud.com/devg-iothub/iot_02_2200.html, MQTT使用指导, 华为云

0. Ubuntu18.04 WSL准备

教程很多有手就行。

1. 前置包准备

Paho MQTT的包对多种语言都有支持,其中特别是嵌入式设备中(之前bz用过海斯Hi3861的paho-embedded-mqtt,是工程师事先构建好在OpenHarmony镜像中,用户层面一般操作不到底层(也可能是本人菜qaq))有一个版本是Embedded-C/C++。相比于标准C/C++库,Embedded版本特意删减了嵌入式设备不常用的几个功能。但如果要在嵌入式Linux设备上板端部署,标准C和Embedded-C都可以,这里选取标准C语言库。

图1:Paho-MQTT不同语言支持包的功能比较

Paho-MQTT-C支持包:

1
https://github.com/eclipse/paho.mqtt.c.git

openssl1.1.1v库:

1
https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1v/openssl-1.1.1v.tar.gz

/home/{$USER}目录下新建一个工作区paho_test用来保存工程和开发资料:(其实也不是很必要,找个文件夹放编译文件就行,注意${USER}换成自己WSL的用户)

1
2
3
4
mkdir paho_test
cd paho_test/
mkdir workspace && cd workspace
mkdir mqtt && cd mqtt

/home/{$USER}/paho_test/workspace/mqtt下将paho-mqtt的仓库克隆下来(master分支就行)

1
git clone https://github.com/eclipse/paho.mqtt.c.git

先别急搞交叉编译,我们先验证一下paho-mqtt能否建立MQTT通信。

/home/{$USER}/paho_test/workspace/mqtt/paho.mqtt.c目录下执行下面两条命令

1
2
3
make -j16
<!-- j16表示调用16线程,可选,编译速度会更快,但也会极小概率编出问题,一般不用在意 -->
sudo make install

执行make后会在当前目录下创建一个build目录,源码和例程编译出来的可执行文件都在里面;执行sudo make install,会将mqtt程序依赖的库文件安装到/usr/local下的bin、lib、include和share下。(路径是由Makefile指定)

下面,在/home/{$USER}/paho_test/workspace/目录下新建一个测试工程,取名就叫mqtt_test

1
2
3
cd /home/{$USER}/paho_test/workspace/
mkdir mqtt_test
cd mqtt_test

将paho.mqtt.c下的src和sample里面的随意一个示例代码copy过来:

1
2
cp -r /home/{$USER}/paho_test/workspace/mqtt/paho.mqtt.c/src ./
cp /home/{$USER}/paho_test/workspace/mqtt/paho.mqtt.c/src/samples/MQTTClient_publish.c ./

我们这里copy的是MQTTClient开头的例程,其表示的是MQTT的客户端发布,依赖的库是libpaho-mqtt3c,如果是MQTTAsync开头的,依赖的库就是libpaho-mqtt3a,如果自己写代码还会用到SSL的话,依赖的库就会变成libpaho-mqt3cs或者ibpaho-mqtt3as。如何确定使用的是Async还是Client呢,根据自己写的代码里面包含的头文件是MQTTAsync.h还是MQTTClient.h,比如我刚才copy的例程MQTTClient_publish.c:

1
2
3
4
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h" // <----这里调用Client头文件

现在来修改这个示例代码。首先是头文件MQTTClient.h,我们需要指定路径,不然在当前目录下是找不到这个头文件的,我们已经将这个头文件所在的官方源文件文件夹 src copy过来了,所以只需要改成:

1
#include "src/MQTTClient.h" 

然后修改url, 客户端id, ADDRESS和CLIENTID以及订阅的TOPIC,还要添加华为云物联网平台设备的用户名USERNAME和密码PASSWORD:

以下面的华为云设备接入信息为例:

1
2
3
4
5
6
7
8
{
"username": "6620c62c2ccc1a583881d5fb_cc2530",
"password": "6e7ff9829d7b19dcfd837930c26cd81ac293e8080950b931c44b9a0b92b3e767",
"clientId": "6620c62c2ccc1a583881d5fb_cc2530_0_0_2024042508",
"hostname": "3c1ab378e9.st1.iotda-device.cn-north-4.myhuaweicloud.com",
"port": 8883,
"protocol": "MQTTS"
}

原始代码改成:

1
2
3
4
5
6
7
8
#define ADDRESS     "mqtt://xxxx.com:1883"
#define CLIENTID "6620c6xxx_xxxx_x_x_202xxxxx08"
#define USERNAME "6620c62c2xxxxx_ccxxxx"
#define PASSWORD "6e7ff9829xxxxxx293exxx095xxxxx9a0b92b3e767"
#define TOPIC "MQTT Examples"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L

将连接控制包的keepAliveInterval设置为大于等于60的值(以90为例)(一定要改,不然会报奇奇怪怪的错),并且对控制包的用户名username和密码password赋值为我们宏定义的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main(int argc, char* argv[])
{
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
conn_opts.username = USERNAME; // <--对应设备接入文件USERNAME
conn_opts.password = PASSWORD; // <--对应设备接入文件PASSWORD
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;

if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to create client, return code %d\n", rc);
exit(EXIT_FAILURE);
}

conn_opts.keepAliveInterval = 90;// <--更改keepAliveInterval值
conn_opts.cleansession = 1;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}

保存退出ESC->:wq

编译修改之后的MQTTClient_publish.c:

1
2
3
gcc MQTTAsync_subscribe.c -lpaho-mqtt3c
ls
---> a.out MQTTAsync_subscribe.c src

可以看到生成了一个a.out,我们执行整个文件:

1
./a.out 

如果连接成功了且订阅也成功了会打印如下信息:

1
2
3
Waiting for up to 10 seconds for publication of Hello World!
on topic MQTT Examples for client with ClientID: 6620c6xxx_xxxx_x_x_202xxxxx08
Message with delivery token 1 delivered

从华为云服务器的控制台消息跟踪也可以看到消息发布成功
图2:消息上报成功

2. 交叉编译与移植至Zynq-7020 PS端(基于Petalinux)

如果没有构建好Petalinux,请参考以下博客进行镜像构建:https://lostacnet.top/post/31220/

检查下编译器是否生效可用:

1
2
3
4
5
6
7
8
9
arm-buildroot-linux-gnueabihf-gcc -v
-->
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/7/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)

修改Makefile:

1
2
3
4
5
CC = arm-linux-gnueabihf-gcc # Line 126
CCFLAGS_SO += -Wno-deprecated-declarations -DOSX -march=arm # Line 202
LDFLAGS_CS += -Wl,-install_name,lib$(MQTTLIB_CS).so.${MAJOR_VERSION} -L /home/{$USER}/openssl-arm/lib # Line 204
LDFLAGS_AS += -Wl,-install_name,lib${MQTTLIB_AS}.so.${MAJOR_VERSION} -L /home/{$USER}/openssl-arm/lib # Line 206
FLAGS_EXES += -L /home/ericzh/openssl-arm/lib # New

进行交叉编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!-- 可选make clean,清理之前的编译文件 -->
make -j 16
--->
mkdir -p build/output/samples
mkdir -p build/output/test
mkdir -p build
echo OSTYPE is Linux
sed -e "s/@CLIENT_VERSION@/1.3.13/g" -e "s/@BUILD_TIMESTAMP@/Mon Apr 29 12:35:38 CST 2024/g" src/VersionInfo.h.in > build/VersionInfo.h
OSTYPE is Linux
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3c.so.1.3 src/Heap.c src/LinkedList.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c src/MQTTClient.c -shared -Wl,-init,MQTTClient_init -Wl,--start-group -pthread -lanl -Wl,--end-group -Wl,-soname,libpaho-mqtt3c.so.1
# arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3cs.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c src/MQTTClient.c -DOPENSSL -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTClient_init -Wl,-soname,libpaho-mqtt3cs.so.1 -Wl,-no-whole-archive
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3a.so.1.3 src/Heap.c src/LinkedList.c src/MQTTAsyncUtils.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/MQTTAsync.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c -shared -Wl,-init,MQTTAsync_init -Wl,--start-group -pthread -lanl -Wl,--end-group -Wl,-soname,libpaho-mqtt3a.so.1
# arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3as.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTAsyncUtils.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/MQTTAsync.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c -DOPENSSL -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTAsync_init -Wl,-soname,libpaho-mqtt3as.so.1 -Wl,-no-whole-archive
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3cs.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c src/MQTTClient.c -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTClient_init -Wl,-soname,libpaho-mqtt3cs.so.1 -Wl,-no-whole-archive
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3as.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTAsyncUtils.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/MQTTAsync.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTAsync_init -Wl,-soname,libpaho-mqtt3as.so.1 -Wl,-no-whole-archive
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
/lib/../lib/libcrypto.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:267: recipe for target 'build/output/libpaho-mqtt3cs.so.1.3' failed
make: *** [build/output/libpaho-mqtt3cs.so.1.3] Error 1
make: *** Waiting for unfinished jobs....
ln -s libpaho-mqtt3c.so.1.3 build/output/libpaho-mqtt3c.so.1
ln -s libpaho-mqtt3c.so.1 build/output/libpaho-mqtt3c.so
/lib/../lib/libcrypto.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:278: recipe for target 'build/output/libpaho-mqtt3as.so.1.3' failed
make: *** [build/output/libpaho-mqtt3as.so.1.3] Error 1
ln -s libpaho-mqtt3a.so.1.3 build/output/libpaho-mqtt3a.so.1
ln -s libpaho-mqtt3a.so.1 build/output/libpaho-mqtt3a.so

不要惊慌,报错信息在提示我们/lib/…/lib/libcrypto.so: file not recognized: File format not recognized,也有可能是/lib/…/lib/libssl.so。首先我们去查看一下这两个文件类型是什么样的:

运行locate命令定位链接库文件位置:

1
2
3
locate libssl.so
-> /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
/usr/lib/x86_64-linux-gnu/libssl.so.1.1

运行file命令查看文件类型

1
2
file /lib/libssl.so
-> /lib/libssl.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=27aee7be3c71555217d5a7f70a791405eca003bd, not stripped

(libcrypto.so同理同样是x86-64指令集的)

这么一来,交叉编译肯定是走不通,因为ARM指令集和x86指令集不同。所以我们需要ARM架构的libssl.so, libcrypto.so

3. openssl交叉编译安装(arm-linux-gnueabihf)

在用户根目录下(/home/{$USER}/)下载openssl1.1.1v release版本

1
2
3
wget https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1v/openssl-1.1.1v.tar.gz
tar xvf openssl-1.1.1v.tar.gz
cd openssl-1.1.1v/

执行以下命令生成指定编译链的Makefile:

1
./config no-asm shared no-async --prefix=$(pwd)/install --cross-compile-prefix=arm-linux-gnueabihf-

参数说明:

1
2
3
4
5
6
7
8
9
no-asm:  在交叉编译过程中不使用汇编代码代码加速编译过程;

shared: 生成动态连接库。

no-async: 交叉编译工具链没有提供GNU C的ucontext库

–prefix=: 安装路径

–cross-compile-prefix=: 交叉编译工具

进入Makefile,删除所有的’-m64’

1
vim Makefile
1
:/m64 找到之后删除,保存Esc->:wq

编译openssl

1
make

文件夹里会多出几个动态链接库以及他们的软链接:

1
2
3
4
5
6
7
8
9
 ericzh@DESKTOP-EMLOSHV:~/openssl-1.1.1v ls
ACKNOWLEDGEMENTS LICENSE NOTES.WIN config external libssl.a pod2htmd.tmp
AUTHORS Makefile README config.com fuzz libssl.map ssl
CHANGES NEWS README.ENGINE configdata.pm include libssl.pc test
CONTRIBUTING NOTES.ANDROID README.FIPS crypto libcrypto.a libssl.so tools
Configurations NOTES.DJGPP VMS demos libcrypto.map libssl.so.1.1 util
Configure NOTES.PERL apps doc libcrypto.pc ms wycheproof
FAQ NOTES.UNIX appveyor.yml e_os.h libcrypto.so openssl.pc
INSTALL NOTES.VMS build.info engines libcrypto.so.1.1 os-dep

将生成的两个动态链接库复制到/lib中,并将之前的x86架构的链接库另存为.save文件以备不时之需(万一哪天想用了找不到)

1
2
3
4
5
6
7
cd /lib
sudo mv libcrypto.so libcrypto.so.save
sudo mv libcrypto.so.3 libcrypto.so.3.save
sudo cp /home/{$USER}/openssl-arm/lib/libcrypto.so /lib
sudo mv libssl.so libssl.so.save
sudo mv libssl.so.3 libssl.so.3.save
sudo cp /home/ericzh/openssl-arm/lib/libssl.so /lib

回到paho.mqtt工程中进行编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
cd ~/paho_test/workspace/mqtt/paho.mqtt.c
make clean
make -j 16
--->
mkdir -p build/output/samples
mkdir -p build/output/test
mkdir -p build
echo OSTYPE is Linux
sed -e "s/@CLIENT_VERSION@/1.3.13/g" -e "s/@BUILD_TIMESTAMP@/Mon Apr 29 12:37:39 CST 2024/g" src/VersionInfo.h.in > build/VersionInfo.h
OSTYPE is Linux
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3c.so.1.3 src/Heap.c src/LinkedList.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c src/MQTTClient.c -shared -Wl,-init,MQTTClient_init -Wl,--start-group -pthread -lanl -Wl,--end-group -Wl,-soname,libpaho-mqtt3c.so.1
# arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3cs.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c src/MQTTClient.c -DOPENSSL -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTClient_init -Wl,-soname,libpaho-mqtt3cs.so.1 -Wl,-no-whole-archive
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3a.so.1.3 src/Heap.c src/LinkedList.c src/MQTTAsyncUtils.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/MQTTAsync.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c -shared -Wl,-init,MQTTAsync_init -Wl,--start-group -pthread -lanl -Wl,--end-group -Wl,-soname,libpaho-mqtt3a.so.1
# arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3as.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTAsyncUtils.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/MQTTAsync.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c -DOPENSSL -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTAsync_init -Wl,-soname,libpaho-mqtt3as.so.1 -Wl,-no-whole-archive
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3cs.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c src/MQTTClient.c -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTClient_init -Wl,-soname,libpaho-mqtt3cs.so.1 -Wl,-no-whole-archive
arm-linux-gnueabihf-gcc -g -fPIC -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -Ibuild -DPAHO_MQTT_EXPORTS=1 -o build/output/libpaho-mqtt3as.so.1.3 src/Heap.c src/LinkedList.c src/SSLSocket.c src/MQTTAsyncUtils.c src/MQTTProtocolClient.c src/MQTTProtocolOut.c src/MQTTAsync.c src/SHA1.c src/MQTTPersistence.c src/MQTTProperties.c src/MQTTPersistenceDefault.c src/Messages.c src/MQTTTime.c src/MQTTPacketOut.c src/Socket.c src/WebSocket.c src/Clients.c src/OsWrapper.c src/Thread.c src/MQTTPacket.c src/Base64.c src/Log.c src/StackTrace.c src/MQTTReasonCodes.c src/utf-8.c src/SocketBuffer.c src/Proxy.c src/Tree.c -shared -Wl,--start-group -pthread -lanl -ldl -lssl -lcrypto -Wl,--end-group -Wl,-init,MQTTAsync_init -Wl,-soname,libpaho-mqtt3as.so.1 -Wl,-no-whole-archive
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
src/WebSocket.c:124:13: warning: ‘uuid_unparse’ defined but not used [-Wunused-function]
static void uuid_unparse( uuid_t uu, char *out )
^~~~~~~~~~~~
ln -s libpaho-mqtt3c.so.1.3 build/output/libpaho-mqtt3c.so.1
ln -s libpaho-mqtt3c.so.1 build/output/libpaho-mqtt3c.so
arm-linux-gnueabihf-gcc -DNOSTACKTRACE -DNOLOG_MESSAGES src/Thread.c -g -o build/output/test/test1 src/../test/test1.c -lpaho-mqtt3c -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -DNOSTACKTRACE -DNOLOG_MESSAGES src/Thread.c -g -o build/output/test/test15 src/../test/test15.c -lpaho-mqtt3c -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -DNOSTACKTRACE -DNOLOG_MESSAGES src/Thread.c -g -o build/output/test/test2 src/../test/test2.c -lpaho-mqtt3c -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -DNOSTACKTRACE -DNOLOG_MESSAGES src/Thread.c -g -o build/output/test/sync_client_test src/../test/sync_client_test.c -lpaho-mqtt3c -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -DNOSTACKTRACE -DNOLOG_MESSAGES src/Thread.c -g -o build/output/test/test_mqtt4sync src/../test/test_mqtt4sync.c -lpaho-mqtt3c -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -DNOSTACKTRACE -DNOLOG_MESSAGES src/Thread.c -g -o build/output/test/test10 src/../test/test10.c -lpaho-mqtt3c -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
ln -s libpaho-mqtt3cs.so.1.3 build/output/libpaho-mqtt3cs.so.1
ln -s libpaho-mqtt3cs.so.1 build/output/libpaho-mqtt3cs.so
arm-linux-gnueabihf-gcc -o build/output/samples/MQTTClient_publish src/samples/MQTTClient_publish.c -lpaho-mqtt3cs -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -o build/output/samples/MQTTClient_publish_async src/samples/MQTTClient_publish_async.c -lpaho-mqtt3cs -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -o build/output/samples/MQTTClient_subscribe src/samples/MQTTClient_subscribe.c -lpaho-mqtt3cs -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -o build/output/samples/paho_cs_pub src/samples/paho_cs_pub.c -lpaho-mqtt3cs -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output src/samples/pubsub_opts.c
arm-linux-gnueabihf-gcc -o build/output/samples/paho_cs_sub src/samples/paho_cs_sub.c -lpaho-mqtt3cs -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output src/samples/pubsub_opts.c
arm-linux-gnueabihf-gcc -g -o build/output/test/test3 src/../test/test3.c -lpaho-mqtt3cs -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
# arm-linux-gnueabihf-gcc -o build/output/samples/MQTTClient_publish src/samples/MQTTClient_publish.c -lpaho-mqtt3cs
# arm-linux-gnueabihf-gcc -o build/output/samples/MQTTClient_publish_async src/samples/MQTTClient_publish_async.c -lpaho-mqtt3cs
# arm-linux-gnueabihf-gcc -o build/output/samples/MQTTClient_subscribe src/samples/MQTTClient_subscribe.c -lpaho-mqtt3cs
# arm-linux-gnueabihf-gcc -o build/output/samples/paho_cs_pub src/samples/paho_cs_pub.c -lpaho-mqtt3cs src/samples/pubsub_opts.c
# arm-linux-gnueabihf-gcc -o build/output/samples/paho_cs_sub src/samples/paho_cs_sub.c -lpaho-mqtt3cs src/samples/pubsub_opts.c
# arm-linux-gnueabihf-gcc -g -o build/output/test/test3 src/../test/test3.c -lpaho-mqtt3cs
ln -s libpaho-mqtt3a.so.1.3 build/output/libpaho-mqtt3a.so.1
ln -s libpaho-mqtt3a.so.1 build/output/libpaho-mqtt3a.so
arm-linux-gnueabihf-gcc -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output -o build/output/paho_c_version -lpaho-mqtt3a src/MQTTVersion.c -ldl
arm-linux-gnueabihf-gcc -g -o build/output/test/test4 src/../test/test4.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test45 src/../test/test45.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test6 src/../test/test6.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test9 src/../test/test9.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test95 src/../test/test95.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test_mqtt4async src/../test/test_mqtt4async.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test11 src/../test/test11.c -lpaho-mqtt3a -I src -Wl,--start-group -pthread -lanl -Wl,--end-group -L build/output
ln -s libpaho-mqtt3as.so.1.3 build/output/libpaho-mqtt3as.so.1
ln -s libpaho-mqtt3as.so.1 build/output/libpaho-mqtt3as.so
arm-linux-gnueabihf-gcc -o build/output/samples/MQTTAsync_subscribe src/samples/MQTTAsync_subscribe.c -lpaho-mqtt3as -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -o build/output/samples/MQTTAsync_publish src/samples/MQTTAsync_publish.c -lpaho-mqtt3as -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
arm-linux-gnueabihf-gcc -o build/output/samples/paho_c_pub src/samples/paho_c_pub.c -lpaho-mqtt3as -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output src/samples/pubsub_opts.c
arm-linux-gnueabihf-gcc -o build/output/samples/paho_c_sub src/samples/paho_c_sub.c -lpaho-mqtt3as -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output src/samples/pubsub_opts.c
arm-linux-gnueabihf-gcc -g -o build/output/test/test5 src/../test/test5.c -lpaho-mqtt3as -I src -Wl,--start-group -pthread -lanl -lssl -lcrypto -Wl,--end-group -L build/output
# arm-linux-gnueabihf-gcc -o build/output/samples/MQTTAsync_subscribe src/samples/MQTTAsync_subscribe.c -lpaho-mqtt3as
# arm-linux-gnueabihf-gcc -o build/output/samples/MQTTAsync_publish src/samples/MQTTAsync_publish.c -lpaho-mqtt3as
# arm-linux-gnueabihf-gcc -o build/output/samples/paho_c_sub src/samples/paho_c_sub.c -lpaho-mqtt3as src/samples/pubsub_opts.c
# arm-linux-gnueabihf-gcc -o build/output/samples/paho_c_pub src/samples/paho_c_pub.c -lpaho-mqtt3as src/samples/pubsub_opts.c
# arm-linux-gnueabihf-gcc -g -o build/output/test/test5 src/../test/test5.c -lpaho-mqtt3as

编译成功(撒花!!!★,°:.☆( ̄▽ ̄)/$:.°★ 。)

进入build目录中,可以看到生成了一个新的output文件夹,里面存放的就是我们需要的动态链接库啦

1
2
3
4
5
6
7
8
cd build/
ls
---> VersionInfo.h output
cd output/
ls
--->
libpaho-mqtt3a.so libpaho-mqtt3a.so.1.3 libpaho-mqtt3as.so.1 libpaho-mqtt3c.so libpaho-mqtt3c.so.1.3 libpaho-mqtt3cs.so.1 paho_c_version test
libpaho-mqtt3a.so.1 libpaho-mqtt3as.so libpaho-mqtt3as.so.1.3 libpaho-mqtt3c.so.1 libpaho-mqtt3cs.so

随便看一个文件

1
2
3
file libpaho-mqtt3a.so.1.3
--->
libpaho-mqtt3a.so.1.3: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=9127172e087d577670530e0c86d2fb337b159de0, with debug_info, not stripped

可以看到架构已经变成ARM了,证明了编译成功。

4. 测试程序编译与下板

在paho.mqtt.c/build/output中,将编译好的动态链接库打包,先传到本机,之后通过网线scp传到开发板

1
2
3
4
cd ~/paho_test/workspace/mqtt/paho.mqtt.c/build/output
tar cf mqtt-arm-lib.tar ./libpaho-mqtt3*
cp mqtt-arm-lib.tar /mnt/d/
<!-- 这里我选择先复制到D盘中 -->

进入我们之前创建的mqtt_test工作环境中,开始编译测试程序

1
2
cd ~/paho_test/workspace/mqtt_test 
arm-linux-gnueabihf-gcc MQTTClient_publish.c -o pub-arm.o

开发板上电,网线接好,IP地址配到同一网段,之后通过scp命令传输文件
(这里跳过文件传输,假设已经传输好,并且开发板能够通外网(需要无线网卡))

开发板petalinux环境中执行

1
2
3
4
5
6
7
8
9
10
11
12
13
mkdir mqtt-arm-lib
mv mqtt-arm-lib.tar ./mqtt-arm-lib/
cd mqtt-arm-lib/
tar -xvf mqtt-arm-lib.tar
mv lib* /lib/
cd ~
chmod +x pub-arm.o
./pub-arm.o
---> Failed to connect, return code -1 (没通网时会报错)
--->
Waiting for up to 10 seconds for publication of Hello World!
on topic MQTT Examples for client with ClientID: 6620c62c2ccc1a583881d5fb_cc2530_0_0_2024042508
Message with delivery token 1 delivered (正常输出)

至此,板端MQTT工程已移植完毕。