cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H563 - LWIP memory corruption - Linker configuration with Cube IDE for RAM utilization

ChauNguyen
Associate

Hi, 

I'm using STM32H563 to develop an application that utilizes the MQTT and TCP connection with LwIP stack. 

When running mqtt ping-pong application for testing, I got memory corruption in lwip stack (mem.c).

Further debug I found that, with the default code generated by CubeIDE

in lwipopts.h

#define LWIP_RAM_HEAP_POINTER 0x20044000 
the lwip heap start at 0x20044000
 
In the linker that is used by default: STM32H563RGTX_FLASH.ld, the lwIP sections was declared as: 
.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x20040000);
*(.RxDecripSection)

. = ABSOLUTE(0x20040060);
*(.TxDecripSection)

. = ABSOLUTE(0x20040200);
*(.RxArraySection)
} >RAM2
But when building the project, in the map file I found that.
*(.RxArraySection)
.RxArraySection
0x20040200 0x4983 ./LWIP/Target/ethernetif.o
0x20040200 memp_memory_RX_POOL_base
so that the memp_memory_RX_POOL_base ranges from 0x20040200 to 0x20044B83 which overlaps with the LwIP heap and caused the corruption. 
Increase the LWIP_RAM_HEAP_POINTER to 0x20050000 then the application works fine. 
I think you should fix this issue when the IDE generated the code. 
 
Besides, In default linker, the RAM was defined as: 
RAM2 (xrw) : ORIGIN = 0x20040000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20050000, LENGTH = 320K  
which means 256K of RAM1 on the MCU (form 0x20000000 to 2003FFFF) was not used for the application. 

Can you help to advise if there is a special reason that RAM1 is not used. I think it's a big waste since 256K RAM for embedded application is considered big.
 
2 REPLIES 2
SDu T
Associate III

Hi ChauNguyen

 

Is it possible for you to share the code. I am having difficulty in implementing MQTT on the H563. 

 

Hi @SDu T 

I check with my colleague and found that the memory allocation was due to his modification.

For lwIP to work in H563, you will need to have a ethernetif.c file that provide ethernet low_level_init, low_level_input ... etc. ST already provide the implementation. 

You may need to have the new PHY driver depends on which ethernet PHY that you are using. 

From the memory point of view: 

The lwIP will need a free memory space in RAM that is not accessible from other module.

The address of the memory space is defined in lwipopts.h with macro LWIP_RAM_HEAP_POINTER. The size of this memory defined by MEM_SIZE in the same file.

So you should configured your linker to spare a memory space in RAM from LWIP_RAM_HEAP_POINTER to (LWIP_RAM_HEAP_POINTER + MEM_SIZE)>

Besides, there is 3 memory regions used by ethernetif.c

ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection")));   /* Ethernet Tx DMA Descriptors */
__attribute__((section(".RxArraySection"))) extern u8_t memp_memory_RX_POOL_base[];
 
So, that from the linker I have such declaration as below: 
/* Memories definition */
MEMORY
{
RAM2 (xrw) : ORIGIN = 0x20000000, LENGTH = 64K --> This RAM2 is for ethernetif and lwip usage.
RAM (xrw) : ORIGIN = 0x20010000, LENGTH = 576K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K0
}

and

.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x20000000);
*(.RxDecripSection)

. = ABSOLUTE(0x20000060);
*(.TxDecripSection)

. = ABSOLUTE(0x20000200);
*(.RxArraySection)
} >RAM2 // this is the section for ethernetif memory.

Then from the output map file, I can see the RxArraySection size is 0x4983.

So that the free memory for lwIP stack should be from 0x20004B84 to end of RAM2 (in this case: 0x20010000)