Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by elgroves on February 18, 2015

I've ported FreeRTOS 8.1.2 to the TI TM4C1294NCPDT. I've configured FreeRTOS+TCP labs (141019) and written an interface driver for the TM4C part.

I'm writing an HTTP server that has a thread listening for inbound TCP connections. Once the connection is received, the new socket will be passed to a thread pool via a queue and handled there. My problem is that the FreeRTOS_accept call doesn't wake up the thread. I can see in Wire Shark that the TCP stack takes the connection (SYN, ACK, HTTP request), but the handling thread is never woken up to handle it, so it just remains connected until some other event closes the socket.

If I configure the listening socket w/ a non-zero FREERTOSSORCVTIMEO, the accept call returns. If no connection was found, I retry. If a connection is found, I pass it along and it is handled correctly, data flows, and all is well. But I'd prefer the accept call wake up my thread when a connection is received to reduce both latency and un-needed cycles. Is this not supported in the current version of FreeRTOS+TCP?

I am very ready to acknowledge that I may have mis-configured FreeRTOS or FreeRTOS+TCP.

My connection accepting thread:

~~~~~~ void httpserver(void * params) { static const TickTypet xReceiveTimeOut = 1000 / portTICKRATEMS; // portMAX_DELAY;

xSocket_t client_socket;
struct freertos_sockaddr bindAddress;
struct freertos_sockaddr clientAddress;

socklen_t size = sizeof(clientAddress);

(void) params;

server.listen_socket = FreeRTOS_socket(FREERTOS_AF_INET,
		FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);

configASSERT(server.listen_socket != FREERTOS_INVALID_SOCKET);

FreeRTOS_setsockopt(server.listen_socket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof(xReceiveTimeOut));

bindAddress.sin_port = (uint16_t) server.settings.listen_port;
bindAddress.sin_port = FreeRTOS_htons(bindAddress.sin_port);

FreeRTOS_bind(server.listen_socket, &bindAddress, sizeof(bindAddress));

FreeRTOS_listen(server.listen_socket, 20);

for (;;)
{

	client_socket = FreeRTOS_accept(server.listen_socket, &clientAddress, &size);

	if (client_socket == FREERTOS_INVALID_SOCKET
			|| client_socket == NULL)
	{
		continue;
	}

	xQueueSendToBack(server.rx_sockets_queue, &client_socket, 1000 /portTICK_PERIOD_MS); //portMAX_DELAY);
}

} ~~~~~~

Thanks for any help!


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by rtel on February 18, 2015

[we actually have a simple http server - it should have been released by now - but we have been busy :o) ]

Did you see the example implemented by the SimpleTCPEchoServer.c file in the download? I think that is doing something similar to what you want, albeit with a different protocol (echo rather than HTTP). The part that is equivalent looks like this:

<!-- HTML generated using hilite.me -->

static void prvConnectionListeningTask( void *pvParameters )
{
struct freertossockaddr xClient, xBindAddress;
xSockett xListeningSocket, xConnectedSocket;
socklent xSize = sizeof( xClient );
static const TickTypet xReceiveTimeOut = portMAXDELAY;
const BaseTypet xBacklog = 20;
xWinProperties_t xWinProps;

/* Just to prevent compiler warnings. */ ( void ) pvParameters;

/* Attempt to open the socket. */ xListeningSocket = FreeRTOSsocket( FREERTOSAFINET, FREERTOSSOCKSTREAM, FREERTOSIPPROTO_TCP );

configASSERT( xListeningSocket != FREERTOSINVALIDSOCKET );

/* Set a time out so accept() will just wait for a connection. */ FreeRTOSsetsockopt( xListeningSocket, 0, FREERTOSSO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );

/* Fill in the buffer and window sizes that will be used by the socket. / xWinProps.lTxBufSize = 6 ipconfigTCPMSS; xWinProps.lTxWinSize = 3; xWinProps.lRxBufSize = 6 * ipconfigTCPMSS; xWinProps.lRxWinSize = 3;

/* Set the window and buffer sizes. / FreeRTOSsetsockopt( xListeningSocket, 0, FREERTOSSOWINPROPERTIES, ( void ) &xWinProps, sizeof( xWinProps ) );

/* Bind the socket to the port that the client task will send to, then listen for incoming connections. */ xBindAddress.sinport = tcpechoPORTNUMBER; xBindAddress.sinport = FreeRTOShtons( xBindAddress.sinport ); FreeRTOSbind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); FreeRTOS_listen( xListeningSocket, xBacklog );

