cancel
Showing results for 
Search instead for 
Did you mean: 

Can the Tx of the Ethernet of STM32H743BIT work without inserting SCB_CleanDCache_by_Addr() in low_level_output()?

KYama.4
Associate

I have STM32H743BIT and want to get its UDP communication working. It uses FreeRTOS and LWIP.

I followed this article for the project configuration. (https://community.st.com/s/article/FAQ-Ethernet-not-working-on-STM32H7x3)

But my STM32H743BIT is able to transmit correct Tx data only when this fix is also implemented. (https://community.st.com/s/question/0D50X00009XkXUWSA3/stm32h7-lwip-cache-bug-fix) Otherwise, the transmit packet has correct length but it is filled with 0x0.

My question is whether STM32H743BIT always require this fix (in the 2nd article) regardless of MPU configuration?

Is there any way to make sure Tx buffer is properly set without modifying automatically generated code like ethernetif.c?

Thank you very much.

Ken

4 REPLIES 4

Control what memory is used, and config the MPU for the designated memory as NON CACHED, NON BUFFERED

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
KYama.4
Associate

Thank you very much for your response.

I have investigated my problem and found out the problem is coming from the address where STM32CubeMx allocates to memp_pools" (defined in memp.c.)

I discovered it by checking the pbuf behavior in low_level_output().

When the problem occurs, the packet to be transmitted has 430 bytes in total. That is passed to low_level_output() as a chain of two "pbuf"s.

The contents of the chained pbufs are as follows.

In low_level_output(struct netif *netif, struct pbuf *p)....

   p is at 0x30044008.

   p->tot_len is 430 (Total packet length).

   p->payload is at 0x3004401a

   p->next is 0x240145ec <memp_memory_PBUF_base+240>

   p->next->tot_len is 388

   p->next->payload is at 0x2401496c <memp_memory_TCP_PCB_base+156>

   p->next->next is at 0x0 (Meaning it is the end of pbuf chain)

The first part of the Tx packet is from 0x3004401a (p->payload), which is allocated from LWIP_RAM_HEAP_POINTER area. The data of this part is set correctly to the Tx packet because it is set non-chachable by MPU.

However, the 2nd part of the Tx packet is from 0x2401496c (p->next->payload), which is from the element [1] of "memp_pools" defined in memp.c.

Address 0x2401496c is not a configured region by MPU. So the cache is enabled.

In fact, the 388 bytes are the data that remain 0x0 if SCB_CleanDCache_by_Addr() was not called. Calling SCB_CleanDCache_by_Addr() to the address (p->next->payload) within low_level_output() makes sure the 388 bytes contain proper data. This proves that cache is preventing right data from being transfered by DMA. (0x2401496c is within RAM_D1 by the way)

It seems to me that it is necessary to place "memp_pools" defined in memp.c to a specific address range and configure it to be non-cacheable. Otherwise SCB_CleanDCache_by_Addr() seems to be required.

Do you know how to make sure the cache behavior of "mempools" is configured by STM32CubeMx?

It is true that I get a .map file by building the project and I may be able to configure STM32CubeMx accordingly. But I want STM32CubeMx to know that "mempools" should not be cachable because it is apparently used by DMA for Tx data.

Or is there any better way?

Thomas E.
Associate II

The function SCB_CleanDCache_by_Addr needs to be able to handle address that are not 32 byte aligned, but expanding the data cache flushing region to conforming addresses.

netXduo calls that function regardless of regions. So right now I have to turn off data caching and force the following in stm32h743xx.h for the Nucleo board we are using and stm32h725xx.h on our target

#define __DCACHE_PRESENT          0       /*!< CM7 data cache present                        */