STM32H7 ETH Tx fails depending on buffer address

Hi,

I have been porting an application on STM32H723 with FreeRTOS. I am using STMCube IDE 1.10.0 for the configuration, along with LWIP and MBEDTLS

Based on samples on GITHUB (stm32-hotspot/STM32H7-LwIP-Examples - I cannot post any link but you’ll find) I was able to make a good start, however, as soon as I add MbedTLS I get issues in Tx of ETH buffers.

After long debugging, I figured out that the DMA failed when the buffer is outside the memory region “RAM_D2” (0x3000_0000 + 32K) (no Ack of emission and we’re stuck waiting for the semaphore)

Currently I patched my application to manually copy the UDP (Multicast) buffer into a reserved region in RAM_D2 and it works fine, but I do not understand where this issue comes from. (And I want to remove this ugly patch)

Just to make it clear, here is the “ugly” patch that works:


#ifdef SOPC_FREERTOS_UDP_RAM_BASE
    static uint8_t* DTCMR_Buffer = (void*) 0x30007000; // DTCM + 28K (=32 - 4 K)
    SOPC_ASSERT(buffer->length < 4 * 1024);
    static SOPC_Mutex* mutex = NULL;

    if (NULL == mutex)
    {
        SOPC_Mutex_Initialization(mutex);
    }

    SOPC_Mutex_Lock(mutex);

    memcpy(DTCMR_Buffer, buffer->data, buffer->length);
    ssize_t res = sendto(sock, DTCMR_Buffer, buffer->length, 0, destAddr->ai_addr, destAddr->ai_addrlen);

    SOPC_Mutex_Unlock(mutex);
#else
#warning \
    "SOPC_FREERTOS_UDP_RAM_BASE is not defined and UDP sending may probably fail if RAM section is not properly set with DMA!"
    ssize_t res = sendto(sock, buffer->data, buffer->length, 0, destAddr->ai_addr, destAddr->ai_addrlen);
#endif

I can confirm that

  • the Tx descriptor are correctly located in RAM_D2 (cache disabled).
  • the MPU is configured as (from example on github):
    • region 0 : disable 4GB
    • region 1 : RAM_D2 disable cache/share/buffer for 32K (full size)
    • region 2 : RAM_D2 disable cache, enable share/buffer for 512b (where the TRx & Rx descr. are located)
    • I added regions 3…6 that were initially not in the demo:
    • region 3 & 4 : enable all on RAMD1 : 265 + 64K (hum I do not understand how all this was OK previoulsy without this…)
    • region 5 :enable all on DTCM (I need more HEAP for MbedTLS, using HEAP5 to extend heap)

Can anyone tell me :

  • Shall I enforce actual data to be on a non-cacheable section (As far as I understood, only the descriptor need that, but that may be where I am wrong) ?
  • Is there any option to do this automatically (something like LWIP_MPU_COMPATIBLE which seems to have a close enough behavior) ?
  • Why does this only happen when adding MBEDTLS module?
  • Why only section on RAM_D2 are enabled on MPU ? Is my MPU configuration OK ? (I can provide precise configuration if required)
  • Is it a mistake to use DTCM for additional HEAP? (section not cacheable?)

I’ll be grateful for anny answers :slight_smile:

Regards,

A number of PODs do not allow DMA to access certain memory regions depending on the internal bus architecture, have you checked that with your MCUs user guide?

This article provides the information you are looking for - Ethernet not working on STM32H7x3 - STMicroelectronics Community.

[EDIT] This post also has useful discussion - FreeRTOS+TCP for STM32H7?.

1 Like

Ok thanks.

I don’t know where to get this information from H723 user manual… but his make sens.

I also guess that enabling Cache for DCTM in MPU configuration will not miraculously make it Cacheable… ?