📖 Scenario: You are working on a small embedded system using FreeRTOS. You need to send messages between tasks using a queue. Sometimes the queue might be full, so you want to wait for a short time before giving up sending a message.
🎯 Goal: Build a FreeRTOS program that creates a queue, sets a timeout value, tries to send an item to the queue with blocking behavior using the timeout, and then prints whether the send was successful or timed out.
📋 What You'll Learn
Create a queue called myQueue that can hold 3 integers
Create a variable called timeoutTicks and set it to 100
Use xQueueSend with myQueue, an integer value, and timeoutTicks to send to the queue
Print "Send successful" if the send succeeds, or "Send timed out" if it fails
💡 Why This Matters
🌍 Real World
Queues are used in embedded systems to safely pass data between tasks without conflicts. Managing blocking behavior with timeouts prevents tasks from waiting forever and helps keep the system responsive.
💼 Career
Understanding queue operations and blocking behavior is essential for embedded software engineers working with real-time operating systems like FreeRTOS, especially in industries like automotive, IoT, and industrial automation.
Progress0 / 4 steps
1
Create the queue
Create a queue called myQueue that can hold 3 integers using xQueueCreate.
FreeRTOS
Hint
Use xQueueCreate(3, sizeof(int)) to create a queue for 3 integers.
2
Set the timeout value
Create a variable called timeoutTicks and set it to 100.
FreeRTOS
Hint
Use TickType_t timeoutTicks = 100; to set the timeout.
3
Send an item to the queue with timeout
Use xQueueSend to send the integer 42 to myQueue with the timeout timeoutTicks. Store the result in a variable called sendResult.
FreeRTOS
Hint
Use xQueueSend(myQueue, &valueToSend, timeoutTicks) and save the result in sendResult.
4
Print the send result
Write an if statement that prints "Send successful" if sendResult equals pdPASS, otherwise print "Send timed out".
FreeRTOS
Hint
Use if (sendResult == pdPASS) to check success and printf to print the messages.
Practice
(1/5)
1. What does the xTicksToWait parameter control in FreeRTOS queue functions like xQueueReceive() or xQueueSend()?
easy
A. The number of items currently in the queue.
B. The size of the queue in bytes.
C. The maximum time a task will wait for the queue operation before timing out.
D. The priority of the task accessing the queue.
Solution
Step 1: Understand the role of xTicksToWait
This parameter specifies how long a task should wait if the queue is full (for send) or empty (for receive).
Step 2: Relate to queue blocking behavior
If the queue operation cannot proceed immediately, the task blocks for up to xTicksToWait ticks before timing out.
Final Answer:
The maximum time a task will wait for the queue operation before timing out. -> Option C
Quick Check:
Timeout duration = xTicksToWait [OK]
Hint: Remember: xTicksToWait sets wait time before giving up [OK]
Common Mistakes:
Confusing xTicksToWait with queue size
Thinking it sets task priority
Assuming it counts queue items
2. Which of the following is the correct way to call xQueueReceive() with a timeout of 10 ticks?
easy
A. xQueueReceive(queueHandle, &data);
B. xQueueReceive(queueHandle, data, 10);
C. xQueueReceive(queueHandle, &data, "10");
D. xQueueReceive(queueHandle, &data, 10);
Solution
Step 1: Check function parameters
xQueueReceive() requires the queue handle, pointer to data buffer, and timeout in ticks as a number.
Step 2: Validate correct syntax
xQueueReceive(queueHandle, &data, 10); correctly passes the address of data and numeric timeout 10 ticks.
Final Answer:
xQueueReceive(queueHandle, &data, 10); -> Option D
Quick Check:
Correct parameters and timeout type = xQueueReceive(queueHandle, &data, 10); [OK]
Hint: Use &data and numeric timeout for xQueueReceive [OK]
A. Using 0 as timeout means the task will wait forever.
B. Using 0 as timeout means the function returns immediately if the queue is full.
C. The timeout parameter should be a pointer, not a number.
D. The return value should be compared to pdPASS, not pdFAIL.
Solution
Step 1: Understand timeout=0 behavior in xQueueSend
A timeout of 0 means the function does not block; it returns immediately if the queue is full.
Step 2: Check the error handling logic
If the queue is full, xQueueSend() returns pdFAIL immediately, so the failure handling code runs correctly.
Final Answer:
Using 0 as timeout means the function returns immediately if the queue is full. -> Option B
Quick Check:
Timeout 0 means no wait, immediate return = Using 0 as timeout means the function returns immediately if the queue is full. [OK]
Hint: Timeout 0 means no wait, immediate fail if full [OK]
Common Mistakes:
Thinking 0 means wait forever
Confusing timeout type with pointer
Comparing return to wrong constant
5. You want a task to send data to a queue but only wait up to 20 ticks if the queue is full. If the queue remains full after 20 ticks, the task should perform an alternative action. Which code snippet correctly implements this behavior?
hard
A. if(xQueueSend(queue, &data, 20) == pdPASS) {
// sent successfully
} else {
// alternative action
}
B. if(xQueueSend(queue, &data, 0) == pdFAIL) {
// alternative action
} else {
// sent successfully
}
C. if(xQueueSend(queue, &data, portMAX_DELAY) == pdPASS) {
// sent successfully
} else {
// alternative action
}
D. if(xQueueSend(queue, &data, 20) == pdFAIL) {
// sent successfully
} else {
// alternative action
}
Solution
Step 1: Understand desired behavior
The task should wait up to 20 ticks to send data, then do alternative action if it fails.
Step 2: Analyze each option
if(xQueueSend(queue, &data, 20) == pdPASS) {
// sent successfully
} else {
// alternative action
} waits 20 ticks and checks for pdPASS to confirm success; else runs alternative action. if(xQueueSend(queue, &data, 0) == pdFAIL) {
// alternative action
} else {
// sent successfully
} waits 0 ticks (no wait). if(xQueueSend(queue, &data, portMAX_DELAY) == pdPASS) {
// sent successfully
} else {
// alternative action
} waits forever. if(xQueueSend(queue, &data, 20) == pdFAIL) {
// sent successfully
} else {
// alternative action
} reverses success/failure logic.
Final Answer:
if(xQueueSend(queue, &data, 20) == pdPASS) {
// sent successfully
} else {
// alternative action
} -> Option A