Bird
Raised Fist0
FreeRTOSprogramming~20 mins

xSemaphoreGive() and xSemaphoreTake() in FreeRTOS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Semaphore Mastery
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 semaphore code?

Consider the following FreeRTOS code snippet using a binary semaphore. What will be the output printed?

FreeRTOS
SemaphoreHandle_t xSemaphore;

void task1(void *params) {
    if (xSemaphoreTake(xSemaphore, 100 / portTICK_PERIOD_MS) == pdTRUE) {
        printf("Semaphore taken by task1\n");
        vTaskDelay(200 / portTICK_PERIOD_MS);
        xSemaphoreGive(xSemaphore);
    } else {
        printf("Task1 failed to take semaphore\n");
    }
    vTaskDelete(NULL);
}

void task2(void *params) {
    if (xSemaphoreTake(xSemaphore, 300 / portTICK_PERIOD_MS) == pdTRUE) {
        printf("Semaphore taken by task2\n");
        xSemaphoreGive(xSemaphore);
    } else {
        printf("Task2 failed to take semaphore\n");
    }
    vTaskDelete(NULL);
}

int main() {
    xSemaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(xSemaphore); // Initial give to make semaphore available
    xTaskCreate(task1, "Task1", 1000, NULL, 1, NULL);
    xTaskCreate(task2, "Task2", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}
A
Semaphore taken by task1
Semaphore taken by task2
B
Task1 failed to take semaphore
Semaphore taken by task2
C
Semaphore taken by task1
Task2 failed to take semaphore
D
Task1 failed to take semaphore
Task2 failed to take semaphore
Attempts:
2 left
💡 Hint

Remember that the semaphore is initially given before tasks start, so the first task to take it will succeed.

❓ Predict Output
intermediate
2:00remaining
What happens if xSemaphoreTake() times out?

Given this code snippet, what will be printed?

FreeRTOS
SemaphoreHandle_t xSemaphore;

void task(void *params) {
    if (xSemaphoreTake(xSemaphore, 50 / portTICK_PERIOD_MS) == pdTRUE) {
        printf("Semaphore acquired\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
        xSemaphoreGive(xSemaphore);
    } else {
        printf("Timeout waiting for semaphore\n");
    }
    vTaskDelete(NULL);
}

int main() {
    xSemaphore = xSemaphoreCreateBinary();
    // Note: semaphore is NOT given initially
    xTaskCreate(task, "Task", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}
A
Timeout waiting for semaphore
B
Semaphore acquired
C
No output
D
Semaphore acquired
Timeout waiting for semaphore
Attempts:
2 left
💡 Hint

The semaphore is created but never given before the task tries to take it.

🔧 Debug
advanced
2:00remaining
Identify the error in this semaphore usage

What error will this code cause when run?

FreeRTOS
SemaphoreHandle_t xSemaphore;

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

int main() {
    // Semaphore is NOT created
    xTaskCreate(task, "Task", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}
ADeadlock: task waits forever
BSemaphore taken
CCompile-time error: missing semaphore creation
DNull pointer dereference or crash due to uninitialized semaphore
Attempts:
2 left
💡 Hint

Check if the semaphore is created before use.

🧠 Conceptual
advanced
2:00remaining
What is the effect of calling xSemaphoreGive() multiple times on a binary semaphore?

In FreeRTOS, if you call xSemaphoreGive() multiple times on a binary semaphore without taking it, what happens?

AThe semaphore count increases beyond 1, allowing multiple takes without blocking
BThe semaphore resets and causes an error
CThe semaphore count remains at 1; extra gives have no effect
DThe semaphore blocks the task that calls xSemaphoreGive()
Attempts:
2 left
💡 Hint

Think about the nature of a binary semaphore as a flag.

❓ Predict Output
expert
3:00remaining
What is the final value of sharedCounter after these tasks run?

Two tasks increment a shared counter protected by a binary semaphore. What is the final value of sharedCounter after both tasks finish?

FreeRTOS
SemaphoreHandle_t xSemaphore;
volatile int sharedCounter = 0;

void task1(void *params) {
    for (int i = 0; i < 5; i++) {
        if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
            sharedCounter++;
            xSemaphoreGive(xSemaphore);
        }
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

void task2(void *params) {
    for (int i = 0; i < 5; i++) {
        if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
            sharedCounter++;
            xSemaphoreGive(xSemaphore);
        }
        vTaskDelay(15 / portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

int main() {
    xSemaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(xSemaphore); // Make semaphore available
    xTaskCreate(task1, "Task1", 1000, NULL, 1, NULL);
    xTaskCreate(task2, "Task2", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    // After scheduler ends (in real system it won't), print value
    printf("Final sharedCounter: %d\n", sharedCounter);
    return 0;
}
AFinal sharedCounter: 5
BFinal sharedCounter: 10
CFinal sharedCounter: 0
DFinal sharedCounter: 15
Attempts:
2 left
💡 Hint

Each task increments 5 times, semaphore protects increments from race conditions.

Practice

(1/5)
1. What is the main purpose of xSemaphoreTake() in FreeRTOS?
easy
A. To lock the semaphore and gain exclusive access to a resource
B. To unlock the semaphore and release the resource
C. To create a new semaphore
D. To delete an existing semaphore

Solution

  1. Step 1: Understand the role of xSemaphoreTake()

    This function is used by a task to lock a semaphore, which means it tries to gain exclusive access to a shared resource.
  2. Step 2: Differentiate from xSemaphoreGive()

    xSemaphoreGive() is used to release or unlock the semaphore, not to lock it.
  3. Final Answer:

    To lock the semaphore and gain exclusive access to a resource -> Option A
  4. Quick Check:

    xSemaphoreTake() locks = B [OK]
Hint: Take locks resource, Give unlocks it [OK]
Common Mistakes:
  • Confusing take with give
  • Thinking take creates semaphore
  • Mixing up locking and unlocking
2. Which of the following is the correct syntax to take a semaphore named xSemaphore with a block time of 100 ticks?
easy
A. xSemaphoreTake(100, xSemaphore);
B. xSemaphoreTake(xSemaphore, 100);
C. xSemaphoreGive(xSemaphore, 100);
D. xSemaphoreGive(100, xSemaphore);

Solution

  1. Step 1: Recall function signature of xSemaphoreTake()

    The correct syntax is xSemaphoreTake(SemaphoreHandle, BlockTimeTicks); where the first argument is the semaphore handle and second is the block time.
  2. Step 2: Match the options with correct order

    xSemaphoreTake(xSemaphore, 100); matches the correct order: xSemaphoreTake(xSemaphore, 100);. Options B and D use xSemaphoreGive which is wrong here. xSemaphoreTake(100, xSemaphore); reverses the arguments.
  3. Final Answer:

    xSemaphoreTake(xSemaphore, 100); -> Option B
  4. Quick Check:

    Take(semaphore, time) = C [OK]
Hint: Take(semaphore, time) is correct order [OK]
Common Mistakes:
  • Swapping arguments order
  • Using xSemaphoreGive instead of xSemaphoreTake
  • Passing block time as first argument
3. Consider the following code snippet:
if (xSemaphoreTake(xSemaphore, 10) == pdTRUE) {
    // Critical section
    xSemaphoreGive(xSemaphore);
    printf("Access granted\n");
} else {
    printf("Access denied\n");
}
What will be printed if the semaphore is already taken by another task and not given back within 10 ticks?
medium
A. Access granted
B. Runtime error
C. No output
D. Access denied

Solution

  1. Step 1: Understand xSemaphoreTake() behavior with timeout

    If the semaphore is already taken and not released within the 10 tick block time, xSemaphoreTake() returns pdFALSE.
  2. Step 2: Analyze the if condition and output

    Since xSemaphoreTake() returns pdFALSE, the else branch executes, printing "Access denied".
  3. Final Answer:

    Access denied -> Option D
  4. Quick Check:

    Semaphore busy + timeout = Access denied [OK]
Hint: If take fails within timeout, else branch runs [OK]
Common Mistakes:
  • Assuming take always succeeds
  • Ignoring block time effect
  • Expecting 'Access granted' always
4. Identify the error in this code snippet:
if (xSemaphoreGive(xSemaphore) == pdTRUE) {
    // Critical section
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
}
medium
A. xSemaphoreGive should not be called before taking the semaphore
B. xSemaphoreTake should not use portMAX_DELAY
C. xSemaphoreGive returns void, so comparison is invalid
D. No error, code is correct

Solution

  1. Step 1: Understand correct semaphore usage order

    A task must first take (lock) the semaphore before giving (unlocking) it. Calling xSemaphoreGive() before xSemaphoreTake() is incorrect.
  2. Step 2: Check function return types and usage

    xSemaphoreGive() returns BaseType_t, so comparing to pdTRUE is valid. Using portMAX_DELAY in xSemaphoreTake() is allowed to wait indefinitely.
  3. Final Answer:

    xSemaphoreGive should not be called before taking the semaphore -> Option A
  4. Quick Check:

    Give before Take is wrong order [OK]
Hint: Always take before give [OK]
Common Mistakes:
  • Calling give before take
  • Misunderstanding return values
  • Thinking portMAX_DELAY is invalid
5. You have two tasks sharing a resource protected by a binary semaphore xSemaphore. Task A takes the semaphore, performs work, then gives it back. Task B tries to take the semaphore with a 50 tick timeout. If Task A forgets to give the semaphore back, what will happen to Task B?
hard
A. Task B will block forever waiting for the semaphore
B. Task B will immediately take the semaphore without blocking
C. Task B will block for 50 ticks, then continue without the resource
D. Task B will cause a system crash

Solution

  1. Step 1: Understand semaphore blocking with timeout

    Task B calls xSemaphoreTake() with a 50 tick timeout, so it will wait up to 50 ticks for the semaphore to become available.
  2. Step 2: Analyze effect of Task A not giving semaphore back

    If Task A never gives the semaphore back, Task B will wait the full 50 ticks, then xSemaphoreTake() returns pdFALSE, so Task B continues without the resource.
  3. Final Answer:

    Task B will block for 50 ticks, then continue without the resource -> Option C
  4. Quick Check:

    Timeout reached without give = block then continue [OK]
Hint: Timeout means wait then fail, not infinite block [OK]
Common Mistakes:
  • Assuming infinite block without timeout
  • Thinking semaphore is taken immediately
  • Believing system crashes on semaphore misuse
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