硬汉嵌入式论坛

 找回密码
 立即注册
查看: 351|回复: 6
收起左侧

[以太网] stm32+以太网 DMA ERROR的问题

[复制链接]

7

主题

15

回帖

36

积分

新手上路

积分
36
发表于 2025-6-12 14:52:50 | 显示全部楼层 |阅读模式
本帖最后由 snikeguo 于 2025-6-12 16:40 编辑

只要一调用HAL_ETH_Start_IT后,那么就会进入ETH中断,提示DMA ERROR,DMA相关状态寄存器:


寄存器相关位描述:

几个重要数据结构 MAP:
[C] 纯文本查看 复制代码
.lwip_sec       0x30000000     0x4a83 load address 0x08021634
 *(.RxDecripSection)
 .RxDecripSection
                0x30000000       0x60 ./LWIP/Target/ethernetif.o
                0x30000000                DMARxDscrTab
 *(.TxDecripSection)
 .TxDecripSection
                0x30000060       0x60 ./LWIP/Target/ethernetif.o
                0x30000060                DMATxDscrTab
                0x30000100                        . = ALIGN (0x100)
 *fill*         0x300000c0       0x40 
 *(.Rx_PoolSection)
 .Rx_PoolSection
                0x30000100     0x4983 ./LWIP/Target/ethernetif.o
                0x30000100                memp_memory_RX_POOL_base


对应MPU的配置:
[C] 纯文本查看 复制代码
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x30000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
  MPU_InitStruct.SubRegionDisable = 0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER2;
  MPU_InitStruct.BaseAddress = 0x30000100;
  MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
  MPU_InitStruct.SubRegionDisable = 0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);


对DMA描述符所在的区域设置为Device模式 或者Strongly order 模式,
对0x30000100这块区域用作LWIP 静态内存。
I/D cache 都开了

下载.png
下载 (1).png

评分

参与人数 1金币 +6 收起 理由
不吃鱼的猫大人 + 6 赞一个!

查看全部评分

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-6-13 06:51:01 | 显示全部楼层
分配到这里试试

RW_ETH_RX_DESC 0x30040000 0x00000060 {
  *(.RxDecripSection)
}
RW_ETH_TX_DESC 0x30040060 0x00000060 {
  *(.TxDecripSection)
}
RW_ETH_RX_BUF  0x30040100 0x00001800 {
  *(.RxArraySection)
}
RW_ETH_TX_BUF  0x30041900 0x00001800 {
  *(.TxArraySection)
}

然后这个RAM空间时钟记得单独开启
回复

使用道具 举报

7

主题

15

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2025-6-14 00:15:35 | 显示全部楼层
eric2013 发表于 2025-6-13 06:51
分配到这里试试

