cancel
Showing results for 
Search instead for 
Did you mean: 

lwIP TCP STM32F7

arturo.fg
Associate

I'm developing an ethernet application on a NUCLEO-F746ZG board using the LWIP library. My app basically consists of the board (ip:192.168.1.21) is receiving a message every 20ms form a TCP client (my PC ip: 192.168.1.150) while the board sends UDP messages to another UDP server. All works fine until it reaches 1 hour since I started the connection with the TCP server of the board.

I´ve analyzed the network traffic and what I can see form Wireshark is that the NUCLEO suddenly stops responding messages, so the client aborts the connection few minutes after with the board few minutes after, as you can see at the photo. This happens 48/52 minutes after the first TCP message is received by the board. 0690X000008i5uZQAQ.png

*If I don’t start the TCP server UDP Client never stops sending messages, so I suppose the problem is from the TCP server.

The code I´m using for the TCP echo server is the example code developed by ST developed for stm32f4 using the LWIP library. You can download it form this link:

https://www.st.com/en/embedded-software/stm32cubef4.html

I also have found the same code, in this case for the stm32f7 series in this github repo:

https://github.com/pellepl/verisure1512/blob/master/ext-libs/STM32Cube_FW_F7_V1.2.0/Projects/STM32756G_EVAL/Applications/LwIP/LwIP_TCP_Echo_Server/Src/tcp_echoserver.c

In case you are not familiar with the previous code I´m going to share some (not all) of the parts of my code:

TCP server init/start called at the main.c:

void tcp_echoserver_init(void)
{
	ip_addr_t DestIPaddr;
 
  /* create new tcp pcb */
  tcp_echoserver_pcb = tcp_new();
 
  if (tcp_echoserver_pcb != NULL)
  {
    err_t err;
    IP4_ADDR(&DestIPaddr, 192, 168, 1, 21);
    /* bind echo_pcb to port 7 (ECHO protocol) */
    err = tcp_bind(tcp_echoserver_pcb, &DestIPaddr, 1337);
 
    if (err == ERR_OK)
    {
      /* start tcp listening for echo_pcb */
      tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
 
      /* initialize LwIP tcp_accept callback function */
      tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);
    }
    else
    {
      /* deallocate the pcb */
      memp_free(MEMP_TCP_PCB, tcp_echoserver_pcb);
    }
  }
 
}

TCP recieved message callback:

static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
  struct tcp_echoserver_struct *es;
  err_t ret_err;
 
  LWIP_ASSERT("arg != NULL",arg != NULL);
 
  es = (struct tcp_echoserver_struct *)arg;
 
  /* if we receive an empty tcp frame from client => close connection */
  if (p == NULL)
  {
    /* remote host closed connection */
    es->state = ES_CLOSING;
    if(es->p == NULL)
    {
       /* we're done sending, close connection */
       tcp_echoserver_connection_close(tpcb, es);
    }
    else
    {
      /* we're not done yet */
      /* acknowledge received packet */
      tcp_sent(tpcb, tcp_echoserver_sent);
 
      /* send remaining data*/
      tcp_echoserver_send(tpcb, es);
    }
    ret_err = ERR_OK;
  }
  /* else : a non empty frame was received from client but for some reason err != ERR_OK */
  else if(err != ERR_OK)
  {
    /* free received pbuf*/
    if (p != NULL)
    {
      es->p = NULL;
      pbuf_free(p);
    }
    ret_err = err;
  }
  else if(es->state == ES_ACCEPTED)
  {
    /* first data chunk in p->payload */
    es->state = ES_RECEIVED;
 
    /* store reference to incoming pbuf (chain) */
    es->p = p;
 
    /* initialize LwIP tcp_sent callback function */
    tcp_sent(tpcb, tcp_echoserver_sent);
 
    /* send back the received data (echo) */
    tcp_echoserver_send(tpcb, es);
 
    ret_err = ERR_OK;
  }
  else if (es->state == ES_RECEIVED)
  {
    /* more data received from client and previous data has been already sent*/
    if(es->p == NULL)
    {
      es->p = p;
 
      /* send back received data */
      tcp_echoserver_send(tpcb, es);
    }
    else
    {
      struct pbuf *ptr;
 
      /* chain pbufs to the end of what we recv'ed previously  */
      ptr = es->p;
      pbuf_chain(ptr,p);
    }
    ret_err = ERR_OK;
  }
  else if(es->state == ES_CLOSING)
  {
    /* odd case, remote side closing twice, trash data */
    tcp_recved(tpcb, p->tot_len);
    es->p = NULL;
    pbuf_free(p);
    ret_err = ERR_OK;
  }
  else
  {
    /* unkown es->state, trash data  */
    tcp_recved(tpcb, p->tot_len);
    es->p = NULL;
    pbuf_free(p);
    ret_err = ERR_OK;
  }
  return ret_err;
}

If anyone knows why its that happening please answare this question, 🙏 :revolving_hearts:

Thanks in advance.

1 REPLY 1
TPham.17
Associate

could you share whole your project or setting STN32CUBEMX? I try follow your guide but it work like your show above.