STM32 LWIP TCP服务器调试正常但脱机无法连接的问题求助
问题:STM32 LWIP TCP服务器仅脱机时无法建立连接
问题代码
void Tcp_Task(void const * argument) { /* USER CODE BEGIN Tcp_Task */ struct netconn *conn, *newconn; err_t err, accept_err; struct netbuf *buf; void *data; u16_t len; HAL_GPIO_WritePin(GPIOK, GPIO_PIN_3, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOK, GPIO_PIN_5, GPIO_PIN_SET); LWIP_UNUSED_ARG(argument); HAL_Delay(1000); HAL_GPIO_WritePin(GPIOK, GPIO_PIN_3, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOK, GPIO_PIN_5, GPIO_PIN_RESET); conn = netconn_new(NETCONN_TCP); HAL_Delay(1000); HAL_GPIO_WritePin(GPIOK, GPIO_PIN_3, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOK, GPIO_PIN_5, GPIO_PIN_SET); if (conn!=NULL) { // netconn_bind(conn, NULL, port 번호) err = netconn_bind(conn, NULL, 5001); if (err == ERR_OK) { netconn_listen(conn); while (1) { accept_err = netconn_accept(conn, &newconn); if (accept_err == ERR_OK) { while (netconn_recv(newconn, &buf) == ERR_OK) { do { netbuf_data(buf, &data, &len); memcpy(receivemsg, data, len); // 메시지 송신 netconn_write(newconn, data, msg_len, NETCONN_COPY); } while (netbuf_next(buf) >= 0); netbuf_delete(buf); } netconn_close(newconn); netconn_delete(newconn); } osDelay(100); } } else { netconn_delete(newconn); } } /* Infinite loop */ for(;;) { osDelay(100); } /* USER CODE END Tcp_Task */ }
问题现象
- 通过ST-Link调试时,TCP服务器功能正常,可正常响应客户端消息;
- 仅连接电源(无ST-Link调试)时,LED显示代码运行正常,但客户端无法建立连接;
- 怀疑问题出在
conn = netconn_new(NETCONN_TCP)或LWIP_UNUSED_ARG(argument),但调试时正常的现象与此矛盾; - 已通过CubeMX配置LWIP、FreeRTOS、ETH、RCC模块。
排查与解决方案
1. 时钟配置差异
调试模式下ST-Link会强制同步时钟,脱机时可能存在时钟启动或配置异常:
- 检查RCC配置,确保HSE/LSE晶振在脱机时能正常起振,延长CubeMX中时钟超时时间;
- 验证ETH外设的时钟分频参数,脱机时钟频率异常会直接导致LWIP栈失效。
2. LWIP初始化时机调整
当前TCP任务启动后直接创建连接,可能LWIP栈尚未完成初始化:
- 降低TCP任务的启动优先级,确保ETH和LWIP初始化任务(如
ethernetif_init)先执行; - 在TCP任务开头添加网卡就绪等待逻辑:
// 等待LWIP网卡初始化完成 while(!netif_is_up(&gnetif)){ osDelay(100); }
3. 内存分配故障排查
脱机时系统内存可能存在初始化异常,导致netconn_new分配失败:
- 在
conn = netconn_new(NETCONN_TCP)后添加错误检测,若分配失败触发LED闪烁提示; - 在CubeMX中增大LWIP内存池参数(如
MEM_SIZE、TCP_MSS),减少内存分配压力。
4. 代码逻辑修复
当前代码存在隐性错误,调试时ST-Link干预掩盖了问题:
- 错误分支中
netconn_delete(newconn)属于野指针操作,应改为netconn_delete(conn); netconn_write中使用未定义的msg_len,替换为实际接收的len;- 替换
HAL_Delay为FreeRTOS的osDelay,避免阻塞LWIP调度。
修改后的核心代码片段:
// 等待LWIP网卡初始化完成 while(!netif_is_up(&gnetif)){ osDelay(100); } conn = netconn_new(NETCONN_TCP); // 内存分配失败检测 if(conn == NULL){ while(1){ HAL_GPIO_TogglePin(GPIOK, GPIO_PIN_3); osDelay(500); } } // ... // 修正错误分支的指针操作 else { netconn_delete(conn); } // ... // 使用实际接收长度发送数据 netconn_write(newconn, data, len, NETCONN_COPY);
5. 硬件稳定性检查
脱机时电源纹波或硬件接触不良可能影响ETH模块:
- 检查电源模块输出稳定性,确保ETH PHY芯片供电符合规格;
- 验证以太网接口接线,确认PHY芯片复位引脚工作正常。
内容的提问来源于stack exchange,提问作者user11503466
相关产品推荐
相关产品推荐

