Semaphores help tasks share resources safely without crashing or mixing data. They keep things organized when many tasks want the same thing.
When two tasks need to use the same printer without printing over each other.
When a sensor data buffer must be accessed by multiple tasks without corrupting data.
When a task must wait for another task to finish before continuing.
When controlling access to a shared variable to avoid wrong values.
When signaling between tasks that an event has happened.
Syntax
FreeRTOS
SemaphoreHandle_t xSemaphore;
xSemaphore = xSemaphoreCreateBinary();
// To take (wait) the semaphore
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
// Access shared resource
xSemaphoreGive(xSemaphore); // Release semaphore
}
Semaphores are created before use and tasks take or give them to control access.
Taking a semaphore means waiting until it is available; giving it releases it for others.
Examples
This example creates a mutex semaphore and tries to take it with a 1000 tick timeout.
FreeRTOS
xSemaphore = xSemaphoreCreateMutex();
if (xSemaphoreTake(xSemaphore, 1000 / portTICK_PERIOD_MS) == pdTRUE) {
// Use resource
xSemaphoreGive(xSemaphore);
}
This shows a binary semaphore given first, then taken by a task waiting indefinitely.
FreeRTOS
xSemaphore = xSemaphoreCreateBinary();
xSemaphoreGive(xSemaphore); // Make it available
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
// Proceed after semaphore is given
}
Sample Program
This program creates a mutex semaphore and two tasks that take and release it. The output shows how tasks wait for the semaphore to be free before running.
Step 1: Understand semaphore creation and initial state
The binary semaphore is created and then given once, so it is available (count = 1).
Step 2: Check the take operation with zero wait
The xSemaphoreTake tries to take the semaphore immediately (timeout 0). Since it was given before, it succeeds.
Final Answer:
Access granted -> Option B
Quick Check:
Semaphore given then taken immediately = Access granted [OK]
Hint: Semaphore given before take means immediate success [OK]
Common Mistakes:
Assuming zero timeout means failure
Forgetting to give semaphore before take
Confusing binary semaphore initial state
4. This FreeRTOS code snippet tries to protect a shared resource:
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
// Task A
xSemaphoreTake(sem, portMAX_DELAY);
// Access resource
xSemaphoreGive(sem);
// Task B
xSemaphoreTake(sem, portMAX_DELAY);
// Access resource
xSemaphoreGive(sem);
What is the main problem here?
medium
A. The semaphore is created as binary but used as counting
B. The semaphore is given twice causing overflow
C. The semaphore is never given initially, so tasks block forever
D. The tasks do not take the semaphore before accessing resource
Solution
Step 1: Check semaphore initial state after creation
Binary semaphore created with xSemaphoreCreateBinary() starts empty (not given).
Step 2: Analyze task behavior on take
Task A tries to take semaphore but it was never given, so it blocks forever. Same for Task B.
Final Answer:
The semaphore is never given initially, so tasks block forever -> Option C
Quick Check:
Binary semaphore must be given once before take = C [OK]
Hint: Binary semaphore must be given once before tasks take it [OK]
Common Mistakes:
Assuming semaphore is given automatically on creation
Thinking multiple gives cause overflow
Ignoring semaphore take before resource access
5. You have two tasks sharing a sensor. Task 1 reads data and Task 2 processes it. Without semaphores, data corruption occurs. How should you use semaphores to fix this?
hard
A. Use a counting semaphore with count 0 to block both tasks
B. Use a mutex but never give it back after taking
C. Use no semaphore and rely on task priorities to avoid conflicts
D. Use a binary semaphore to let only one task access the sensor at a time
Solution
Step 1: Identify the problem of simultaneous access
Both tasks accessing the sensor at the same time cause data corruption.
Step 2: Choose semaphore type and usage
A binary semaphore ensures only one task accesses the sensor at a time, preventing conflicts.
Final Answer:
Use a binary semaphore to let only one task access the sensor at a time -> Option D
Quick Check:
Binary semaphore controls exclusive access = B [OK]
Hint: Binary semaphore allows one task access at a time [OK]
Common Mistakes:
Using counting semaphore incorrectly with zero count
Ignoring semaphore and trusting priorities alone
Not releasing mutex causing deadlock
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.