FreeRTOS – LPC2148 Queue Tutorial

Hi guys… Today we are going to see FreeRTOS Queue Tutorial Using LPC2148.

Suggestion To Read

FreeRTOS Queue Tutorial Using LPC2148

Introduction

Queues are the primary form of intertask communications. They can be used to send messages between tasks, and between interrupts and tasks. In most cases they are used as thread safe FIFO (First In First Out) buffers with new data being sent to the back of the queue, although data can also be sent to the front.

queue_animation FreeRTOS - LPC2148 Queue Tutorial
Writing to and reading from a queue. In this example the queue was created to hold 5 items, and the queue never becomes full.

When a task attempts to read from an empty queue the task will be placed into the Blocked state (so it is not consuming any CPU time and other tasks can run) until either data becomes available on the queue, or the block time expires.

When a task attempts to write to a full queue the task will be placed into the Blocked state (so it is not consuming any CPU time and other tasks can run) until either space becomes available in the queue, or the block time expires.

If more than one task block on the same queue then the task with the highest priority will be the task that is unblocked first.

APIs Used

  • xQueueCreate()
  • vQueueDelete()
  • xQueuePeek()
  • xQueuePeekFromISR()
  • xQueueReceive()
  • xQueueReceiveFromISR()
  • xQueueSend()
  • xQueueSendToFront()
  • xQueueSendToBack()
  • xQueueSendFromISR()
  • xQueueSendToBackFromISR()
  • xQueueSendToFrontFromISR()

Now we will see one by one APIs.

xQueueCreate()

This API is used to create the queue.

#include “FreeRTOS.h”
#include “queue.h”

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,
                  UBaseType_t uxItemSize );

Creates a new queue and returns a handle by which the queue can be referenced.
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.

Parameters

  • uxQueueLength : The maximum number of items that the queue being created can hold at any one time.
  • uxItemSize : The size, in bytes, of each data item that can be stored in the queue.

Return Values

  • NULL The queue cannot be created because there is insufficient heap memory available for FreeRTOS to allocate the queue data structures and storage area.
  • Any other value The queue was created successfully. The returned value is a handle by which the created queue can be referenced.

Queues can be created before or after the scheduler has been started.

vQueueDelete()

Deletes a queue that was previously created using a call to xQueueCreate(). vQueueDelete() can also be used to delete a semaphore.

#include “FreeRTOS.h”
#include “queue.h”

void vQueueDelete( TaskHandle_t pxQueueToDelete );

Parameters

  • pxQueueToDelete The handle of the queue being deleted. Semaphore handles can also be used.

Return Values

  • None

Note

A queue/semaphore must not be deleted if there are any tasks currently blocked on it.

xQueuePeek()

Reads an item from a queue, but without removing the item from the queue. The same item will be returned the next time xQueueReceive() or xQueuePeek() is used to obtain an item from the same queue.

#include “FreeRTOS.h”
#include “queue.h”

BaseType_t xQueuePeek( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait );

Parameters

  • xQueue : The handle of the queue from which data is to be read.
  • pvBuffer : A pointer to the memory into which the data read from the queue will be copied. The length of the buffer must be at least equal to the queue item size. The item size will have been set by the uxItemSize parameter of the call to xQueueCreate() used to create the queue.
  • xTicksToWait : The maximum amount of time the task should remain in the Blocked state to wait for data to become available on the queue, should the queue already be empty. If xTicksToWait is zero, then xQueuePeek() will return immediately if the queue is already empty.

Return Values

  • pdPASS : Returned if data was successfully read from the queue. If a block time was specified (xTicksToWait was not zero), then it is possible that the calling task was placed into the Blocked state, to wait for data to become available on the queue, but data was successfully read from the queue before the block time expired.
  • errQUEUE_EMPTY : Returned if data cannot be read from the queue because the queue is already empty. If a block time was specified (xTicksToWait was not zero) then the calling task will have been placed into the Blocked state to wait for another task or interrupt to send data to the queue, but the block time expired before this happened.

xQueuePeekFromISR()

