Skip to main content
Associate III
December 6, 2023
Solved

STM32H755 LwIP FreeRTOS StackOverflowHook - Wrong configuration?

  • December 6, 2023
  • 3 replies
  • 4433 views

Hi everyone,

I try to impement the LwIP Stack on my NUCLEO-H755ZI-Q Evaluation Board. I want to use the M4 core for the ethernet communication.

Unfortunately it results always in a StackOverflowHook if I connet with "Hercules" TCP Client and send a string.

I have configured the stack as described under https://github.com/stm32-hotspot/STM32H7-LwIP-Examples/tree/v1.2_ide_v1.9.0/STM32H745_Nucleo_M4_ETH.

The adapted LinkerScript "STM32H755ZITX_FLASH.ld" see below.

My TCPServer implementation tcpServerRAW.c is from https://controllerstech.com/stm32-ethernet-4-tcp-server/

I attached my .ioc fiile and a video of the Stackoverflow error.

Maybe there is a configuration mistake?

Thank you.

 

** File : LinkerScript.ld

...

/* Specify the memory areas */
MEMORY
{
 FLASH (rx) : ORIGIN = 0x08100000, LENGTH = 1024K
 /* ETH_CODE: split memory to data and ethernet buffers */
 RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 128K /* ETH_CODE *
 ETH_RAM (xrw) : ORIGIN = 0x10020000, LENGTH = 160K /* ETH_CODE *
 MTI_SRAM (xrw) : ORIGIN = 0x38008000, LENGTH = 32K /* MTI: Shared Memory Bereich halber SRAM4 */ 
}

/* MTI: Shared Memory Bereich */
__MTI_SRAM_region_M4_start__ = ORIGIN(MTI_SRAM);
__MTI_SRAM_region_M7_start__ = ORIGIN(MTI_SRAM) + 1024;
__MTI_SRAM_region_end__ = ORIGIN(MTI_SRAM) + LENGTH(MTI_SRAM);
...
 /* ETH_CODE: add placement of DMA descriptors and RX buffers */
 .lwip_sec (NOLOAD) :
 {
 . = ABSOLUTE(0x10040000); /* 0x10040000 */
 *(.RxDecripSection) 
 
 . = ABSOLUTE(0x10040060); /* 0x10040060 */
 *(.TxDecripSection)
 
 . = ABSOLUTE(0x10040200); /* 0x10040200 */
 *(.Rx_PoolSection) 
 } >ETH_RAM
 /* ETH_CODE: end */
...
}

 

Best answer by Martin42

After further attempts, I have now reached an initial working state where the uC does not crash. I sent more than 2,000,000 TCP/IP frames.
I am using STM32CubeIDE 1.9 and STM32Cube FW_H7 V1.10.0. The LWIP stack will probably also work in the latest STM32CubeIDE 1.13.1, with STM32Cube_FW_H7_V1.11.1.

3 replies

Technical Moderator
December 6, 2023

Hello @Martin42 

Check this FreeRTOS - stacks and stack overflow checking 

It should be helpful

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.Best regards,FBL
Martin42Author
Associate III
December 7, 2023

Hi,

thank you for the link to https://www.freertos.org/Stacks-and-stack-overflow-checking.html.

I have already implemented the vApplicationStackOverflowHook. In the attached video you can see the implemented function vApplicationStackOverflowHook() and how the program ends there.

I also monitored the stack size of each task with STM32CubeMonitor with the function https://www.freertos.org/uxTaskGetStackHighWaterMark.html. The stack size is for each task always the same size.

I have also added the configuration.
Maybe someone here can see at first glance what was configured incorrectly.

FreeRTOS M4 Configuration

Martin42_0-1701942477657.png

LWIP Configuration

Martin42_2-1701942593033.png

 

Martin42_1-1701942530874.png

 

Also if I use the LWIP without FreeRTOS there is someting wrong...

 

 

Martin42Author
Associate III
December 11, 2023

Hello,

after spending several hours trying the versions of the STMCubeIDE (1.6.1, 1.9.0, 1.13.1) with various combinations of the STM32Cube FW_H7 (V1.9.0, V1.9.1, V1.10.0, V1.11.0), I come to the conclusion that the application implementation is probably causing the problem.

/* Handle the incoming TCP Data */

static void tcp_server_handle (struct tcp_pcb *tpcb, struct tcp_server_struct *es)
{
	struct tcp_server_struct *esTx;
	/* allocate structure es to maintain tcp connection information */
	esTx = (struct tcp_server_struct *)mem_malloc(sizeof(struct tcp_server_struct));

	/* get the Remote IP */
	ip4_addr_t inIP = tpcb->remote_ip;
	uint16_t inPort = tpcb->remote_port;

	/* Extract the IP */
	char *remIP = ipaddr_ntoa(&inIP);

	esTx->state = es->state;
	esTx->pcb = es->pcb;
	esTx->p = es->p;

	char buf[100];
	memset (buf, '\0', 100);

	strncpy(buf, (char *)es->p->payload, es->p->tot_len);
	strcat (buf, "+ Hello from TCP SERVER\n");


	esTx->p->payload = (void *)buf;
	esTx->p->tot_len = (es->p->tot_len - es->p->len) + strlen (buf);
	esTx->p->len = strlen (buf);

	tcp_server_send(tpcb, esTx);

	pbuf_free(es->p);

	mem_free(esTx);
}

Incorrect memory access can also be seen in the example video from ControllersTech https://youtu.be/olYTNjM2kwE?t=598. I thought it was because of the LWIP version.

 

I adapted the function to write to the same memory as the received data. So far this has been working without any problems.

static void tcp_server_handle (struct tcp_pcb *tpcb, struct tcp_server_struct *es)
{
	char a[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	uint8_t ui8_loop;
	static uint8_t ui8_switcher = 0;
	uint8_t *pui8_payload;
 
	pui8_payload = es->p->payload;

	for(ui8_loop = 0; ui8_loop < (es->p->len - 1); ui8_loop++)
	{
		*pui8_payload = a[(ui8_loop + ui8_switcher) % ((sizeof(a)/sizeof(a[0])))];
		pui8_payload++;
	}
	*pui8_payload = '\n';
	ui8_switcher++;
	tcp_server_send(tpcb, es);
}

 I have attached the original tcpServerRAW.c.

 

Is there a simple example of a TCP/IP or UDP client-server implementation?

 

 

Martin42AuthorBest answer
Associate III
December 13, 2023

After further attempts, I have now reached an initial working state where the uC does not crash. I sent more than 2,000,000 TCP/IP frames.
I am using STM32CubeIDE 1.9 and STM32Cube FW_H7 V1.10.0. The LWIP stack will probably also work in the latest STM32CubeIDE 1.13.1, with STM32Cube_FW_H7_V1.11.1.