Actions

EmSys

FreeRTOS - Queue management

From EdWiki

Queue management

Characteristics of a Queue

  • Queue is used for inter-communication among autonomous tasks
  • A queue can hold a finite number of fixed size data items
  • Normally, it is First In First Out (FIFO) buffers
  • Writing data to a queue causes a byte for byte copy of data
  • Reading data from a queue will remove the data
  • Any number of tasks can write/read to/from the same queue

Blocking on Queue Reads

If the queue is empty, a task attempting to read from the queue will be blocked

  • When new data is placed into the queue, the blocked task will automatically be moved from the Blocked state to the Ready state
  • When multiple tasks are blocked, the task with the highest priority will be unblocked
  • If the blocked tasks have equal priority, the task that has been waiting for data the longest will be unblocked
  • The blocked task will also be automatically moved to the Ready state if the specified block time expires before data becomes available.

Blocking on Queue Writes

If the queue is already full, a task attempting to write to the queue will be blocked

  • When there is space available in the queue, the blocked task will automatically be moved from the Blocked state to the Ready state
  • When multiple tasks are blocked, the task waiting for space with the highest priority will be unblocked
  • If the blocked tasks have equal priority, the task that has been waiting for space the longest will be unblocked
  • The blocked task will also be automatically moved to the Ready state if the specified block time expires

Using a Queue

A queue must be explicitly created before it can be used. xQueueCreate() is used to create a queue and returns an xQueueHandle to reference the queue it creates.

xQueueHandle xQueueCreate(unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
  • 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 value
    If NULL is returned then the queue could not be created because there was insufficient heap memory available
    A non-NULL value being returned indicates that the queue was created successfully.

Write to a Queue

  • xQueueSendToFront() and xQueueSendToBack() is used to send data to the back/tail (front/head) of a queue
    They should never be called from an interrupt service routine
  • In ISRs, xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() should be used.

Read from a Queue

  • xQueueReceive() is used to receive (read) an item from a queue and the item is removed from the queue
  • xQueuePeek() is used to receive an item from a queue without the item being removed from the queue
  • In ISRs, xQueueReceiveFromISR() API function should be used

Query a Queue

  • uxQueueMessagesWaiting() is used to query the number of items that are currently in a queue
  • In ISRs, uxQueueMessagesWaitingFromISR() API function should be used

Working with Large Data

  • If the size of data being stored in the queue is large, it is preferable to use pointers to the data rather than copy the data itself
    More efficient in both processing time and the amount of RAM required
  • It is essential to ensure that both tasks do not modify the memory contents simultaneously
  • Dynamically allocated memory should be freed by exactly one task and no tasks should attempt to access the memory after it has been freed.