结果:当前版本已能 Ping 通,连续 Ping 时不再出现串口错误提示。今天排查的关键,是从启动错误逐步追到时钟配置、ETH 中断和 lwIP 接收缓冲。
调试过程
确认系统初始化失败阶段:mx_system_init() 返回 0x6d6d6d6d,对应 SYSTEM_PERIPHERAL_ERROR。继续逐段检查后,发现失败在 mx_eth1_init() 的 HAL_ETH_SetConfig()。
定位 ETH 软件复位卡住
调试时发现 ETH1->DMAMR.SWR 一直为 1,表示 ETH 软件复位未完成。检查 CubeMX 时钟配置后,修正了 RMII 参考时钟选择,系统随后可以启动并进入 FreeRTOS 调度器。
接入 USART2 日志
使用已配置的 USART2(115200、8N1)输出诊断信息,看到:
text
lwIP init OK
PHY link up
这表明 lwIP 初始化成功,PHY 最终检测到链路建立。
从 ARP 抓包追查收包路径
Wireshark 最初显示电脑反复广播查询 192.168.1.100,但没有 ARP 响应。检查 ETH 接收路径时发现缺少 ETH1_IRQHandler() 和 ETH1 NVIC 配置。补上 ETH 中断处理并设置适合 FreeRTOS ISR API 的优先级后,抓包出现了 STM32 的 ARP 应答,以及 ICMP Echo Reply。
处理 RX pbuf 缓冲不足
连续 Ping 时出现 pbuf_alloc(PBUF_POOL) != NULL。ETH RX 缓冲区配置为 1528 字节,而 lwIP 池缓冲原先不足以容纳单个 RX 缓冲区。将 PBUF_POOL_BUFSIZE 设为 1536 后,Ping 恢复正常。
处理输入队列资源不足及异常提示
后续偶尔看到 netif input error -1,其中 -1 是 lwIP 的 ERR_MEM。调整了 TCP/IP 输入消息池,并修正输入失败时 RX pbuf 的释放和描述符回收;同时将 RX pbuf 池从 20 增至 32,并把缓冲耗尽诊断改为限频输出。最终连续 Ping 未再出现错误提示。
可复用的排查流程
- 先确认系统初始化返回值,定位失败的外设初始化阶段。
- 检查 ETH 软件复位是否完成,核对 RMII 参考时钟配置。
- 接入串口日志,确认 lwIP 初始化与 PHY 链路状态。
- 用 Wireshark 抓包,确认 ARP 与 ICMP 收发路径是否打通。
- 检查 ETH 中断处理函数与 NVIC 优先级配置。
- 核对 RX 缓冲区与
PBUF_POOL_BUFSIZE的匹配关系。 - 调整 TCP/IP 输入消息池与 RX pbuf 池,并修正失败路径的资源释放。
相关代码位置
mx_eth1.c、mx_cortex_nvic.c、lwipopts.h、eth_interface_freertos.c。
后续验证建议
建议最终再做一次较长时间的连续 Ping,同时观察丢包率、串口是否再出现 RX 缓冲或输入队列提示,以及链路是否稳定保持 UP。