Skip to main content
Marina Brener
Associate III
December 7, 2017
Question

Streaming buffers of float numbers via ETH (STM32H7 nucleo)

  • December 7, 2017
  • 1 reply
  • 1812 views

Posted on December 07, 2017 at 22:04

Hello, 

I have created via the cubeMX project for my stm32H7 nucleo board, it has Eth + lwip+ freeRTos + dhcp + dma + tcpServer.

I updated the linker file and changed the cube generated code related to the ETH pins, added dhcp thread and added a TCP server thread. 

PS: my MPU is set to 1500, and I do not use cache.

Now I want to stream buffers of float numbers via ethernet,

the tcp server in the example code uses netconn_write to send data, so I used this method as well with the flag NO_COPY, but then, if I send the data to fast the write hangs. If I use vTaskDelay(200) between my writes, all works fine.

I would prefer to perform writes with a callback, so i want to use this callback HAL_ETH_TxCpltCallback but it is not fired, I can see that the packet is transmitted and I can perform async read from the tcp client, after that HAL_ETH_IRQHandler is firing and this code should be executed but it never does: 

/* Packet transmitted */

if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_TI) && __HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE))

{

/* Transfer complete callback */

HAL_ETH_TxCpltCallback(heth);

/* Clear the Eth DMA Tx IT pending bits */

__HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);

heth->ErrorCode = HAL_ETH_ERROR_NONE;

heth->gState = HAL_ETH_STATE_READY;

}

I saw that it was investigated here:

https://community.st.com/message/172318-re-example-using-hal-eth-without-lwip-for-raw-ethernet-frames?commentID=172318&sharpcomment-172318

 aleksandar.radulovic

‌ 

Any help/advise is appreciated! 

Marina

