Home | Projects | Notes > Real-Time Operating Systems (RTOS) > FreeRTOS Queue Management
Items are enqueued to the front (or head) of the queue, and dequeued from the back (or tail) of the queue.
FreeRTOS API to create a queue:
xxxxxxxxxx
71/* queue.h */
2
3// Param : @uxQueueLength - Max number of items the queue can hold at any one time
4// @uxItemSize - // Size of a single item in bytes
5// Retval : A handle (a pointer) to the created queue if successful, NULL otherwise.
6QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,
7 UBaseType_t uxItemSize );
Creates a new queue and returns a handle by which the queue can be referenced. configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h
, or left undefined (in which case it will default to 1), for this RTOS API function to be available.
Each queue requires RAM that is used to hold the queue state, and to hold the items that are contained in the queue (the queue storage area).
If a queue is created using xQueueCreate()
then the required RAM is automatically allocated from the FreeRTOS heap.
If a queue is created using xQueueCreateStatic() then the RAM is provided by the application writer, which results in a greater number of parameters, but allows the RAM to be statically allocated at compile time. See the Static Vs Dynamic allocation page for more information.
Example usage:
xxxxxxxxxx
301struct AMessage
2{
3 char ucMessageID;
4 char ucData[ 20 ];
5};
6
7void vATask( void *pvParameters )
8{
9QueueHandle_t xQueue1, xQueue2;
10
11 /* Create a queue capable of containing 10 unsigned long values. */
12 xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
13
14 if( xQueue1 == NULL )
15 {
16 /* Queue was not created and must not be used. */
17 }
18
19 /* Create a queue capable of containing 10 pointers to AMessage
20 structures. These are to be queued by pointers as they are
21 relatively large structures. */
22 xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
23
24 if( xQueue2 == NULL )
25 {
26 /* Queue was not created and must not be used. */
27 }
28
29 /* ... Rest of task code. */
30 }
L22: Making the type of items 'pointer' to an object of large size can be a great strategy to save space consumed by queues.
Two ways to send data to the queue:
xQueueSendToFront()
xQueueSendToBack()
xQueueSendToFront()
This is a macro that calls xQueueGenericSend()
.
xxxxxxxxxx
151/* queue.h */
2
3// Brief : Posts an item to the front of the queue
4// Param : @xQueue - The handle to the queue on which the item is to be posted
5// @pvItemToQueue - A pointer to the item that is to be placed on the queue
6// @xTicksToWait - The maximum amount of time the task should block waiting
7// for space to become available on the queue, should it already
8// be full. The call will return immediately if this is set to 0.
9// The time is defined in tick periods so the constant
10// portTICK_PERIOD_MS should be used to convert to real time if
11// this is required.
12// Retval : pdTRUE if the item was successfully posted, errQUEUE_FULL otherwise
13BaseType_t xQueueSendToFront( QueueHandle_t xQueue,
14 const void * pvItemToQueue,
15 TickType_t xTicksToWait );
Example usage:
xxxxxxxxxx
451struct AMessage
2{
3 char ucMessageID;
4 char ucData[ 20 ];
5} xMessage;
6
7unsigned long ulVar = 10UL;
8
9void vATask( void *pvParameters )
10{
11QueueHandle_t xQueue1, xQueue2;
12struct AMessage *pxMessage;
13
14 /* Create a queue capable of containing 10 unsigned long values. */
15 xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
16
17 /* Create a queue capable of containing 10 pointers to AMessage
18 structures. These should be passed by pointer as they contain a lot of
19 data. */
20 xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
21
22 /* ... */
23
24 if( xQueue1 != 0 )
25 {
26 /* Send an unsigned long. Wait for 10 ticks for space to become
27 available if necessary. */
28 if( xQueueSendToFront( xQueue1,
29 ( void * ) &ulVar,
30 ( TickType_t ) 10 ) != pdPASS )
31 {
32 /* Failed to post the message, even after 10 ticks. */
33 }
34 }
35
36 if( xQueue2 != 0 )
37 {
38 /* Send a pointer to a struct AMessage object. Don't block if the
39 queue is already full. */
40 pxMessage = & xMessage;
41 xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
42 }
43
44 /* ... Rest of task code. */
45}
xQueueSendToBack()
This is a macro that calls xQueueGenericSend()
.
xxxxxxxxxx
61/* queue.h */
2
3// Brief : Posts an item to the back of the queue
4BaseType_t xQueueSendToBack( QueueHandle_t xQueue,
5 const void * pvItemToQueue,
6 TickType_t xTicksToWait );
Similar to the xQueueSendToFront()
. See the FreeRTOS kernel API documentation for more details.
Two ways to receive data to the queue:
xQueueReceive()
xQueuePeek()
xQueueReceive()
This is a macro that calls the xQueueGenericReceive()
function.
It removes an item from the queue.
xxxxxxxxxx
171/* queue.h */
2
3// Brief : Receive an item from a queue. The item is received by copy so a buffer of
4// adequate size must be provided. The number of bytes copied into the buffer
5// was defined when the queue was created.
6// Param : @xQueue - The handle to the queue from which the item is to be received.
7// @pvBuffer - Pointer to the buffer into which the received item will be copied.
8// @xTicksToWait - The maximum amount of time the task should block waiting for
9// an item to receive should the queue be empty at the time of
10// the call. Setting xTicksToWait to 0 will cause the function
11// to return immediately if the queue is empty. The time is
12// defined in tick periods so the constant portTICK_PERIOD_MS
13// should be used to convert to real time if this is required.
14// Retval : pdTRUE if an item was successfully received from the queue, pdFALSE otherwise.
15BaseType_t xQueueReceive( QueueHandle_t xQueue,
16 void *pvBuffer,
17 TickType_t xTicksToWait );
xQueuePeek()
This is a macro that calls the xQueueGenericReceive()
function.
It does NOT remove an item from the queue.
xxxxxxxxxx
181/* queue.h */
2
3// Brief : Receive an item from a queue without removing the item from the queue.
4// The item is received by copy so a buffer of adequate size must be provided.
5// The number of bytes copied into the buffer was defined when the queue was
6// created.
7// Param : @xQueue - The handle to the queue from which the item is to be received.
8// @pvBuffer - Pointer to the buffer into which the received item will be copied.
9// @xTicksToWait - The maximum amount of time the task should block waiting for
10// an item to receive should the queue be empty at the time of
11// the call. Setting xTicksToWait to 0 will cause the function
12// to return immediately if the queue is empty. The time is
13// defined in tick periods so the constant portTICK_PERIOD_MS
14// should be used to convert to real time if this is required.
15// Retval : pdTRUE if an item was successfully received (peeked) from the queue, otherwise pdFALSE.
16BaseType_t xQueuePeek( QueueHandle_t xQueue,
17 void *pvBuffer,
18 TickType_t xTicksToWait );
Nayak, K. (2022). Mastering RTOS: Hands on FreeRTOS and STM32Fx with Debugging [Video file]. Retrieved from https://www.udemy.com/course/mastering-rtos-hands-on-with-freertos-arduino-and-stm32fx/