Skip to main content
Adam BERLINGER
ST Employee
March 11, 2020

How to create a project for STM32H7 with Ethernet and LwIP stack working

  • March 11, 2020
  • 54 replies
  • 290842 views

This readme is intended for STM32CubeIDE version 1.9.0 and STM32CubeH7 version 1.10.0. For older tool versions please see older version of this readme in the repository. 

If you have any questions regarding Ethernet topics in general, please visit our MCU forum and create a thread. Doing so will provide you with a shorter response time. 

Example project code and older version of this article is provided on Github: https://github.com/stm32-hotspot/STM32H7-LwIP-Examples. Detailed how to step-by-step is provided below.

Features

  • Fixed IP address 192.168.1.10
  • Code should work even when re-generating the code in STM32CubeMX
  • Changes in code can be find by searching for
    ETH_CODE
    keyword

Release notes

Version STM32CubeIDE version STM32CubeH7 version Description / Update Date
1.2 1.9.0 1.10.0 Ported to new IDE/library version. Ethernet driver reworked in new library release. Added iperf measurement and TCP/IP settings tuned. Published on Github August 9th 2022
1.1 1.6.1 1.9.0 Added Cortex-M4 base examples July 19th 2021
1.0 1.6.1 1.9.0 Initial release on ST community (with minor changes on Github) June 21st 2021

Using GIT tags it should be easy to find examples for particular version of STM32CubeIDE and HAL library

TCP/IP configuration in LwIP

Below configuration is necessary to achieve good TCP/IP performance

Parameter Value Formula Needs to be changed in MX
TCP_MSS 1460
1500-40
yes
TCP_SND_BUF 5840
4 * TCP_MSS
yes
TCP_WND 5840
4 * TCP_MSS
no
TCP_SND_QUEUELEN 16
UPPER((4 * TCP_SND_BUF) / TCP_MSS)
yes

Memory layout

On STM32H74x/H75x devices, all data related to Ethernet and LwIP are placed in D2 SRAM memory (288kB). First 128kB of this memory are reserved for Cortex-M4 on dual-core devices. On single core devices this part can be used for other purposes.

Variable STM32H74x/H75x address Cortex-M4 alias Size Source file
DMARxDscrTab 0x30040000 0x10040000 96 (256 max.) ethernetif.c
DMATxDscrTab 0x30040100 0x10040100 96 (256 max.) ethernetif.c
memp_memory_RX_POOL_base 0x30040200 0x10040200 12*(1536 + 24) ethernetif.c
LwIP heap 0x30020000 0x10020000 131048 (128kB - 24) lwipopts.h

For STM32H72x/H73x devices, the D2 SRAM is more limited (only 32kB). The RX buffers need to be placed in AXI SRAM, since they won't fit to D2 RAM, together with LwIP heap. The LwIP heap is reduced to fit the rest of D2 RAM together with DMA descriptors.

Variable STM32H72x/H73x address Size Source file
DMARxDscrTab 0x30000000 96 (256 max.) ethernetif.c
DMATxDscrTab 0x30000100 96 (256 max.) ethernetif.c
memp_memory_RX_POOL_base AXI SRAM (32-byte aligned) 12*(1536 + 24) ethernetif.c
LwIP heap 0x30000200 32232 (32kB - 512 - 24) lwipopts.h

Value provided here are an example implementation, other configurations are also possible in order to optimize memory usage. When changing memory layout, the MPU configuration needs to be updated accordingly.

License

Libraries and middleware is taken from STM32CubeH7 package. So the same licenses apply to the these examples. There is minimum code added on top of STM32CubeMX and HAL libraries, this code is provided AS-IS.

How to create project from scratch

Goal

Goal of this example is to:

  • Configure project in STM32CubeMX for STM32H750-Discovery
  • Configure FreeRTOS and LwIP middlewares correctly
  • Send UDP message periodically (optional)

Although the example is using STM32H750-Discovery, it might be easy to use the same steps for other STM32H7 based boards. The main differences are usually pinout and clock configuration. You might also need to check board solder bridges to make sure the Ethernet is connected to MCU.

STM32CubeMX project configuration

  • Create new project in STM32CubeMX, select STM32H750-Discovery board and select "No" to "Initialize all peripherals in default mode?" pop-up.
    • This will help with pin assignment.

Basic configuration

Configure clock tree:

  • In pinout/RCC configure HSE in bypass mode
  • In clock tree configure 400MHz for core

92.png

  • In pinout/SYS configure different timebase than SysTick (recommended when using FreeRTOS)
    • TIM6 is usually a good option, since it is a simple timer

