lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [lwip-users] Unable to allocate TCP_SEG


From: Josh Rothstein
Subject: RE: [lwip-users] Unable to allocate TCP_SEG
Date: Wed, 16 Jan 2008 17:20:48 -0800

One more behavioral thing I noticed:

 

If I do lwip_send() and watch the debug output I will see the TCP header information showing the stack received an ack for that packet.   If I do a couple more lwip_send(), I will eventually stop seeing the TCP header information and the tcp_enqueue() will begin to fill with TCP_SEGs.  I if then close() the socket all the pending receives will then come through the debug output. How can I stop this bottleneck?

 

Any suggestions?

 


From: address@hidden [mailto:address@hidden On Behalf Of Josh Rothstein
Sent: Wednesday, January 16, 2008 12:57 PM
To: 'Mailing list for lwIP users'
Cc: 'Campanella, David'; 'John'
Subject: RE: [lwip-users] Unable to allocate TCP_SEG

 

I have done some more debugging and it looks like tcp_enqueue cannot allocate memory for another TCP_SEG because acks are not getting received by tcp_receive(), who would in turn would free the pool for MEMP_TCP_SEG.

 

Further examination shows that the problem lies within tcpip.c. For some reason tcpip_input() fails when trying to memp_malloc(MEMP_TCPIP_MSG). This occurs before tcp_enqueue() fills the MEMP_TCP_SEG pool. tcpip_thread() does call memp_free(MEMP_TCPIP_MSG, msg) at the end of the loop, so I am at a loss as to why the MEMP_TCPIP_MSG pool fills up.

 

Any suggestions?

 

 

 


From: address@hidden [mailto:address@hidden On Behalf Of Josh Rothstein
Sent: Tuesday, January 15, 2008 5:35 PM
To: address@hidden
Cc: 'John'
Subject: [lwip-users] Unable to allocate TCP_SEG

 

In order to learn how to properly use LwIP in conjunction with FreeRTOS, I am trying to write a simple Telnet client on an Atmel AVR32 Demo Board.  Disregarding the reset button, there are three tactile buttons on the board. I have enabled the first button to open a connection to the development PC, the second button to transmit a character string, and the third button to close the connection. I have included the code for my Telnet task at the bottom of the email; formatting is a little funny due to pasting into MS Outlook.

 

For some reason after, a certain amount of transmissions (about 9 or 10) my tcp/ip stack is unable to allocate memory for the next transmission and the entire stack locks up.  The error occurs in the LwIP Raw API implementation in lwip/core/tcp_out.c within the function tcp_enqueue().  I have pasted the area below where the stack is unable to allocated memory. 

 

err_t

tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,

  u8_t flags, u8_t copy,

  u8_t *optdata, u8_t optlen)

{

……

……

……

……

    /* Allocate memory for tcp_seg, and fill in fields. */

    seg = memp_malloc(MEMP_TCP_SEG);

    if (seg == NULL) {

      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for                  tcp_seg\n"));

      goto memerr;

    }

……

……

……

……

            return ERR_OK;

}

 

memp_malloc() allocates memory from a predefined memory pool. It seems that the TCP/IP stack is not properly freeing memory from the pool after successful transmissions.  I am able to tweak the lwipopts.h file to allow for more successful transmissions but eventually the stack always uses up the pool. Oddly, I have noticed that if I quickly and repeatedly press my transmit button, I can send endless amounts of data without any stack lockup.  If I transmit with approximately 1 or more seconds between transmissions the memory pool runs dry after 9 or 10 presses.

 

I have attached a log of the debug output from lwip as well as a Wireshark log from the Host.  The Host (windows PC) is 192.168.0.10 and the lwip stack sits on 192.168.0.2.

 

 

portTASK_FUNCTION( vBasicTELNETClient, pvParameters )

{

   t_ButtonStatus xData;

   struct sockaddr_in xSockAddr;

  

   portSHORT sErrorEverOccurred = pdFALSE;

   portLONG l_socketFD = 0;

   Bool bConnectionOpen = FALSE;

 

   pxButtonQueueParameters = ( xBlockingQueueParameters * ) pvParameters;

  

   b_pushb1_init(); /* configures GPIO and interrupts */

   b_pushb2_init(); /* configures GPIO and interrupts */

   b_pushb3_init(); /* configures GPIO and interrupts */

  

   memset(&xSockAddr, 0, sizeof(xSockAddr));

   xSockAddr.sin_family = AF_INET;

   xSockAddr.sin_len = sizeof(xSockAddr);

   xSockAddr.sin_port = htons(23);

   xSockAddr.sin_addr.s_addr = inet_addr("192.168.0.10");

 

      for( ;; )

      {    

if( xQueueReceive( pxButtonQueueParameters->xQueue, &xData, pxButtonQueueParameters->xBlockTime ) == pdPASS )

            {

                  /* We have successfully received a message, so increment the

                  variable used to check we are still running and process queue. */

                  if( sErrorEverOccurred == pdFALSE )

                  {                     

            if ( xData.xStates.uc_pushb1 == PUSHB_EVENT_PRESS && !bConnectionOpen )

            {

               l_socketFD = lwip_socket(PF_INET, SOCK_STREAM, 0);                        

               if (lwip_connect(l_socketFD, (struct sockaddr*) &xSockAddr, sizeof(xSockAddr)) >= 0)

                  bConnectionOpen = TRUE;                 

            }

            if ( xData.xStates.uc_pushb2 == PUSHB_EVENT_PRESS && bConnectionOpen)

            {             

                  if ( lwip_send(l_socketFD, (void *) MSG_HELLO, 20, 0) < 0 )

                     lwip_close(l_socketFD);                  

            }

            if ( xData.xStates.uc_pushb3 == PUSHB_EVENT_PRESS && bConnectionOpen)

            {

                  lwip_shutdown(l_socketFD, 2);

                  lwip_close(l_socketFD);

                  bConnectionOpen = FALSE;

            }                      

         }             

            }          

      }    

}

 

Any suggestions would be greatly appreciated.

Thanks,

 

Josh


reply via email to

[Prev in Thread] Current Thread [Next in Thread]