STM32H7x3上的以太网外围设备未正确发送或接收数据。或者,IP堆栈无法建立与其他设备的连接。

可能是什么问题?
 

在大多数情况下,问题与内存布局和内存保护单元(MPU)配置有关。
解决方案

强烈建议遵循与STM32CubeH7封装中提供的示例相同的配置:

例如Projects\STM32H743ZI Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netcon_RTOS。

应满足以下条件:

  • 传递到以太网外围设备(ETH)的所有数据必须不是存储在DTCM RAM中,因为ETH DMA无法访问DTCM RAM(从0x20000000开始)
    • 使用STM32CubeMX生成的项目默认情况下可以将变量放入DTCM RAM。解决方案是将它们放置到D1 SRAM(从0x24000000开始)。
  • TX和RX DMA描述符(在ethernetif.c文件中定义)应位于D2 SRAM中,并由MPU配置为设备 内存或强有序类型。
    • 默认情况下,这些应该由CubeMX为IAR和Keil IDE设置。对于GCC,您需要修改linkerscript(请参阅示例)
    • MPU配置可以在示例中的main.c文件中找到
  • RX缓冲区(在ethernetif.c文件中定义)应位于D2 SRAM中,并且不得配置为设备内存类型(因为像LwIP这样的IP堆栈可以访问未对齐的接收数据)。
    • 这也是默认情况下由CubeMX为Keil和IAR IDE设置的。同样,对于GCC,您需要修改linkerscript(请参阅示例)
    • 不应放置在TX和RX DMA描述符的MPU区域中
    • 应配置为不可缓存内存,或写入
      • 这是HAL库1.2.0版本所必需的,可能不会在库示例中实现

MPU配置示例如下所示(请参阅附件中的MPU配置代码

  • 256字节,0x30040000配置为共享设备,MPU区域2(重叠时需要)
    • 这是用于RX和TX DMA描述符
  • 16 kb,0x304000,配置为直写,MPU区域1
    • 这是由LwIP分配的TX缓冲区
  • 16 kb,0x30040000配置为不可缓存,MPU区域0(重叠时需要)
    • 这是用于以太网驱动程序使用的RX缓冲区

这就是它在STM32Cube7示例中的实现方式,它与库的当前实现(v1.2.0)一起工作。其他配置(例如MPU)也可能工作,但也可能因特定的编译器选项(尤其是优化标志)而失败。
解释

数据由以太网外围设备中的专用DMA管理。这意味着:

  • DMA必须能够访问接收和传输缓冲区
  • 在触发/启用DMA之前,所有数据(包括DMA描述符)必须有效地写入SRAM

Cortex-M7可以无序地执行对普通内存类型的访问。因此,如果我们有序列写入SRAM(默认为Normal类型),然后写入以太网寄存器(默认为Device),这两个操作可以由CPU切换。这种情况在某些情况下确实会发生。

因此,TX和RX DMA描述符应配置为设备或强有序类型,因为:

  • 与其他设备类型访问相比,必须按顺序执行对设备类型的访问
  • 必须执行对强有序类型的访问才能访问所有其他类型(强有序访问充当内存屏障)。

RX缓冲区应该是不可缓存的或直写的,因为在某些情况下,RX缓冲区可以在LwIP堆栈内重新用作TX缓冲区。例如,当ping设备时。因此,有时有效数据将在高速缓存(TX)中,有时在SRAM(RX)中。直写配置可以解决这个问题,但需要在数据接收期间使缓存无效。
 

客户注意事项:
1) 如果您想提交评论,反馈或者关于这篇文章或我们的知识数据库的任何建议,您可以通过电子邮件至kb.feedback@st.com
2) 如果您需要特定的(产品)支持请参阅我们的
支持主页(https://www.st.com/content/st_com/en/support/support-home.html)您可以从各种在线支持选项中进行选择,并选择最符合您要求的服务。