📖 Scenario: Imagine you have a small kitchen where only one person can use the stove at a time. If two people try to cook at the same time, they might bump into each other or spoil the food. To avoid this, you use a simple rule: only one person can use the stove, and others wait their turn.In FreeRTOS, when multiple tasks want to use the same resource like a printer or a sensor, we need a way to control access so they don't interfere with each other. This is where semaphores come in.
🎯 Goal: You will create a simple FreeRTOS program that uses a semaphore to control access to a shared resource. This will show why semaphores are needed to avoid conflicts between tasks.
📋 What You'll Learn
Create two tasks that try to access a shared resource
Create a semaphore to control access to the shared resource
Use the semaphore to make sure only one task uses the resource at a time
Print messages to show when a task is using or waiting for the resource
💡 Why This Matters
🌍 Real World
In embedded systems, many tasks share hardware like sensors, displays, or communication ports. Semaphores ensure these tasks do not interfere with each other.
💼 Career
Understanding semaphores is essential for embedded software developers to write safe multitasking applications using FreeRTOS or similar real-time operating systems.
Progress0 / 4 steps
1
Create two tasks and a shared resource variable
Create two FreeRTOS tasks called Task1 and Task2. Also, create a global integer variable called shared_resource and set it to 0.
FreeRTOS
Hint
Use int shared_resource = 0; outside the tasks. Create two functions Task1 and Task2 with the correct signature.
2
Create a semaphore to control access
Create a binary semaphore called xSemaphore using xSemaphoreCreateBinary(). Then give the semaphore once using xSemaphoreGive(xSemaphore) in main() before starting the scheduler.
FreeRTOS
Hint
Remember to include semphr.h and create xSemaphore as a SemaphoreHandle_t. Give the semaphore once before starting the scheduler.
3
Use the semaphore in tasks to access the shared resource
In both Task1 and Task2, use xSemaphoreTake(xSemaphore, portMAX_DELAY) before accessing shared_resource. Increase shared_resource by 1, print a message showing the task name and the new value, then call xSemaphoreGive(xSemaphore). Add a delay of 1000 ms after releasing the semaphore.
FreeRTOS
Hint
Use xSemaphoreTake and xSemaphoreGive around the code that changes shared_resource. Print the task name and the new value.
4
Print the output showing semaphore control
Run the program and observe the printed messages. The output should show Task1 and Task2 accessing shared_resource one after another without overlap. Print statements are already in the tasks.
FreeRTOS
Hint
Look at the printed messages. They should show that Task1 and Task2 take turns accessing the shared resource without conflict.
Practice
(1/5)
1. Why are semaphores needed in FreeRTOS when multiple tasks share a resource?
easy
A. To prevent tasks from accessing the resource at the same time and causing errors
B. To speed up the execution of all tasks simultaneously
C. To allow tasks to ignore each other and run independently
D. To increase the memory usage of the system
Solution
Step 1: Understand resource sharing in multitasking
When multiple tasks share a resource, simultaneous access can cause data corruption or crashes.
Step 2: Role of semaphores in synchronization
Semaphores act as signals to control access, allowing only one task at a time to use the resource safely.
Final Answer:
To prevent tasks from accessing the resource at the same time and causing errors -> Option A
Quick Check:
Semaphores prevent simultaneous access = A [OK]
Hint: Semaphores stop tasks from clashing over shared resources [OK]
Common Mistakes:
Thinking semaphores speed up all tasks
Believing tasks run independently without coordination
Assuming semaphores increase memory usage
2. Which of the following is the correct way to create a binary semaphore in FreeRTOS?
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.