Bird
Raised Fist0
FreeRTOSprogramming~20 mins

Mutex vs binary semaphore difference in FreeRTOS - Practice Questions

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
FreeRTOS Synchronization Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
2:00remaining
Key difference between Mutex and Binary Semaphore
In FreeRTOS, what is the main conceptual difference between a mutex and a binary semaphore?
AA binary semaphore automatically deletes itself after use, but a mutex must be manually deleted.
BA binary semaphore can only be used for mutual exclusion, but a mutex can be used for signaling.
CA mutex can be given from an interrupt context, but a binary semaphore cannot.
DA mutex includes priority inheritance to avoid priority inversion, while a binary semaphore does not.
Attempts:
2 left
💡 Hint
Think about how FreeRTOS handles priority inversion with these synchronization tools.
❓ Predict Output
intermediate
2:00remaining
Output of binary semaphore usage in FreeRTOS
What will be the output of this FreeRTOS code snippet using a binary semaphore?
FreeRTOS
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;
}
ATask1 failed to take semaphore
BSemaphore taken by Task1
CNo output because scheduler never starts
DRuntime error due to double creation of semaphore
Attempts:
2 left
💡 Hint
Consider the order of task execution and semaphore give/take calls.
🔧 Debug
advanced
2:00remaining
Why does this mutex cause a deadlock?
Examine the following FreeRTOS code using a mutex. Why does it cause a deadlock?
FreeRTOS
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;
}
AThe task tries to take the mutex twice without giving it back, causing a deadlock.
BThe mutex is created incorrectly and is NULL, causing a deadlock.
CThe task deletes itself before giving the mutex, causing a deadlock.
DThe mutex is given twice without being taken, causing a deadlock.
Attempts:
2 left
💡 Hint
Think about how mutex ownership works in FreeRTOS.
📝 Syntax
advanced
2:00remaining
Identify the syntax error in binary semaphore creation
Which option contains the correct syntax to create a binary semaphore in FreeRTOS?
ASemaphoreHandle_t sem = xSemaphoreCreateBinary[]();
BSemaphoreHandle_t sem = xSemaphoreCreateBinary;
CSemaphoreHandle_t sem = xSemaphoreCreateBinary();
DSemaphoreHandle_t sem = xSemaphoreCreateBinary();;
Attempts:
2 left
💡 Hint
Remember how functions are called in C.
🚀 Application
expert
3:00remaining
Choosing synchronization for priority inversion prevention
You have two FreeRTOS tasks: a high priority task and a low priority task. The low priority task accesses a shared resource. To prevent priority inversion, which synchronization primitive should you use?
AUse a binary semaphore to guard the shared resource.
BUse a mutex to guard the shared resource.
CUse a counting semaphore to guard the shared resource.
DUse no synchronization primitive; just disable interrupts.
Attempts:
2 left
💡 Hint
Consider which primitive supports priority inheritance.

Practice

(1/5)
1. Which of the following best describes the main difference between a mutex and a binary semaphore in FreeRTOS?
easy
A. Binary semaphores have ownership; mutexes do not.
B. Mutexes have ownership and priority inheritance; binary semaphores do not.
C. Mutexes are used only for signaling; binary semaphores are for exclusive access.
D. There is no difference; both behave exactly the same.

Solution

  1. Step 1: Understand ownership concept

    Mutexes have ownership, meaning the task that locks it must unlock it. Binary semaphores do not have ownership.
  2. Step 2: Understand priority inheritance

    Mutexes support priority inheritance to avoid priority inversion; binary semaphores do not.
  3. Final Answer:

    Mutexes have ownership and priority inheritance; binary semaphores do not. -> Option B
  4. Quick Check:

    Ownership + priority inheritance = Mutex [OK]
Hint: Mutex = ownership + priority; binary semaphore = simple flag [OK]
Common Mistakes:
  • Thinking binary semaphores have ownership
  • Confusing signaling role of binary semaphores
  • Assuming mutexes do not support priority inheritance
2. Which of the following is the correct way to create a mutex in FreeRTOS?
easy
A. xSemaphoreCreateMutex()
B. xQueueCreateMutex()
C. xSemaphoreCreateBinary()
D. xMutexCreateSemaphore()

