Value returned by xQueueReceive()

Hi,

This is a silly comment only for updating the official documentation. While xQueueSend() returns errQUEUE_FULL if the queue was full, the function xQueueReceive() returns pdFALSE:

Returns:
pdTRUE if an item was successfully received from the queue, otherwise pdFALSE.

From projdefs.h we can see that:

#define pdPASS                                   ( pdTRUE )
#define pdFAIL                                   ( pdFALSE )
#define errQUEUE_EMPTY                           ( ( BaseType_t ) 0 )
#define errQUEUE_FULL                            ( ( BaseType_t ) 0 )

Yes, errQUEUE_EMPTY and errQUEUE_FULL have the same value. My point is to be consistent all along the code: while in some places one tests against errQUEUE_FULL, in others one tests against pdFALSE. That’s weird and inconsistent.

Any reason to use pdFALSE instead of errQUEUE_EMPTY. A workaround is to test always against pdTRUE and all problems are gone.

Greetings!

I think the idea is that for a xQueueReceive() you could check for a ‘generic’ failure with pdFAIL, or check for the type of error that would actual occur with errQUEUE_EMPTY to document what the error was. And for a send, the actual error would be errQUEUE_FULL

Hi,

What do you mean for “generic failure” on reading from a queue? That scares me! A queue is empty or it’s not, that’ all (I think).

Is this the list of errors you’re refering to that the Queue module throws when reading from a queue?:

/* FreeRTOS error definitions. */
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY    ( -1 )
#define errQUEUE_BLOCKED                         ( -4 )
#define errQUEUE_YIELD                           ( -5 )

None of them seems to be related for the reading operation.

Greetings!

Hi Xavier,

If you see that, both defines using for error detection, in this case, if you want to receive something from queue, but it’s EMPTY you can’t get any of data → so it’s error (0).
If you want to write into the queue and it’s full, it’s FULL so you can’t write any data → so it’s error (0).

There is no sense to know queue is full when you want to read, because it’s can’t cause any of errors.
If you want to get number of items, you could use functions like: uxQueueMessagesWaiting().
Regards.

you could also pass an invalid queue handle into xQueueReceive(), that might qualify as a “generic failure?”…

I mean detecting an error without implying the type (which will only be the queue was empty/full).

You can read and test for ‘any error’ or you can read and test if you got a ‘queue empty’ error. They both are the same error code as that is the only error there is.

Yes, I already know that. My point here is TO BE CONSISTENT! For Richard Barry the naming is very important (although the prefix ‘x’ is meaningless in so many situations). If I test against errQUEUE_FULL when using xQueueSend(), then it would be logical to test against errQUEUE_EMPTY when using xQueueReceive(), THAT’S CONSISTENCY!

@RAc wrote:

Following this line of thought we must also test against pdFALSE in the xQueueSend() instead of errQUEUE_FULL.

I think this question might clarify my point: Why don’t you use pdFALSE instead of errQUEUE_FULL in xQueueSend()?

Hi,

What is the error code when you pass the wrong handler?

if( xQueueReceive( handler, &data, ( TickType_t ) 10 ) == pdFALSE)
{
   // Are we here for a timeout or for something else?
   // How do you know what is that "something else"?
}
else
{
   // process the incoming data
}

Greetings!

Nasal Demon, aka Undefined Behavior. They will check for 0 if configASSERT is defined at trap on that, other random values are unpredictable.

Yes, consistancy would be to use pdFAIL everywhere or errQUEUE_FULL / errQUEUE_EMPTY. My guess is that the documentation is old (but still accurate) and some has been updated to more current practices.

Personally, I just use if(xQueueReceive(…)) { …

1 Like

Hi,

That question of my own was following this comment:

You can’t set the same value to different errors; an empty queue is one thing, and passing the wrong handler is other thing, so you can’t use the value 0 for both. That’s what I wanted to point out. By the way the wrong handler former can’t be catched by configAssert() if the handler is assigned to a very different object (like a semaphore or timer) but it’s not NULL.

Greetings!

That is what I was talking about!. We can even use the values 0 and 1 instead of the symbolic constants, but it would be a bad programming practice.

Greetings!

I regularly use that fact that these function return a ‘truthy’ value on success and a ‘falsey’ value on failure, so I can just do:

if(xQueueReceive(…)) {
// Do something with item received.
}

Actually, I tend to use wrappers defined to return a bool.