📖 Scenario: You are building a simple embedded system using FreeRTOS. The system has multiple tasks that need to access a shared resource, such as a sensor or communication interface. To avoid conflicts, you will create a resource manager task that controls access to this shared resource.
🎯 Goal: Build a FreeRTOS program where a dedicated ResourceManagerTask manages access requests from other tasks using a queue. The resource manager grants access one task at a time, demonstrating the resource manager task pattern.
📋 What You'll Learn
Create a queue to hold resource access requests
Create a ResourceManagerTask that waits for requests and grants access
Create two tasks (Task1 and Task2) that send access requests to the resource manager
Print messages showing when tasks request and receive the resource
💡 Why This Matters
🌍 Real World
Embedded systems often have multiple tasks needing access to a single hardware resource. Using a resource manager task pattern helps coordinate access safely and efficiently.
💼 Career
Understanding resource management in FreeRTOS is essential for embedded software engineers working on real-time systems like IoT devices, automotive controllers, and industrial automation.
Progress0 / 4 steps
1
Create the queue for resource requests
Create a FreeRTOS queue called resourceQueue that can hold 5 integers. Use xQueueCreate(5, sizeof(int)) and assign it to resourceQueue.
FreeRTOS
Hint
Use xQueueCreate with length 5 and item size sizeof(int).
2
Create the ResourceManagerTask
Create a FreeRTOS task called ResourceManagerTask with priority 2 and stack size 1000. The task should run a function named ResourceManagerTaskFunction. Use xTaskCreate(ResourceManagerTaskFunction, "ResourceManagerTask", 1000, NULL, 2, NULL).
FreeRTOS
Hint
Use xTaskCreate with the function name, task name, stack size 1000, no parameters, priority 2, and no task handle.
3
Implement ResourceManagerTaskFunction to handle requests
Write the function ResourceManagerTaskFunction that runs an infinite loop. Inside the loop, use xQueueReceive(resourceQueue, &request, portMAX_DELAY) to wait for an integer request. When a request is received, print "Resource granted to task %d" with the request value. Use printf for printing.
FreeRTOS
Hint
Use an infinite loop and xQueueReceive to wait for requests. Print the granted message when a request is received.
4
Create two tasks that send requests to the resource manager
Create two tasks named Task1 and Task2 with priority 1 and stack size 1000. Each task runs a function (Task1Function and Task2Function) that sends its task ID (1 or 2) to resourceQueue every 1000 ms using xQueueSend. Print "Task 1 requesting resource" or "Task 2 requesting resource" before sending the request. Use vTaskDelay(pdMS_TO_TICKS(1000)) for delay. Finally, start the scheduler with vTaskStartScheduler().
FreeRTOS
Hint
Create two tasks that send their ID to the queue every second and print a request message. Then start the scheduler.
Practice
(1/5)
1. What is the main purpose of the Resource Manager Task Pattern in FreeRTOS?
easy
A. To centralize control of shared resources and prevent conflicts
B. To create multiple tasks accessing resources directly
C. To increase CPU usage by running more tasks simultaneously
D. To eliminate the need for task synchronization mechanisms
Solution
Step 1: Understand resource sharing challenges
When multiple tasks access shared resources directly, conflicts and data corruption can occur.
Step 2: Role of Resource Manager Task
The Resource Manager Task centralizes access, so tasks send requests to it instead of accessing resources directly, preventing conflicts.
Final Answer:
To centralize control of shared resources and prevent conflicts -> Option A
Quick Check:
Centralized control = Prevent conflicts [OK]
Hint: Resource manager centralizes resource access to avoid conflicts [OK]
Common Mistakes:
Thinking tasks access resources directly
Assuming it increases CPU usage
Believing it removes synchronization needs
2. Which of the following is the correct way to send a request to a Resource Manager Task in FreeRTOS?
easy
A. Using a queue to send a request message to the manager task
B. Calling the resource manager function without synchronization
C. Directly accessing the shared resource variable
D. Using global variables without any task communication
Solution
Step 1: Identify communication method
Resource Manager Tasks typically receive requests via queues to serialize access.
Step 2: Evaluate options
Only Using a queue to send a request message to the manager task uses a queue to send requests, which is the correct and safe method.
Final Answer:
Using a queue to send a request message to the manager task -> Option A
Quick Check:
Queue communication = Correct request method [OK]
Hint: Use queues to send requests to resource manager task [OK]
Common Mistakes:
Accessing shared variables directly
Ignoring synchronization
Using global variables without communication
3. Given the following FreeRTOS code snippet, what will be the output?
ClientTask sends a message with command=1 and data=5 to the resourceQueue.
Step 2: Analyze ResourceManagerTask processing
ResourceManagerTask receives the message, checks command==1, then prints data*2 = 5*2 = 10.
Final Answer:
Processed data: 10 -> Option B
Quick Check:
Data 5 doubled = 10 output [OK]
Hint: Multiply data by 2 when command is 1 [OK]
Common Mistakes:
Confusing data value with output
Assuming no message received
Ignoring the multiplication by 2
4. Identify the bug in this Resource Manager Task code snippet:
void ResourceManagerTask(void *params) {
RequestMessage req;
while (1) {
if (xQueueReceive(resourceQueue, &req, 0) == pdPASS) {
if (req.command == 1) {
// Process command
}
}
}
}
What is the problem?
medium
A. xQueueReceive should not be used in Resource Manager Task
B. RequestMessage struct is not defined
C. ResourceManagerTask should not use a while loop
D. Using zero block time causes missed messages if queue is empty
Solution
Step 1: Understand xQueueReceive block time
Using 0 as block time means the call returns immediately if queue is empty, possibly missing messages.
Step 2: Effect on Resource Manager Task
The task may spin without waiting, causing high CPU usage and missed processing.
Final Answer:
Using zero block time causes missed messages if queue is empty -> Option D
Quick Check:
Zero block time = possible missed messages [OK]
Hint: Use portMAX_DELAY to wait for messages in resource manager [OK]
Common Mistakes:
Ignoring block time effect
Thinking struct is undefined
Believing while loop is wrong
5. You want to design a Resource Manager Task that handles multiple resource types (e.g., UART, SPI) with different commands. Which approach best applies the Resource Manager Task Pattern to handle this efficiently?
hard
A. Create separate manager tasks for each resource type and let clients send requests directly to each
B. Let clients access resources directly with mutexes protecting each resource
C. Use a single queue with a message struct containing resource type and command fields, then switch-case inside the manager task
D. Use global variables to store resource states and update them without task communication
Solution
Step 1: Consider centralized control for multiple resources
A single Resource Manager Task can handle multiple resource types by differentiating requests.
Step 2: Use message struct with resource type and command
This allows the manager task to use a switch-case to process requests efficiently and safely.
Final Answer:
Use a single queue with a message struct containing resource type and command fields, then switch-case inside the manager task -> Option C
Quick Check:
Single queue + message struct = efficient multi-resource management [OK]
Hint: Use message struct with resource type and switch-case in manager [OK]
Common Mistakes:
Creating multiple manager tasks unnecessarily
Allowing direct resource access with mutexes
Using global variables without communication
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.