/* Create the clients that will connect to the listening socket. */ prvCreateWindowsThreadClients();

for( ;; ) { /* Wait for a client to connect. */ xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );

configASSERT( xConnectedSocket <span style="color: #333333">!=</span> FREERTOS_INVALID_SOCKET );

<span style="color: #888888">/* Spawn a task to handle the connection. */</span>
xTaskCreate( prvServerConnectionInstance, 
      <span style="background-color: #fff0f0">&quot;EchoServer&quot;</span>, 
      usUsedStackSize, 
      ( <span style="color: #333399; font-weight: bold">void</span> <span style="color: #333333">*</span> ) xConnectedSocket, 
      tskIDLE_PRIORITY, 
      <span style="color: #007020">NULL</span> );

} }

Basically it should work. If that does not help I will defer to our TCP expert.

Regards.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by rtel on February 18, 2015

By the way please ensure to post your work (just the FreeRTOS+TCP part if the rest is confidential) to the FreeRTOS Interactive site when you are happy it is working.

Regards.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by elgroves on February 18, 2015

Thanks for getting back to me so quickly!

I did see a note that an HTTP server was in the works, but I didn't want to wait to find out what support it included. I'm developing a flexible server that can serve static resources from internal memory (.html, .css, .js, etc.), and process get/post/put/delete requests in CGI handlers as well.

I referenced the example in SimpleTCPEchoServer.c quite a bit when I was writing the connection listener. I don't see a material difference from my implementation up to the accept call, other than the Windowing options. I've since included the missing parts in the code and I am still seeing the same behavior: connection accepted by the server, data sent by the client, no response from the server, the listening thread is never woken.

I'd be glad to contribute some of my code! What precisely do I need to post, and what can I keep confidential? I'd like to keep my server code confidential until it's a bit more completed.

Thanks again!


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by heinbali01 on February 20, 2015

Hi,

What precisely do I need to post, and what can I keep confidential?

What you could share is the interfacing between the hardware drivers and +TCP. Normally this code would be put in a file like:

FreeRTOS-Plus-TCP/portable/NetworkInterface/TM4C1294/NetworkInterface.c

I tried-out you http_server() code but it does work properly:

~~~~~ static void httphandler( void * params ) { xSockett xSocket = NULL; for (;;) { clearWdt ();

    if( ( xSocket != FREERTOS_INVALID_SOCKET ) && ( xSocket != NULL ) )
    {
    char buffer[80];
        BaseType_t rc = FreeRTOS_recv( xSocket, buffer, sizeof buffer, 0 );
        if (rc != 0)
            printf("recv %ld bytes\n", rc);
        if (rc < 0) {
            FreeRTOS_closesocket( xSocket );
            xSocket = NULL;
        }
    }
    else if( xQueueReceive( server.rx_sockets_queue, (void *)&xSocket, 1000 ) )
    {
        printf("recv socket\n");
    }
}

} ~~~~~

When a connection closes, the logging shows recv -128 bytes which is the error:

~~~~~ #define FREERTOSERRNOENOTCONN 128 /* Socket is not connected */ ~~~~~

Please note that all settings done with FreeRTOS_setsockopt() will be inherited by the child-sockets. That includes all timings and buffer sizes.

In some cases a connection may have a very short life, like 25 ms to receive 50 KB. The handling task may wake-up after the connection has gone. The data can still be read though.

