[STM32F4] STM32F407 以太网 DMA 触发HARDFault错误

[复制链接]
117|22
封存into 发表于 2026-7-6 13:39 | 显示全部楼层 |阅读模式
在 STM32F407 芯片上启用以太网外设时出现 DMA 总线错误。
以太网 PHY 芯片从路由器收到数据包时,该错误就会出现。
给 PCB 开发板上电;执行外设初始化,初始化阶段无任何报错;
插上网线;对局域网内任意设备执行 ping 操作;随后以太网错误回调函数 HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) 立即触发。
259446a4b23d739aed.png
进入以下错误代码
/* ETH DMA Error */
if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_AIS))
{
if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMAIER_AISE))
{
heth->ErrorCode |= HAL_ETH_ERROR_DMA;

/* if fatal bus error occurred */
if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMASR_FBES))
{
/* Get DMA error code */
heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_FBES | ETH_DMASR_TPS | ETH_DMASR_RPS)); <<--- HERE!

/* Disable all interrupts */
__HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMAIER_NISE | ETH_DMAIER_AISE);

/* Set HAL state to ERROR */
heth->gState = HAL_ETH_STATE_ERROR;
}
else
{
/* Get DMA error status */
heth->DMAErrorCode = READ_BIT(heth->Instance->DMASR, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
ETH_DMASR_RBUS | ETH_DMASR_AIS));

/* Clear the interrupt summary flag */
__HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMASR_ETS | ETH_DMASR_RWTS |
ETH_DMASR_RBUS | ETH_DMASR_AIS));
}

solty 发表于 2026-7-7 14:56 | 显示全部楼层
触发ETH_DMASR_FBES表明DMA访问AHB总线时发生严重异常,常见原因是描述符地址未对齐或指向无效内存区域。
classroom 发表于 2026-7-7 15:30 | 显示全部楼层
以太网DMA描述符必须放置在__attribute__((aligned(4)))的SRAM中,若描述符位于CCM RAM(仅CPU可访问)或地址未对齐,DMA无法访问将触发总线错误。
cr315 发表于 2026-7-7 15:56 | 显示全部楼层
收到数据包即触发错误,意味着接收描述符Rx_Buff指向的内存区域可能超出了DMA可寻址范围,STM32F407的DMA只能访问0x20000000~0x2001FFFF范围内的SRAM。
duo点 发表于 2026-7-7 16:32 | 显示全部楼层
初始化阶段无报错但收包时出错,说明描述符链表构建时有部分信息(如Buffer地址)在初始化时未被DMA检查,直到实际收包时才会触发。
flycamelaaa 发表于 2026-7-7 17:05 | 显示全部楼层
ETH_DMASR_RPS寄存器值可反馈DMA接收引擎当前状态,读取该位有助于定位是空闲、暂停还是挂起状态。
jcky001 发表于 2026-7-7 17:38 | 显示全部楼层
若开启了Cache或使用外部SRAM作为缓冲区,可能存在数据一致性问题,DMA和CPU访问同一块内存时需要使用__DMB()和SCB_CleanInvalidateDCache进行同步。
onlycook 发表于 2026-7-7 20:59 | 显示全部楼层
建议先检查ETH->DMASR寄存器的TPS和RPS位,结合DMAErrorCode读回的完整错误码,可细化判断是传输错误、总线错误还是描述符错误。
powerantone 发表于 2026-7-7 21:29 | 显示全部楼层
PHY芯片收包后通过MII接口将数据传给MAC,MAC再通过DMA搬运到内存,若RMII接口时钟或IO配置有误,可能产生数据损坏进而诱发DMA异常。
probedog 发表于 2026-7-7 22:00 | 显示全部楼层
以太网初始化时未使能ETH_DMAIER_AISE时不会进入该回调,但既然触发了中断,说明初始化中已使能该中断源,需确认是否被误使能。
solty 发表于 2026-7-7 22:34 | 显示全部楼层
以太网DMA的DMASR寄存器在Fatal Bus Error发生后不会自动清除,需软件写1清除,若未清理,下次收包时旧错误标志仍会触发中断。
spicy 发表于 2026-7-7 22:58 | 显示全部楼层
硬件设计上,F407的ETH_DMA通过AHB总线矩阵访问SRAM,若多个DMA同时访问,可能因仲裁问题导致ETH_DMA无法及时获取总线控制权。
stormwind123 发表于 2026-7-7 15:20 | 显示全部楼层
排查时可使用逻辑分析仪或示波器观测ETH_RMII_REF_CLK和ETH_RMII_CRS_DV等信号线,硬件时钟不稳定或电平不匹配也可能导致MAC层异常,进而触发DMA错误。
亚瑟 发表于 2026-7-8 12:02 | 显示全部楼层
寄存器ETH_DMASR的TPS和RPS位要仔细检查,确认DMA状态,结合DMAErrorCode读回的完整错误码,看是传输错误还是描述符错误。同时,检查描述符是否对齐,是否在DMA可访问范围内。
公羊子丹 发表于 2026-7-8 13:22 | 显示全部楼层
看你DMAErrorCode数值很大,大概率是接收描述符内存没做4字节对齐!F4以太网DMA严格要求缓冲区32位对齐,数组不加__ALIGN_BEGIN就会触发FBES总线错误。
周半梅 发表于 2026-7-8 13:23 | 显示全部楼层
我之前F407以太网ping包就报同款DMA总线错,你看下收发描述符列表是不是放在栈里了,栈内存不稳定,移到全局SRAM里再测试基本能解决。
帛灿灿 发表于 2026-7-8 13:23 | 显示全部楼层
建议你先读取DMASR寄存器完整打印出来,FBES置1代表严重总线错误,分发送/接收侧故障,能快速区分是收包缓冲区还是描述符配置出问题。
童雨竹 发表于 2026-7-8 13:24 | 显示全部楼层
怀疑你CubeMX里以太网时钟配置不对,F4的ETH外设需要HSE 25MHz精准晶振,外部晶振不准会导致PHY和MAC时序错乱,一收数据包直接报错。
万图 发表于 2026-7-8 13:25 | 显示全部楼层
调试小技巧:临时把接收缓冲区扩大一倍,关闭DMA中断改用轮询收包,要是不再进错误回调,就是描述符链表断链或者缓冲区溢出导致总线异常。
Wordsworth 发表于 2026-7-8 13:26 | 显示全部楼层
很多新手忽略PHY复位时序,初始化ETH前必须拉低PHY复位脚保持10ms再释放,PHY未就绪时接收数据包,DMA极易触发总线Fault。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

230

主题

288

帖子

0

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