Bird
Raised Fist0
FreeRTOSprogramming~20 mins

Binary semaphore creation and usage in FreeRTOS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
FreeRTOS Binary Semaphore Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this FreeRTOS binary semaphore code?

Consider the following FreeRTOS code snippet that creates a binary semaphore and attempts to take it without giving it first. What will be the output?

FreeRTOS
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include <stdio.h>

SemaphoreHandle_t xSemaphore;

void vTaskFunction(void *pvParameters) {
    if (xSemaphoreTake(xSemaphore, (TickType_t)10) == pdTRUE) {
        printf("Semaphore taken successfully\n");
    } else {
        printf("Failed to take semaphore\n");
    }
    vTaskDelete(NULL);
}

int main(void) {
    xSemaphore = xSemaphoreCreateBinary();
    if (xSemaphore == NULL) {
        printf("Failed to create semaphore\n");
        return 1;
    }
    xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}
AFailed to take semaphore
BSemaphore taken successfully
CFailed to create semaphore
DProgram hangs indefinitely
Attempts:
2 left
💡 Hint

Think about the initial state of a binary semaphore created with xSemaphoreCreateBinary() and whether it is given before taking.

❓ Predict Output
intermediate
2:00remaining
What happens when a binary semaphore is given twice without taking?

Given this FreeRTOS code snippet, what will be the output?

FreeRTOS
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include <stdio.h>

SemaphoreHandle_t xSemaphore;

void vTaskFunction(void *pvParameters) {
    if (xSemaphoreTake(xSemaphore, (TickType_t)10) == pdTRUE) {
        printf("Semaphore taken successfully\n");
    } else {
        printf("Failed to take semaphore\n");
    }
    vTaskDelete(NULL);
}

int main(void) {
    xSemaphore = xSemaphoreCreateBinary();
    if (xSemaphore == NULL) {
        printf("Failed to create semaphore\n");
        return 1;
    }
    xSemaphoreGive(xSemaphore);
    xSemaphoreGive(xSemaphore);
    xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}
ASemaphore taken successfully
BFailed to take semaphore
CSemaphore count is 2
DProgram crashes
Attempts:
2 left
💡 Hint

Remember that binary semaphores can only be 'given' once before they must be 'taken'. What happens if you give twice?

🔧 Debug
advanced
2:00remaining
Why does this FreeRTOS binary semaphore code cause a deadlock?

Examine the code below. The task waits indefinitely on the semaphore, but the semaphore is never given. What is the cause of this deadlock?

FreeRTOS
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include <stdio.h>

SemaphoreHandle_t xSemaphore;

void vTaskFunction(void *pvParameters) {
    if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
        printf("Semaphore taken\n");
    }
    vTaskDelete(NULL);
}

int main(void) {
    xSemaphore = xSemaphoreCreateBinary();
    if (xSemaphore == NULL) {
        printf("Failed to create semaphore\n");
        return 1;
    }
    xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}
ASemaphoreTake timeout is too short
BSemaphore was created incorrectly and is NULL
CTask priority is too low to run
DSemaphore is never given, so task waits forever
Attempts:
2 left
💡 Hint

Check if the semaphore is ever given in the code.

📝 Syntax
advanced
2:00remaining
Which option correctly creates and gives a binary semaphore in FreeRTOS?

Choose the code snippet that correctly creates a binary semaphore and gives it so that a task can take it.

ASemaphoreHandle_t sem = xSemaphoreCreateMutex(); xSemaphoreGive(sem);
BSemaphoreHandle_t sem = xSemaphoreCreateBinary(); xSemaphoreTake(sem, 0);
CSemaphoreHandle_t sem = xSemaphoreCreateBinary(); xSemaphoreGive(sem);
DSemaphoreHandle_t sem = xSemaphoreCreateCounting(1, 1); xSemaphoreGive(sem);
Attempts:
2 left
💡 Hint

Remember the function to create a binary semaphore and how to make it available initially.

🚀 Application
expert
2:00remaining
How many times can a FreeRTOS binary semaphore be given before a take?

In FreeRTOS, if you create a binary semaphore and call xSemaphoreGive() multiple times before any xSemaphoreTake(), how many times will the semaphore count increase?

AAs many times as you call give; it counts each give
BOnly once; subsequent gives have no effect until taken
CZero times; binary semaphore cannot be given manually
DTwice; binary semaphore allows two counts before take
Attempts:
2 left
💡 Hint

Think about the nature of binary semaphores and their maximum count.

Practice

(1/5)
1. What is the primary purpose of a binary semaphore in FreeRTOS?
easy
A. To store multiple values for task communication
B. To signal and control access to shared resources between tasks
C. To create multiple tasks automatically
D. To allocate memory dynamically

Solution

  1. Step 1: Understand the role of binary semaphores

    Binary semaphores are used to signal availability or control access to resources between tasks.
  2. Step 2: Compare options with this role

    Only To signal and control access to shared resources between tasks describes signaling and controlling access, which matches the purpose of binary semaphores.
  3. Final Answer:

    To signal and control access to shared resources between tasks -> Option B
  4. Quick Check:

    Binary semaphore = resource signaling [OK]
