Number of waiting elements in a queue set not the same as sum of waiting elements from members

embgangsta wrote on Monday, November 02, 2015:

Hi,

I am facing a complex issue to debug around queueset usage.

My queueset is made of 2 queues Q1 and Q2 which are filled in different contexts

I respected the queueset construction by setting a size for whole queueset which is the sum of the elements for each Q1 and Q2.

Q1 is filled using xQueueSend in two different tasks T1, T2 and T3.
Q2 is filled using xQueueSendFromISR in always the same interrupt source

I am using T1 to make decisions based on Q1/Q2 data coming into. T1 is the only task waiting for events from Q1/Q2 using the queueset.

When I am waiting for the queueset to unblock from Q1 or Q2 from T1 task, I am using xQueueSelectFromSet function with an portMAX_DELAY tick delay generally.

Then once I get the member result from function, I consume Q1 or Q2 data using xQueueReceive function with 0 delay.

As stated above, T1 can sometimes sends data inside Q1, but Q1 can also be filled from anoter T2 or T3 task as well.

In 99% of the time, the handle of my mecanism is working fine, HOWEVER I found a weird issue : I am loosing an event in Q1 and the sum of waiting messages from Q1 + Q2 is not the same as waiting messages in queueset !!

How can it be possible ??

Maybe I am doing something wrong, please advice.

Regards
David

rtel wrote on Monday, November 02, 2015:

Which version of FreeRTOS are you using? I know there was a version that had an issue sending to a queue set from an interrupt - although it was some time ago. If you tell me the version number I can look it up for you.

As an aside, do you really need to use a queue set? Normally I would only use them when integrating third party code, in situations when I have no control over what is sent to a queue.

If you do have control over what is sent to a queue then normally you can use a single queue, and send structures to the queue. The first member of the structure can say how the reader of the data should interpret the rest of the structure.

For example, you could define a structure:

typedef MY_STRUCT
{
enum eType_t eType;
void *pvData;
} myStruct_t;

Then when T1 sends to the queue it sends a myStruct_t structure to the queue with the enumerated type eType set to, for example, “eTemperature”, and pvData set to an integer that represents the temperature. When T1 writes to the queue it could, for example, set eType to eBluetoothPacket, and set pvData to point to the data.

Then the receiving task reads a myStruct_t from the queue, inspects the eType member, after which it knows how what pvData is, and how to interpret it.

embgangsta wrote on Tuesday, November 03, 2015:

Hi,

I am using v7.5.2 FreeRTOS version.

Actually I am using a queueset because I am mixing data queue with cmd queue, but as you said I could indeed use one queue with enums to tell if it’s data or cmd …

However I would be interested to understand how my issue could occur.

Regards

rtel wrote on Tuesday, November 03, 2015:

Search for “queue sets” on the following page:
http://www.freertos.org/History.txt

embgangsta wrote on Monday, November 23, 2015:

Hi,

Actually I just figured out what was my issue !

I am doing a “wrong” usage of queueset : for at least one occurence, I am NOT consuming one of the Q1 / Q2 queues whereas I am executing the call of xQueueSelectFromSet function.

As a result, the OS in xQueueGenericReceive will decrement number of pending messages from queueset Q whereas there are still events in one of my Q1 or Q2 queues … So at some time, I am able to recover from situation because another task is posting a command in Q1 or Q2 hence the xQueueSelectFromSet give me a handler to Q1 or Q2 to read …

So definitely, the xQueueSelectFromSet function CANNOT be executed alone without consuming data from queues just after if result is not null … !!!

rtel wrote on Monday, November 23, 2015:

That’s right - thanks for getting back with the answer.

embgangsta wrote on Wednesday, December 02, 2015:

Hi again,

I have a concern again about Qset usage.

In the FreeRTOS API documentation page, it’s written in the xQueueCreateSet() help that “An additional 4 bytes of RAM are required for each space in every queue added to a queue set. Therefore a counting semaphore that has a high maximum count value should not be added to a queue set.”

Is it automatically handled by OS at queue addition to queue set ?
OR
Do I need to extend queue size when queue is created with xQueueCreate ?

Please advice

rtel wrote on Wednesday, December 02, 2015:

It needs to be done manually.

embgangsta wrote on Wednesday, December 02, 2015:

Could you tell me how ?

rtel wrote on Wednesday, December 02, 2015:

If you have the following three items in a queue set:

  1. A queue that can hold 3 elements.
  2. A binary semaphore.
  3. A counting semaphore that has a maximum count of 10.

Then to be 100% sure of correct operation in all cases the queue set
needs to be created with 3 (the queue) + 1 (the binary semaphore) + 10
(the counting semaphore) = 14 spaces.

Of course, in practical cases this may not need to be the case. For
example, if the task that was reading from the queue set was the highest
priority task in the system, then it would execute immediately that
anything was placed in the queue set, so the queue set would never
actually contain more than one or two items anyway.

embgangsta wrote on Wednesday, December 02, 2015:

Thanks.

I understand the point you mention about Qset size, but I was talking about the argument “An additional 4 bytes of RAM are required for each space in every queue added to a queue set”

Please advice

rtel wrote on Wednesday, December 02, 2015:

I think that is referring to the fact that you need to have space in the
queue set (each of which is four bytes) for each possible count in the
counting semaphore (as per the calculation in my previous example),
therefore you should avoid using counting semaphores with a high maximum
count value.

embgangsta wrote on Wednesday, December 02, 2015:

Thanks for confirmation.

I thought it was on queue itself, not the queueset.