一、硬件与软件环境
- 开发板:STM32F407
- 操作系统:RT-Thread 4.1.0
二、工程配置步骤
2.1 以太网配置
首先,需要在RT-Thread的配置菜单中启用以太网驱动,以确保设备具备网络通信能力。完成配置后,可以通过 ping 命令测试网络连通性。


2.2 启用RTC实时时钟
部分网络协议和TLS握手过程对时间有要求,因此需要启用板载的RTC(实时时钟)模块。在芯片外设驱动配置中找到并启用RTC。


2.3 软件包配置
这是实现 MQTT协议 通信的核心步骤。
1. 添加Paho MQTT包
- 软件包名称:
pahomqtt
- 版本:
v1.2.0
- 关键配置:若需启动TLS功能,必须将“Set MQTT thread stack size”设置为 6144 或以上。

2. 配置mbedtls加密库
- 软件包:
mbedtls
- 版本:
v2.28.1
- 关键配置:必须将“Maximum fragment length in bytes”(最大分片长度)从默认值增大,例如设置为 8192,以满足TLS握手过程的数据包大小需求。

3. 选择TLS证书类型
在配置mbedtls时,需要选择根证书,这决定了认证方式:
- 无证书SSL连接(单向认证):选择类似 “Using Digicert Global Root CA” 的预设CA证书。这种方式只验证服务器证书,客户端无需证书。

- 使用自定义CA证书(单/双向认证):选择 “Using user CA”。你需要将自己的根证书文件(如
broker.emqx.io-ca.crt)复制到工程目录下的 certs 文件夹中。这种方式可用于更严格的双向认证。

配置完成后,保存设置,退出菜单,并让 RT-Thread系统 自动下载软件包并生成工程。
2.4 证书导出(如需自定义证书)
如果需要使用自定义CA证书,通常需要将.crt格式证书转换为嵌入式系统可用的格式。
转换步骤:
- 双击
broker.emqx.io-ca.crt 文件,打开证书查看器。
- 点击「详细信息」选项卡,然后点击「复制到文件」按钮,启动证书导出向导。
- 点击「下一步」,选择「否,不导出私钥」。
- 选择导出格式:
- 二进制格式:选择“DER 编码的二进制 X.509 (.CER)”。
- 文本格式(常用):选择“Base64 编码的 X.509 (.CER)”。本示例选择此格式。
- 点击「下一步」,指定保存路径(如
broker.emqx.io-ca.cer),完成导出。
注意:使用scons命令编译工程后,构建系统会自动将certs目录下的证书文件内容转换并拷贝到代码中的 const char mbedtls_root_certificate[] 数组中。
完成证书放置后,需重新生成工程以使证书生效。
2.5 编译错误修正
在编译过程中可能会遇到一些错误,需要进行修正。
1. 函数参数名错误
在 pahomqtt 软件包的某些版本中,MQTTPublish 函数的参数名可能存在拼写错误。需要找到该函数定义,将 topicname 和 c 分别修改为 topic 和 client。
修改后的函数头应如下所示:
/**
* This function publish message to specified mqtt topic.
* [MQTTMessage] + [payload] + [topic] + '\0'
*
* @param client the pointer of MQTT context structure
* @param topic topic filter name
* @param message the pointer of MQTTMessage structure
*
* @return the error code, 0 on subscribe successfully.
*/
int MQTTPublish(MQTTClient *client, const char *topic, MQTTMessage *message)
{
// ... 函数体保持不变
}
2. 修改 MEMP_NUM_NETDB 宏定义
网络相关内存池大小可能不足,导致运行时错误。需要修改LwIP配置。
- 文件路径:
rt-thread\components\net\lwip\lwip-2.1.2\src\include\lwip\opt.h
- 修改内容:找到
MEMP_NUM_NETDB 宏定义,将其值修改为 2。
/*
* MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls
* (before freeing the corresponding memory using lwip_freeaddrinfo()).
*/
#if !defined(MEMP_NUM_NETDB) || defined(__DOXYGEN__)
#define MEMP_NUM_NETDB 2
#endif

3. MQTTS测试连接地址
本次测试使用的公共MQTT Broker地址为:
# 测试链接:
ssl://broker-cn.emqx.io:8883
三、功能测试
完成上述配置和修正后,编译并下载程序到STM32开发板,进行MQTTS通信测试。
测试结果:
1. 无证书SSL单向认证测试
使用预设CA证书,连接成功并可以正常订阅、发布消息。
msh /mqtt_start
[D/mqtt.sample] inter mqtt_connect_callback!
[D/mqtt] ipv4 address port: 8883
[D/mqtt] HOST = 'broker-cn.emqx.io'
msh /D/mqtt tls connect success...
[I/mqtt] MQTT server connect success.
[I/mqtt] Subscribe #0 /mqtt/test OK!
[D/mqtt.sample] inter mqtt_online_callback!
msh /mqtt_publish 123456
msh /[D/mqtt.sample] mqtt sub callback: /mqtt/test 123456

2. 有证书SSL单向认证测试
使用自定义CA证书,同样可以成功建立安全连接并进行通信。
msh /> mqtt_publish 123456
msh /[D/mqtt.sample] mqtt sub callback: /mqtt/test 123456
msh /> mqtt_publish dkjfiowehfbdmjfp0213uwebnf
msh /[D/mqtt.sample] mqtt sub callback: /mqtt/test dkjfiowehfbdmjfp0213uwebnf

四、参考资料
- EMQX TLS/SSL 连接文档:https://docs.emqx.com/zh/cloud/latest/deployments/tls_ssl.html
- RT-Thread 连接 EMQX Cloud:https://www.emqx.com/zh/blog/rt-thread-connects-to-emqx-cloud-with-tls
希望这份详细的配置指南能帮助你成功在STM32与RT-Thread上实现安全的MQTTS通信。在实践中遇到任何问题,欢迎到 云栈社区 的嵌入式开发板块与更多开发者交流探讨。