Skip to main content
_AdamNtrx
Associate III
July 15, 2026
Question

Questions regarding the proper configuration of Ethernet LwIP project

  • July 15, 2026
  • 3 replies
  • 47 views

Hello!

I have been trying to review and fix the configuration of my Ethernet LwIP+FreeRTOS STM32 project and I would like to ask more experienced people if I have correctly chosen memory locations, modified the linker script, configured MPU and a few other things.

 

My project uses STM32F746VGT6 MCU that has 320KB of RAM and 1024KB of flash memory:

MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}

 

Since this project uses Ethernet peripheral and LwIP library, a few memory sectors need to be defined: one for Tx Descriptor, one for Rx Descriptor, one for RX POOL and one for LwIP heap.

I have set Tx and RX Descriptor addresses to 0x20048000 and 0x20048100 and checked in debugger that each one of them takes 160B of space, so 256B is more than enough to store a single Descriptor.

I decided to store memp_memory_RX_POOL_base under 0x20040000 address in 32KB section. With ETH_RX_BUFFER_CNT defined to 16U, size of memp_memory_RX_POOL_base is equal to 25795B, though I don’t really know how it is calculated. I guess the formula is 1612*ETH_RX_BUFFER_CNT +4-1, but I don’t know where the 1612 does come from.

Also, I have added the memp_memory_RX_POOL_base declaration to ethernetif.c file:

/* ethernetif.c */

/* USER CODE BEGIN 2 */

#if defined ( __GNUC__ )
__attribute__((section(".RxArraySection"))) extern u8_t memp_memory_RX_POOL_base[];
#endif

/* USER CODE END 2 */

I have set LWIP_RAM_HEAP_POINTER to point at 0x20048000 address and set MEM_SIZE to 32KB-512B-24B. I don’t know why those values have to be subtracted from 32KB, but such size was used in this guide.

 

Knowing that, I have defined memory in linker script this way:

/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x3FE00/* 256KB-512B | up to 0x2003FDFF */

MEM_1 (xrw) : ORIGIN = 0x2003FE00, LENGTH = 256 /* Tx Descriptor | up to 0x2003FEFF */
MEM_2 (xrw) : ORIGIN = 0x2003FF00, LENGTH = 256 /* Rx Descriptor | up to 0x2003FFFF */
MEM_RX_POOL (xrw) : ORIGIN = 0x20040000, LENGTH = 32K /* RX_POOL | up to 0x20047FFF */
ETH_RAM (xrw) : ORIGIN = 0x20048000, LENGTH = 32K /* LWIP_RAM_HEAP_PONTER | up to 0x2004FFFF*/

FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}

and memory sections like this:

/* Sections */
SECTIONS
{

.TxDecripSection (NOLOAD) :
{
. = ALIGN(4);
*(.TxDecripSection)
. = ALIGN(4);
} >MEM_1

.RxDecripSection (NOLOAD) :
{
. = ALIGN(4);
*(.RxDecripSection)
. = ALIGN(4);
} >MEM_2

.RxArraySection(NOLOAD) :
{
. = ALIGN(4);
*(.RxArraySection)
. = ALIGN(4);
} >MEM_RX_POOL

I have not defined a memory section for ETH_RAM, however, and I don’t know if it is needed. If it is, then I would like to ask how to do it correctly?

 

Since STM32F7 MCUs have Memory Protection Unit, I had to configure it as well. I followed the mentioned guide to do it:

 

Because in the guide there was no memory protection set for RX_POOL, I didn’t set any as well.

 

 

I have run the program with this configuration and it seems to be working fine. I would like to ask though if the things I have done are done correctly. I would also like to know:

  1. does there have to be defined a separate section for LwIP heap (ETH_RAM memory)? If yes, how to do it correctly?
  2. does RX_POOL need to be protected by MPU or can it be left as it is?
  3. what is the exact role of LwIP heap (u8_t ram variable in mem.c file) and MEM_SIZE value? What does the heap store, what to take into account when choosing the value for MEM_SIZE?

 

Thanks to everyone answering to this post in advance!

 

3 replies

_AdamNtrx
_AdamNtrxAuthor
Associate III
July 17, 2026

I have met with a new bug. Ocasionally I get a HardFault in pbuf_free() function where struct pbuf *p variable points to an address within the RX_POOL section . The problem doesn’t seem to appear if MPU is configured to treat memp_memory_RX_POOL_base as non-cacheable.

_AdamNtrx
_AdamNtrxAuthor
Associate III
July 17, 2026

ST Support confirmed that RX_POOL has to be non-cacheable as well. Here is the missing MPU configuration:

 

Guillaume K
ST Employee
July 17, 2026

The STM32F746 you are using has a data cache. If you enable the data cache in main() then yes the RX buffer pool must be configured as non cacheable.

If you were on an STM32 without data cache then no need for special MPU configuration.

The ethernet descriptors (RX and TX) must be in a memory area configured as non cacheable and strongly ordered . 

strongly ordered is used to ensure the OWN bit of the ethernet descriptor is written last, after the other words that define a transfer. This gives ownership of the descriptor to the Ethernet hardware, so that it starts the data transfer.

 

Jgleckg
Visitor
July 17, 2026

For Ethernet + LWIP, I would first verify the basics separately: PHY address, RMII/MII mode, clock source, MPU/cache settings, and whether the link status is actually detected. On STM32 parts with cache enabled, buffer placement and cache coherency can also cause confusing network issues, so checking the linker section and DMA buffers is important before debugging the LWIP layer itself.

Johny Gleck