RW_ETH_RX_DESC 0x30040000 0x00000060 {

目前这个问题解决了,是因为LWIP动态内存管理开始地址这里出问题了,我改成0x30004000就好了
回复

使用道具 举报

7

主题

15

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2025-6-14 00:18:28 | 显示全部楼层
目前新问题是:我收到PC发来的ARP包,我调试发现命名单片机发出去了ARP回复。但是PC死活收不到,不是板子问题,同一块板子,其他程序就可以。我打印了LOG:
ethernet_input: dest:FF:FF:FF:FF:FF:FF, src:00:0E:C6:E6:FF:06, type:806
etharp_update_arp_entry: 192.168.0.11 - 00:0E:C6:E6:FF:06
etharp_find_entry: found matching entry 0
etharp_update_arp_entry: updating stable entry 0
etharp_input: incoming ARP request
etharp_raw: sending raw ARP packet.
ethernet_output: sending packet 3000404C
gq:low_level_output: 42 bytes sent,p->payload address:0x3000405E,p->payload :00 0e c6 e6 ff 06 01 02 03 04 05 06 08 06 00 01 08 00 06 04 00 02 01 02 03 04 05 06 c0 a8 00 c8 00 0e c6 e6 ff 06 c0 a8 00 0b ,errval:0
然后我让AI解答了一下:

根据你提供的详细配置信息(PC:192.168.0.11/00:0E:C6:E6:FF:06;单片机:192.168.0.200/01:02:03:04:05:06)和LOG数据,结合LwIP协议栈机制及STM32硬件特性,重新分析如下:

🔍 一、ARP响应包结构验证(基于LOG数据)
你提供的原始数据包解析如下(已按正确IP-MAC映射标注):

hex
复制
00 0E C6 E6 FF 06  // 目的MAC(PC的正确MAC)✅  
01 02 03 04 05 06  // 源MAC(STM32的预设MAC)✅  
08 06              // 帧类型(ARP)✅  
00 01 08 00 06 04  // 硬件/协议类型✅  
00 02              // 操作码(ARP响应)✅  
01 02 03 04 05 06  // 发送方MAC(STM32)✅  
C0 A8 00 C8        // 发送方IP(192.168.0.200,STM32)✅  
00 0E C6 E6 FF 06  // 目标MAC(PC)✅  
C0 A8 00 0B        // 目标IP(192.168.0.11,PC)✅  
​结论​:ARP响应包中的IP-MAC映射关系完全正确,无逻辑错误


⚠️ 二、核心问题诊断
1. ​短帧未填充导致物理层丢弃​(根本原因)
你的LOG显示发送帧长度仅42字节,但以太网帧最小长度要求64字节​(含14B帧头 + 46B数据 + 4B CRC)

实际有效数据为28B ARP报文 + 14B以太网头 = ​42B,​缺少22B填充字段。
​后果​:PHY芯片或交换机检测到短帧会直接丢弃,PC网卡无法收到

2. ​DMA缓冲区Cache未刷新​(STM32H7高频问题)
STM32H7的DMA无法自动维护Cache一致性,若发送缓冲区未手动清理,可能导致:
DMA发送旧数据​(如全0)
发送空包​(实际无数据输出)
LOG中errval:0仅表示驱动层提交成功,​不保证数据已写入物理内存。
3. &#8203C端ARP响应处理延迟容忍度低​
你的测试表明:当STM32响应延迟 >1ms时,PC可能丢弃后续UDP包

当前LOG未记录时间戳,但短帧和Cache问题会显著增加物理层延迟。
🛠️ 三、解决方案(按优先级排序)
1. ​补足以太网帧长度至60B(不含CRC)​​
在low_level_output()中添加填充逻辑:

c
复制
// 确保帧长度≥60字节(14B头+46B数据)
if (len < 60) {
    memset((uint8_t*)buffer + len, 0, 60 - len); // 填充0
    len = 60; // 更新有效长度
}
// 提交填充后的数据到DMA
ETH_TxPkt_ChainMode(buffer, len);
&#8203;作用&#8203;:满足IEEE 802.3最小帧长要求,避免物理层丢弃


2. &#8203;强制刷新DMA缓冲区Cache&#8203;
在发送前调用Cache清理函数:

c
复制
SCB_CleanDCache_by_Addr((uint32_t*)buffer, len); // 清理发送缓冲区
&#8203;注意&#8203;:缓冲区地址需对齐32字节边界(STM32H7要求)


3. &#8203;优化PC端ARP响应容忍时间&#8203;
临时方案:在PC端添加静态ARP表项(避免依赖动态响应)

bash
复制
arp -s 192.168.0.200 01-02-03-04-05-06
长期方案:优化STM32中断响应,确保ARP响应在100μs内完成&#8203;

&#128295; 四、其他潜在问题排查
问题类型        检测方法        解决方案
&#8203HY状态异常&#8203;        读取PHY芯片的BASIC_STATUS寄存器(地址0x01),检查Link Up和Duplex位        检查复位时序、RMII时钟稳定性
&#8203;MAC地址过滤&#8203;        PC端用Wireshark抓包,观察是否收到01:02:03:04:05:06的帧        关闭PC防火墙/安全软件的ARP过滤功能
&#8203;子网掩码不匹配&#8203;        确认PC和STM32的子网掩码均为255.255.255.0        修改netif->netmask配置
&#128142; 总结
你的ARP响应包内容正确,但存在两个致命硬件层问题:

&#8203;短帧丢弃&#8203; → 补足至60B;
&#8203;Cache未刷新&#8203; → 调用SCB_CleanDCache_by_Addr。
按此修复后,PC应能立即收到ARP响应。若问题仍存,建议用逻辑分析仪捕获ETH_TXD信号,验证物理层是否有波形输出
回复

使用道具 举报

7

主题

15

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2025-6-14 00:21:41 | 显示全部楼层
就赶紧想回环一样,或者是好像TX引脚没有发出去一样? 但是能进入HAL_ETH_TxCpltCallback
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-6-14 08:00:18 | 显示全部楼层
snikeguo 发表于 2025-6-14 00:21
就赶紧想回环一样,或者是好像TX引脚没有发出去一样? 但是能进入HAL_ETH_TxCpltCallback

MPU配置好后,你的底层接口文件里面,还有些Cache操作也要做下,你这个做了没。

还有就是HAL库使用新版,不要使用老版,老版有bug
回复

使用道具 举报

7

主题

15

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2025-6-14 23:13:00 | 显示全部楼层
eric2013 发表于 2025-6-14 08:00
MPU配置好后,你的底层接口文件里面,还有些Cache操作也要做下,你这个做了没。

还有就是HAL库使用新 ...

问题已经解决,我遇到的问题有
1.Start IT 后就进入DMA ERROR,原因是我用的STM32H723 D2RAM只有32K字节,lwipopt.h文件中我配置的动态内存的区域不合理,之前有问题的动态内存启动地址+长度已经超过了32K的边界。
2.解决完第一个问题后,我又遇到了能收不能发的问题,这个发现是我另外一个线程在测试FATFS,由于没有插入TF卡,导致卡住了,占用了CPU,而那个线程优先级又很高,所以导致发不出去,我插入TF卡或者临时屏蔽或者修改优先级 三个手段任一都可以解决问题。
至此,对stm32h7的cache、mpu、以太网IP相关寄存器也有了更深入的认识。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 07:01 , Processed in 0.051298 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表