Counting semaphore - my wrong application

yevpator75 wrote on Tuesday, January 22, 2019:

Hi,

I believe I am improperly using the counting sempahore which is the reason for the problem I am facing now,

I implemented a circular queue by myself and have 8 instances of such a queue, which are 2 queues per each of 4 tasks. 8 = 2 x 4.

I wanted every task to wake up once a new message from other tasks arives at any of its 2 queues. It checks then each of these 2 queues according to predefined priority , pulls a new message and starts processing it.

I assigned a counting sempahore to each of these 4 tasks (4 semaphores). Every time a new message arrives at any of the 2 queues I thought to “give” the semaphore with xSemaphoreGive, which in fact increments it, and in each of these 4 tasks I intended to block with xSemaphoreTake until the semaphore count increases .

My problem is when the count of the semaphore is 0, xSemaphoreTake returns with 0 and then I get configASSERT(0). I get it actually immediately after initialization, because the initial semaphore value is 0.

The question is whether my application is wrong or using of semaphore is not applicable here?

Thanks!

rtel wrote on Tuesday, January 22, 2019:

Can you please show the code where you are blocking on the semaphore.

rtel wrote on Tuesday, January 22, 2019:

As an aside…another alternative is to just use a single queue and no
semaphores. If the data held in the queue says what the data is and/or
where it came from, in addition to whatever the value of the data is,
then often a single queue is all that is needed. See the 'Alternatives
to using queue sets" section on this page:
https://www.freertos.org/Pend-on-multiple-rtos-objects.html

yevpator75 wrote on Wednesday, January 23, 2019:

Thank you Richard,

I get a real data of a variable size from an upper layer of some protocol. The data can be very small or big. If I use the FreeRTOS queue to puch there the datga of the maximal size, it will be not efficient, since in the most cases the data length is short. If I queue only the pointer , I still need some queue to be implemented by myself according to my specific requirements. I did that and looked only for a means to wakeup the pending task.
Becausue the counting semaphore didn’t work for me , finally I did use the queue. While for now it is not principal for me if the waking up method is counting semaphore or queue, I thought queue is indeed a better option for me baring a certain feature in mind. I still will answer you other question since I am learning now and it is important for me to understand the stuff.

Just currious whether you see a merit in some new features for FreeRTOS, like a queue with variable size. I don’t know if other RTOS do provide something like that, will check that later.

Best regards,
Eli

rtel wrote on Wednesday, January 23, 2019:

Just currious whether you see a merit in some new features for FreeRTOS,
like a queue with variable size. I don’t know if other RTOS do provide
something like that, will check that later.

FreeRTOS Message buffers allow variable size data to be [effectively]
queued, but only in single sender single receiver scenarios.

yevpator75 wrote on Wednesday, January 23, 2019:

Sure.

static void * gp_countSemUartTxSom1Handle;
gp_countSemUartTxSom1Handle = xSemaphoreCreateCounting (10,0); 

“Upper Protocol Layer”, which is a task , which wants to pass a data to one of the mentioned 4 tasks, adds it to my circular queue and then gives the semaphore (increase the counter):

res = xSemaphoreGive (gp_countSemUartTxSom1Handle);

Each of the 4 tasks pends on its own counting semaphore

task1
{
    for()
    {
        uint32_t sem = xSemaphoreTake (gp_countSemUartTxSom1Handle, SEM_NO_TIMEOUT);
        configASSERT (pdPASS == sem);
        // proces the new data
        }
}

In the beginning , before the sempahore is “given”, xSemaphoreTake returns 0 and the following configASSERT fails. I wanted to wakeup only when the semaphore count is higher than 0.

What is wrong here?

yevpator75 wrote on Wednesday, January 23, 2019:

Yes, I saw this kernel object. I thought about Message buffer , but as an item inside a queue. Again, I am not sure if this is something that makes sense to be included in RTOS.