Solution

  1. Step 1: Recall FreeRTOS API for mutex creation

    The function to create a mutex is xSemaphoreCreateMutex().
  2. Step 2: Verify other options

    xSemaphoreCreateBinary() creates a binary semaphore, not a mutex. The other options are invalid API calls.
  3. Final Answer:

    xSemaphoreCreateMutex() -> Option A
  4. Quick Check:

    Mutex creation function = xSemaphoreCreateMutex() [OK]
Hint: Mutex creation always uses xSemaphoreCreateMutex() [OK]
Common Mistakes:
  • Using xSemaphoreCreateBinary() for mutex
  • Confusing queue creation functions with mutex
  • Inventing non-existent API functions
3. Consider the following FreeRTOS code snippet:
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();
if (xSemaphoreTake(xMutex, 0) == pdTRUE) {
    // Critical section
    xSemaphoreGive(xMutex);
    printf("Mutex taken and released\n");
} else {
    printf("Failed to take mutex\n");
}
What will be the output when this code runs?
medium
A. Mutex taken and released
B. Failed to take mutex
C. Compilation error
D. No output

Solution

  1. Step 1: Analyze mutex creation and take

    The mutex is created successfully. The call to xSemaphoreTake with zero block time tries to take the mutex immediately. Since it is free, it succeeds.
  2. Step 2: Check critical section and release

    The mutex is given back with xSemaphoreGive, and the message "Mutex taken and released" is printed.
  3. Final Answer:

    Mutex taken and released -> Option A
  4. Quick Check:

    Mutex free at start, take succeeds, prints message [OK]
Hint: Mutex initially free, immediate take succeeds [OK]
Common Mistakes:
  • Assuming take fails with zero block time
  • Confusing mutex with binary semaphore behavior
  • Expecting compilation errors from correct API usage
4. Identify the error in the following FreeRTOS code using a binary semaphore:
SemaphoreHandle_t xBinarySemaphore = xSemaphoreCreateBinary();
xSemaphoreGive(xBinarySemaphore);
if (xSemaphoreTake(xBinarySemaphore, portMAX_DELAY) == pdTRUE) {
    // Critical section
    xSemaphoreGive(xBinarySemaphore);
    xSemaphoreGive(xBinarySemaphore);
}
medium
A. Semaphore handle is not initialized.
B. Taking the semaphore with portMAX_DELAY is invalid.
C. Binary semaphore must be created with xSemaphoreCreateMutex().
D. Giving the semaphore twice causes incorrect behavior.

Solution

  1. Step 1: Understand binary semaphore usage

    Binary semaphores act like flags with max count 1. Giving twice without taking in between can cause logic errors.
  2. Step 2: Analyze the code's semaphore give calls

    The code gives the semaphore twice without an intervening take, which can lead to unexpected behavior or overflow.
  3. Final Answer:

    Giving the semaphore twice causes incorrect behavior. -> Option D
  4. Quick Check:

    Binary semaphore max count = 1, double give is wrong [OK]
Hint: Binary semaphore max count 1, don't give twice without take [OK]
Common Mistakes:
  • Thinking portMAX_DELAY is invalid
  • Confusing binary semaphore with mutex creation
  • Ignoring semaphore initialization
5. You have two tasks: Task A (high priority) and Task B (low priority). Both need exclusive access to a shared resource. Which synchronization method should you use to avoid priority inversion and why? A) Use a mutex because it supports priority inheritance. B) Use a binary semaphore because it is simpler. C) Use a counting semaphore to allow multiple accesses. D) Use no synchronization to improve performance.
hard
A. Use a counting semaphore to allow multiple accesses.
B. Use a binary semaphore because it is simpler.
C. Use a mutex because it supports priority inheritance.
D. Use no synchronization to improve performance.

Solution

  1. Step 1: Identify need for exclusive access with priority handling

    Both tasks need exclusive access, so synchronization is required. Priority inversion can occur if a low priority task holds the resource.
  2. Step 2: Choose synchronization with priority inheritance

    Mutexes provide priority inheritance, temporarily boosting the low priority task's priority to avoid blocking the high priority task.
  3. Final Answer:

    Use a mutex because it supports priority inheritance. -> Option C
  4. Quick Check:

    Priority inversion avoidance = mutex [OK]
Hint: Use mutex for priority inheritance and exclusive access [OK]
Common Mistakes:
  • Choosing binary semaphore ignoring priority inversion
  • Using counting semaphore for exclusive access
  • Skipping synchronization to save time
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard