Sometimes many parts of a program want to send data to one place. This setup helps collect all that data safely and in order.
Multiple producers single consumer in FreeRTOS
/* Create a queue for communication */ QueueHandle_t xQueue = xQueueCreate(queueLength, itemSize); /* Producer task sends data */ xQueueSend(xQueue, &data, portMAX_DELAY); /* Consumer task receives data */ xQueueReceive(xQueue, &receivedData, portMAX_DELAY);
xQueueCreate makes a queue that holds items of fixed size.
xQueueSend adds data to the queue from producers.
QueueHandle_t xQueue = xQueueCreate(5, sizeof(int)); // Producer task int value = 10; xQueueSend(xQueue, &value, portMAX_DELAY); // Consumer task int receivedValue; xQueueReceive(xQueue, &receivedValue, portMAX_DELAY);
/* Multiple producers sending different values */ int val1 = 1, val2 = 2; xQueueSend(xQueue, &val1, 0); xQueueSend(xQueue, &val2, 0);
This program creates one queue and three tasks: two producers and one consumer. Each producer sends three numbers. The consumer receives all six numbers and prints them.
#include "FreeRTOS.h" #include "task.h" #include "queue.h" #include <stdio.h> QueueHandle_t xQueue; void vProducerTask(void *pvParameters) { int producerId = (int)(intptr_t)pvParameters; for (int i = 0; i < 3; i++) { int value = producerId * 10 + i; xQueueSend(xQueue, &value, portMAX_DELAY); printf("Producer %d sent %d\n", producerId, value); vTaskDelay(pdMS_TO_TICKS(100)); } vTaskDelete(NULL); } void vConsumerTask(void *pvParameters) { int receivedValue; for (int i = 0; i < 6; i++) { xQueueReceive(xQueue, &receivedValue, portMAX_DELAY); printf("Consumer received %d\n", receivedValue); } vTaskDelete(NULL); } int main(void) { xQueue = xQueueCreate(10, sizeof(int)); if (xQueue == NULL) { printf("Queue creation failed!\n"); return 1; } xTaskCreate(vProducerTask, "Producer1", 1000, (void *)(intptr_t)1, 1, NULL); xTaskCreate(vProducerTask, "Producer2", 1000, (void *)(intptr_t)2, 1, NULL); xTaskCreate(vConsumerTask, "Consumer", 1000, NULL, 2, NULL); vTaskStartScheduler(); for(;;); return 0; }
Make sure the queue is big enough to hold all items to avoid blocking producers.
Use portMAX_DELAY to wait indefinitely when sending or receiving.
Consumer priority is usually higher to process data quickly.
Multiple producers can safely send data to one consumer using a FreeRTOS queue.
Queues keep data in order and prevent conflicts.
Use xQueueSend and xQueueReceive to communicate.
Practice
In FreeRTOS, when multiple producers send data to a single consumer using a queue, what ensures that data is received in the correct order?
Solution
Step 1: Understand FreeRTOS queue behavior
FreeRTOS queues store data in the order it is sent, preserving sequence.Step 2: Analyze producer-consumer interaction
Multiple producers send data to one queue; the queue keeps data ordered for the consumer.Final Answer:
The queue maintains the order of data sent by producers. -> Option DQuick Check:
Queue order = correct data sequence [OK]
- Thinking each producer needs its own queue
- Assuming consumer sorts data
- Believing producers wait for consumer readiness
Which of the following is the correct way to send data to a FreeRTOS queue from a producer task?
QueueHandle_t xQueue;
int data = 10;
// Which function call is correct?Solution
Step 1: Identify the function to send data
xQueueSend is used to send data to a queue in FreeRTOS.Step 2: Confirm parameters
xQueueSend takes the queue handle, pointer to data, and wait time (portMAX_DELAY waits indefinitely).Final Answer:
xQueueSend(xQueue, &data, portMAX_DELAY); -> Option CQuick Check:
Send data = xQueueSend [OK]
- Using xQueueReceive to send data
- Confusing queue creation with sending
- Deleting queue instead of sending
Consider this FreeRTOS code snippet where two producer tasks send integers to a queue and one consumer task receives them:
QueueHandle_t xQueue = xQueueCreate(5, sizeof(int));
// Producer 1 sends 1
xQueueSend(xQueue, &(int){1}, 0);
// Producer 2 sends 2
xQueueSend(xQueue, &(int){2}, 0);
int receivedValue;
xQueueReceive(xQueue, &receivedValue, 0);
printf("%d", receivedValue);What will be printed?
Solution
Step 1: Analyze the order of sending
Producer 1 sends 1 first, then Producer 2 sends 2 to the queue.Step 2: Understand queue receive behavior
xQueueReceive reads the first item in the queue, which is 1.Final Answer:
1 -> Option AQuick Check:
First sent = first received = 1 [OK]
- Assuming last sent is received first
- Thinking receive returns 0 by default
- Confusing send and receive functions
In a FreeRTOS system with multiple producers and one consumer, the consumer task sometimes blocks indefinitely waiting on xQueueReceive. What is the most likely cause?
Solution
Step 1: Understand blocking on xQueueReceive
If the consumer blocks indefinitely, it means no data is available in the queue.Step 2: Identify why no data is available
Most likely, producers are not sending data, so the queue remains empty.Final Answer:
Producers never send data to the queue. -> Option AQuick Check:
No data sent = consumer blocks [OK]
- Blaming queue size for blocking
- Mixing send and receive functions
- Ignoring queue deletion effects
You have three producer tasks sending sensor readings to a single consumer task via a FreeRTOS queue. The queue size is 5. If all producers send data rapidly, what is the best way to avoid losing data?
Solution
Step 1: Understand queue overflow risk
If producers send data faster than consumer processes, queue fills and data can be lost.Step 2: Choose solution to prevent data loss
Increasing queue size or blocking send calls (like xQueueSendToBack with wait) lets producers wait instead of losing data.Final Answer:
Increase the queue size or use xQueueSendToBack with blocking wait. -> Option BQuick Check:
Prevent overflow = bigger queue or blocking send [OK]
- Using separate queues without consumer changes
- Making consumer sleep longer causes more overflow
- Deleting queue causes data loss
Ready to prove it?
Pass the test and this pattern moves unknown
