Skip to main content
Visitor II
September 20, 2020
Question

UDP packet drop on STM32H7, HAL_ETH_Transmit problem!!

  • September 20, 2020
  • 5 replies
  • 7398 views

 Hi

I have a customized stm32h750 board, my work is to read data from SD memory of board and send through UDP to a client PC.I use stm32cubeMX v5.6.1,STM32H7 MCU package v1.7 and LWIP cubeMX supported v2.0.3. when I send small size files everything is OK and I get the same data and file on PC,but for bigger size files(in MByte size and over) the data I get on PC is less than sent and clearly some packets are dropped.for example in sending of 26Mbyte data I receive  21Mbyte .

I tried to debug the code,first thing I checked was reading from SD by fatfs function f_read,it was OK. The second thing I checked was udp_send function that seems to be the reason.it returns no error,but When I add time delay(in few miliseconds range) before udp_send in my for loop, the problem goes away.but if I send a bigger size data I need to increase delay time. For example it must be 30 ms for a 26Mbyte data file.I read many posts in community about bug fix (specially from Alister and Piranha)in STM32H7 ethernet,I think I have correct MPU config and it seems other bugs are fixed in v.1.7 package. But I think also there is a problem with HAL_ETH_Transmit function that use a polling mode to send Ethernet data.

Has anyone similar experience? Would anyone give me a hint or solution to fix this problem.

Below is a piece of my code related to UDP send, also necessary files for review of set parameters in cube are attached.

Dcache and Icache,are enabled, but I also tested the code by disabling them,and again failed.

Phy = DP83848.

BYTE SD_read_buffer[8192];  /* File copy buffer */

Chunk of server_rec function:                  

                               if(data_read[0]=='9')

                               {

                                               HAL_Delay(2000);

                                               f_open(&SDFile, "REC_26MB.DAT", FA_READ); //640kb file

                                               for (;;)

                                               {

                                                               f_read(&SDFile, SD_read_buffer, sizeof SD_read_buffer, &br); // Read a chunk of data from the source file

                                                               if (br == 0) break; // error or eof

                                                               HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_SET);

                                                               server_send(upcb);

                                                               HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_RESET);

                                                               HAL_Delay(10);

                                               }

                                               f_close(&SDFile);

                                               

Server_send function:

void server_send(struct udp_pcb *upcb)

{

               struct pbuf *sb;

               err_t err;

 /* allocate pbuf from RAM*/

               

               sb = pbuf_alloc(PBUF_TRANSPORT,sizeof SD_read_buffer, PBUF_RAM);

               memcpy(sb->payload,SD_read_buffer,sizeof SD_read_buffer);

               err=udp_send(upcb, sb);

               pbuf_free(sb); 

}

this got me crazy and i can't debug it, please help me.

    This topic has been closed for replies.

    5 replies

    Saghi.1Author
    Visitor II
    September 20, 2020

    also my MPU config:

    void MPU_Config(void)

    {

     MPU_Region_InitTypeDef MPU_InitStruct = {0};

     /* Disables the MPU */

     HAL_MPU_Disable();

     /** Initializes and configures the Region and the memory to be protected

     */

     MPU_InitStruct.Enable = MPU_REGION_ENABLE;

     MPU_InitStruct.Number = MPU_REGION_NUMBER0;

     MPU_InitStruct.BaseAddress = 0x30040000;

     MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;

     MPU_InitStruct.SubRegionDisable = 0x0;

     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;

     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

     MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

     HAL_MPU_ConfigRegion(&MPU_InitStruct);

     /** Initializes and configures the Region and the memory to be protected

     */

     MPU_InitStruct.Enable = MPU_REGION_ENABLE;

     MPU_InitStruct.Number = MPU_REGION_NUMBER1;

     MPU_InitStruct.BaseAddress = 0x30040000;

     MPU_InitStruct.Size = MPU_REGION_SIZE_256B;

     MPU_InitStruct.SubRegionDisable = 0x0;

     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

     MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;

     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

     MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

     HAL_MPU_ConfigRegion(&MPU_InitStruct);

     /* Enables the MPU */

     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

    }

    Super User
    September 20, 2020

    >        sb = pbuf_alloc(PBUF_TRANSPORT,sizeof SD_read_buffer, PBUF_RAM);

    If you're dealing with megabytes of data, you should be checking this to ensure it's able to allocate enough memory. You could be running out.

    >               err=udp_send(upcb, sb);

    You should also check the return status here.

    Instead of having a fixed delay, poll the port to see when it's finished before you send more data.

    Note also that UDP is a send and forget scheme and packets can get lost without any sort of notification. If you need a robust protocol, you'll need to use TCP or implement your own handshaking protocol.

    Saghi.1Author
    Visitor II
    September 21, 2020

    thanks for your reply TDK.

    as you see I sd buffer size is 8kbyte and I send megabytes data in chunk of 8kbytes, how should I check this allocation, do you mean ​maybe its not enough ram when I do this allocation in a for loop?I make it free at end of sending every 8kbyte.

    about checking of udp_send error, in this code it does not done, but as I said I did it in my debugging and it returns no error in whole for loop!​

    I think udp_send finally calls hal_eth_transmit, and this function has a polling scheme, but seems it does not work properly.

    I your right about udp forgetting scheme, but I used this for it's speed and have to go with that.

    Explorer
    September 21, 2020

    > it seems other bugs are fixed in v.1.7 package

    Which bugs are those?

    Saghi.1Author
    Visitor II
    September 21, 2020

    it seems polling function in hal_eth_transmit does not work properly sometimes!​have you ever tried to send burst data with it?

    Explorer
    September 21, 2020

    No eth bugs were fixed in H7_FW V1.7.0. All the bugs described at https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet apply it.

    The last post that thread by @Community member​  says it appears to have solved some number of eth bugs , but none of the implementation improvements I'd provided.

    >have you ever tried to send burst data with it?

    I don't recall. I'd found most of the bugs I'd listed by inspection.

    The list includes ethernetif.c's low_level_output and the driver's HAL_ETH_Transmit.

    You may also need to check your lwIP heap is dimensioned appropriately as transmit pbufs are typically allocated from there.

    Saghi.1Author
    Visitor II
    September 21, 2020

    thanks

    I did not find the thread by adunc.1 you mentioned, would u send the link here?

    I 'll check the heap,thanks​.

    Explorer
    September 21, 2020

    > I did not find the thread by adunc.1 you mentioned, would u send the link here?

    I'm referring his post recently to https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet.

    Visitor II
    September 26, 2021

    Hi @Saghi.1​ 

    I have stm32H7 Nucleo board and i want to send data from ADC to PC via Ethernet, because It is faster that transmision via Rs232.

    For getting data from rs232 i use terminal program (Realterm) that give me occunity to save data to file and i could comunicate with MCU from PC.

    What program you use for getting data from MCU via Ethernet UDP ?

    Best regards.