cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723ZG Ethernet

Srivatsan
Associate II

Hello everyone,

I am working with the NUCLEO-H723ZG board and attempting to establish Ethernet communication using TCP/IP. The firmware was built and flashed successfully using STM32CubeIDE version 1.19.0.

However, I am facing issues with basic network connectivity. Below are the details of my setup and observations:

Setup Details

  • Board: NUCLEO-H723ZG

  • IDE: STM32CubeIDE v1.19.0

  • Ethernet stack: LwIP

  • PHY interface: RMII

  • Flashing tool: ST-LINK (onboard)

  • Test performed: Ping test from PC

Observed Behavior

  • The Ethernet port LEDs (orange and green) remain solid ON after connecting the Ethernet cable.

  • Ping requests consistently fail (Request timed out).

  • No response is received from the board.

Troubleshooting Already Performed

  • Tested both Static IP and Dynamic IP (DHCP) configurations.

  • Verified IP address, subnet mask, and gateway settings.

  • Tried multiple Ethernet cables to rule out cable-related issues.

  • Rebuilt and reflashed the project multiple times.

  • Verified that the firmware flashes successfully and runs without build errors.

Despite these steps, the board does not respond to ping requests.

Questions / Assistance Required

  • Does solid ON state of both Ethernet LEDs indicate a known PHY or clock configuration issue?

  • Are there any known issues with RMII_REF_CLK configuration on the NUCLEO-H723ZG?

  • Are there specific CubeMX clock, MPU, or cache settings required for reliable Ethernet operation on STM32H723?

  • Any recommended minimal or verified example project for Ethernet ping testing on this board?

I need some guidance or suggestions to identify and resolve this issue.

Srivatsan_0-1768820714125.png

13 REPLIES 13
Srivatsan
Associate II

Here are some attachments, 

Hello @Srivatsan and welcome to the ST community;

This knowledge base may help you: How to create a project for STM32H7 with Ethernet and LwIP stack working

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I have downloaded the ZIP file from the link you provided:

Link: https://github.com/stm32-hotspot/STM32H7-LwIP-Examples

I also installed STM32CubeIDE version 1.9.0 and flashed the firmware onto the board. After flashing the code, I tested whether the assigned IP address responds to ping requests; however, the ping test still fails.

While flashing the project the memory locations are 

Srivatsan_0-1768888978768.png

The CubeMX parameter settings are,

Srivatsan_1-1768889023858.png

The ping test result is,

Srivatsan_2-1768889080601.png

For your reference, I have attached the project folder used for this test.

 

 

Hi,

Your MPU configuration is incorrect, and the Rx_PoolSection must not be placed in SRAM2.
For STM32H7 Ethernet + LwIP, RX buffers must be located in D1 RAM (address range 0x24000000–0x30007FFF).

1) Update the linker script:

 

.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30000000);
*(.RxDecripSection)
. = ABSOLUTE(0x30000100);
*(.TxDecripSection)
 
} >RAM_D2 AT> FLASH

2) Configure the MPU as described in the following ST article:
https://community.st.com/t5/stm32-mcus/how-to-create-a-project-for-stm32h7-with-ethernet-and-lwip-stack/ta-p/49308

~Aj

sergey23
Associate II

If you want to try an alternative to LWIP, go to https://mongoose.ws/wizard/#/output?board=h723&ide=CubeIDE&rtos=FreeRTOS&file=README.md , choose the destination directory in the settings tab, , click generate button - then load the saved project in your Cube IDE.

That uses Mongoose TCP/IP stack instead of LWIP, and gives you a ready-to-use Web UI, MQTT, and remote firmware updates.

 

Regardless of the TCP/IP stack you use, the trick with STM32H7 is that Ethernet DMA controller can access only certain memory regions. The driver code defines DMA buffers with a special flag, __attribute__ section ..., which places those buffers in a specific ELF section, and your linker script must place that section in the region accessible by the Ethernet DMA controller. That what ajmw_' s suggestion is about.

 

The H723 has the following regions;

 

MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 320K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
}

 

You can get the same info from the https://www.st.com/resource/en/datasheet/stm32h723zg.pdf datasheet, section 3.3.2. Ethernet controller is on D2 domain, thus place DMA buffers in any of the D2 domain region, for example ITCMRAM, or RAM_D1 or RAM_D2

Srivatsan
Associate II

Project creation 

Board: NUCLEO-H723ZG
STM32CubeIDE version 1.9.0

Srivatsan_16-1768912881833.png

Basic configuration:

