A mutex in FreeRTOS supports priority inheritance to prevent priority inversion, which is not supported by binary semaphores. This is the key conceptual difference.
SemaphoreHandle_t xSemaphore;
void Task1(void *pvParameters) {
if(xSemaphoreTake(xSemaphore, 0) == pdTRUE) {
printf("Semaphore taken by Task1\n");
} else {
printf("Task1 failed to take semaphore\n");
}
vTaskDelete(NULL);
}
void Task2(void *pvParameters) {
xSemaphoreGive(xSemaphore);
vTaskDelete(NULL);
}
int main() {
xSemaphore = xSemaphoreCreateBinary();
xTaskCreate(Task1, "Task1", 1000, NULL, 1, NULL);
xTaskCreate(Task2, "Task2", 1000, NULL, 1, NULL);
vTaskStartScheduler();
return 0;
}Task1 is created first and, with the same priority as Task2, runs first when the scheduler starts. A newly created binary semaphore has an initial count of 0 (unavailable), so the non-blocking xSemaphoreTake() fails and prints 'Task1 failed to take semaphore'. Task2 then runs and calls xSemaphoreGive().
SemaphoreHandle_t xMutex;
void TaskA(void *pvParameters) {
xSemaphoreTake(xMutex, portMAX_DELAY);
// Do some work
xSemaphoreTake(xMutex, portMAX_DELAY); // Second take without give
// Do more work
xSemaphoreGive(xMutex);
xSemaphoreGive(xMutex);
vTaskDelete(NULL);
}
int main() {
xMutex = xSemaphoreCreateMutex();
xTaskCreate(TaskA, "TaskA", 1000, NULL, 1, NULL);
vTaskStartScheduler();
return 0;
}A mutex can only be taken once by the same task before it is given back. Taking it twice without giving causes the task to wait forever on the second take, causing deadlock.
The correct syntax calls the function with parentheses and no extra characters. Option C is correct.
Mutexes in FreeRTOS support priority inheritance, which helps prevent priority inversion. Binary semaphores do not provide this feature.
