How can I find out if another task is currently blocked waiting for my binary semaphore?

Yes, you are correct, the test task that was calling readRegs had rather low priority whereas my UART-task has high priority. So that’s probably why the RTOS decided to execute the UART-task instead of letting the test task get the semaphore and continue.

You just believe it is working…

Consider the sequence

if (masterInitiatedAccessIsPending())
{
< do something>
}

there will be race conditions where the predicate will not be true anymore when you execute the “do something”, contradicting the assumption.

This is the kind of thing that conditional critical sections were made for, but even those may cause you more trouble.

I still believe your architecture is fundamentally broken, and if you try to stick with the approach, you will never get it to work robustly (sorry, 30+ years of developing serial protocols leave their trace), but it’s your code, and if you are happy with it, that’s all that counts

If the value of the numTasksTryingToTakeThisMutex changes 1 picosecond after I evaluate it it’s really not that big of a deal, the master-initiated access simply has to wait for the slave-initiated access to finish first instead of being serviced immediately. The line has to be drawn somewhere and in this example the call to readRegs inside the master happened 1 picosecond too late.

As long as you don’t publish your entire code, it is guesswork, but if, for example, your “do something” clause allows the caller access to the UART registers, you may end up with two tasks attempting to access the peripheral unsynchronized and overlapped, ending up with exactly what you do not want.

But whatever, you appear to know what you are doing, so there’s nothing to add from my side here. Good luck.

Which is why I specifically qualified it with the task taking needed to be of at least the priority of the task seeing if it should relinquish.

General rule is the highest priority task wanting something should get. it, so by that rule if the current task (the UARTtask) has higher priority then the test task, the test task shouldn’t get the resource until the UART task actually decides it is done with the resource. The case you seem to be describing indicates a priority definition problem.

You could do a vTaskDelay(1) instead of a vTaskYield to give other tasks an opportunity, but that WILL delay the UART task even if no one else wants the semaphore.

I will repeat my advice, that seems to be echoed by others, you need to think what you actually want to do, and solve that problem, rather than trying to solve the problem you created by a wrong attempt to do that.

There seems to be a need for a higher level control over who is using the serial port.