FAQ: Ethernet not working on STM32H7x3

Document created by Adam Berlinger Employee on Jan 4, 2018Last modified by Adam Berlinger Employee on Jun 10, 2018
Version 8Show Document
  • View in full screen mode

Q:
The Ethernet peripheral on STM32H7x3 is not sending, or receiving data correctly. Or, the IP stack is not able to establish connection to other devices.

What could be the problem?

 

 

A:

In most cases, the problem is related to memory layout and Memory Protection Unit (MPU) configuration.

Solution

It is strongly recommended to follow the same configuration as in examples provided in STM32CubeH7 package:

e.g. Projects\STM32H743ZI-Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS.

 

The following conditions should be met:

  • All data passed to Ethernet peripheral (ETH) must NOT be stored in DTCM RAM, since the ETH DMA can't access DTCM RAM (starting at 0x20000000)
    • Projects generated with STM32CubeMX can put variables by default to DTCM RAM. The solution is to place them to D1 SRAM (starting at 0x24000000).
  • TX and RX DMA descriptors (defined in ethernetif.c file) should be located in D2 SRAM and be configured by MPU as Device memory or Strongly-ordered type.
    • These should be set by default by CubeMX for IAR and Keil IDEs. For GCC, you need to modify the linkerscript (please see the examples)
    • MPU configuration can be found in main.c file in the example
  • RX buffer (defined in ethernetif.c file) should be located in D2 SRAM and must not be configured as Device memory type (because IP stacks like LwIP can access the received data unaligned).
    • This is also set by default by CubeMX for Keil and IAR IDEs. Again For GCC, you need to modify the linkerscript (please see the examples)
    • Shouldn't be placed in MPU region of TX and RX DMA descriptors
    • Should be configured as non-cacheable memory, or write-through
      • This is required for HAL library version 1.2.0 and might not be implemented in the library examples

The example MPU configuration can look like (please see attached file for MPU configuration code):

  • 256 bytes at 0x30040000 configured as Shared Device, MPU region 2 (required for overlapping)
    • This is for RX and TX DMA descriptors
  • 16 kb at 0x30044000 configured as write-through, MPU region 1
    • This is for TX buffers allocated by LwIP
  • 16 kb at 0x30040000 configured as non-cacheable, MPU region 0 (required for overlapping)
    • This is for RX buffer used by the Ethernet driver

This is how it is implemented in STM32CubeH7 examples, and it works with the current implementation of the library (v1.2.0). Other configurations (e.g. MPU) might also work, but might also fail with specific compiler options (especially with optimization flags).

 

Explanation

The data are managed by the dedicated DMA in the Ethernet peripheral. This means that:

  • Receive and transmit buffers must be accessible by DMA
  • All data (including DMA descriptors) must be effectively written to the SRAM before triggering/enabling the DMA

 

The Cortex-M7 can perform accesses to Normal memory type out-of-order. So if we have sequence write to SRAM (Normal type by default), then write to Ethernet register (Device by default), those two operations can be switched by the CPU. And this actually happens in some cases.

 

So the TX and RX DMA descriptors should be configured to Device or Strongly-ordered type, since:

  • accesses to Device type must be performed in-order compared to other Device type accesses
  • accesses to Strongly-ordered type must be executed in-order to all other types (Strongly-ordered access acts as memory barrier).

The RX buffer should be non-cacheable or write-through, because at some cases the RX buffer can be reused as TX buffer inside the LwIP stack. E.g. when pinging the device. So sometimes the valid data would be in cache (TX) and sometimes in SRAM (RX). The write-through configuration can solve this issue, but requires cache invalidation during the data reception.

Outcomes