If your still find the above problem, please drop an email to Richard (see FreeRTOS' main page). We'll send you the latest release of +TCP.

Regards.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by hmf55 on March 5, 2015

Hi, I've got the simmilar if not the same problem. "FreeRTOS_accept" never commes back, also WireShark shows no outgoing messages nor any ACKs.

I've implementented the zero copy EDMAC for the RX63N. I think its running as far as I could send and receive UDP packets.

My code looks like the one above, except that "prvCreateWindowsThreadClients();"

Is this the missing link? Where could I get/find it?

BTW: I'm also eager for a webserver. At the moment I've planned to rewrite the A.Dunkels-Code to get rid of those magic PT macros.

Tanks.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by heinbali01 on March 5, 2015

Regarding: FreeRTOS_accept doesn't work:

When you bind() the socket to a port, are all values in network byte-order, like in:

~~~~~ /* sinaddr is not yet use, keep it zero for now. */ bindAddress.sinaddr = 0ul; /* If '80' is your server port... */ bindAddress.sinport = FreeRTOShtons( 80 ); FreeRTOS_bind(pxServerSocket, &bindAddress, sizeof(bindAddress)); ~~~~~

Is the IP-task running fine?

Did you give some reasonable value to the socket options FREERTOS_SO_RCVTIMEO and FREERTOS_SO_SNDTIMEO ? Or else, did you set:

#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME  ( 10000 )
#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME     ( 10000 )

or any other value?

Can you set a break in the code? Like here for instance:

~~~~~ static void prvIPTask( void *pvParameters ) { case eNetworkRxEvent: prvHandleEthernetPacket( ( xNetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ) ); break; ~~~~~

Can you assert that there are always enough Network Buffers available? Does pvPortMalloc() ever return NULL?

Edit: How much is enough? I would say always at least 3 or 4 Network Buffer.

Regards.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by ewnert on October 19, 2015

I now this thread is a bit old but it is the only one I have found addressing this problem.

I had the exact same problem as described in the first post. The TCP connection is made and I can see in WireShark that SYN and ACK is transmitted and received.

After hours of investigating I tried increasing the value of ipconfigEVENT_QUEUE_LENGTH and all of a sudden it started working. I assume that the queue was full so the connection event did not reach the FreeRTOS_accept().

I had the constant ipconfigEVENT_QUEUE_LENGTH set to ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 which is the recommended minimum value. I increased it to ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 20 and FreeRTOS_accept() started working.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by heinbali01 on October 20, 2015

Hi Carl,

thanks for letting this know.

'xNetworkEventQueue' is the Queue that hold the messages for the IP-task. It should never run out of space.

Some NetworkInterface.c files already had the following check in their MAC task:

~~~~~ { uxCurrentCount = uxGetMinimumFreeNetworkBuffers(); if( uxLastMinBufferCount != uxCurrentCount ) { /* The logging produced below may be helpful while tuning +TCP: see how many buffers are in use. */ uxLastMinBufferCount = uxCurrentCount; FreeRTOS_printf( ( "Network buffers: %lu lowest %lun", uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) ); } } ~~~~~

It would be good to monitor the space in the 'xNetworkEventQueue' as well.

Without changing anything to FreeRTOS_IP.c you can define this macro in your 'FreeRTOSIPConfig.h':

~~~~~ extern UBaseTypet uxQueueMinimumSpace; #define iptraceNETWORKEVENTRECEIVED( EventType ) { if( xReceivedEvent.eEventType != eNoEvent ) { UBaseTypet uxCount; uxCount = uxQueueSpacesAvailable( xNetworkEventQueue ); if( uxQueueMinimumSpace > uxCount ) { uxQueueMinimumSpace = uxCount; } } } ~~~~~

Declare and initialise it as follows:

~~~~~ /* Define and initialise 'uxQueueMinimumSpace' */ UBaseTypet uxQueueMinimumSpace = ipconfigEVENTQUEUE_LENGTH; ~~~~~

and finally add some logging:

~~~~~ if( uxLastLowCount != uxQueueMinimumSpace ) { uxLastLowCount = uxQueueMinimumSpace; FreeRTOS_printf( ( "Lowest queue space: %lun", uxLastLowCount ) ); } ~~~~~

Regards.


FreeRTOS+TCP labs - FreeRTOS_accept not waking up thread on connect.

Posted by elgroves on October 28, 2015

Hein, I'd like to thank you for your support and also to apologize for not participating more in this conversation. The project ended up being pre-empted, and I have just been able to get back to it after having lost all of my source code. I'm having different issues while re-implementing the Network Interface driver, but I won't attempt to address them here.

Thanks again for your hard work.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS