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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Josh Rothstein Sent: Tuesday, January 15, 2008 5:35 PM To: [email protected] 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
_______________________________________________ lwip-users mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/lwip-users
