MCU+5G模组MQTT上云架构:HAL层串口收发与设备信息非易失存储的移植接口设计
引言
在MCU+5G模组的物联网终端架构中,MQTT协议栈通常运行在模组侧而非MCU侧——模组固件内置完整的MQTT、TCP/IP和TLS协议,MCU只需通过AT指令集调用模组能力即可完成设备认证、MQTT连接和数据交互。这种架构的核心优势是:MCU侧无需集成复杂的网络协议栈,仅需实现串口收发、模组上下电控制及设备信息的非易失存取三个关键接口,即可完成设备上云。
HAL层接口定义:三组必须实现的硬件抽象
腾讯云物联网平台提供的AT-SDK框架将HAL层接口细分为三个独立模块:hal_uart.h负责串口收发,hal_os.c负责线程管理、互斥锁和延时,hal_export.h则定义设备信息存取接口。这种分层设计的核心逻辑是:将底层硬件操作与上层协议处理解耦,使同一套AT指令框架可适配不同MCU平台。
串口收发接口(中断接收)
串口通信是MCU与5G模组之间的物理通道。HAL层需要实现中断接收和阻塞发送两种模式。以STM32HAL库为例,中断接收接口每次接收单字节数据后进入回调函数,再由上层AT解析线程完成帧组装与命令匹配。原型如下:
// hal_uart.h - 串口收发接口定义
int HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
int HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
中断接收的核心价值在于:模组返回的AT响应和URC(非请求结果码)是异步到达的,必须通过中断机制捕获,轮询方式无法满足实时性要求。
设备信息非易失存取接口
设备三元组(ProductID、DeviceName、DeviceSecret)需持久化存储,确保设备断电重启后无需重新写入认证信息。腾讯AT-SDK通过以下接口抽象非易失存储操作:
// hal_export.h - 设备信息存取接口
int HAL_GetProductID(char *buf, int len);
int HAL_SetProductID(const char *buf);
int HAL_GetDevName(char *buf, int len);
int HAL_SetDevName(const char *buf);
int HAL_GetDevSec(char *buf, int len);
int HAL_SetDevSec(const char *buf);
量产阶段,设备信息通常通过烧录工具预先写入MCU的Flash模拟EEPROM或外部EEPROM中,而非在运行时通过AT指令写入模组。这样做的好处是:设备上电后MCU可直接读取本地存储的设备信息,通过AT指令一次性完成模组配置,无需在生产线上逐台下发参数。
程序实现:中断驱动的数据流设计
串口接收的数据流模型
整个通信链路的程序架构基于"中断接收+线程解析"模型。其工作流程为:
1. **中断接收**:UART中断服务程序每收到一个字节即存入环形缓冲区,并释放信号量通知解析线程。
2. **AT解析线程**:被信号量唤醒后,从缓冲区提取数据,匹配AT响应或URC。
3. **命令发送与超时处理**:发送AT指令后阻塞等待响应信号量,超时则重试或报错。
腾讯AT-SDK的源码结构体现了这一设计:src/module_at/目录下实现AT命令的异步匹配和超时管理,sample/目录则提供MQTT连接、数据模板上报的示例代码。开发者只需移植port/目录下的HAL层接口,上层协议栈逻辑无需修改。
非易失存储的移植示例
以STM32F103平台为例,设备信息存取接口的典型实现如下:
// port/hal_stm32_flash.c
#include "hal_export.h"
#define DEV_INFO_ADDR 0x0800FC00 // Flash最后一个扇区
int HAL_GetProductID(char *buf, int len) {
// 从Flash指定地址读取ProductID字符串
return read_flash_string(DEV_INFO_ADDR, buf, len);
}
int HAL_SetProductID(const char *buf) {
// 擦除扇区后写入新的ProductID
flash_erase_sector(DEV_INFO_ADDR);
return write_flash_string(DEV_INFO_ADDR, buf);
}
量产阶段,设备信息通过离线烧录工具直接写入Flash。该方案无需电池供电保持数据,每次上电MCU通过HAL_GetProductID等接口读出设备信息,通过AT指令完成模组配置。
架构设计的三个关键决策
决策一:协议栈在模组侧而非MCU侧
将MQTT协议栈运行在5G模组侧而非MCU侧,是当前架构的主流选择。nRF9160等模组采用双Cortex-M33内核架构——一个内核运行LTE协议栈,另一个作为应用处理器,开发者通过BSD Socket API或AT指令调用网络能力。这种设计的优势在于:MCU无需处理复杂的TCP/IP协议栈和TLS加密,可选用低成本、低功耗的平台。
决策二:设备信息在MCU侧存储而非模组侧
设备信息存储位置的选择影响量产效率和安全性。在MCU侧Flash存储设备信息,配合离线烧录工具,可实现产线批量写入,生产线无需联网逐个配置设备。需要说明的是:5G模组本身也可通过eSIM或iSIM方案存储运营商凭证,但与设备三元组(MQTT认证凭据)存储在不同位置,两者用途不同。
决策三:AT指令集标准化
腾讯、阿里等云平台与主流模组厂商合作,将MQTT协议封装为标准化的AT指令集。MCU通过`AT+MQTTCONN`、`AT+MQTTPUB`等命令即可完成MQTT连接和数据发布,无需关心MQTT协议的具体实现。这大大降低了MCU侧软件的复杂度。
结语
MCU+5G模组MQTT上云架构的核心设计原则是"将复杂性推向模组,将简洁性留给MCU"。MCU仅需实现三组HAL接口:UART中断收发、设备信息非易失存取、以及线程/互斥锁等OS适配层。一旦这些接口完成移植,设备即可通过AT指令完成5G网络注册、MQTT连接建立和数据上报,无须在MCU侧集成复杂的MQTT协议栈和TLS加密库。对于追求"低代码"量产效率的物联网终端设计,这套架构是一条经过验证的简洁路径。





