I am trying to understand the Queue Sets, in particular how xQueueSelectFromSet and xQueueReceive work. Consider the following code, in which the main creates a queue, one sender task and two receiver tasks. The queue is added to a queue set. vReceiverTask1 uses xQueueSelectFromSet and then xQueueReceive to read data from queue while vReceiverTask2 directly reads from queue.
Can vReceiverTask2 create problem for vReceiverTask1 while it reads data from queue?
My actual DOUBT is noted in the code below for vReceiverTask1.
/* The queue is added to a queue set. */
static QueueHandle_t xQueue = NULL;
/* This is the queue set to which the queue is added. */
static QueueSetHandle_t xQueueSet = NULL;
int main( void )
{
/* Create the queue, which send character pointers.
The priority of the sending task is more than the priority of the receiving task. */
xQueue = xQueueCreate( 1, sizeof( char * ) );
/* Create the queue set. The queue will be added to the set. */
xQueueSet = xQueueCreateSet( 1 );
/* Add the queue to the set. */
xQueueAddToSet( xQueue, xQueueSet );
/* Create the task that send to the queue. */
xTaskCreate( vSenderTask, "Sender", 1000, NULL, 2, NULL );
/* Create the tasks that read from the queue set and the queue directly. */
xTaskCreate( vReceiverTask1, "Receiver1", 1000, NULL, 1, NULL );
xTaskCreate( vReceiverTask2, "Receiver2", 1000, NULL, 1, NULL );
/* Start the scheduler so the created tasks start executing. */
vTaskStartScheduler();
for( ;; );
return 0;
}
/
———————————————————–/
void vSenderTask( void *pvParameters )
{
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
const char * const pcMessage = “Message from vSenderTaskrn”;
for( ;; )
{
/* Send this task's string to xQueue. */
xQueueSend( xQueue, &pcMessage, 5 );
/* Block for 20ms. */
vTaskDelay( xBlockTime );
}
}
/
———————————————————–/
void vReceiverTask1( void
pvParameters )
/ The task that reads using the queue set */
{
const TickType_t xBlockTime = pdMS_TO_TICKS( 10 );
QueueHandle_t xQueueThatContainsData;
char *pcReceivedString;
for( ;; )
{
/* DOUBT: Does a call to xQueueSelectFromSet guarantee availability of data in the returned queue xQueueThatContainsData? */
xQueueThatContainsData = ( QueueHandle_t ) xQueueSelectFromSet(xQueueSet, portMAX_DELAY );
/* DOUBT: If a task switch occurs to vReceiverTask2 task here, */
/* how the following xQueueReceive read the expected data? */
xQueueReceive( xQueueThatContainsData, &pcReceivedString, xBlockTime );
/* Process the string received from the queue. */
/* Block for 10ms. */
vTaskDelay( xBlockTime );
}
}
void vReceiverTask2( void
pvParameters )
/ The task that reads directly from the queue */
{
const TickType_t xBlockTime = pdMS_TO_TICKS( 10 );
char *pcReceivedString;
for( ;; )
{
xQueueReceive( xQueue, &pcReceivedString, xBlockTime );
/* Process the string received from the queue. */
/* Block for 10ms. */
vTaskDelay( xBlockTime );
}
}
I found the following Note in the documentation.
“Do not read data from a queue or semaphore that is a member of a set unless the handle of the queue or semaphore has first been returned from a call to xQueueSelectFromSet().”
Does this mean the onus is on the developer that she has to read from a queue, which belongs to a queue set, only after getting the handle from xQueueSelectFromSet?
Thanks.