cancel
Showing results for 
Search instead for 
Did you mean: 

Cortex M4 with FreeRtos httpd hangs when opening page

MRaff.1
Associate III
Hello, 
     I am unable to make httpd server. I am working with the following platform:
 
CPU: STM32F407VET6 (Cortex-M4)
LAN PHY: LAN8720AI
SO: FREERTOS V10.3.1
 
I configured the LWIP and FreeRTOS using CubeMX tool.
The ping command works fine.
 
I defined in fsdata.c a very simple webpage, a sort of "hello world" html. 
 
I checked possible stack overflow and MallocFailed from freertos.
 
When I try to open the webpage I see from debugger that the TCP connection is set ESTABILISHED. But there is no packets sent from the board toward the client.
As soon as I try to open the webpage the whole LWIP stack stop working and also the ping fails until the next reboot.
 
I tried also to increase the MEMP_NUM_PBUF to 64 (from 16).
 
LwIP is initialized calling from DefaultTask():
MX_LWIP_Init()
 
The httpd server is initialized calling from DefaultTask():
httpd_init();
 
Enabling the LWIP_DEBUIG I cannot print everythink since the sprintf and the sent to UART is too slow, but enabling a message ring buffer I see something like this:
 
-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n0dd7c new 0x14 (0)\n chksum)\n)\nx0,
State: \030ù\002\b\003\n   |1056668|    6716   | (id, flags, offset)\nn, fl
TCP connection established 56644 -> 31422
http_accept 0x2000dd34 / 0\n-----+\n(src port, dest port[...]
tcp_receive: ACK for 536927516, unacked->seqno 6511:0\n
tcp_receive: removing 536927468:134412984 from pcb->036934304\n\0, flags (\00x0)\n\00x0)\n\0\0\0\075c)\n"
 
The size in tcp_receive is quite suspect. 
 
The last message I get seems to be "tcp_receive: removing 536927468 etc"
 
It looks a memory allocation issue but I can't figure the cause. 
 
 
Thank you
 
10 REPLIES 10
STea
ST Employee

Hello @MRaff.1 ,

There is no such thing as STM32G407 I think you have a typo (maybe F407?). can you specify what is exactly the CPU you are using and is it your custom board or one of ST nucleo or Disco boards?
if it is an F4 series MCU you can take STM32Cube_FW_F4_V1.28.0\Projects\STM32469I_EVAL\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS as a reference.
Regards

In order 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.

Hello, 

    sorry for the typo. The CPU is a STM32F407VET6.

Since it is a custom board it is not so straighforward to run the demo (I found the STM32F429ZI-Nucleo --> LwIP_HTTP_Server_Netconn_RTOS demo, inside the en.stm32cubef4-v1-28-0 package).

The idea was:

1) start from a CubeMX HW configuration with only LWIP, FreeRTOS without the application I have developed on my board.

2) Add the LAN8720 Driver

3) Port the LwIP_HTTP_Server_Netconn_RTOS code in the project above. 

I was able to port LwIP_HTTP_Server_Netconn_RTOS code on my board. 

The behaviour unfortunately is the same. The ping is OK but as soon as I try to open the web page the TCP/IP stack seems to crash. 

Looking at the registers of the PHY the link remains UP and there are no errors. Also the LED are status is on. 

MRaff1_0-1727086833564.png

The stack hangs in the call to 

netconn_write_partly();

Hello @MRaff.1 ,

Could you try to port the hole code with even the configuration from the example you mentioned and not using CubemX as this can lead to conflicts between the code executed For the Init phase with MX which works fine by the way as you are able to ping the board, and the response throw the TCP socket that should be opened and handled in a separate thread. this could be because incompatibility between the software and Middleware used in the example and in you MX generated code which I assume is defaulted to the latest version. 
you can start porting the example the other way around started with the one on the F429 board and changing the necessary to accommodate your F407 Hardware needs. 
Regards

In order 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.
MRaff.1
Associate III

Thank you STea,
     I tried what you suggested but the problem persist. 

I did the following:

1. Start from  LwIP_HTTP_Server_Netconn_RTOS project.

2. Changed the .ld and the .startup to support the STM32F407

3. Commented the BSP_Config(); it manages led and lcd. 

4. added MXGPIO_INIT()  from my cube project and called from main() in order to correctly init the Board HW.

