heinbali01 wrote on Friday, August 14, 2015:
Hi Zdenek,
There are many ways to reach your goal.
Here are some ideas for FreeRTOS+TCP :
-
One way is to use two separate tasks, one for sending and one for receiving. But you probably want to do both things from within a single task?
-
Use FreeRTOS_select() to wait for RX, TX and Error events on a set of sockets.
#define ipconfigSUPPORT_SELECT_FUNCTION 1
This method will need a small hack: make a new function:
BaseType_t FreeRTOS_SelectAbort( SocketSet_t xSocketSet );
which can be called from any other task.
A possible implementation would be:
BaseType_t FreeRTOS_SelectAbort( SocketSet_t xSocketSet )
{
SocketSelect_t *pxSocketSet = ( SocketSelect_t * ) xSocketSet;
xEventGroupSetBits( pxSocketSet->xSelectGroup, eSELECT_EXCEPT );
}
-
Here is yet another way, define in FreeRTOSIPConfig.h
:
#define ipconfigSOCKET_HAS_USER_SEMAPHORE ( 1 )
Your task must create a semaphore and in stead of calling FreeRTOS_recv() in a blocking way, your task will block on the semaphore. You can use any value for time-out (maximum blocking time).
After creating a socket, advertise your semaphore:
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
FreeRTOS_setsockopt( xMySocket, 0, FREERTOS_SO_SET_SEMAPHORE,
( void * ) &( xSemaphore ), sizeof( TickType_t ) );
#endif
Please note the ampersand in &( xSemaphore )
: setsockopt() wants to receive a pointer to the value.
Now you can do the following, with either Select() or using a Semaphore:
BaseType_t xMustSendMessage = 0;
void vMyTask( void *pvParameters )
{
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
SemaphoreHandle_t xSemaphore;
xSemaphore = xSemaphoreCreateBinary();
#elif( ipconfigSUPPORT_SELECT_FUNCTION != 0 )
SocketSet_t xSocketSet;
xSocketSet = FreeRTOS_CreateSocketSet();
#endif
for( ;; )
{
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 5000ul );
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
{
xSemaphoreTake( xSemaphore, ulMaxBlockTime );
}
#elif( ipconfigSUPPORT_SELECT_FUNCTION != 0 )
{
FreeRTOS_select( xSocketSet, ulMaxBlockTime )
}
#endif
lRc = FreeRTOS_recv( xMySocket, pcBuffer,
sizeof pcBuffer, FREERTOS_MSG_DONTWAIT );
if( lRc > 0 )
{
/* Data received */
}
else if( lRc < 0 )
{
/* Connection error, probably -pdFREERTOS_ERRNO_ENOTCONN
or -pdFREERTOS_ERRNO_ENOMEM. */
}
if( xMustSendMessage != pdFALSE )
{
xMustSendMessage = pdFALSE;
/* xSemaphoreTake was aborted because we must send
a message. */
}
}
}
Got the idea?
The above is not a polling solution: the task may sleep/block as long as it wants.
Regards.