Ethernet configuration

  • Enable Ethernet peripheral in pinout view in MII mode (MII used on the board).
  • Enable Ethernet interrupt and set preemption priority to 5. This is required by FreeRTOS in order to call its functions from interrupt handler.
  • Relocate Ethernet CRS and COL signals from PH2/PH3 to PA0/PA3
    • These signals are optional in full-duplex mode and not connected in default configuration
    • This will also allow use PH2/PH3 for QSPI
  • Other pins should be correctly placed, since we create the project from board selector.

93.png

  • Set GPIO pin speed to Very High.

94.png

The ETH_MDC speed couldn't be changed for some reason, but it doesn't affect the application and it was already fixed in new versions.

Cortex-M7 configuration

This step can be skipped when using Cortex-M4 core.

  • Enable ICache and DCache.
  • Enable memory protection unit (MPU) in “Background Region Privileged access only + MPU Disabled ...” mode. Configure regions according to the picture below:

95.png

Above example is for STM32H743 device. For other devices or Cortex-M4 core on dual-core device, different addresses and size might be necessary. Please refer to section Memory layout

When using dual-core device and running Ethernet on Cortex-M7 core, it must be ensured that memory used by Ethernet is not used by Cortex-M4. Also note the Cortex-M4 can use different address alias for D2 RAM

FreeRTOS configuration

  • Enable the FreeRTOS with CMSIS_V1 API.
  • Increase the size of defaultTask stack to 512 words1
  • Lower stack values cause memory corruptions
  • Please check also that the generated code is correct, since there is bug when increasing the MINIMAL_STACK_SIZE and there might be old value in code (this should be fixed in new versions)

96.png

LwIP configuration

  • Enable LwIP in middleware.
  • In "General settings" tab, disable DHCP server and configure fixed IP address (unless you know how to configure and use DHCP).

97.png

  • In the attached examples, the 192.168.1.10 IP address is used (instead of 192.168.0.10 shown on the screenshot).
  • In "Platform settings" tab select "LAN8742" in both select boxes. The LAN8742 driver is also compatible with LAN8740 device, which is actually present on the STM32H750-Discovery board. The main difference between these devices is support of MII interface. On other boards LAN8742 PHY chip is used.

98.png

In "Key options" tab:

  • Configure MEM_SIZE to 16360. This specifies the heap size, which we will relocated to D2 SRAM (16kb minus 24 bytes for allocator metadata).
  • Also enable LWIP_NETIF_LINK_CALLBACK (needed for cable plugging/unplugging detection).
  • Set the LWIP_RAM_HEAP_POINTER to proper address2
  • Set the MEM_SIZE parameter to proper size2

99.png

  • (Should be done automatically by new CubeMX) In "Checksum" tab enable CHECKSUM_BY_HARDWARE. Other options should automatically reconfigure and you can leave them in this state.

100.png

Generate project

Save project to some folder of your selection. Now you can generate the project for IDE. We will use STM32CubeIDE in this example, but it should work with other IDEs.

Modyfying the code (STM32CubeIDE)

There are several places where some additional code should be placed, also depending on selected device. In the examples all these places are marked with comment containing

ETH_CODE

and some basic explanation. Searching for

ETH_CODE

can show all these places.

Only main interesting points are mentioned below:

  • Placement of the RX_POOL buffers (although we configured the address in CubeMX) in ethernetif.c2:
/* USER CODE BEGIN 2 */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30040200
extern u8_t memp_memory_RX_POOL_base[];

#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((at(0x30040200)) extern u8_t memp_memory_RX_POOL_base[];

#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];

#endif
/* USER CODE END 2 */
/* USER CODE BEGIN 1 /
#undef LWIP_PROVIDE_ERRNO
#define LWIP_ERRNO_STDINCLUDE
/ USER CODE END 1 */
  • Add DATA_IN_D2_SRAM to macro definitions in project:

101.png

Modify linkerscript (not valid for Keil/IAR)2

This step should be skipped for Keil and IAR, since they support placing variables at specific address in C code. Modify the linkerscript (*.ld) that the ETH descriptors and buffers are located in D2 SRAM. Also it is recommended to place all RAM to RAM_D1. In STM32CubeMX generated project, the "_FLASH" suffix linkerscript should be modified, which is used by default (e.g.: STM32H750XBHx_FLASH.ld). The "_RAM" suffix linkerscript is template for executing code from internal RAM memory.

 } >RAM_D1

 /* Modification start */
 .lwip_sec (NOLOAD) :
 {
 . = ABSOLUTE(0x30040000);
 *(.RxDecripSection) 
 
 . = ABSOLUTE(0x30040060);
 *(.TxDecripSection)
 
 . = ABSOLUTE(0x30040200);
 *(.Rx_PoolSection) 
 } >RAM_D2
 /* Modification end */

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

