Depending on use case Mutex’s, Binary Semaphores, Counting Semaphores or Queues can be used. Useful FreeRTOS documentation on Mutex/ Semaphores and Queues.
Mutex
A Mutex (hence ‘MUT’ual ‘EX’clusion) is an object that blocks resources from being used more than once at the time. It is basically a binary Semaphore including priority inheritance and a Mutex can only be given back by the task that took the Mutex. This prevents concurrency problems like mentioned above. Typically, the Mutex is being taken before, and given back after accessing a critical resource.
Important freeRTOS commands are: xSemaphoreCreateMutex(), xSemaphoreTake() and xSemaphoreGive().
If called from ISR it is important to use xSemaphoreTakeFromISR() and xSemaphoreGiveFromISR().
Binary Semaphore
A Binary Semaphore is a Queue with length of one. It is of no interest which Data is stored in the Queue - only whether Data is received. Unlike a Mutex it has no priority inheritance and can also be given back by other Tasks. Therefore, they are used for something different - Task synchronization.
Producer-Consumer example:
Important freeRTOS commands are: xSemaphoreCreateBinary(), xSemaphoreTake() and xSemaphoreGive().
If called from ISR it is important to use xSemaphoreTakeFromISR() and xSemaphoreGiveFromISR().
Counting Semaphore
A Counting Semaphore is just as a Binary Semaphore but with length greater than one. It is of no interest which Data is stored in the Queue - only whether Data is received. Counting Semaphores are used for Counting Events and Resource Management.
Important freeRTOS commands are: xSemaphoreCreateCounting(), xSemaphoreTake() and xSemaphoreGive().
If called from ISR it is important to use xSemaphoreTakeFromISR() and xSemaphoreGiveFromISR().
Queue
Queues are the primary form of intertask communications. They can be used to send messages between tasks, and between interrupts and tasks. In most cases they are used as thread safe FIFO (First In First Out) buffers with new data being sent to the back of the queue, although data can also be sent to the front.
Important freeRTOS commands are: xQueueCreate(), xQueueSend() and xQueueReceive().
If called from ISR it is important to use xQueueReceiveFromISR() and xQueueSendFromISR().