This is the version of xQueuePeek() that can be used from an interrupt service routine (ISR).
Reads an item from a queue, but without removing the item from the queue. The same item will be returned the next time xQueueReceive() or xQueuePeek() is used to obtain an item from the same queue.

#include “FreeRTOS.h”
#include “queue.h”

BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void *pvBuffer );

Parameters

  • xQueue : The handle of the queue from which data is to be read.
  • pvBuffer : A pointer to the memory into which the data read from the queue will be copied. The length of the buffer must be at least equal to the queue item size. The item size will have been set by the uxItemSize parameter of the call to xQueueCreate() used to create the queue.

Return Values

  • pdPASS : Returned if data was successfully read from the queue.
  • errQUEUE_EMPTY : Returned if data cannot be read from the queue because the queue is already empty.

xQueueReceive()

This API used to Receive (read) an item from a queue.

#include “FreeRTOS.h”
#include “queue.h”

BaseType_t xQueueReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait );

Parameters

  • xQueue : The handle of the queue from which the data is being received (read). The queue handle will have been returned from the call to xQueueCreate() used to create the queue.
  • pvBuffer : A pointer to the memory into which the received data will be copied. The length of the buffer must be at least equal to the queue item size. The item size will have been set by the uxItemSize parameter of the call to xQueueCreate() used to create the queue.
  • xTicksToWait : The maximum amount of time the task should remain in the Blocked state to wait for data to become available on the queue, should the queue already be empty. If xTicksToWait is zero, then xQueueReceive() will return immediately if the queue is already empty.

Return Values

  • pdPASS : Returned if data was successfully read from the queue. If a block time was specified (xTicksToWait was not zero), then it is possible that the calling task was placed into the Blocked state, to wait for data to become available on the queue, but data was successfully read from the queue before the block time expired.
  • errQUEUE_EMPTY : Returned if data cannot be read from the queue because the queue is already empty.

xQueueReceiveFromISR()

A version of xQueueReceive() that can be called from an ISR. Unlike xQueueReceive(), xQueueReceiveFromISR() does not permit a block time to be specified.

#include “FreeRTOS.h”
#include “queue.h”

BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken );

Parameters

  • xQueue : The handle of the queue from which the data is being received (read). The queue handle will have been returned from the call to xQueueCreate() used to create the queue.
  • pvBuffer : A pointer to the memory into which the received data will be copied. The length of the buffer must be at least equal to the queue item size. The item size will have been set by the uxItemSize parameter of the call to xQueueCreate() used to create the queue.
  • pxHigherPriorityTaskWoken : It is possible that a single queue will have one or more tasks blocked on it waiting for space to become available on the queue. Calling xQueueReceiveFromISR() can make space available, and so cause such a task to leave the Blocked state. If calling the API function causes a task to leave the Blocked state, and the unblocked task has a priority equal to or higher than the currently executing task (the task that was interrupted), then, internally, the API function will set *pxHigherPriorityTaskWoken to pdTRUE.  If xQueueReceiveFromISR() sets this value to pdTRUE, then a context switch should be performed before the interrupt is exited. This will ensure that the interrupt returns directly to the highest priority Ready state task.

Return Values

  • pdPASS : Data was successfully received from the queue.
  • pdFAIL : Data was not received from the queue because the queue was already empty.

Notes

Calling xQueueReceiveFromISR() within an interrupt service routine can potentially cause a task that was blocked on a queue to leave the Blocked state. A context switch should be performed if such an unblocked task has a priority higher than or equal to the currently executing task (the task that was interrupted). The context switch will ensure that the interrupt returns directly to the highest priority Ready state task. Unlike the xQueueReceive() API function, xQueueReceiveFromISR() will not itself perform a context switch. It will instead just indicate whether or not a context switch is required. xQueueReceiveFromISR() must not be called prior to the scheduler being started. Therefore an interrupt that calls xQueueReceiveFromISR() must not be allowed to execute prior to the scheduler being started.

xQueueSend(), xQueueSendToFront(), xQueueSendToBack()