Configure clock tree:

  • In pinout/RCC, configured HSE in bypass mode.
  • In clock tree, configured 400MHz for core.
    Srivatsan_17-1768913094820.png

     


    Srivatsan_2-1768910331442.png

    Ethernet configuration:

  • Enabled Ethernet interrupt
    Srivatsan_19-1768913376692.pngSrivatsan_20-1768913384540.png
    • Set GPIO pin speed to Very High.
      Srivatsan_18-1768913349044.png
    •  ETH_MDC speed couldn't be changed

      Cortex-M7 configuration:

    • Enable ICache and DCache.
    • Enable memory protection unit (MPU) in “Background Region Privileged access only + MPU Disabled ...” mode.
      Srivatsan_5-1768911146315.png
      Srivatsan_6-1768911205073.png

       

      LwIP configuration:

    • Enabled LwIP in middleware.
      Srivatsan_7-1768911372506.png
      Platfrom settings:
      Srivatsan_8-1768911402443.png
      Key options: 
      Srivatsan_9-1768911533068.png
      Checksum:
      Srivatsan_10-1768911632765.png

      Generate project:

    • Now we generate the project for IDE.

      Modifying the code (STM32CubeIDE):

      ethernetif.c:

      Srivatsan_11-1768911844749.png
      FLASH.ld:
      Srivatsan_12-1768912076483.png

       
       

       


      Finally, I am able to receive a response when performing the ping test, as shown below.

      Srivatsan_14-1768912316990.png

      Srivatsan_15-1768912393584.png

       

      However, after following all of your instructions earlier, I was initially unable to ping the IP address. Could you please help clarify why the ping was not successful at that stage?

Srivatsan_2-1768914662510.png

I have attached my FLASH.ld file below for you reference:

/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7 series
** 1024Kbytes FLASH and 560Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2022 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
}



/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH

/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)

KEEP (*(.init))
KEEP (*(.fini))

. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH

/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH

.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH

.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH

.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH

/* used by the startup to initialize data */
_sidata = LOADADDR(.data);

/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */

. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH

/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)

. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM_D1

/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM_D1
/* Modification start */
.lwip_sec (NOLOAD) :
{
. = ALIGN(32);
*(.RxDecripSection)

. = ALIGN(32);
*(.TxDecripSection)

. = ALIGN(32);
*(.Rx_PoolSection)
} >RAM_D2

/* Modification end */
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

.ARM.attributes 0 : { *(.ARM.attributes) }
}



Kindly review it.

 

Refer to the following article carefully instead of directly copy-pasting the configuration:
https://community.st.com/t5/stm32-mcus/how-to-create-a-project-for-stm32h7-with-ethernet-and-lwip-stack/ta-p/49308

Your current configuration targets STM32H74x/H75x devices, but you are using STM32H723ZGT6, which has only 32 KB of SRAM2.Therefore, the RX buffers must be placed in AXI SRAM at 0x24000000, not in SRAM2. Also, the lwip_sec linker section is incorrect. Please refer to my previous reply for the correct linker script configuration. 

1)LWIP_RAM_HEAP_POINTER (RAM Heap Pointer) should be in SRAM2 @0x30000200"
2) MEM_SIZE (Heap Memory Size) = 32232

 

ajmw__0-1768915255157.png

 

~ AJ

The shared article contains the memory allocation for the STM32H74x/H75x devices only, Whenever I'm using the STM32H723ZGT6, I have some confusions. 
I have done the configuration/code & allocation with the help of the article:  https://community.st.com/t5/stm32-mcus/how-to-create-a-project-for-stm32h7-with-ethernet-and-lwip-stack/ta-p/49308.

Now with your guidance, I've changed the LWIP_RAM_HEAP_POINTER MEM_SIZE (Heap Memory Size) respectively. 

Srivatsan_0-1768917077749.png
and also updated the Flash.ld with your guidance. Review it.

/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7 series
** 1024Kbytes FLASH and 560Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2022 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
}

 

/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH

/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)

KEEP (*(.init))
KEEP (*(.fini))

. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH

/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH

.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH

.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH

.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH

/* used by the startup to initialize data */
_sidata = LOADADDR(.data);

/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */

. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH

/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)

. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM_D1

/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM_D1
/* Modification start */
.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30000000);
*(.RxDecripSection)
. = ABSOLUTE(0x30000100);
*(.TxDecripSection)

} >RAM_D2 AT> FLASH

/* Modification end */
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

.ARM.attributes 0 : { *(.ARM.attributes) }
}

Srivatsan_1-1768917198119.png