STM32H7使用全局/静态变量后以太网故障求助
问题描述
我使用STM32H735ZGTx_LQFP144开发板,已完成以太网配置。未使用全局或静态变量时以太网工作正常,但声明并使用这类变量后,以太网停止工作,且变量大小不同引发不同错误:
- 初始化全局变量
char buff[5] = "123":出现Hard Fault错误 - 未初始化全局变量
char buff[100]:触发断言pc->custom_free_function != NULL(../Middlewares/Third_Party/LwIP/src/core/pbuf.c第767行) - 未初始化全局变量
char buff[200]:触发断言pbuf_free: p->ref > 0(../Middlewares/Third_Party/LwIP/src/core/pbuf.c第753行)及断言mem_trim: legal memory(../Middlewares/Third_Party/LwIP/src/core/mem.c第721行)
经检查全局变量均存储在RAM_D1中,Hard Fault发生在pbuf_free()函数执行时。
排查步骤
检查RAM分配与LwIP内存区域重叠
STM32H7的RAM_D1包含AXI SRAM、DTCM等子区域,LwIP会占用部分SRAM作为内存池。打开工程的链接脚本(.ld文件),找到.bss、.data段的起始/结束地址(对应全局/静态变量存储区),对比lwipopts.h中MEM_START和MEM_SIZE定义的内存池范围,确保两者无重叠。若重叠,可调整MEM_START到未被占用的RAM区域,或修改链接脚本中全局变量段的地址/大小。调整LwIP内存池配置
全局变量占用RAM会挤压LwIP内存池空间,导致内存分配失败或损坏。打开lwipopts.h:- 增大
MEM_SIZE(比如从默认16KB调整到32KB,根据RAM剩余空间调整) - 检查
MEMP_NUM_PBUF、MEMP_NUM_TCP_SEG等缓冲区数量,确保满足通信需求。
- 增大
定位Hard Fault具体原因
用调试器查看Hard Fault发生时的栈回溯和寄存器值(PC、LR、SP),定位到具体代码行。这类错误通常是内存越界或空指针解引用导致,全局变量的分配可能破坏了LwIP内部内存结构。确认全局变量存储区域的DMA可访问性
以太网DMA需要访问LwIP内存池,若全局变量存储在DTCM(仅CPU可访问),且LwIP内存池也在DTCM,会导致DMA访问出错。检查链接脚本,确保全局变量和LwIP内存池都在AXI SRAM(RAM_D1的DMA可访问区域)。排查编译器优化问题
高等级编译器优化可能引发未定义行为。将优化等级调整为-O0(无优化)测试,若问题消失,再逐步调整优化等级,同时检查代码中是否存在数组越界等未定义操作。验证内存对齐设置
LwIP的pbuf缓冲区需满足DMA对齐要求(通常4/8字节对齐)。检查链接脚本中.bss、.data段的对齐设置,确保与LwIP内存池的对齐要求一致,避免因全局变量分配破坏内存对齐导致DMA访问错误。
内容的提问来源于stack exchange,提问作者Nazish Hussain