It is used to Sends (writes) an item to the front or the back of a queue.
xQueueSend() and xQueueSendToBack() perform the same operation so are equivalent. Both send data to the back of a queue. xQueueSend() was the original version, and it is now recommended to use xQueueSendToBack() in its place.

#include “FreeRTOS.h”
#include “queue.h”

BaseType_t xQueueSend( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );

BaseType_t xQueueSendToFront( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );

BaseType_t xQueueSendToBack( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );

Parameters

  • xQueue : The handle of the queue to which the data is being sent (written). The queue handle will have been returned from the call to xQueueCreate() used to create the queue.
  • pvItemToQueue : A pointer to the data to be copied into the queue. The size of each item the queue can hold is set when the queue is created, and that many bytes will be copied from pvItemToQueue into the queue storage area.
  • xTicksToWait : The maximum amount of time the task should remain in the Blocked state to wait for space to become available on the queue, should the queue already be full. xQueueSend(), xQueueSendToFront() and xQueueSendToBack() will return immediately if xTicksToWait is zero and the queue is already full.

Return Values

  • pdPASS : Returned if data was successfully sent to the queue. If a block time was specified (xTicksToWait was not zero), then it is possible that the calling task was placed into the Blocked state, to wait for space to become available in the queue before the function returned, but data was successfully written to the queue before the block time expired.
  • errQUEUE_FULL : Returned if data could not be written to the queue because the queue was already full. If a block time was specified (xTicksToWait was not zero) then the calling task will have been placed into the Blocked state to wait for another task or interrupt to make room in the queue, but the specified block time expired before that happened.

xQueueSendFromISR(), xQueueSendToBackFromISR(), xQueueSendToFrontFromISR()

This is a Versions of the xQueueSend(), xQueueSendToFront() and xQueueSendToBack() API functions that can be called from an ISR. Unlike xQueueSend(), xQueueSendToFront() and xQueueSendToBack(), the ISR safe versions do not permit a block time to be specified. xQueueSendFromISR() and xQueueSendToBackFromISR() perform the same operation so are equivalent. Both send data to the back of a queue. xQueueSendFromISR() was the original version and it is now recommended to use xQueueSendToBackFromISR() in its place.

#include “FreeRTOS.h”
#include “queue.h”

BaseType_t xQueueSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken );

BaseType_t xQueueSendToBackFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );

BaseType_t xQueueSendToFrontFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );

Parameters

xQueue :The handle of the queue to which the data is being sent (written). The queue handle will have been returned from the call to xQueueCreate()  used to create the queue.

pvItemToQueue : A pointer to the data to be copied into the queue. The size of each item the queue can hold is set when the queue is created, and that many bytes will be copied from pvItemToQueue into the queue storage area.

pxHigherPriorityTaskWoken : It is possible that a single queue will have one or more tasks blocked on it waiting for data to become available. Calling xQueueSendFromISR(), xQueueSendToFrontFromISR() or xQueueSendToBackFromISR() can make data available, and so cause such a task to leave the Blocked state. If calling the API function causes a task to leave the Blocked state, and the unblocked task has a priority equal to or higher than the currently executing task (the task that was interrupted), then, internally, the API function will set *pxHigherPriorityTaskWoken to pdTRUE. If xQueueSendFromISR(), xQueueSendToFrontFromISR() or xQueueSendToBackFromISR() sets this value to pdTRUE, then a context switch should be performed before the interrupt is exited. This will ensure that the interrupt returns directly to the highest priority Ready state task.

Return Values

  • pdTRUE : Data was successfully sent to the queue.
  • errQUEUE_FULL : Data could not be sent to the queue because the queue was already full.

Code

Here i’ve created two tasks.

  1. Sender
  2. Receiver

Sender task will continuously sending data to queue. Receiver task always waiting for queue. If that queue contains any data, receiver task read that data and prints in serial terminal. Go through the below code. Then you will understand easily. This is only the main code. If you want to download the full project Please visit here.

Output

freertos-queue-tutorial FreeRTOS - LPC2148 Queue Tutorial[Download the Project Here]

Download our new Android app. You can learn all Embedded Tutorials from your Android Phone easily.

Click Here to Download App!