Can FreeRTOS_select() be used with TCP type sockets?

Hi I would like to know if the function FreeRTOSselect() can be used with TCP sockets? The example provided here: https://www.freertos.org/FreeRTOS-Plus/FreeRTOSPlusUDP/API/select.shtml creates the sockets as FREERTOSIPPROTO_UDP In other words is there anyway of having a non-blocking FreeRTOSrecv? Or a blocking FreeRTOSrecv for say 1 second? maybe using FreeRTOS_setsockopt()?

Can FreeRTOS_select() be used with TCP type sockets?

Sure you can use FreeRTOS_select() on TCP sockets as well. You were looking at old documentation of the UDP-only library. Here you find all TCP- and UDP-API calls.

Can FreeRTOS_select() be used with TCP type sockets?

In other words is there anyway of having a non-blocking FreeRTOSrecv? Or a blocking FreeRTOSrecv for say 1 second? maybe using FreeRTOS_setsockopt()?
Yes you can set the maximum time that FreeRTOS_recv() will wait by setting the socket option FREERTOS_SO_RCVTIMEO. There are three different possibilities to handle multiple socket within a single task:
Method 1) Semaphores
Method 2) Socket call-backs
Method 3) Use select
What you can do is call FreeRTOS_recv() and FreeRTOS_send() in a non-blocking way, and let the task block in a central place, either on a semaphore, or a task-notification, or a call to select().

Method 1) Semaphores

Give the task a semaphore and anyone can wake-up your task by giving to the semaphore ( xSemaphoreGive() or xSemaphoreGiveFromISR() ). The IP-task can also give to the semaphore if you bind a socket to that semaphore ( on reception of data, on TX space available, on disconnect etc. ) Define in FreeRTOSIPConfig.h: ~~~ #define ipconfigSOCKETHASUSER_SEMAPHORE 1 ~~~ and bind the semaphore to every socket owned by the task. There is a NTP-demo (Network Time Protocol) which uses a semaphore: ~~~ // Declare it static SemaphoreHandle_t xNTPWakeupSem = NULL;
// Create it
xNTPWakeupSem = xSemaphoreCreateBinary();

// Bind it
FreeRTOS_setsockopt(
    xUDPSocket,
    0,
    FREERTOS_SO_SET_SEMAPHORE,
    ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) );
~~~ This is a UDP socket, but it works the same for TCP sockets. The IP-task will give to the semaphore for any relevant event:
  • Data has arrived
  • Data has been sent and TX space is available ( TCP-only )
  • A connection is established ( either accept() or connect() )
  • A connection is broken ( or an error occurred )
~~~ for( ;; ) { // Sleep for 10 seconds xSemaphoreTake( xNTPWakeupSem, pdMSTOTICKS( 10000ul ) );
    /* Check sockets and messages in a non-blocking way. */
}
~~~

Method 2) Socket call-backs

Define ipconfigUSE_CALLBACKS as 1 in FreeRTOSIPConfig.h Now you can bind call-back ( application hooks ) to each of the sockets: ~~~ FREERTOSSOTCPCONNHANDLER ( 6 ) /* Install a callback for (dis) connection events. / FREERTOS_SO_TCP_RECV_HANDLER ( 7 ) / Install a callback for receiving TCP data. / FREERTOS_SO_TCP_SENT_HANDLER ( 8 ) / Install a callback for sending TCP data. */ FREERTOSSOUDPRECVHANDLER ( 9 ) /* Install a callback for receiving UDP data. / FREERTOS_SO_UDP_SENT_HANDLER ( 10 ) / Install a callback for sending UDP data. */ ~~~ Define a handler, e.g. on-tcp-receive ~~~ BaseTypet xOnTcpReceive( Sockett xSocket, void * pData, size_t xLength ) { xSemaphoreGive( myTaskSemaphore ); // or xTaskNotifyGive( myTaskHandle );
    return 0; // KEEP the packet, it will be stored in the RX buffer of the socket
              // FreeRTOS_recv() must be called later-on
    // or
    return 1; // DISCARD the packet, it will not be stored
}

F_TCP_UDP_Handler_t handler;
handler.pxOnTcpReceive = xOnTcpReceive;
FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_RECV_HANDLER,
    ( void * ) &handler, sizeof( handler ) );
~~~ Call-backs ( Application Hooks ) are always error-prone: it looks like user code, but in fact the code is run ( called ) from the IP-task. Thus most +TCP API’s can not be called from within the call-back.

Method 3) Use select

Define ipconfigSUPPORT_SELECT_FUNCTION as 1 in your FreeRTOSIPConfig.h And now you can use the select() functions. Here you find documentation. Using select() is less flexible: you can only wake-up the task if you can access the sockets. You could use: ~~~ #define ipconfigSUPPORT_SIGNALS 1 ~~~ and interrupt a select() buy calling : ~~~ FreeRTOS_SignalSocket() ~~~ Most compatible is 3) select(), while 2) semaphore is by far the easiest. The FTP/HTTP demo servers use a single task. It blocks in a call to select(). It can handle an unlimited number of FTP- or HTTP-clients, only limited by the amount of available RAM.

Can FreeRTOS_select() be used with TCP type sockets?

wow 🙂 thank you for the juicy info.

Can FreeRTOS_select() be used with TCP type sockets?

When using sockets and after the semaphore has been given how could I find out the reason for the Give? I’m interested in these 3: A connection is established ( either accept() or connect() ) A connection is broken ( or an error occurred ) Data has arrived