The memory definitions at the beginning of the linkerscript should look like:

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

For dual core devices it is better to restrict RAM_D2 section to avoid collision with Cortex-M4. Please see the linkerscripts in examples.

(Optional) Adding simple Hello UDP message

  • Add following include files at the beginning of main.c:
#include “lwip/udp.h”
#include <string.h>
  • Modify the StartDefaultTask in main.c with the following code:
/* USER CODE BEGIN 5 */
const char* message = "Hello UDP message!\n\r";

osDelay(1000);

ip_addr_t PC_IPADDR;
IP_ADDR4(&PC_IPADDR, 192, 168, 1, 1);

struct udp_pcb* my_udp = udp_new();
udp_connect(my_udp, &PC_IPADDR, 55151);
struct pbuf* udp_buffer = NULL;

/* Infinite loop */
for (;;) {
 osDelay(1000);
 /* !! PBUF_RAM is critical for correct operation !! */
 udp_buffer = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM);

 if (udp_buffer != NULL) {
 memcpy(udp_buffer->payload, message, strlen(message));
 udp_send(my_udp, udp_buffer);
 pbuf_free(udp_buffer);
 }
}
/* USER CODE END 5 */

Now you should be able to ping the device and receive UDP messages, assuming that you configure IP address 192.168.1.1 for the receiving device (the 192.168.1.0/24 network is used by attached examples). On Linux machine you can observe the messages with the following command:

netcat –ul 55151

Tips & common mistakes

  1. For STM32H72x/H73x devices, the Ethernet buffers can't be placed in address range 0x30040000 - 0x30048000, since that range is not valid. D2 SRAM on those devices is much smaller, so the buffers need to be placed starting at 0x30000000. This affects RX & TX descriptors and RX buffer addresses (ETH configuration in CubeMX) and LWIP_RAM_HEAP_POINTER used for TX buffers (LWIP > Key options in CubeMX).
  2. When running the stack on Cortex-M4, the buffers can be placed at the same address (0x30040000), but it is better to place them at 0x10040000 which is alias for the same address. This alias is accessible by Cortex-M4 D-bus and helps to utilize the Harvard architecture.
  3. When not using FreeRTOS, the Ethernet interrupt should be disabled and MX_LWIP_Process should be called periodically (in main loop).
  4. On STM32H747-Discovery board, modification needs to be done to default solder bridge configuration. SB8 should be closed and SB21 should be open for Ethernet to work, otherwise the MDC signal is not properly connected.

When facing issues with your own project:

  1. First try example and see if there is proper configuration on PC side. With corporate firewalls and restrictions, it might be difficult to perform simple ping to specific IP address. In some cases it is easier to test from personal PC, or some PC with firewall disabled.
  2. Check if Ethernet interrupt is called and if RX callback is called
    • If not, GPIOs are set to proper speed (very high)
    • and ETH global interrupt is enabled (only for FreeRTOS)
      • Interrupt priority should be 5 - preemption and 0 - subpriority. This is required by default FreeRTOS configuration.
  3. If Hardfault is called, the problem might be in MPU configuration
    • Please check carefully (e.g. slight mistake like having "256KB" instead "256B" can make big difference) 1 RX callback is called but ping still not work
    • check that the buffers are properly placed in linkerscript (the one ending with "_FLASH.ld")
    • in STM32CubeIDE you can use "Build analyzer" window
  4. When allocating buffers via pbuf_alloc (or similar), PBUF_RAM must be used as 3rd parameter. This is necessary to ensure that the allocated buffer is placed in D2 SRAM and synchronized with DMA
  5. Not sufficient stack size for different thread can cause issues.

Questions & Feedback

If you see any issue with these examples please fill an issue inside this repository. If you face some difficulties, but not sure if this is an issue you can start discussion inside this repository, or you can start thread on ST community


  1. Exact size required for different stacks might depend on used compiler and optimization flags. Same goes for FreeRTOS heap size, since thread stacks are allocated from this heap.

  2. Some addresses and sizes depend on the device or core used. Please refer to section Memory layout.

If you have any questions regarding Ethernet topics in general, please visit our MCU forum and create a thread. Doing so will provide you with a shorter response time. 

This topic has been closed for replies.

54 replies

IOvch
Associate II
July 29, 2022

@heveskar​ Thanks for your advice! It didn't help, but I'll use it by default in the future

I think some deeper MPU setup is needed here. But... it works without RTOS, so it's not a fact that this is the case.

FBelt.1
Associate
August 1, 2022

Hi,

if I try to modify ETH_RX_BUFFER_SIZE to 1536 or 1524 project doesn't work, even if the memory is always rigth placed and aligned.

Anyone knows why this value is 1000?

MDega.2
Associate II
August 4, 2022

Hi,

Is there a reason to select the clock at 400MHz, instead of the maximum allowed?

I am using H723 and the clock can be 550MHz, do I have to reduce it to 400?

Adam BERLINGER
ST Employee
August 10, 2022

Hello @ktrofimo​ and @FBelt.1​ ,

The ETH_RX_BUFFER_SIZE should be set to 1536. Sometimes (for unknown reason to me) the STM32CubeMX selects 1524. So far I haven't faced 1000 value on STM32H7.

I know there are were some issues on F4 family where this was hardcoded to the driver.

If this issues is not related to CubeMX configuration, could you be please more specific? Maybe I misunderstood.

Adam

Adam BERLINGER
ST Employee
August 10, 2022

Hello @Ec​ ,

the 192.168.1.10 IP is for the board. I always configure 192.168.1.1 on the PC side, however different IP address from the subnet could be also viable.

victagayun
Senior III
August 13, 2022

Hi,

Newbie here for ETH.

Seems that my Nucleo-H743ZI is not showing in my router.

My setup is Win10 with the ff info:


_legacyfs_online_stmicro_images_0693W00000QNcvoQAD.png 

I have modified the code like so:

 in lwipopts.h

/* USER CODE BEGIN 1 /
#undef LWIP_PROVIDE_ERRNO
#define LWIP_ERRNO_STDINCLUDE
#define LWIP_RAM_HEAP_POINTER (0x30044000)
/ USER CODE END 1 */

in ethernetif.c

/* USER CODE BEGIN 2 */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30040200
extern u8_t memp_memory_RX_POOL_base[];
 
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((at(0x30040200)) extern u8_t memp_memory_RX_POOL_base[];
 
#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
 
#endif
/* USER CODE END 2 */

in LWIP.c

IP_ADDRESS[0] = 192;
 IP_ADDRESS[1] = 168;
 IP_ADDRESS[2] = 50;
 IP_ADDRESS[3] = 10;
 NETMASK_ADDRESS[0] = 255;
 NETMASK_ADDRESS[1] = 255;
 NETMASK_ADDRESS[2] = 255;
 NETMASK_ADDRESS[3] = 0;
 GATEWAY_ADDRESS[0] = 192;
 GATEWAY_ADDRESS[1] = 168;
 GATEWAY_ADDRESS[2] = 50;
 GATEWAY_ADDRESS[3] = 1;

My STM32H743ZITX_FLASH.ld

/* Entry Point */
ENTRY(Reset_Handler)
 
/* Highest address of the user mode stack */
_estack = 0x24080000; /* 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
{
 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
 RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
 RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
 RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
 ITCMRAM (xrw) : ORIGIN = 0x00000000, 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 secion */
 _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
 
 .lwip_sec (NOLOAD) : {
 . = ABSOLUTE(0x30040000);
 *(.RxDecripSection) 
 
 . = ABSOLUTE(0x30040060);
 *(.TxDecripSection)
 
 . = ABSOLUTE(0x30040200);
 *(.RxArraySection) 
 } >RAM_D2
 
 /* Remove information from the standard libraries */
 /DISCARD/ :
 {
 libc.a ( * )
 libm.a ( * )
 libgcc.a ( * )
 }
 
 .ARM.attributes 0 : { *(.ARM.attributes) }
}

Did I miss something?

Only the orange LED in the LAN port is blinking.

Can you possibly add UART for debug messages and/or the LED for indication?

gpmaier
Visitor II
August 17, 2022

I also tried to migrate based on the How to here. Project set up with StmCube, then migrated to 1.10.x. 

As with you both I also get one or some

Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c

