cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with sending UDP using LwIP and STM32F4.

Adsa.1
Associate II

Hello everyone,

I have a small project of sending a serial messages to a remote device using Ethernet. I decided to use LwIP with Netconn API and FreeRTOS to divide the design into threads and send the data using Ethernet.

I made multiple threads and use it to receive the serial data, send it using UDP, adnd to receive UDP data, send it using serial. Its a two way communication. I am using a laptop to debug my design

the problem happens when i start sending serial data to the MCu. the data received correctly, added to the queue, then the ethernet thread read it from the queue and send it to the pc. When program reach the line where the data get send using ethernet the MCu froze and I have to reset it to work again.

The funny part is that, when i send a packet from my PC to the MCu it works fine and I can do the opposite (send serial to the MCu and it send it to the PC using ethernet) without the problem mentioned above to happen.

Similarly, when i send ping from the PC to the MCu the problem disappear.

The send/receive function/thread code:

void StartEthSendTask(void *argument)
{
  /* USER CODE BEGIN StartEthSendTask */
 
  struct netconn *conn;
    struct netbuf *sbuf = NULL, *rbuf = NULL;
    ip_addr_t dst_addr, src_addr;
    err_t bind_err, connection_err, receive_err, send_err;
    u16_t dst_port = DESTINATION_PORT_UDP, src_port = 65300;
 
    uint8_t qDataR[] = "";
    uint8_t qDataS[] = "";
    u16_t len = 0;
 
    /* set up the IP address of the local host */
    src_addr.addr = inet_addr("192.168.1.40");
    /* set up the IP address of the remote host */
    dst_addr.addr = inet_addr("192.168.1.200");
 
    LWIP_UNUSED_ARG(argument);
    conn = netconn_new(NETCONN_UDP);
 
    if (conn != NULL) {
      bind_err = netconn_bind(conn, &src_addr, src_port);
      //connection_err = netconn_connect(conn, &dst_addr, dst_port);
      if (bind_err == ERR_OK) {
        while (1) {
          if(osMessageQueueGet(ReceiveQueueHandle, (void *)&qDataS, NULL, 0) == osOK) {
            /* connect the connection to the remote host */
            connection_err = netconn_connect(conn, &dst_addr, dst_port);
            if (connection_err == ERR_OK) {
              /* create a new netbuf */
              sbuf = netbuf_new();
              /* point the buffer payload to the text */
              netbuf_ref(sbuf, &qDataS, 1);
              send_err = netconn_send(conn, sbuf);
              netbuf_delete(sbuf);
            } else {
              xSemaphoreTake(DebugMutexHandle, portMAX_DELAY);
              printf("Not able to connect to remote host\n");
              xSemaphoreGive(DebugMutexHandle);
            } // if (connection_err == ERR_OK)
          }
        } //while (1)
      } else {
        xSemaphoreTake(DebugMutexHandle, portMAX_DELAY);
        printf("Not able to bind source to new connection\n");
        xSemaphoreGive(DebugMutexHandle);
      } // if (bind_err == ERR_OK)
    } else {
      xSemaphoreTake(DebugMutexHandle, portMAX_DELAY);
      printf("Not able to establish new UDP connection\n");
      xSemaphoreGive(DebugMutexHandle);
    } //if (conn != NULL)
 
  /* USER CODE END StartEthSendTask */
}
void StartEthReceiveTask(void *argument)
{
  /* USER CODE BEGIN StartEthReceiveTask */
 
  struct netconn *conn;
  struct netbuf *sbuf = NULL, *rbuf = NULL;
  ip_addr_t dst_addr, src_addr;
  err_t bind_err, connection_err, receive_err, send_err;
  u16_t dst_port = DESTINATION_PORT_UDP, src_port = 65400;
 
  uint8_t qDataR[] = "";
  uint8_t qDataS[] = "";
  u16_t len = 0;
 
  /* set up the IP address of the local host */
  src_addr.addr = inet_addr("192.168.1.40");
  /* set up the IP address of the remote host */
  dst_addr.addr = inet_addr("192.168.1.200");
 
  LWIP_UNUSED_ARG(argument);
  conn = netconn_new(NETCONN_UDP);
 
  if (conn != NULL) {
    bind_err = netconn_bind(conn, &src_addr, src_port);
    //connection_err = netconn_connect(conn, &dst_addr, dst_port);
    if (bind_err == ERR_OK) {
      while (1) {
        connection_err = netconn_connect(conn, &dst_addr, dst_port);
        if (connection_err == ERR_OK) {
          receive_err = netconn_recv(conn, &rbuf);
          if (receive_err == ERR_OK) {
            netbuf_data(rbuf, (void *)&qDataR, &len);
            if(osMessageQueuePut(SendQueueHandle, (void *)&qDataR, 0, 0) != osOK) {
              xSemaphoreTake(DebugMutexHandle, portMAX_DELAY);
              printf("Queue is full\n");
              xSemaphoreGive(DebugMutexHandle);
            }
            netbuf_delete(rbuf);
          }
        }
      } //while (1)
    } else {
      xSemaphoreTake(DebugMutexHandle, portMAX_DELAY);
      printf("Not able to bind source to new connection\n");
      xSemaphoreGive(DebugMutexHandle);
    } // if (bind_err == ERR_OK)
  } else {
    xSemaphoreTake(DebugMutexHandle, portMAX_DELAY);
    printf("Not able to establish new UDP connection\n");
    xSemaphoreGive(DebugMutexHandle);
  } //if (conn != NULL)
 
  /* USER CODE END StartEthReceiveTask */
}

I hope the explanation is clear, and if there is anything not clear please let me know.

Thanks in advance.

4 REPLIES 4

Hello @Adsa.1​ 

Could you please provide the network traces( Wireshark / tcpdump)?

Thanks in advance.

BeST Regards,

Walid

Guillaume K
ST Employee
    uint8_t qDataR[] = "";
    uint8_t qDataS[] = "";

you set qDataR and qDataS to empty strings (just 1 byte : '\0' - empty string in C).

give them more space:

    uint8_t qDataR[100];
    uint8_t qDataS[100];

100 bytes is just an example (it depends from what your application does).

Hi @Walid ZRELLI​ 

I am not sure if i understood what you say? I only use Packet Sender software to test my code.

Hi @Guillaume K​ 

You are right but in the mean time they are not used. Also I tried with the 100 bytes and the same problem happens again