Help on proper usage of semaphores

billnoyes wrote on Monday, September 10, 2018:

I am using FreeRTOS 8.0.1 an on Atmel SAMD21 (ASF 3.31.0) and have a problem with a Counting Semaphore TAKE (with 500ms timeout) never returning due to some priority issue.

I am using several UARTS and pass packets between them (think traffic cop) as needed. The UART driver performs a GiveFrom ISR when an end of packet is detected. Each UART has its own task that does a semaphore take (500ms timeout) and processes the packets or does maintenance based on if data is present or not. Some tasks are at a higher priority than others to manage things according to importance and other resources. The IRQ semaphores are counting semaphores, so that multiple packets can build up in the queue.

Once a task has a packet to handle, they TAKE a binary semaphore (indefinate) to gain rights to a shared block of ‘working RAM’ to read the data, process it, build return packets, whatever. The TASK that has the buffer may need access to another hardware port or device (binary semaphore protected) and we perform another TAKE (indefinate) to guard access before continuing.

I see no blocking instances or priority inversions in the code, but at some point one of the tasks hangs on a semaphoreTAKE(500ms) and never returns. I initially used MUTEXs, but saw a note that it did not deal with a task holding more than one MUTEX at a time. I switched back to all BINARY semaphores (except for the IRQ events). Maybe this same issue applies to BINARY semaphores.

Increasing the priority of the thread seems to resolve the problem, but I fear it is just moving it somewhere else.

Can multiple semaphores be held by a task?

rtel wrote on Monday, September 10, 2018:

Yes, multiple semaphores can be held by a task. It might be more
confused when using a mutex due to the priority inheritance - although
that functionality has been enhanced in recent versions of FreeRTOS -
the one you are using is quite old. Can you update to the latest
(V10.1.1) and ensure configASSERT() is defined? That may help you - the
newer the code the more assert points there are.

billnoyes wrote on Monday, September 10, 2018:

Thanks for the quick response.

waveringradiant wrote on Monday, September 10, 2018:

Bill - any time I hear “task hangs” and (paraphrasing) “I’m acquiring 2 mutexes (binary semaphores)” - one thing comes to mind: deadlock. 2 tasks, each waiting on something that the other has.

Essentially, if you have (at least) 2 tasks in a preemptive system, each trying to acquire 2 mutexes, but in different order, deadlock can occur due to a race condition.

From your description it’s not at all clear that it really is deadlock, but just in case, I thought I’d mention it.