at startup on both a 

  • STM32H742 (descriptors and pool address are "vanilla" -> 0x30000000 and so on; heap at 0x30002000 because of the 742's limited memory) and a 
  • STM32H743 (here heap at 0x30008000).

I tried to debugging. No luck for 2, 3 days.

Aside from this (or because of this) the Ethernet communication is very instable. 

I made the observation that - also at startup - some allocated RX pBufs in ethernetif.c never will be deallocated and therefore sometimes the buffer pool is full (12, see ETH_RX_BUFFER_CNT) and I get communication issues at startup.

Have you managed the issue for now @Bernd Bartmann​ ​, @ktrofimo​ ​? 

Andrei Chichak
Lead
August 17, 2022

I believe that there are some issues with the MPU setup and the linker file locations for the TX descriptor section. Perhaps I don't understand some of the details though.

A ETH_DMADescTypeDef is 40 bytes, 10 integers of 4 bytes each, and DMARxDscrTab has 4 of them for 160 bytes or 0xA0. DMATxDscrTab is the same 160 bytes or 0xA0. These are placed via the info in the linker file at specific start locations.

So if DMARxDscrTab is placed by the linker file at 0x3004 0000 it will extend to 0x3004 009F,

DMATxDscrTab is placed at 0x3004 0060 for 0xA0 bytes, which is overlapping with DMARxDscrTab.

Ooops?

The MPU setup declares a 32k region starting t 0x3004 0000, and another with the same start address for 256B to contain the DMA descriptors. This second region would extend to 0x3004 00FF. The transmit and receive descriptors are a total of 160+160 = 320 bytes, so the 256B region won't apply the appropriate shareability or bufferabiltiy to the complete transmit descriptor table. A better length for the second region is 512B.

The receiver pool placement seems to be okay, but I don't understand what the LWIP_RAM_HEAP_POINTER is all about and what protections the RX Pool requires. There is a comment "And LWIP_RAM_HEAP_POINTER set to 0x30044B00, with MEM_SIZE12000. This should ensure that all Ethernet specific buffers/descriptors are placed in SRAM3." But those values would have the heap completely in SRAM2. SRAM3 doesn't begin until 0x3008 0000, far above the 0x3004 79E0 end address of the pool. Can you clarify this?

PGrif.2
Associate III
August 21, 2022

since "Your administrator has disabled feed post and comment deletions."

please see below ..

PGrif.2
Associate III
August 21, 2022

Hi there!

I am using the current provided CubeIDE (STM32CubeIDE Version: 1.10.1 Build: 12716_20220707_0928 (UTC)) CubeMX 6.6.1 and H7 Firmware package F1.10.0

I've used the above step by step instruction to get the

  •    FreeRTOS
  •    LWIP
  •    as TCP Server

running on a STM32H723ZG Nucleo-Board including the described fixes

  •    10. STM32Cube_FW_H7_V1.10.0 (and newer) specific issues
  •    ethernet_link_thread() by @Noti
  •    btw I agree with @JChar.3

Flash.ld file was changed to

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 = 288K
 RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
}

and

/* Modification start */
 .lwip_sec (NOLOAD) : {
 . = ABSOLUTE(0x30000000);
 *(.RxDecripSection) 
 
 . = ABSOLUTE(0x30000060);
 *(.TxDecripSection)
 
 
 . = ABSOLUTE(0x30000200);
 *(.Rx_PoolSection) 
 
 } >RAM_D2
 /* Modification end */

LWIP_RAM_HEAP_POINTER set to 0x30004B00, with MEM_SIZE12000

Testing is done with termial program Hercules with serveral ping and connect/diconnect cycles. Start up and connect diconnect run smooth at first, but after a while (or a unplug/replug of Ethernet cable) the device will still ping but refused connection.

Test:

Sending ICMP ECHO REQUEST to module <- frist ping on start up

Received ICMP ECHO REPLY

Connecting to 172.16.17.100 ...

Connected to 172.16.17.100 <- frist connect OK

Connection closed

[.. will continue to be OK for the next 20+ connections ]

Connecting to 172.16.17.100 ...

Connected to 172.16.17.100

// diconnect cable

Connection refused by remote host          <- terminal recognized disconnect OK

Connection closed

// reconnect cable

Sending ICMP ECHO REQUEST to module <- frist ping on reconnect OK

Received ICMP ECHO REPLY

Connecting to 172.16.17.100 ...

Connected to 172.16.17.100             <- frist connect OK

Connection closed

Connecting to 172.16.17.100 ...

Connected to 172.16.17.100              <- second connect OK

Connection closed

Connecting to 172.16.17.100 ...

Connected to 172.16.17.100              <- third connect FAIL

Connection refused by remote host

Connection closed

Sending ICMP ECHO REQUEST to module <- but ping still works

Received ICMP ECHO REPLY

I think it might be some MPU setup or MEMORY assignment issue.

For convienece I'va added a minimal example

address is 172.16.17.100 Port 80

ping, connect and send a string (e.g. ECHO TEST) the server will reply the string and diconnect


_legacyfs_online_stmicro_images_0693W00000QO91yQAD.png 

Any help would be highly appreciated!

Regards!