Hi @richard-damon,
As I mentioned, and that was commented too here years ago, uxQueueSpacesAvailable()
fails:
while( uxQueueSpacesAvailable( g_queue_handler ) > 0 ){ // <-- Program gets stucked here
// program never comes here:
if( xQueueSend( g_queue_handler, (void*) &data, pdMS_TO_TICKS( 100 ) ) == pdFALSE ) {
Serial.print( "TO(W): " );
}
data += 10;
vTaskDelay( pdMS_TO_TICKS( 10 ) );
// I simulate a delay on filling the queue
}
The system gets stucked in uxQueueSpacesAvailable()
. I’ll very happy if you (and @RAc) point me out to the problem with this line of code:
while( uxQueueSpacesAvailable( g_queue_handler ) > 0 ){ // <-- Program gets stuck here
And for that matter, in this code too:
while( uxQueueMessagesWaiting( g_queue_handler ) > 0 ){ // <-- Program gets stucked here too
There are so many real cases, many of them fitting this next scenario: there’s a task that receives serial streams from a serial channel using some protocol. Such task decodes the streams and sends the COMPLETE payload (or at least a known number of items) to a second task using a queue. That second task needs the whole payload before to proceed, so the decoder task MUST fill a queue with the data.
Every other way of determining whether the queue is full/empty suffers from the same race condition problem. I’ve been told (by @RAc) to use the xQueuePeek() function to query the queue emptyness; however, an item might arrive from when the program asks the question and when the program processes an (not longer anymore) empty queue.
Why haven’t you add a simple yes/no functions at task level to query whether a queue is full/empty given the race conditions will be always present in concurrent programs?
You won’t add such functions to FreeRTOS because of me, that’s clear, so let me rephrase the question: How would you fill a queue before it’s processed by a second task, and how this second task processes the queue item by item until it is empty once it’s full?
Thank you!