Skip to main content
Graduate II
August 5, 2022
Question

HTTP request to STM32 + LwIP results that Ping stops working

  • August 5, 2022
  • 7 replies
  • 21229 views

Hello!

Recently I had problems with ping to my STM32 + LwIP + DP83848 + RMII. But the latest FW version 1.27.1, it works very well! But now I have problems with HTTP. Follow me and I show you how to create this bug.

First of all I'm using:

  • STM32CubeIDE 1.10.1
  • STM32F407VGT
  • FW 1.27.1

To reproduce this bug, do the following steps.

  • Step 1: Enable RMII by going to ETH -> RMII (Rx Buffer length 1524, MAC address 00:80:E1:00:00:00, Rx Mode = Interrupt, NVIC settings = Ethernet Global Interrupt)
  • Step 2: Go to FREERTOS and enable CMSIS V2 and go to Task & Queues. Change the Stack Size (Words) in defaultTask from 128 to 1024.
  • Step 3: Inside CMSIS V2, go to Advanced settings and set USE_NEWLIB_REENTRANT = Enabled. Leave everything else as default.
  • Step 4: Go to LWIP and enable it. Set LWIP_DHCP = disabled in General Settings and then write in the fixed IP address. In my case it is 192.168.1.35.
  • Step 5: Inside LWIP, go to HTTPD and set LWIP_HTTPD = enabled. Inside LWIP go to Key Options and set MEM_SIZE = 10*1024. Leave everything else as default.
  • Step 6: Download the FSDATA.zip folder and extract it.
  • Step 7: The FSDATA.zip folder contains a folder called FS and makeFSdata.exe. The makeFSdata.exe file will create a file called fsdata.c. Click on that.
  • Step 8: When the makeFSdata.exe file have created fsdata.c then rename fsdata.c to fsdata_custom.c.
  • Step 9: Place fsdata_custom.c at \Middlewares\Third_Party\LwIP\src\apps
  • Step 10: Right click fsdata_custom.c -> Resource Configurations -> Extract From Build ... -> Select All -> OK.
  • Step 11: Compile the project to your STM32 board and then ping.

0693W00000QN3y9QAD.png 

OK! It Working great!

  • Step 12: Download HTTP_Server.zip and extract it into the projects src folder.
  • Step 13: Write this into your main.c file
#include "HTTP_Server/httpserver.h"
  • Step 14: Add http_server_init(); to
/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief Function implementing the defaultTask thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
 /* init code for LWIP */
 MX_LWIP_Init();
 /* USER CODE BEGIN 5 */
 http_server_init();
 /* Infinite loop */
 for(;;)
 {
 osDelay(1);
 }
 /* USER CODE END 5 */
}
  • Step 15: Compile and go to your web browser and type in 192.168.1.35/index.html. No web site is displayed. Also if I ping now, then I get no response....BUT....if I restart the processor, then ping, the ping is working. But as long I don't go to the 192.168.1.35/index.html website, my STM32 processor have connection to the DHCP server and I can ping it.

Question:

Why does this happen?

I have followed this tutorial 100% (except that he are using another processor) https://www.youtube.com/watch?v=haO8_eLIDeI&ab_channel=ControllersTech

This must be a bug, becase in FW 1.27.0 version, I had problems with ping my processor. In FW 1.27.1, the ping works like a charm. But now FW 1.27.1 resulting that my HTTPD won't work.

