Detailed Description

There is a lot of confusion about differences between semaphores and mutexes, so, it's quite recommended to read small article by Michael Barr: Mutexes and Semaphores Demystified.

Very short:

While mutex is seemingly similar to a semaphore with maximum count of 1 (the so-called binary semaphore), their usage is very different: the purpose of mutex is to protect shared resource. A locked mutex is "owned" by the task that locked it, and only the same task may unlock it. This ownership allows to implement algorithms to prevent priority inversion. So, mutex is a locking mechanism.

Semaphore, on the other hand, is signaling mechanism. It's quite legal and encouraged for semaphore to be waited for in the task A, and then signaled from task B or even from ISR. It may be used in situations like "producer
and consumer", etc.

If current semaphore counter (count) is less than max_count, counter is incremented by one, and first task (if any) that waits for the semaphore becomes runnable with TN_RC_OK returned from tn_sem_wait().

if semaphore counter is already has its max value, no action performed and TN_RC_OVERFLOW is returned

If the current semaphore counter (count) is non-zero, it is decremented and TN_RC_OK is returned. Otherwise, behavior depends on timeout value: task might switch to WAIT state until someone signaled the semaphore or until the timeout expired. refer to TN_Timeout.