最近在搞工业物联网网关开发,发现W5500+MQTT+Modbus这套组合拳真香。踩过几个坑后总结了一套稳定方案,今天把干货掏出来给大伙儿瞧瞧
关键是把每个函数的返回值都当祖宗供着,宁可错杀一千也别放过一个异常状态。代码里到处都是if判断虽然看着啰嗦,但稳定性真是拿这个堆出来的。timeout()就像设备的呼吸节奏,没它整个协议栈直接憋死。曾经因为漏了这个函数,DHCP永远卡在获取状态。这里递归重试比while循环更安全,防止堆栈溢出。实测最多重试3次,超过就放弃治疗,避免设备变砖。这个喂狗策略让设备在异常时能挣扎着尝试恢复,实在没救再重
W5500实现MQTT 稳定连接 自动获取ip 相关函数均带返回值 带freemodbus主从站
先上网络层的硬核操作。W5500的DHCP自动获取IP千万别裸奔,得套个重试马甲:
uint8_t get_ip_retry(uint8_t retries) {
while(retries--) {
if(ctlwizchip(CW_GET_IP, &ip) == NET_OK) {
printf("DHCP成功!IP:%d.%d.%d.%d\n", ip[0],ip[1],ip[2],ip[3]);
return 1;
}
sys_check_timeout(); // 系统滴答时钟必须喂
dhcp_time_handler(); // DHCP状态机推进
}
return 0; // 失败必须返回0,别让程序瞎跑
}
这里syschecktimeout()就像设备的呼吸节奏,没它整个协议栈直接憋死。曾经因为漏了这个函数,DHCP永远卡在获取状态。
MQTT连接要稳得像老狗,得玩点状态机套路。看这个带自动回连的发布函数:
int mqtt_pub(const char* topic, const char* msg) {
static uint8_t reconnect_cnt = 0;
if(mqtt_client.isconnected) {
int rc = MQTTPublish(&mqtt_client, topic, msg, strlen(msg), 0);
if(rc != SUCCESS) {
mqtt_client.isconnected = 0; // 异常立即断线
return -1;
}
return 0;
} else {
while(reconnect_cnt++ < 3) {
if(mqtt_connect() == 0) {
reconnect_cnt = 0;
return mqtt_pub(topic, msg); // 递归重试
}
HAL_Delay(2000);
}
return -2; // 彻底失败明确返回错误码
}
}
这里递归重试比while循环更安全,防止堆栈溢出。实测最多重试3次,超过就放弃治疗,避免设备变砖。

W5500实现MQTT 稳定连接 自动获取ip 相关函数均带返回值 带freemodbus主从站
FreeModbus主从站共存才是真功夫,分享个配置秘方:
void modbus_init() {
// 主站配置
eMBMasterInit(MB_RTU, 0x01, 38400, MB_PAR_NONE);
eMBMasterEnable();
// 从站配置(共用同一个串口)
eMBInit(MB_RTU, 0x02, 0, 38400, MB_PAR_NONE);
eMBEnable();
// 中断里玩双标
void USART2_IRQHandler() {
if(USART_GetITStatus(USART2, USART_IT_RXNE)) {
static uint8_t is_master = 0;
uint8_t ch = USART_ReceiveData(USART2);
// 主站接收
if(is_master) {
xMBMasterRTUReceiveFSM(&ch, 1);
}
// 从站接收
else {
xMBRTUReceiveFSM(&ch, 1);
}
is_master = !is_master; // 交替处理
}
}
}
这招主从分时处理实测在38400波特率下稳如老狗。注意中断里别做复杂操作,否则分分钟丢数据。
最后来个保命符——看门狗喂食策略:
void HAL_IWDG_Refresh() {
static uint8_t feed_counter = 0;
if(net_ok && modbus_ok) {
IWDG_ReloadCounter(); // 全正常时正常喂狗
} else {
if(++feed_counter > 60) { // 异常时延迟复位
IWDG_ReloadCounter();
feed_counter = 0;
}
}
}
这个喂狗策略让设备在异常时能挣扎着尝试恢复,实在没救再重启,避免频繁复位把EEPROM写爆。

实测这套方案在产线跑了三个月没掉过链子。关键是把每个函数的返回值都当祖宗供着,宁可错杀一千也别放过一个异常状态。代码里到处都是if判断虽然看着啰嗦,但稳定性真是拿这个堆出来的。
更多推荐
所有评论(0)