Thank you.

    This topic has been closed for replies.

    7 replies

    Graduate II
    August 9, 2022
    DMårtAuthor
    Graduate II
    August 9, 2022

    So, do you have any suggestions why HTTP not working for me, but ping works?

    Graduate II
    August 9, 2022

    Because of the issues listed in that topic! Until the lower layers are reliable, there is no point in wondering why higher layers don't work.

    ST Employee
    December 20, 2022

    Hi @Daniel Mårtensson​ ,

    Thank you for your feedback.

    The mentioned bug is confirmed.

    It is due to Hardware limitation, in fact the Ethernet MAC does not have access to the Flash (in STM32F407 device) to download http's data.

    The solution is to move HTTP files to SRAM in by removing the "const".

    Sorry for the delayed answer.

    Regards

    Mahdy

    Visitor II
    December 20, 2022

    Where is the const data type? When will ST implement this bug fix in next STCubeMXIDE?

    Graduate II
    January 5, 2023

    > It's an applicative bug

    @Mahdy Sghaier​ , as always about non-trivial topics, you are again talking nonsense. The FLASH is used for storing const data, and const data is not some rarely used feature, but is used extensively everywhere. For example, the applications "httpd", "lwiperf" and others provided together with lwIP are outputting const data without copying and lwIP are actually passing those buffers to the driver. What do you offer? To rewrite them all? What to do in the case of large data, which doesn't fit in RAM? Implement a custom memory copy split in blocks? Duplicate a similar code for every service that needs sending of const data?

    Obviously the sane solution here is to make an exception for these buffers in the lwIP driver. The function low_level_output() should check the address of the buffer and, if it is in the FLASH memory range, then allocate a PBUF from SRAM, copy the data to it from the original PBUF, release the original PBUF and do not increment the reference count on the newly allocated PBUF. Actually, if the buffer address is compared to be below the SRAM base (0x20000000), the same code would work for FLASH, CCM and System/OTP/option bytes memories. Also similarly a solution for DTCM/ITCM access on H7 and ITCM access on F7, can be made, but that is not critical.

    Therefore, yes, this is a deficiency of the lwIP driver, and a pretty severe one. Note that this issue is relevant not only for F407/F417 devices, but also for F2 devices, when the reworked driver will be enabled for that series.

    Visitor II
    January 5, 2023

    Can you show us how to solve the issue?

    Graduate II
    January 6, 2023

    My previous post is literally a detailed instruction of what must be done to solve this issue. And what do you mean by "show"? I'm not going to write a code for you! By the way, it takes less time to develop that code than it took me to write the previous post...

    Visitor II
    January 9, 2023
    static err_t low_level_output(struct netif *netif, struct pbuf *p) {
     void *data = NULL;
     
     uint32_t i = 0U;
     struct pbuf *q = NULL;
     err_t errval = ERR_OK;
     ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT] = { 0 };
     
     memset(Txbuffer, 0, ETH_TX_DESC_CNT * sizeof(ETH_BufferTypeDef));
     
     for (q = p; q != NULL; q = q->next) {
     if (i >= ETH_TX_DESC_CNT)
     return ERR_IF;
     
     Txbuffer[i].buffer = q->payload;
     Txbuffer[i].len = q->len;
     
     // check is it valid ram address {
     if ((q->payload) < (void*)0x20000000) { // RAM starts at => $2000 0000
     // FLASH is under => $0800 0000
     // when not, allocate memory in ram
     data = pvPortMalloc(q->len);
     // then copy data
     memcpy(data, q->payload, (q->len));
     // replace data pointer to valid new address
     Txbuffer[i].buffer = data;
     }
     
     if (i > 0) {
     Txbuffer[i - 1].next = &Txbuffer[i];
     }
     
     if (q->next == NULL) {
     Txbuffer[i].next = NULL;
     }
     
     i++;
     }
     
     TxConfig.Length = p->tot_len;
     TxConfig.TxBuffer = Txbuffer;
     TxConfig.pData = p;
     
     pbuf_ref(p);
     
     HAL_ETH_Transmit_IT(&heth, &TxConfig);
     while (osSemaphoreAcquire(TxPktSemaphore, TIME_WAITING_FOR_INPUT) != osOK)
     
     {
     }
     
     HAL_ETH_ReleaseTxPacket(&heth);
     
     // we need to free memory after sending data
     if (data != NULL) {
     vPortFree(data);
     }
     
     return errval;
    }

    Messy, but seems to work well. I tested the whole 2 minutes so I can't guarantee to nothing...

    Visitor II
    January 9, 2023

    btw, where is info about eth driver dont have access to flash memory space?

    ST Employee
    January 9, 2023

    Hi @mmisz.1​ ,

    Thank you for sharing your solution.

    The info about ETH access to flash memory is available in RM0090 page 60.

    Regards

    Mahdy

    ST Employee
    January 9, 2023

    Hi,

    Thank you everyone for your cooperation.

    The solution of deleting the "const" and placing data on Ram instead of flash is just a workaround proposed to unlock customers which encounter the issue.

    But of course, in the next release, the most suitable solution will be implemented.

    Regards

    Mahdy

    Visitor II
    January 9, 2023

    And don't forget a .ioc example with FreeRTOS + LwIP + Ajax for each hardware!

    Thank you.

    Visitor II
    June 21, 2023

    May I have the courtesy to get response from any STM Engineer ?

    "When the most suitable solution will be available ? I suppose it was supposed to be fixed in June, isn't it ?"

     

    ST Employee
    March 11, 2024

    Hello,

    Apologies for the delay,
    For standalone projects, defining HTTP_IS_DATA_VOLATILE(hs) as TCP_WRITE_FLAG_COPY in lwipopts.h is the proper fix for data to be copied from flash memory.
    No need to define HTTP_IS_HDR_VOLATILE(hs, ptr) as TCP_WRITE_FLAG_COPY if the header is included with the data as HTTP_IS_DATA_VOLATILE(hs) will copy the entire file content.
    As for projects with RTOS using Netconn APIs, the flag NETCONN_COPY must be used in the netconn_write API.

    These fixes will be implemented in the next upcoming cubeF4 maintenance release.

    Kind regards

    Visitor II
    February 13, 2025

    Hello,

    I also have a problem with "const" in fsdata. In year 2025 it seems, there is no fix of this bug.

    And I have other problem, maybe, you can help me... I have easy html page with SSI tags. When I have created fsdata with index.html, page is sent to client correctly, but SSI tags doesn't work - this I understand. So I have renamed file to index.shtm, SSI works fine, but page is always not send completelly - few last lines of HTML code missing in client.

    I am not using RTOS. Thanx for your answer.

    Libor.