嵌入式开发之移植MQTT到RK3568
文章目录
前言
MQTT是一种基于发布/订阅模式的”轻量级”通讯协议。它最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
瑞芯微RK3568芯片是一款定位中高端的通用型SOC,主要面向物联网、NVR存储、工控平板、工业检测、云终端、车载中控等行业定制市场。本人移植MQTT到RK3568的目的是将飞凌的RK3568开发板作为一个物联网的终端,来实时采集相关数据(例如:温度等)。
本次移植的软硬件环境如下:
开发环境操作系统: Ubuntu 18.04 64位
开发环境工具:Qt 5.14.2
交叉工具链:aarch64-linux-gnu
开发板芯片:飞凌 RK3568-C
开发板内核:linux-4.1.19
手机端工具:MQTT Dashboard
一、下载qmqtt源码
github官网下载qmqtt源码(地址GitHub - emqx/qmqtt: MQTT client for Qt)。
下载完成后, 解压qmqtt-master.zip到本地文件夹。
forlinx@ubuntu:~/3568/mqtt$ sudo unzip qmqtt-master.zip
forlinx@ubuntu:~/3568/mqtt/qmqtt-master$ ls
CMakeLists.txt examples qmqtt.pri README.md tests
edl-v10 LICENSE qmqtt.pro src
epl-v10 qmqtt-API.md qmqtt.qbs sync.profile
二、编译库文件
启动Qt-5.14.2,打开qmqtt.pro,配置为rk3568交叉编译环境,编译为Release下的message库。
修改qmqtt-master/src/mqtt/qmqtt.pro配置文件,设置设置库文件的输出目录为mqtt_lib。
# qmqtt-master/src/mqtt/qmqtt.pro
TARGET = QtQmqtt
QT = core network
qtHaveModule(websockets): QMQTT_WEBSOCKETS: QT += websockets
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
# CONFIG += QMQTT_NO_SSL
HEADERS += \
$$PWD/qmqtt_global.h \
$$PWD/qmqtt.h
include(qmqtt.pri)
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
load(qt_module)
# Set the output directory of library files
DESTDIR = $$MODULE_BASE_OUTDIR/../mqtt_lib
编译完成后,在mqtt_lib目录下生成库文件libQt5Qmqtt.so.1.0.2,详细查看如下:
root@ubuntu:/home/forlinx/3568/mqtt/mqtt_lib# ls -all
total 6540
drwxr-xr-x 3 root root 4096 Mar 11 18:19 .
drwx------ 4 root root 4096 Mar 11 18:26 ..
-rw-r--r-- 1 root root 809 Mar 11 18:26 libQt5Qmqtt.la
-rw-r--r-- 1 root root 1651 Mar 11 18:26 libQt5Qmqtt.prl
lrwxrwxrwx 1 root root 20 Mar 11 18:19 libQt5Qmqtt.so -> libQt5Qmqtt.so.1.0.2
lrwxrwxrwx 1 root root 20 Mar 11 18:19 libQt5Qmqtt.so.1 -> libQt5Qmqtt.so.1.0.2
lrwxrwxrwx 1 root root 20 Mar 11 18:19 libQt5Qmqtt.so.1.0 -> libQt5Qmqtt.so.1.0.2
-rwxr-xr-x 1 root root 285448 Mar 11 18:19 libQt5Qmqtt.so.1.0.2
-rw-r--r-- 1 root root 6388344 Mar 11 18:19 libQt5Qmqtt.so.1.0.2.debug
drwxr-xr-x 2 root root 4096 Mar 11 18:19 pkgconfig
三、移植到RK3568
3.1 移植动态库libQt5Qmqtt
复制Ubuntu18.04下交叉编译出的动态库libQt5Qmqtt.so.1.0.2,放到开发板/usr/lib目录下并对应的配置软链接。
cd /usr/lib
sudo ln -s libQt5Qmqtt.so.1.0.2 libQt5Qmqtt.so
sudo ln -s libQt5Qmqtt.so.1.0.2 libQt5Qmqtt.so.1
sudo ln -s libQt5Qmqtt.so.1.0.2 libQt5Qmqtt.so.1.0
若未正确配置软链接,则启动app客户端时会出现错误:
./mqtt_demo: error while loading shared libraries: libQt5Qmqtt.so.1: cannot open shared object file: No such file or directory
四、联机测试
4.1 制作demo
4.1.1 创建demo新项目
创建一个Widget应用程序,其控件布局如下:
4.1.2 添加network模块支持
在mqtt_demo项目的pro文件中添加对网络模块的支持。
QT += network
4.1.3 添加qmqtt外部库
库文件位于mqtt_lib下,mqtt头文件位于源码的src/mqtt目录下,浏览到对应的目录,即可。
4.1.4 功能实现
演示工具的源码已上传到github,链接地址:GitHub - lingdan2008/mqtt_demo。
mqtt_demo.pro文件
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
unix:!macx: LIBS += -L$$PWD/../../mqtt_lib/ -lQt5Qmqtt
INCLUDEPATH += $$PWD/../../qmqtt-master/src/mqtt
DEPENDPATH += $$PWD/../../qmqtt-master/src/mqtt
widget.h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
// add necessary includes here
#include <qmqtt.h>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_Connect_clicked();
void on_pushButton_Subscribe_clicked();
void on_pushButton_Publish_clicked();
void slotConnectedMQTT();
void slotDisconnectedMQTT();
void slotSubscribedMQTT(QString sTopic, quint8 qos = 0);
void slotReceivedMessageByMQTT(QMQTT::Message sMsg);
private:
Ui::Widget *ui;
// the mqtt client pointer
QMQTT::Client *m_pMQTT = nullptr;
};
#endif // WIDGET_H
widget.cpp文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle(tr("MQTT Demo"));
ui->pushButton_Connect->setEnabled(true);
ui->pushButton_Publish->setEnabled(false);
ui->pushButton_Subscribe->setEnabled(false);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_Connect_clicked()
{
if(tr("Connect") == ui->pushButton_Connect->text().trimmed()) {
ui->pushButton_Publish->setEnabled(true);
ui->pushButton_Subscribe->setEnabled(true);
ui->pushButton_Connect->setText(tr("Disconnect"));
QString sHost = ui->lineEdit_Host->text().trimmed();
int nPort = ui->lineEdit_Port->text().trimmed().toInt();
// Create a QMQTT client
if(nullptr == m_pMQTT) {
m_pMQTT = new QMQTT::Client(QHostAddress(sHost), nPort);
Q_ASSERT(m_pMQTT);
}
// Signal-slot initialization
std::vector<bool> vecConnect;
vecConnect.push_back(QObject::connect(m_pMQTT, SIGNAL(connected()), this, SLOT(slotConnectedMQTT())));
vecConnect.push_back(QObject::connect(m_pMQTT, SIGNAL(disconnected()), this, SLOT(slotDisconnectedMQTT())));
vecConnect.push_back(QObject::connect(m_pMQTT, SIGNAL(subscribed(QString, quint8)), this, SLOT(slotSubscribedMQTT(QString, quint8))));
vecConnect.push_back(QObject::connect(m_pMQTT, SIGNAL(received(QMQTT::Message)), this, SLOT(slotReceivedMessageByMQTT(QMQTT::Message))));
for(int i=0; i<(int)vecConnect.size(); i++) {
Q_ASSERT(vecConnect.at(i));
}
// Connect to host
m_pMQTT->setCleanSession(true);
m_pMQTT->connectToHost();
}
else {
ui->pushButton_Publish->setEnabled(false);
ui->pushButton_Subscribe->setEnabled(false);
ui->pushButton_Connect->setText(tr("Connect"));
m_pMQTT->disconnectFromHost();
delete m_pMQTT;
m_pMQTT = nullptr;
}
}
void Widget::on_pushButton_Subscribe_clicked()
{
// Subscribe a topic
QString sTopic = ui->lineEdit_SubscribeTopic->text().trimmed();
m_pMQTT->subscribe(sTopic, 1);
}
void Widget::on_pushButton_Publish_clicked()
{
// Publish a topic
QMQTT::Message sMsg;
QString sTopic = ui->lineEdit_PublishTopic->text().trimmed();
QString sContent = ui->lineEdit_PublishContent->text().trimmed();
sMsg.setTopic(sTopic);
sMsg.setPayload(sContent.toLocal8Bit());
m_pMQTT->publish(sMsg);
}
void Widget::slotConnectedMQTT()
{
ui->textBrowser_ReceivedMessage->append(tr("Connection succeeded"));
}
void Widget::slotDisconnectedMQTT()
{
ui->textBrowser_ReceivedMessage->append(tr("Connection disconnected"));
}
void Widget::slotSubscribedMQTT(QString sTopic,quint8 qos)
{
Q_UNUSED(sTopic);
Q_UNUSED(qos);
QString sMsg = "Subscribe Topic ";
sMsg += ui->lineEdit_SubscribeTopic->text();
sMsg += " Succeeded";
ui->textBrowser_ReceivedMessage->append(sMsg);
}
void Widget::slotReceivedMessageByMQTT(QMQTT::Message sMsg)
{
QString sPayload = sMsg.payload();
QString sMsgTotal = "Topic:";
sMsgTotal += sMsg.topic();
sMsgTotal += " Payload:";
sMsgTotal += sPayload;
ui->textBrowser_ReceivedMessage->append(sMsgTotal);
}
4.1.5 编译与发布
使用3568 Kit交叉编译后得到mqtt_demo,并将其发布到开发板。
4.2 移植与测试
4.2.1 启动应用程序
cd /home/forlinx/work/example/mqtt
sudo ./mqtt_dem
4.2.2 联合测试
(1)搭建MQTT服务器,
启动MQTT服务器,可参阅我的博客linux下搭建MQTT服务。
(2)启动MQTT Dashboard
从Google Paly商店下载,安装到手机后,连接MQTT服务器后,即可在手机端监控开发板。
(3)连接网络
(4)运行demo
在demo上配置服务器IP、端口、订阅主题、发布主题和发布内容,执行连接、订阅和发布,演示效果如下图所示:
总结
至此,云服务器、RK3568和手机端通过了联合测试,它们组成了一个小型的物联网智能监控系统,通过MQTT轻松的实现了物联网,很有成就感!
- 分享
- 举报
-
浏览量:8790次2019-09-01 11:08:57
-
浏览量:5848次2021-12-10 15:40:21
-
浏览量:1645次2020-08-19 16:43:27
-
浏览量:2729次2024-03-18 14:27:20
-
浏览量:2424次2020-08-20 17:57:43
-
浏览量:872次2024-03-12 16:42:47
-
浏览量:2417次2020-08-19 16:46:46
-
浏览量:3832次2020-07-17 16:50:14
-
浏览量:2309次2020-08-17 18:01:42
-
浏览量:1698次2024-03-13 15:15:04
-
浏览量:757次2023-10-23 16:21:43
-
浏览量:4944次2022-09-30 16:40:59
-
浏览量:3418次2022-05-17 09:00:46
-
浏览量:1985次2020-08-20 18:01:22
-
浏览量:3279次2020-08-17 18:05:11
-
浏览量:2062次2020-08-17 18:06:38
-
浏览量:818次2023-12-25 15:42:30
-
浏览量:2073次2020-08-17 18:04:26
-
浏览量:2383次2020-08-20 18:03:14
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
thatk
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明