[STM32H7] 长时间空闲之后 UDP 数据包无法发送

[复制链接]
378|48
发货后已经wi 发表于 2026-10-9 12:15 | 显示全部楼层
FreeRTOS 的任务优先级设置也有讲究。tcpip_thread 优先级高是好事,但如果应用层任务优先级太低,可能会导致 socket 层的消息队列积压。试着把发送任务的优先级稍微提一点,或者在 sendto 后加个 taskYIELD,让 tcpip_thread 有机会立刻处理
哈根达斯uz 发表于 2026-10-10 10:03 | 显示全部楼层
关于 sys_check_timeouts,虽然你说没用,但还是要确认它调用的频率。LwIP 内部有很多定时器依赖这个函数,如果长时间没调用,ARP 表项过期或者 DHCP 租约问题都可能间接影响发送。建议在 idle hook 里也调用一下,确保后台任务能跑起来
广告商宝宝xx 发表于 2026-10-11 12:59 | 显示全部楼层
还有一个可能是 PHY 的节能模式。有些 PHY 芯片在链路长时间无数据时会自动进入 EEE 或 Deep Sleep 模式,唤醒需要时间。虽然 STM32 侧显示链路正常,但 PHY 侧可能还没完全醒来。试着在初始化时禁用 PHY 的节能功能看看
更多更合适ii 发表于 2026-10-12 09:00 | 显示全部楼层
检查 lwipopts.h 里的 MEMP_NUM_PBUF 和 MEMP_NUM_UDP_PCB 配置。如果长时间运行后有内存泄漏(比如 pbuf 没释放),可能导致内存池耗尽。虽然 sendto 返回成功,但实际上可能分配的是临时缓冲,后续处理时发现没资源了就静默丢弃了
根特皇宫w 发表于 2026-10-13 08:00 | 显示全部楼层
H7 的以太网外设时钟配置要仔细核对。如果使用了外部晶振作为 ETH_REF_CLK,确保频率精准度在 50ppm 以内。时钟偏差过大会导致长时间运行后累积误差,MAC 层时序错乱,虽然中断能触发,但数据发不出去
发的非官方的 发表于 2026-10-15 12:01 | 显示全部楼层
试试在 sendto 之前调用一次 netif_set_link_up 再 netif_set_link_down 模拟链路翻转。如果这样能恢复发送,说明问题出在链路状态维护上,可能是 LwIP 误判了链路状态,导致发送队列被挂起
发顺丰更大nc 发表于 2026-10-16 09:16 | 显示全部楼层
调试时可以打开 LwIP 的 LWIP_DEBUG 宏,特别是 UDP_DEBUG 和 ETHARP_DEBUG。观察长时间空闲后再次发送时的日志,看是否有 "pbuf_alloc failed" 或者 "ethernetif_link_output: link down" 之类的隐藏报错
王派oo 发表于 2026-10-17 10:02 | 显示全部楼层
检查 MPU 对 SRAM 的配置。H7 有多个 SRAM 块,如果 LwIP 缓冲区放在了 DTCM 或 ITCM 里,DMA 是访问不到的。必须确保缓冲区在 AXI SRAM 或 SRAM1/2/3 且配置为 Device 或 Normal Non-cacheable 属性
斧王FUWANG 发表于 2026-10-18 10:15 | 显示全部楼层
既然不修改协议栈源码,可以在应用层做一个看门狗机制。记录上次成功发送的时间戳,如果超过阈值(比如 5 秒)没有发送动作,主动调用一次低层级的 etharp_gratuitous 发送个免费 ARP,既能保活链路,又能唤醒 MAC 引擎
发GV第几啊 发表于 2026-10-19 09:03 | 显示全部楼层
检查 FreeRTOS 的 tickless idle 模式。如果开启了低功耗模式,系统时钟可能会停止,导致 LwIP 的定时器基准出错。长时间空闲后,时间计算可能出现跳变,导致重传机制失效。试着关闭 tickless 模式测试一下
感觉很反感mva 发表于 2026-10-20 10:18 | 显示全部楼层
H7 的 ETH 描述符是放在描述符表里的,这个表的位置也要对齐且非 Cache。有时候数据缓冲区对了,但描述符表被 Cache 缓存了,CPU 更新了 OWN 位但 DMA 看不到,依然认为描述符不可用
kzlzqi 发表于 2026-10-22 09:16 | 显示全部楼层
建议用 Wireshark 在 PC 端抓包,同时用 ST-Link 抓取 MCU 侧的 ITM 日志。对比两边的时间点,确认是 MCU 没发出来,还是发出来被交换机过滤了。有时候是交换机的端口安全策略导致长时间无流量后端口被阻塞
一点点0321 发表于 2026-10-5 21:58 | 显示全部楼层
这个问题在 H7 上太经典了,90% 是 Cache 一致性没处理好。虽然你说关了 Cache,但如果是通过 MPU 配置的,必须确认 LwIP 的 RX/TX 描述符和缓冲区真的被映射成了 Non-cacheable 区域,否则 CPU 改了 OWN 位但 DMA 看不到,或者 DMA 写了数据 CPU 读不到旧值
喂什么玩意 发表于 2026-10-6 08:18 | 显示全部楼层
检查一下 ETH 驱动里的 HAL_ETH_Transmit 实现。H7 的 HAL 库有些老版本在处理空闲队列时,如果长时间不发送,可能会漏掉唤醒 MAC 发送引擎的操作。试着在 sendto 之后手动调用一下 HAL_ETH_StartTransmission,看看能不能把数据“推”出去
突然下起雨 发表于 2026-10-7 10:15 | 显示全部楼层
既然 DMA 描述符 OWN 位为 0,说明 DMA 确实认为任务完成了或者根本没拿到所有权。重点检查 tx_config_descriptor 的初始化逻辑,长时间空闲后,是不是某个指针指飞了,或者描述符链表断了,导致新数据没挂到正确的发送队列上
怎么总是重复啊 发表于 2026-10-8 11:36 | 显示全部楼层
FreeRTOS 的任务优先级设置也有讲究。tcpip_thread 优先级高是好事,但如果应用层任务优先级太低,可能会导致 socket 层的消息队列积压。试着把发送任务的优先级稍微提一点,或者在 sendto 后加个 taskYIELD,让 tcpip_thread 有机会立刻处理
lxs0026 发表于 2026-10-9 10:00 | 显示全部楼层
关于 sys_check_timeouts,虽然你说没用,但还是要确认它调用的频率。LwIP 内部有很多定时器依赖这个函数,如果长时间没调用,ARP 表项过期或者 DHCP 租约问题都可能间接影响发送。建议在 idle hook 里也调用一下,确保后台任务能跑起来
烟雨蒙蒙520 发表于 2026-10-10 11:05 | 显示全部楼层
还有一个可能是 PHY 的节能模式。有些 PHY 芯片在链路长时间无数据时会自动进入 EEE 或 Deep Sleep 模式,唤醒需要时间。虽然 STM32 侧显示链路正常,但 PHY 侧可能还没完全醒来。试着在初始化时禁用 PHY 的节能功能看看
大鹏2365 发表于 2026-10-11 08:01 | 显示全部楼层
检查 lwipopts.h 里的 MEMP_NUM_PBUF 和 MEMP_NUM_UDP_PCB 配置。如果长时间运行后有内存泄漏(比如 pbuf 没释放),可能导致内存池耗尽。虽然 sendto 返回成功,但实际上可能分配的是临时缓冲,后续处理时发现没资源了就静默丢弃了
有何不可0365 发表于 2026-10-12 08:01 | 显示全部楼层
H7 的以太网外设时钟配置要仔细核对。如果使用了外部晶振作为 ETH_REF_CLK,确保频率精准度在 50ppm 以内。时钟偏差过大会导致长时间运行后累积误差,MAC 层时序错乱,虽然中断能触发,但数据发不出去
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部