2025-09-17 6:53 AM - last edited on 2025-09-17 9:29 AM by mƎALLEm
Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code.
Hi all,
I am working with STM32H723VGT6, using ETH and SPI4.
I have configured Ethernet following this ST Community guide:
https://community.st.com/t5/stm32-mcus/how-to-create-a-project-for-stm32h7-with-ethernet-and-lwip-stack/ta-p/49308
When I follow the instructions exactly, I noticed that memp_memory_RX_POOL_base is located at 0x24000000.
Current problem
When running my program, the crash occurs at:
struct pbuf *q;
q = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_RAM);
Inside pbuf_alloc, in the case PBUF_RAM:
p = (struct pbuf *)mem_malloc(alloc_len);
In mem_malloc, the program fails at:
/* Scan through the heap searching for a free block that is big enough */
for (ptr = mem_to_ptr(lfree); ptr < MEM_SIZE_ALIGNED - size;
ptr = ptr_to_mem(ptr)->next) {
mem = ptr_to_mem(ptr);
}
Although mem is allocated with the LWIP heap pointer address successfully, at the same time, ETH->DMAErrorCode reports 0x4080.
What I have configured
I have set up MPU regions for DMA descriptors and LWIP RAM heap.
RX pool is located in D1 SRAM (0x24000000).
DMA descriptors are in D2 SRAM (0x30000000 onwards).
LWIP RAM heap pointer for TX buffers is set correctly in D2 SRAM.
Observations
The crash seems related to mem_malloc scanning the heap, possibly because of DMA or MPU configuration.
ETH DMA fails immediately with code 0x4080 when trying to allocate pbuf.
Files attached
main.c with MPU configuration
Screenshots showing memory map and error
Other relevant configuration
Questions
Is it safe to locate memp_memory_RX_POOL_base in D1 SRAM (0x24000000) on STM32H723?
Should RX pool be moved to D2 SRAM, even if only 32 KB is available? How to divide RX descriptors, RX pool, and TX heap safely?
Are there known issues with mem_malloc + pbuf_alloc when using D1 SRAM + DMA ETH on H723?
Any guidance or suggestions will be highly appreciated!
Thanks,
2025-09-17 9:21 AM
Hello, and welcome to ST community!
Have you ensured that the memory sections for the descriptors and memory pool are properly configured in the linker file? Also, please verify that the address of the LwIP heap pointer in your lwipopts.h
aligns with your configuration. Additionally, could you attach a screenshot of the call stack when the HardFault occurs?
Best regards,
2025-09-17 9:11 PM - last edited on 2025-09-22 9:52 AM by STackPointer64
Hello,
I have checked the addresses of the related buffers:
DMARxDscrTab: 0x30000000
DMATxDscrTab: 0x30000100
memp_memory_RX_POOL_base: 0x24003460
In lwipopts.h I configured:
#define LWIP_RAM_HEAP_POINTER 0x30000200
#define MEM_SIZE 32232
For the MPU configuration, I am using the following setup:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
HAL_MPU_Disable();
// Region 0: default no access //
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);
// Region 1: descriptors in D2 SRAM //
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
// Region 2: small buffer region //
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.Size = MPU_REGION_SIZE_512B;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
// Region 3: D1 SRAM (disabled in current config) //
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
//HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
When I set a breakpoint inside HAL_ETH_ReadData, the execution reaches HAL_ETH_RxLinkCallback but then fails with a DMAErrorCode.
If I do not set any breakpoint, there is no error, but the board does not respond to pings.
From Wireshark, I can see that the PC sends ARP requests to the STM32, but the STM32 does not reply.
My LWIP network configuration is as follows:
IP_ADDRESS: 192.168.1.198
NETMASK: 255.255.255.0
GATEWAY: 192.168.1.1
On my PC I am using:
IP_ADDRESS: 192.168.1.68
NETMASK: 255.255.255.0
GATEWAY: 192.168.1.1
The firewall on the PC is disabled.
In the main loop I call the following:
while (1)
{
ethernetif_input(&gnetif);
sys_check_timeouts();
}
Could you please advise if there is anything wrong with the current MPU or memory configuration, or if additional steps are required for proper Ethernet RX/TX operation?
Best regards,
2025-09-17 9:17 PM
2025-09-18 3:26 AM
I don't know about the absolute.
I do it this way (also on H723 / H733), with only one descriptor section for both RX & TX:
...
0/* internal */
SRAXI_D1(xrw) : ORIGIN = 0x24000000, LENGTH = 320K
SRAM1_D2(xrw) : ORIGIN = 0x30000000, LENGTH = 16K
SRAM2_D2(xrw) : ORIGIN = 0x30004000, LENGTH = 16K
SRAM4_D3(xrw) : ORIGIN = 0x38000000, LENGTH = 16K
...
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* ethernet descriptor section */
/* MUST be in RAM_D2 */
.EthDescrSection (NOLOAD):
{
. = ALIGN(4);
*(.EthDescrSection)
*(.EthDescrSection*)
. = ALIGN(4);
} >SRAM1_D2
Then I like to use some macros to place the descriptors there in the *.c file:
somewhere in main.h:
/* alignment */
#define __ATT_PACKED __attribute__((packed))
#define __ATT_ALIGN4 __attribute__((aligned(4)))
#define __ATT_ALIGN8 __attribute__((aligned(8)))
#define __ATT_ALIGN16 __attribute__((aligned(16)))
/* RAM sections
* as defined in linker file *.ld
* make sure that the peripheral using the variables
* can access this memory section / domain
*/
#define __ATT_SECT_RAMD1 __attribute__((section(".RamD1Section")))
#define __ATT_SECT_NOINIT __attribute__((section(".NoInitSection")))
#define __ATT_SECT_A2IPCTL __attribute__((section(".A2IpCtlSection")))
#define __ATT_SECT_C2IPCTL __attribute__((section(".C2IpCtlSection")))
#define __ATT_SECT_A2IPBUFX __attribute__((section(".A2IpBufExtSection")))
#define __ATT_SECT_LWIPPOOL __attribute__((section(".LwipPoolSection")))
#define __ATT_SECT_LWIPHEAP __attribute__((section(".LwipHeapSection")))
#define __ATT_SECT_ETHTXBUF __attribute__((section(".EthTxBufSection")))
#define __ATT_SECT_ETHDESCR __attribute__((section(".EthDescrSection")))
... and finally:
/* DESCRIPTOR lists:
* DESC0 .. DESC7 (status, control, addresses, PTP timestamp)
* aligned
* in dedicated RAM section (see linker script)
*/
/* TX */
__ATT_SECT_ETHDESCR __ATT_ALIGN4 EthDmaDescr_t DmaTxDescriptors[ETH_TX_DESC_CNT];
/* RX */
__ATT_SECT_ETHDESCR __ATT_ALIGN4 EthDmaDescr_t DmaRxDescriptors[ETH_RX_DESC_CNT];
Anyway, it looks more like you don't free the RX buffers fast enough / at all.
I'd first try to increase the RX buffer pool, install some counters and debug info where I'm at.
And look for any buffers which might "hang" somewhere without getting free.
PS: each time I see "Decrip" it gives me the crips -er, creeps I mean.
Just because some years ago an ST guy forgot the "s", everybody's keeping that. Makes me rather think of decryption than descriptor.