Hint: Binary semaphore controls resource access between tasks [OK]
Common Mistakes:
  • Confusing binary semaphore with counting semaphore
  • Thinking it stores multiple values
  • Assuming it creates tasks
2. Which of the following is the correct way to create a binary semaphore in FreeRTOS?
easy
A. xSemaphoreCreateBinary();
B. xSemaphoreCreateCounting(1, 0);
C. xSemaphoreCreateMutex();
D. xSemaphoreCreateBinary(1);

Solution

  1. Step 1: Recall the function to create a binary semaphore

    The correct function is xSemaphoreCreateBinary() with no parameters.
  2. Step 2: Check each option

    xSemaphoreCreateBinary(); matches the correct function. xSemaphoreCreateCounting(1, 0); creates a counting semaphore, C creates a mutex, and D is invalid syntax.
  3. Final Answer:

    xSemaphoreCreateBinary(); -> Option A
  4. Quick Check:

    Create binary semaphore = xSemaphoreCreateBinary() [OK]
Hint: Use xSemaphoreCreateBinary() with no arguments [OK]
Common Mistakes:
  • Using counting semaphore creation instead
  • Adding parameters to xSemaphoreCreateBinary()
  • Confusing mutex creation with binary semaphore
3. Consider the following FreeRTOS code snippet:
SemaphoreHandle_t xBinarySemaphore = xSemaphoreCreateBinary();

void Task1(void *pvParameters) {
    if (xSemaphoreTake(xBinarySemaphore, portMAX_DELAY) == pdTRUE) {
        // Critical section
    }
}

void Task2(void *pvParameters) {
    xSemaphoreGive(xBinarySemaphore);
}
What will happen when Task1 runs before Task2?
medium
A. Task1 will enter the critical section immediately
B. Task1 will skip the critical section
C. Task1 will cause a runtime error
D. Task1 will block indefinitely until Task2 gives the semaphore

Solution

  1. Step 1: Analyze xSemaphoreTake with portMAX_DELAY

    Task1 calls xSemaphoreTake with portMAX_DELAY, so it waits indefinitely for the semaphore.
  2. Step 2: Consider initial semaphore state and Task2 action

    The semaphore is created but not given initially, so Task1 blocks until Task2 calls xSemaphoreGive.
  3. Final Answer:

    Task1 will block indefinitely until Task2 gives the semaphore -> Option D
  4. Quick Check:

    xSemaphoreTake with portMAX_DELAY blocks until given [OK]
Hint: xSemaphoreTake with portMAX_DELAY waits until given [OK]
Common Mistakes:
  • Assuming semaphore is initially available
  • Thinking Task1 runs critical section immediately
  • Confusing blocking with error
4. Identify the error in this FreeRTOS binary semaphore usage:
SemaphoreHandle_t xBinarySemaphore = xSemaphoreCreateBinary();

void Task(void *pvParameters) {
    if (xSemaphoreTake(xBinarySemaphore, 0) == pdTRUE) {
        // Do work
        xSemaphoreGive(xBinarySemaphore);
    }
}
medium
A. xSemaphoreCreateBinary requires a parameter
B. xSemaphoreGive should be called before xSemaphoreTake
C. Semaphore is never given before take, so take always fails
D. xSemaphoreTake timeout cannot be zero

Solution

  1. Step 1: Check initial semaphore state after creation

    xSemaphoreCreateBinary creates a semaphore that is initially empty (not given).
  2. Step 2: Analyze xSemaphoreTake with zero timeout

    With zero timeout, xSemaphoreTake returns immediately. Since semaphore is empty, it returns pdFALSE, so the if block never runs.
  3. Final Answer:

    Semaphore is never given before take, so take always fails -> Option C
  4. Quick Check:

    Binary semaphore empty at creation, take with zero timeout fails [OK]
Hint: Binary semaphore must be given before take succeeds [OK]
Common Mistakes:
  • Assuming semaphore is initially given
  • Thinking zero timeout means wait forever
  • Confusing function parameters
5. You want to synchronize two tasks so that Task B only runs after Task A signals completion using a binary semaphore. Which sequence correctly implements this?
hard
A. Task A calls xSemaphoreGive() after work; Task B calls xSemaphoreTake() with portMAX_DELAY before work
B. Task B calls xSemaphoreGive() before work; Task A calls xSemaphoreTake() after work
C. Both tasks call xSemaphoreTake() simultaneously; semaphore is given once at start
D. Task A and Task B both call xSemaphoreGive() without taking

Solution

  1. Step 1: Understand synchronization with binary semaphore

    Task B must wait for Task A's signal, so Task B should take the semaphore and block until given.
  2. Step 2: Match sequence to this logic

    Task A gives the semaphore after finishing work; Task B takes it with portMAX_DELAY to wait indefinitely.
  3. Final Answer:

    Task A calls xSemaphoreGive() after work; Task B calls xSemaphoreTake() with portMAX_DELAY before work -> Option A
  4. Quick Check:

    Give after work, take before work = sync tasks [OK]
Hint: Give semaphore after work; take before work to sync tasks [OK]
Common Mistakes:
  • Reversing give and take roles
  • Both tasks giving without taking
  • Taking without giving semaphore
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