Using xSemaphoreGive() and xSemaphoreTake() in FreeRTOS
📖 Scenario: You are working on a FreeRTOS project where two tasks share a resource. To avoid conflicts, you need to use a semaphore to control access.
🎯 Goal: Build a simple FreeRTOS program that creates a binary semaphore, uses xSemaphoreTake() to wait for the semaphore, and xSemaphoreGive() to release it, simulating safe resource sharing between two tasks.
📋 What You'll Learn
Create a binary semaphore using xSemaphoreCreateBinary()
Use xSemaphoreTake() to wait for the semaphore in Task 1
Use xSemaphoreGive() to release the semaphore in Task 2
Print messages to show when the semaphore is taken and given
💡 Why This Matters
🌍 Real World
Semaphores are used in embedded systems to control access to shared hardware or data, preventing errors and crashes.
💼 Career
Understanding semaphores is essential for embedded software developers working with real-time operating systems like FreeRTOS.
Progress0 / 4 steps
1
Create a binary semaphore
Create a variable called xSemaphore and assign it the result of xSemaphoreCreateBinary().
FreeRTOS
Hint
Use xSemaphoreCreateBinary() to create the semaphore and assign it to xSemaphore.
2
Give the semaphore initially
Call xSemaphoreGive(xSemaphore) once to make the semaphore available initially.
FreeRTOS
Hint
Call xSemaphoreGive() with xSemaphore to release it initially.
3
Take the semaphore in Task 1
Write a function called Task1 that calls xSemaphoreTake(xSemaphore, portMAX_DELAY) and prints "Semaphore taken by Task1" if successful.
FreeRTOS
Hint
Use xSemaphoreTake() with portMAX_DELAY to wait indefinitely. Print the message only if it returns pdTRUE.
4
Give the semaphore in Task 2 and print message
Write a function called Task2 that calls xSemaphoreGive(xSemaphore) and prints "Semaphore given by Task2".
FreeRTOS
Hint
Call xSemaphoreGive() with xSemaphore and then print the message.
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
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.
Step 2: Differentiate from xSemaphoreGive()
xSemaphoreGive() is used to release or unlock the semaphore, not to lock it.
Final Answer:
To lock the semaphore and gain exclusive access to a resource -> Option A
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
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.
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.
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
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.
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.
Final Answer:
xSemaphoreGive should not be called before taking the semaphore -> Option A
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
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.
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.
Final Answer:
Task B will block for 50 ticks, then continue without the resource -> Option C
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 unknownstrongwhile earning +1 Grip toward your certificate.