Queues in FreeRTOS help tasks send and receive data safely. Blocking with timeout means a task waits for a limited time if the queue is full or empty, so it doesn't wait forever.
Queue blocking behavior (timeout) in FreeRTOS
/* Create a queue */ QueueHandle_t xQueue = xQueueCreate( queue_length, item_size ); /* Send to queue with timeout */ BaseType_t xQueueSend( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait ); /* Receive from queue with timeout */ BaseType_t xQueueReceive( QueueHandle_t xQueue, void * pvBuffer, TickType_t xTicksToWait );
xTicksToWait is the maximum time to wait in ticks. Use 0 for no wait, portMAX_DELAY for indefinite wait.
Functions return pdTRUE if successful, pdFALSE if timeout occurred.
/* Send with no wait (non-blocking) */ BaseType_t result = xQueueSend(xQueue, &data, 0);
/* Send with 100 tick timeout */ BaseType_t result = xQueueSend(xQueue, &data, 100);
/* Receive with indefinite wait */
BaseType_t result = xQueueReceive(xQueue, &buffer, portMAX_DELAY);/* Receive with 50 tick timeout */ BaseType_t result = xQueueReceive(xQueue, &buffer, 50);
This program creates a queue with space for 1 integer. The receiver task waits up to 300 ticks for data. The sender task tries to send data with a 200 tick timeout. The receiver starts first and waits, then the sender sends data. The output shows the blocking behavior with timeout.
#include "FreeRTOS.h" #include "task.h" #include "queue.h" #include <stdio.h> QueueHandle_t xQueue; void vSenderTask(void *pvParameters) { int data_to_send = 100; BaseType_t send_result; printf("Sender: Trying to send data %d with 200 tick timeout...\n", data_to_send); send_result = xQueueSend(xQueue, &data_to_send, 200); if (send_result == pdTRUE) { printf("Sender: Data sent successfully.\n"); } else { printf("Sender: Failed to send data (timeout).\n"); } vTaskDelete(NULL); } void vReceiverTask(void *pvParameters) { int received_data = 0; BaseType_t receive_result; printf("Receiver: Waiting to receive data with 300 tick timeout...\n"); receive_result = xQueueReceive(xQueue, &received_data, 300); if (receive_result == pdTRUE) { printf("Receiver: Received data: %d\n", received_data); } else { printf("Receiver: Failed to receive data (timeout).\n"); } vTaskDelete(NULL); } int main(void) { xQueue = xQueueCreate(1, sizeof(int)); if (xQueue == NULL) { printf("Failed to create queue.\n"); return 1; } printf("Queue created with length 1.\n"); xTaskCreate(vReceiverTask, "Receiver", configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskDelay(50); // Delay to ensure receiver starts first xTaskCreate(vSenderTask, "Sender", configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskStartScheduler(); // Should never reach here printf("Scheduler ended unexpectedly.\n"); return 0; }
Time complexity: Sending and receiving are O(1) operations.
Space complexity: Depends on queue length and item size.
Common mistake: Using zero timeout when you want to wait, causing immediate failure.
Use blocking with timeout to avoid tasks getting stuck forever and to improve system responsiveness.
Queue blocking with timeout lets tasks wait for limited time when sending or receiving.
Use xTicksToWait to control how long a task waits before giving up.
This helps keep multitasking systems responsive and safe.
Practice
xTicksToWait parameter control in FreeRTOS queue functions like xQueueReceive() or xQueueSend()?Solution
Step 1: Understand the role of
This parameter specifies how long a task should wait if the queue is full (for send) or empty (for receive).xTicksToWaitStep 2: Relate to queue blocking behavior
If the queue operation cannot proceed immediately, the task blocks for up toxTicksToWaitticks before timing out.Final Answer:
The maximum time a task will wait for the queue operation before timing out. -> Option CQuick Check:
Timeout duration = xTicksToWait [OK]
- Confusing xTicksToWait with queue size
- Thinking it sets task priority
- Assuming it counts queue items
xQueueReceive() with a timeout of 10 ticks?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 DQuick Check:
Correct parameters and timeout type = xQueueReceive(queueHandle, &data, 10); [OK]
- Passing data instead of &data
- Using string "10" instead of number 10
- Omitting timeout parameter
if(xQueueReceive(queue, &item, 5) == pdPASS) {
process(item);
} else {
handleTimeout();
}
What happens if the queue is empty and no item arrives within 5 ticks?Solution
Step 1: Analyze xQueueReceive behavior with timeout
If the queue is empty, the task waits up to 5 ticks for an item to arrive.Step 2: Understand return values
If no item arrives in 5 ticks,xQueueReceive()returns a failure code (notpdPASS), sohandleTimeout()runs.Final Answer:
The function returns after 5 ticks with a failure code, andhandleTimeout()is called. -> Option AQuick Check:
Timeout triggers failure return = The function returns after 5 ticks with a failure code, andhandleTimeout()is called. [OK]
- Assuming indefinite block without timeout
- Thinking pdPASS is returned on timeout
- Believing queue deletes itself
BaseType_t result = xQueueSend(queue, &data, 0);
if(result == pdFAIL) {
// handle failure
}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()returnspdFAILimmediately, so the failure handling code runs correctly.Final Answer:
Using 0 as timeout means the function returns immediately if the queue is full. -> Option BQuick Check:
Timeout 0 means no wait, immediate return = Using 0 as timeout means the function returns immediately if the queue is full. [OK]
- Thinking 0 means wait forever
- Confusing timeout type with pointer
- Comparing return to wrong constant
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 forpdPASSto 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 AQuick Check:
Wait 20 ticks, success check = if(xQueueSend(queue, &data, 20) == pdPASS) { // sent successfully } else { // alternative action } [OK]
- Using 0 ticks instead of 20
- Waiting forever with portMAX_DELAY
- Mixing up pdPASS and pdFAIL checks
Ready to prove it?
Pass the test and this pattern moves unknown
