2025-06-10 7:24 AM - edited 2025-06-10 9:05 AM
Hi everyone,
I’m working with a custom board that uses the STM32H733VGT and the LAN8742AI Ethernet PHY. I’ve configured the MPU and middleware following the ST example for the STM32H75_DISCO board. The board responds to ping in release mode and after a watchdog reset in debug mode—but it fails to respond on the first run after flashing or power-up.
Please find attached my .ioc and ETH Init function file in the attachments.
Any comment or advice would be highly appreciated.
Tnx,
Amir
2025-06-13 2:41 AM
Hello @amirshn,
It seems like your issue might be related to MPU configuration or cache handling, which are critical when working with Ethernet RX buffers. Based on your description, it’s possible that incorrect MPU settings are causing data corruption or loss, especially during the first run after flashing or power-up.
MPU Configuration:
Ensure that the Ethernet RX buffer is configured as non-cacheable or write-through. This prevents cache maintenance operations from discarding data written by the TX process. Misconfigured MPU regions can lead to unpredictable behavior, such as the one you’re experiencing.
Alignment:
Make sure the MPU region is aligned to the size of the region (e.g., 16kB). Proper alignment is crucial for correct operation.
H723 Reference:
Since the only difference between the STM32H733VGT and STM32H723 is the crypto module, I recommend using the MPU configuration for the STM32H723 as a reference. You can adapt it to your STM32H733VGT implementation to ensure compatibility. NUCLEO-H723ZG LwIP GitHub
Best regards,
2025-06-17 10:21 AM
Hi @STackPointer64 ,
Thanks for your response.
I did exactly the same configuration as the example you mentioned but getting exactly the same behavior yet.
I have attached my .ioc file, flash memory configuration and ethernetif.c file.
Here is my MPU config:
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30004000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
Here is the the consul log when the code crashes:
sct calling h=lwip_cyclic_timer t=8 arg=0x8038d54
tcpip: ip_reass_tmr()
sys_timeout: 0x24007c38 abs_time=2283 handler=ip_reass_tmr arg=0x8038d54
sct calling h=lwip_cyclic_timer t=9 arg=0x8038d60
tcpip: etharp_tmr()
etharp_timer
sys_timeout: 0x24007c24 abs_time=2283 handler=etharp_tmr arg=0x8038d60
pbuf_alloced_custom(length=0)
pbuf_alloced_custom(length=0)
pbuf_alloced_custom(length=0)
pbuf_alloced_custom(length=0)
etharp_request: sending ARP request.
pbuf_alloc(length=28)
pbuf_alloc(length=28) == 0x30000208
etharp_raw: sending raw ARP packet.
Also it worth mentioning that no matter what i try i can't place ethernet RX buffer in RAM_S2 ( i assign address 0x30000100 to it in ETH setting in MX_CUBE also set it in Flash memory map config file), it seems it uses the main RAM, here is the consul log when the code works:
etharp_timer
sys_timeout: 0x24007c24 abs_time=3283 handler=etharp_tmr arg=0x8038d60
pbuf_alloced_custom(length=0)
ethernet_input: dest:0hx:0hx:0hx:0hx:0hx:0hx, src:0hx:0hx:0hx:0hx:0hx:0hx, type:ff
pbuf_remove_header: old 0x24011d60 new 0x24011d6e (14)
etharp_update_arp_entry: 0.0.0.0 - ac:1a:3d:6a:cb:cc
etharp_update_arp_entry: will not add non-unicast IP address to ARP cache
etharp_input: incoming ARP request
etharp_input: ARP request was not for us.
pbuf_free(0x24011d40)
pbuf_free: deallocating 0x24011d40
sct calling h=ip_reass_tmr t=0 arg=0x8038d54
tcpip: ip_reass_tmr()
sys_timeout: 0x24007c38 abs_time=4283 handler=ip_reass_tmr arg=0x8038d54
sct calling h=etharp_tmr t=0 arg=0x8038d60
tcpip: etharp_tmr()
Any help or hint would be highly appreciated.
Truly yours,
Amir