null

    This topic has been closed for replies.

    1 reply

    Joerg Wagner
    Senior III
    December 8, 2017
    Posted on December 08, 2017 at 19:03

    Hi Marina.

    You use TCP/IP, what should be the advantage to use a Callback or to know the DMA processed the data?

    In case of UDP it makes sense, but with TCP/IP you will have a manager for the communication.

    A different sequence order, spurious, retransmission, delay or timeout, all will be managed.

    You don't know which data is currently processed. Other questions: who is the receiver, is it a keep alive

    connection, and if not who will close the connection? Will it be in a FIN packet or the receiver closes it?

    Greetings, Joerg

    Marina Brener
    Associate III
    December 8, 2017
    Posted on December 08, 2017 at 21:51

    Hi Joerg,

    Agree, I get your point about TCP connection and callback relevance.

    As you suggested, will explore my alternatives, a different sequence order, spurious, re transmission, delay or timeout.

    I am adding a print screen of my cubeMX lwip key options tab.

    Can you please take a look?

    This is the code I want to execute from my tcp server only without the Delay between the writes:

    for(int i= 0; i< 256; i++)

    {

    buffFloat[i] = 1.0*i;

    }

    while(1)

    {

    err = netconn_write(newconn, buffFloat, 1024, NETCONN_NOCOPY);

    vTaskDelay(200);

    err = netconn_write(newconn, buffFloat, 1024 , NETCONN_NOCOPY);

    vTaskDelay(200);

    err = netconn_write(newconn, buffFloat, 1024 , NETCONN_NOCOPY);

    vTaskDelay(200);

    }

    About the TCP client,

    it will continue to read values until it decides to close the connection.

    So the client closes the connection.

    I guess, it is also possible that the client is too slow.

    Thanks for the help,

    Marina

    0690X000006096bQAA.png
    Joerg Wagner
    Senior III
    December 9, 2017
    Posted on December 09, 2017 at 00:11

    Hey ho Marina.

    You send 1024 Bytes (netconn_write) but you have a tiny segment size of 536 bytes? Pump it up.

    Some parameters should be tweaked to have a better performance.

    It's also a good idea to turn on LWIP_DEBUG to see what's going on with the traffic.

    Go to the Debug tab and turn on: LWIP_DBG_TYPES_ON, TCP_DEBUG, TCP_OUTPUT_DEBUG, TCPIP_DEBUG.

    Turn on LWIP_Stats (Tab Statistics) to get a feeling for the memory pool buffers (pbuf).

    Take a look at the maximum usage, like a peak, if you need more.

    Do not forget providing enough space on the FreeRTOS Heap as well.

    If you do not use a printf for output you can simply run your code in debug mode, wait for some actions pause it

    and in the Expressions tab analyse the variable lwip_stats. It's a structure with all the statistic information.

    Another good tool for you would be Systemview from Segger for profiling the execution over the time.

    Greetings,  Joerg

    PS: I do not set the LWIP settings in CubeMX anymore, I modify lwiptopts.h later.

    Here are my settings without debug and statistics activated:

    * STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/

    /* Parameters set in STM32CubeMX LwIP Configuration GUI -*/

    /*----- WITH_RTOS enabled (Since FREERTOS is set) -----*/

    ♯ define WITH_RTOS 1

    /*----- CHECKSUM_BY_HARDWARE enabled -----*/

    ♯ define CHECKSUM_BY_HARDWARE 1

    /*-----------------------------------------------------------------------------*/

    /* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/

    /* Parameters set in STM32CubeMX LwIP Configuration GUI -*/

    /*----- Default Value for MEMP_NUM_UDP_PCB: 4 ---*/

    ♯ define MEMP_NUM_UDP_PCB 6

    /*----- Default Value for MEMP_NUM_TCP_PCB: 5 ---*/

    ♯ define MEMP_NUM_TCP_PCB 10

    /*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/

    ♯ define MEM_ALIGNMENT 4

    /*----- Default Value for MEM_SIZE: 1600 ---*/

    ♯ define MEM_SIZE 10240

    /*----- Default Value for MEMP_NUM_PBUF: 16 ---*/

    ♯ define MEMP_NUM_PBUF 10

    /*----- Default Value for MEMP_NUM_TCP_PCB_LISTEN: 8 ---*/

    ♯ define MEMP_NUM_TCP_PCB_LISTEN 5

    /*----- Default Value for MEMP_NUM_TCP_SEG: 16 ---*/

    ♯ define MEMP_NUM_TCP_SEG 8

    /*----- Default Value for PBUF_POOL_BUFSIZE: 592 ---*/

    ♯ define PBUF_POOL_BUFSIZE 1524

    /*----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -*/

    ♯ define LWIP_ETHERNET 1

    /*----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -*/

    ♯ define LWIP_DNS_SECURE 7

    //*----- Default Value for MEMP_OVERFLOW_CHECK: 0 ---*/

    ♯ define MEMP_OVERFLOW_CHECK 1

    /*----- Default Value for MEMP_SANITY_CHECK: 0 ---*/

    ♯ define MEMP_SANITY_CHECK 0

    /*----- Default Value for TCP_WND: 5840 ---*/

    ♯ define TCP_WND 5840

    /*----- Default Value for TCP_QUEUE_OOSEQ: 1 ---*/

    ♯ define TCP_QUEUE_OOSEQ 0

    /*----- Default Value for TCP_MSS: 536 ---*/

    ♯ define TCP_MSS 1460

    /*----- Default Value for TCP_SND_BUF: 2920 ---*/

    ♯ define TCP_SND_BUF (4*TCP_MSS)

    /*----- Default Value for TCP_SND_QUEUELEN: 17 ---*/

    ♯ define TCP_SND_QUEUELEN (2* TCP_SND_BUF/TCP_MSS)

    /*----- Default Value for MEMP_NUM_RAW_PCB: 4 ---*/

    ♯ define MEMP_NUM_RAW_PCB 16

    /*----- Default Value for MEMP_NUM_FRAG_PBUF: 15 ---*/

    ♯ define MEMP_NUM_FRAG_PBUF 16

    /*----- Default Value for MEMP_NUM_SYS_TIMEOUT: 3 ---*/

    ♯ define MEMP_NUM_SYS_TIMEOUT 16

    /*----- Default Value for MEMP_NUM_NETBUF: 2 ---*/

    ♯ define MEMP_NUM_NETBUF 16

    /*----- Default Value for MEMP_NUM_NETCONN: 4 ---*/

    ♯ define MEMP_NUM_NETCONN 16

    /*----- Default Value for MEMP_NUM_TCPIP_MSG_INPKT: 8 ---*/

    ♯ define MEMP_NUM_TCPIP_MSG_INPKT 32

    /*----- Default Value for MEMP_NUM_API_MSG: 8 ---*/

    ♯ define MEMP_NUM_API_MSG 16

    /*----- Default Value for MEMP_NUM_DNS_API_MSG: 8 ---*/

    ♯ define MEMP_NUM_DNS_API_MSG 16

    /*----- Default Value for MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: 8 ---*/

    ♯ define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA 16

    /*----- Default Value for MEMP_NUM_NETIFAPI_MSG: 8 ---*/

    ♯ define MEMP_NUM_NETIFAPI_MSG 16

    /*----- Default Value for PBUF_POOL_SIZE: 16 ---*/

    ♯ define PBUF_POOL_SIZE 8

    /*----- Value in opt.h for TCP_SND_QUEUELEN: (4*TCP_SND_BUF + (TCP_MSS - 1))/TCP_MSS -----*/

    // ♯ define TCP_SND_QUEUELEN TCP_SND_QUEUELEN: (4*TCP_SND_BUF + (TCP_MSS - 1))/TCP_MSS

    /*----- Value in opt.h for TCP_SNDLOWAT: LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -*/

    // ♯ define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)

    /*----- Value in opt.h for TCP_SNDQUEUELOWAT: LWIP_MAX(TCP_SND_QUEUELEN)/2, 5) -*/

    ♯ define TCP_SNDQUEUELOWAT 5

    /*----- Default Value for LWIP_NETIF_API: 0 ---*/

    ♯ define LWIP_NETIF_API 1

    /*----- Value in opt.h for TCPIP_THREAD_STACKSIZE: 0 -----*/

    ♯ define TCPIP_THREAD_STACKSIZE 1024

    /*----- Value in opt.h for TCPIP_THREAD_PRIO: 1 -----*/

    ♯ define TCPIP_THREAD_PRIO 3

    /*----- Value in opt.h for TCPIP_MBOX_SIZE: 0 -----*/

    ♯ define TCPIP_MBOX_SIZE 6

    /*----- Value in opt.h for SLIPIF_THREAD_STACKSIZE: 0 -----*/

    ♯ define SLIPIF_THREAD_STACKSIZE 1024

    /*----- Value in opt.h for SLIPIF_THREAD_PRIO: 1 -----*/

    ♯ define SLIPIF_THREAD_PRIO 3

    /*----- Value in opt.h for DEFAULT_THREAD_STACKSIZE: 0 -----*/

    ♯ define DEFAULT_THREAD_STACKSIZE 1024

    /*----- Value in opt.h for DEFAULT_THREAD_PRIO: 1 -----*/

    ♯ define DEFAULT_THREAD_PRIO 3

    /*----- Value in opt.h for DEFAULT_UDP_RECVMBOX_SIZE: 0 -----*/

    ♯ define DEFAULT_UDP_RECVMBOX_SIZE 6

    /*----- Value in opt.h for DEFAULT_TCP_RECVMBOX_SIZE: 0 -----*/

    ♯ define DEFAULT_TCP_RECVMBOX_SIZE 6

    /*----- Value in opt.h for DEFAULT_ACCEPTMBOX_SIZE: 0 -----*/

    ♯ define DEFAULT_ACCEPTMBOX_SIZE 6

    /*----- Value in opt.h for LWIP_SOCKET: 1 -----*/

    ♯ define LWIP_SOCKET 0

    /*----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----*/

    ♯ define RECV_BUFSIZE_DEFAULT 2000000000

    /*----- Default Value for LWIP_STATS_DISPLAY: 0 ---*/

    ♯ define LWIP_STATS_DISPLAY 0

    /*----- Value in opt.h for LINK_STATS: 0 or 1 -*/

    ♯ define LINK_STATS 0

    /*----- Value in opt.h for ETHARP_STATS: 0 or LWIP_ARP -----*/

    ♯ define ETHARP_STATS 0

    /*----- Value in opt.h for ICMP_STATS: 0 or LWIP_ICMP -----*/

    ♯ define ICMP_STATS 0

    /*----- Value in opt.h for MIB2_STATS: 0 or SNMP_LWIP_MIB2 -----*/

    ♯ define MIB2_STATS 0

    /*----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----*/

    ♯ define CHECKSUM_GEN_IP 0

    /*----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----*/

    ♯ define CHECKSUM_GEN_UDP 0

    /*----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----*/

    ♯ define CHECKSUM_GEN_TCP 0

    /*----- Value in opt.h for CHECKSUM_GEN_ICMP: 1 -----*/

    ♯ define CHECKSUM_GEN_ICMP 0

    /*----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----*/

    ♯ define CHECKSUM_GEN_ICMP6 0

    /*----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----*/

    ♯ define CHECKSUM_CHECK_IP 0

    /*----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----*/

    ♯ define CHECKSUM_CHECK_TCP 0

    /*----- Value in opt.h for CHECKSUM_CHECK_ICMP: 1 -----*/

    ♯ define CHECKSUM_CHECK_ICMP 0

    /*----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----*/

    ♯ define CHECKSUM_CHECK_ICMP6 0

    /*-----------------------------------------------------------------------------*/

    /* USER CODE BEGIN 1 */

    ♯ define ETHARP_SUPPORT_STATIC_ENTRIES   1

    ♯ define LWIP_DEBUG    0

    // ♯ define TCP_DEBUG LWIP_DBG_ON

    /*----- Default Value for TCP_QUEUE_OOSEQ: 1 ---*/

    ♯ define TCP_QUEUE_OOSEQ 0

    /* USER CODE END 1 */