UDP and TCP concurrent operation causing fault

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

UDP and TCP concurrent operation causing fault

Applebee, Robert

My application is built with LWIP 1.4.1 running on a TI MCU and uses raw TCP and raw UDP calls, no RTOS.

 

The TCP is used to send commands to the hardware and is always acknowledged with an “ACK” message.

 

The UDP is used to send sensor data to the client every 10ms.

 

I can send messages and receive “ACK” without error and I can enable the UDP output without error but when I combine TCP and UDP my application will eventually generate a hardware fault.  Looking at the stack it seems to be in the “plug_holes” function.

 

I am a first time user of LWIP.  Any assistance would be appreciated.

 

This is my main loop that outputs the UDP:

 

    // allocate pbuf for UDP

    p=pbuf_alloc(PBUF_TRANSPORT, 32, PBUF_RAM);

 

    //

    // Loop forever, processing the LED blinking.  All the work is done in

    // interrupt handlers.

    //

    while(1)

    {

        // get latest input

        change = updateUdpPacket(udpOut);

 

        /* can't send UDP untill TCP connected */

        if (clientIpAddr.addr != 0) {

            // send UPD if data delay expires or input changed state

            if (change || g_100usTick == 0) {

                // only output UDP if data delay is enabled (-1 is disabled)

                if (data_stream_delay_ms >= 0) {

                    if (p) {

                        // Toggle the red LED.

                        MAP_GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_5,

                                         (MAP_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_5) ^

                                          GPIO_PIN_5));

 

                        sprintf(p->payload, "%s %04X %s\n", VM.PodId, g_usSeq, udpOut);

 

                        // increment the UDP number

                        g_usSeq++;

 

                        // send the UDP message

                        udp_sendto(UDPpcb, p, &clientIpAddr, UDP_PORT);

                    }

                }

 

                // reset the data delay counter

                VM.DataStreamDelay = data_stream_delay_ms;  // convert to float

                g_100usTick = VM.DataStreamDelay / 0.1;     // set data delay counter to 100us ticks

            }

        }

   }

 

This is my TCP receive callback:

 

err_t TCPrecv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)

{

  err_t ret_err;

  u16_t len;

  int cmdDone = false;

 

  if (p != NULL && err == ERR_OK)

  {

      /* process pcb */

      cmdDone = ProcessData(p->payload, p->len, tcpOut);

 

      // cleanup receive window and pcb

      tcp_recved(tpcb, p->len);

      pbuf_free(p);

  }

  //

  // If a null packet is passed in, close the connection.

  //

  else if((err == ERR_OK) && (p == NULL))

  {

      //

      // Clear out all of the TCP callbacks.

      //

      TCPclose(tpcb);

  }

  else

  {

      ret_err = err;

  }

 

  if (cmdDone) {

      len = strlen(tcpOut);

 

      // write the response (tcp_output not needed when tcp_write called from receive callback)

      ret_err = tcp_write(tpcb, tcpOut, len, 1);

      if (ret_err)

         len = 0;

  }

  return ret_err;

}

 

Regards,

 

Robert Applebee

Software Project Engineer

Astronics Test Systems Inc.,

4 Goodyear

Irvine, California 92618 USA

O: +1.949.460.6795

E: [hidden email]

www.astronicstestsystems.com

 


This E-mail is confidential. It may also be legally privileged. If you are not the addressee you may not copy, forward, disclose or use any part of it. If you have received this message in error, please delete it and all copies from your system and notify the sender immediately by return E-mail.

Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions.


_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: UDP and TCP concurrent operation causing fault

Sylvain Rochet
Hi,

On Thu, Nov 15, 2018 at 05:59:58PM +0000, Applebee, Robert wrote:
>
> My application is built with LWIP 1.4.1 running on a TI MCU and uses
> raw TCP and raw UDP calls, no RTOS.

lwIP 1.4.1 was released 6 years ago…


> This is my main loop that outputs the UDP:
>
>     // allocate pbuf for UDP
>     p=pbuf_alloc(PBUF_TRANSPORT, 32, PBUF_RAM);
>
>     //
>     // Loop forever, processing the LED blinking.  All the work is done in
>     // interrupt handlers.

This doesn't seem right, are you sure you are not violating lwIP
threading/contexts requirements ?

http://www.nongnu.org/lwip/2_1_x/pitfalls.html

RAW API (udp_*, tcp_*, netif_*, …) is not thread nor IRQ safe!!!


>     while(1)
>     {

Where are you calling lwIP timeouts in this loop ?


Sylvain

_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users

signature.asc (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: UDP and TCP concurrent operation causing fault

Patrick Klos-2
In reply to this post by Applebee, Robert
On 11/15/2018 12:59 PM, Applebee, Robert wrote:

My application is built with LWIP 1.4.1 running on a TI MCU and uses raw TCP and raw UDP calls, no RTOS.

 

The TCP is used to send commands to the hardware and is always acknowledged with an “ACK” message.

 

The UDP is used to send sensor data to the client every 10ms.


FWIW, I have been using LwIP 1.4.1 for over 5 years on a TI Tiva platform with both TCP and UDP without any trouble.

I can send messages and receive “ACK” without error and I can enable the UDP output without error but when I combine TCP and UDP my application will eventually generate a hardware fault.  Looking at the stack it seems to be in the “plug_holes” function.

 

I am a first time user of LWIP.  Any assistance would be appreciated.

 

This is my main loop that outputs the UDP:

 

    // allocate pbuf for UDP

    p=pbuf_alloc(PBUF_TRANSPORT, 32, PBUF_RAM);

 

    //

    // Loop forever, processing the LED blinking.  All the work is done in

    // interrupt handlers.

    //

    while(1)

    {

        // get latest input

        change = updateUdpPacket(udpOut);

 

        /* can't send UDP untill TCP connected */

        if (clientIpAddr.addr != 0) {

            // send UPD if data delay expires or input changed state

            if (change || g_100usTick == 0) {

                // only output UDP if data delay is enabled (-1 is disabled)

                if (data_stream_delay_ms >= 0) {

                    if (p) {

                        // Toggle the red LED.

                        MAP_GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_5,

                                         (MAP_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_5) ^

                                          GPIO_PIN_5));

 

                        sprintf(p->payload, "%s %04X %s\n", VM.PodId, g_usSeq, udpOut);

 

                        // increment the UDP number

                        g_usSeq++;

 

                        // send the UDP message

                        udp_sendto(UDPpcb, p, &clientIpAddr, UDP_PORT);

                    }

                }

 

                // reset the data delay counter

                VM.DataStreamDelay = data_stream_delay_ms;  // convert to float

                g_100usTick = VM.DataStreamDelay / 0.1;     // set data delay counter to 100us ticks

            }

        }

   }


How "stripped down" is this sample from your actual code? 

From the looks of it, you're only ever allocating a single pbuf, then constantly reusing it?  If the stack hasn't completed the previous UDP send by the time you try to use it again, that could break things?

Patrick Klos
Klos Technologies, Inc.


_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users