Skip to main content
Graduate II
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 */
...
}

 

    This topic has been closed for replies.
    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

    Martin42Author
    Graduate II
    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
    Graduate II
    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?

     

     

    Martin42AuthorAnswer
    Graduate II
    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.