5 Copy the SystemClock_Config() from the CubeMX project to get the correct clock configuration;

6. In ethernetif.c take HAL_ETH_MspInit()  from CubeMx project in order to have the correct pin mapping for the ethernet.

7. In  ethernetif.c replace the LAN8742 driver with LAN8720.

Result: ping OK, also with greater packet sizes (1400 bytes) but as soon as I write the ip address on the browser the ping goes down and I don't load the page. 

 

I implemented a TCP echo server and also this is working. The problem involves the HTTP only. Could be related to the fs and the way the page is stored in FLASH? I start to investigate this.  

I used LAN8720 with cortex M7 (STM32F765) and the schematics is almost the same I don't think there are HW issues but at this point I have run out of ideas.

 

   

MRaff.1
Associate III

Looking at httpserver-netconn.c, I see that the netconn_write() never exits.

At the first call

 

 else if((strncmp(buf, "GET /STM32F4xx.html", 19) == 0)||(strncmp(buf, "GET / ", 6) == 0)) 
 {
          /* Load STM32F4xx page */
          fs_open(&file, "/STM32F4xx.html"); 
          netconn_write(conn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY);
          fs_close(&file);
 }

 

necconn_write() does not exits since it is blocked by the semphore in api_lib.c

 

 

static err_t
netconn_apimsg(tcpip_callback_fn fn, struct api_msg *apimsg)
{
  err_t err;

#ifdef LWIP_DEBUG
  /* catch functions that don't set err */
  apimsg->err = ERR_VAL;
#endif /* LWIP_DEBUG */

#if LWIP_NETCONN_SEM_PER_THREAD
  apimsg->op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
#endif /* LWIP_NETCONN_SEM_PER_THREAD */

  err = tcpip_send_msg_wait_sem(fn, apimsg, LWIP_API_MSG_SEM(apimsg));
  if (err == ERR_OK) {
    return apimsg->err;
  }
  return err;
}

 

 There are two calls to netconn_apimsg(). The first exits:

MRaff1_0-1727190420821.png

 

the second is blocked by

 tcpip_send_msg_wait_sem()

MRaff1_1-1727190484214.png

This is the problem but the mechanism according which these semaphores are managed is still obscure to me. 

However it seems I have the same problem pointed out here and here.

In any case both 

#define LWIP_TCPIP_CORE_LOCKING 0

and 

#define LWIP_TCPIP_CORE_LOCKING 1

puts a semaphore which block the thread. 

Solution?

MRaff.1
Associate III

Looking at wireshark capture I get this kind of packets.

 

MRaff1_0-1727266362486.png

The LwIP blocks in netconn_write call for the semaphore issue as stated above.

 

fs_open(&file, "/404.html"); 
          netconn_write(conn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY);
fs_close(&file);

 

 

Thank you. 

 

 

 

 

 

 

 

Hello. 

It seems that the problem is in reading the page from fsdata.c.When I copy the page source as a static variable as below it works:

static const unsigned int dummy_align__STM32F4xx_html = 4;
static const unsigned char data__STM32F4xx_html[] = {
/* /STM32F4xx.html (16 chars) */
//0x2f,0x53,0x54,0x4d,0x33,0x32,0x46,0x34,0x78,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
/* raw file data (9821 bytes) */
0x3c,0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x48,0x54,0x4d,0x4c,0x20,0x50,
0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,
0x54,0x44,0x20,0x48,0x54,0x4d,0x4c,0x20,0x34,0x2e,0x30,0x31,0x20,0x54,0x72,0x61,
...
};

len = strlen((char*)data__STM32F4xx_html);
pdata = data__STM32F4xx_html;
netconn_write(conn, pdata, len, NETCONN_COPY);

On the other hand when reading from fsdata.c, netconn_write() hangs:

fs_open(&file, "/STM32F4xx.html");
len = file.len;
pdata = file.data;
netconn_write(conn, (const unsigned char*)pdata, len, NETCONN_NOCOPY);
fs_close(&file);

Comparing the two cases the length (len) is the same and the content of the pdata array is the same. 

Both the arrays are in the .rodata section (0x0801EA6C in the first case 0x08026BFC in the second case).

 

STea
ST Employee

Hello @MRaff.1 ,

