📖 Scenario: You are working on a small embedded system that uses FreeRTOS. You need to manage a queue to send messages between tasks. It is important to handle cases when the queue is full or empty to avoid losing messages or blocking tasks indefinitely.
🎯 Goal: Build a simple FreeRTOS program that creates a queue, sends messages to it, receives messages from it, and properly handles the cases when the queue is full or empty.
📋 What You'll Learn
Create a queue with a fixed size
Create a variable to hold a message
Send messages to the queue and check if the queue is full
Receive messages from the queue and check if the queue is empty
Print messages indicating queue full or empty conditions
💡 Why This Matters
🌍 Real World
Queues are used in embedded systems to safely pass data between different tasks without losing messages or causing crashes.
💼 Career
Understanding queue handling in FreeRTOS is essential for embedded software developers working on real-time applications like IoT devices, automotive systems, and industrial controllers.
Progress0 / 4 steps
1
Create a queue and a message variable
Create a queue called myQueue that can hold 3 items of type int. Also create an int variable called message and set it to 10.
FreeRTOS
Hint
Use xQueueCreate to create the queue. The first argument is the number of items, the second is the size of each item.
2
Create a variable for queue send timeout
Create a variable called sendTimeout of type TickType_t and set it to 0 to specify no wait when sending to the queue.
FreeRTOS
Hint
Use TickType_t type for timeout values in FreeRTOS.
3
Send message to queue and check if full
Use xQueueSend to send message to myQueue with timeout sendTimeout. Use an if statement to check if xQueueSend returns errQUEUE_FULL. If full, set message to -1.
FreeRTOS
Hint
Check the return value of xQueueSend. If it equals errQUEUE_FULL, the queue is full.
4
Receive message from queue and print status
Use xQueueReceive to receive an int from myQueue into a variable called receivedMessage with timeout 0. If xQueueReceive returns pdFALSE, print "Queue is empty". Otherwise, print "Received: " followed by the received message.
FreeRTOS
Hint
Use xQueueReceive with timeout 0 to check if queue is empty. Use printf to print messages.
Practice
(1/5)
1. In FreeRTOS, what happens if you try to send an item to a queue that is already full without waiting?
easy
A. The send operation fails immediately and returns an error.
B. The queue automatically expands to fit the new item.
C. The oldest item in the queue is overwritten.
D. The task sending the item is suspended indefinitely.
Solution
Step 1: Understand queue full behavior
When a queue is full, FreeRTOS does not allow new items to be added without waiting or handling the error.
Step 2: Check send operation without wait
If the send function is called with zero wait time and the queue is full, it returns immediately with an error indicating failure.
Final Answer:
The send operation fails immediately and returns an error. -> Option A
Quick Check:
Queue full + no wait = send fails [OK]
Hint: Send with zero wait fails if queue is full [OK]
Common Mistakes:
Assuming queue grows automatically
Thinking oldest data is overwritten
Believing task suspends indefinitely
2. Which of the following is the correct way to receive an item from a FreeRTOS queue with a block time of 10 ticks?
easy
A. xQueueReceive(queue, &item, 10);
B. xQueueReceive(queue, item, 10);
C. xQueueReceive(queue, &item, 0);
D. xQueueReceive(queue, &item, -1);
Solution
Step 1: Understand xQueueReceive parameters
The function takes the queue handle, a pointer to the variable to store the item, and the block time in ticks.
Step 2: Identify correct syntax
Passing &item as the second argument is correct to provide the address. Block time 10 means wait up to 10 ticks.
Final Answer:
xQueueReceive(queue, &item, 10); -> Option A
Quick Check:
Pointer + block time 10 = correct receive call [OK]
Hint: Use &item and positive ticks for blocking receive [OK]
Common Mistakes:
Passing item instead of &item
Using zero or negative block time incorrectly
Confusing send and receive parameters
3. Consider the following code snippet:
QueueHandle_t queue = xQueueCreate(2, sizeof(int));
int val = 10;
xQueueSend(queue, &val, 0);
val = 20;
xQueueSend(queue, &val, 0);
val = 30;
BaseType_t result = xQueueSend(queue, &val, 0);
What is the value of result after the last send call?
medium
A. pdPASS (send succeeded)
B. errQUEUE_FULL (send failed due to full queue)
C. pdFAIL (generic failure)
D. Block indefinitely until space is available
Solution
Step 1: Analyze queue creation and sends
The queue can hold 2 integers. Two sends with zero wait fill it completely.
Step 2: Evaluate last send with zero wait
The third send tries to add an item when the queue is full and does not wait, so it fails returning errQUEUE_FULL.
Final Answer:
errQUEUE_FULL (send failed due to full queue) -> Option B
Quick Check:
Queue full + zero wait = send fails with errQUEUE_FULL [OK]
Hint: Queue size 2 + 3 sends with zero wait = last send fails [OK]
Common Mistakes:
Assuming last send blocks
Thinking last send overwrites data
Confusing pdPASS and pdFAIL
4. Given this code snippet, why does xQueueReceive never return pdPASS?
QueueHandle_t queue = xQueueCreate(1, sizeof(int));
int data;
// Task A
xQueueReceive(queue, &data, 0);
// Task B
int val = 5;
xQueueSend(queue, &val, 0);
medium
A. xQueueSend is called with zero wait time, so it fails.
B. Queue size is too small to hold any data.
C. xQueueReceive is called with incorrect pointer.
D. Task A tries to receive before Task B sends, queue is empty, no wait time.
Solution
Step 1: Understand queue state at receive
Task A calls receive immediately with zero wait, but queue is empty because Task B hasn't sent yet.
Step 2: Effect of zero wait on empty queue
With zero wait, receive returns immediately with failure since no data is available yet.
Final Answer:
Task A tries to receive before Task B sends, queue is empty, no wait time. -> Option D
Quick Check:
Receive zero wait + empty queue = no pdPASS [OK]
Hint: Receive zero wait on empty queue always fails [OK]
Common Mistakes:
Thinking queue size 1 means no data can be stored
Assuming send fails with zero wait
Confusing pointer usage in receive
5. You want to design a FreeRTOS task that sends sensor data to a queue but must never block if the queue is full. Which approach correctly handles the queue full condition?
hard
A. Increase the queue size dynamically when full.
B. Use xQueueSend with portMAX_DELAY to wait indefinitely until space is available.
C. Use xQueueSend with zero block time and check the return value to discard data if full.
D. Use xQueueOverwrite to replace the oldest data in the queue automatically.
Solution
Step 1: Understand non-blocking send requirement
The task must never block, so waiting indefinitely or for a long time is not allowed.
Step 2: Choose correct send method and handling
Using xQueueSend with zero block time returns immediately. Checking the return value lets the task discard data if the queue is full.
Step 3: Evaluate other options
Use xQueueSend with portMAX_DELAY to wait indefinitely until space is available. blocks indefinitely, violating requirement. Use xQueueOverwrite to replace the oldest data in the queue automatically. overwrites data but may lose important info. Increase the queue size dynamically when full. is not supported by FreeRTOS.
Final Answer:
Use xQueueSend with zero block time and check the return value to discard data if full. -> Option C