I have started a http example from scratch, and it is working as expected unfraternally I can't test on F407 so I used a nucleo f439 to test the example you will find it attached.
Regards

In order 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.

Hello STea,

     thank you for your reply. 

I ordered a NUCLEO F439 but I am pretty sure your code will work. 

But I have to start the production with our board. 

I have found the point which cause the issue.

When I include the page inside httpserver-netconn.c

static const unsigned char data__STM32F4xx_html2[] = {
/* /STM32F4xx.html (16 chars) */
//0x2f,0x53,0x54,0x4d,0x33,0x32,0x46,0x34,0x78,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
/* raw file data (9821 bytes) */
0x3c,0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x48,0x54,0x4d,0x4c,0x20,0x50,
0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,
0x54,0x44,0x20,0x48,0x54,0x4d,0x4c,0x20,0x34,0x2e,0x30,0x31,0x20,0x54,0x72,0x61,
...
};

len = strlen((char*)data__STM32F4xx_html2);
pdata = data__STM32F4xx_html2;
netconn_write(conn, pdata, len, NETCONN_COPY);

everything works.

When I take the same page from fsdata.c, netconn_write() blocks.

I tried to map both the local defined page (data__STM32F4xx_html2) and the fsdata.c defined page in the same flash section but the problem remains. 

 

This is very obscure. In the call to netcon_write() I see that only the pdata address changes, but from the same flash section (0x0801E000 + offsett). The length is the same and teh content is the same:

MRaff1_0-1727355245729.png

 

I tried also to directly use the flash address:

len = 9821;
pdata = 0x080A80A0;
netconn_write(conn, pdata, len, NETCONN_NOCOPY);

 

Again, when using the address of the locally defined page it works, when using the fsdata.c address it fails. 

To resume, in the code below,   A works, B does not work. B is taken from fsdata.c while  A from a local define array. Both A and B are in the same flash section.

 

static const unsigned char data__STM32F4xx_html2[] __attribute__ ((section (".filesys"))) = {
/* /STM32F4xx.html (16 chars) */
//0x2f,0x53,0x54,0x4d,0x33,0x32,0x46,0x34,0x78,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
/* raw file data (9821 bytes) */
0x3c,0x21,0x44,0x4f,0x43,0x54,0x59,0x50,0x45,0x20,0x48,0x54,0x4d,0x4c,0x20,0x50,
0x55,0x42,0x4c,0x49,0x43,0x20,0x22,0x2d,0x2f,0x2f,0x57,0x33,0x43,0x2f,0x2f,0x44,
0x54,0x44,0x20,0x48,0x54,0x4d,0x4c,0x20,0x34,0x2e,0x30,0x31,0x20,0x54,0x72,0x61,
0x6e,0x73,0x69,0x74,0x69,0x6f,0x6e,0x61,0x6c,0x2f,0x2f,0x45,0x4e,0x22,0x3e,0x0d,
0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x76,0x3d,0x22,
0x75,0x72,0x6e,0x3a,0x73,0x63,0x68,0x65,0x6d,0x61,0x73,0x2d,0x6d,0x69,0x63,0x72,
0x6f,0x73,0x6f,0x66,0x74,0x2d,0x63,0x6f,0x6d,0x3a,0x76,0x6d,0x6c,0x22,0x20,0x78,
0x6d,0x6c,0x6e,0x73,0x3a,0x6f,0x3d,0x22,0x75,0x72,0x6e,0x3a,0x73,0x63,0x68,0x65,
0x6d,0x6
....
};


if (strncmp((char const *)buf,"GET /index.html",15) == 0 || (strncmp(buf, "GET / ", 6) == 0))
{
//A. Works fine
    		  len = sizeof(data__STM32F4xx_html2);//9821;
    		  pdata = (unsigned char*)data__STM32F4xx_html2;//0x080A0000
    		  netconn_write(conn, pdata, len, NETCONN_COPY);
}
else if((strncmp(buf, "GET /STM32F4xx.html", 19) == 0))
{
//B. Blocks forever
    		  fs_open(&file, "/STM32F4xx.html");
    		  len = file.len;//9821; 
    		  pdata = (unsigned char*)file.data;//0x080A80A0;
    		  netconn_write(conn, pdata, len, NETCONN_NOCOPY);
    		  fs_close(&file);
}