ME507 Utility Library  0.2.1
Mechatronics Course Support Software for ARM/Arduino/FreeRTOS
Queue< dataType > Class Template Reference

Implements a queue to transmit data from one RTOS task to another. More...

#include <taskqueue.h>

Inheritance diagram for Queue< dataType >:
Collaboration diagram for Queue< dataType >:

Public Member Functions

 Queue (BaseType_t queue_size, const char *p_name=NULL, TickType_t=portMAX_DELAY)
 Construct a queue object, allocating memory for the buffer. More...
 
bool put (const dataType item)
 Put an item into the queue behind other items. More...
 
bool ISR_put (const dataType item)
 Put an item into the queue from within an ISR. More...
 
bool butt_in (const dataType item)
 Put an item into the front of the queue to be retrieved first. More...
 
bool ISR_butt_in (const dataType item)
 Put an item into the front of the queue from within an ISR. More...
 
bool is_empty (void)
 Return true if the queue is empty. More...
 
bool ISR_is_empty (void)
 Return true if the queue is empty, from within an ISR. More...
 
void get (dataType &recv_item)
 Retrieve and remove the item at the head of the queue. More...
 
dataType get (void)
 Retrieve, remove, and return the item at the head of the queue. More...
 
void ISR_get (dataType &recv_item)
 Remove the item at the head of the queue from within an ISR. More...
 
dataType ISR_get (void)
 Retrieve, remove, and return the item at the head of the queue when called by ISR code. More...
 
void peek (dataType &recv_item)
 Get the item at the queue head without removing it. More...
 
dataType peek (void)
 Return a copy of the item at the queue head without removing it. More...
 
void ISR_peek (dataType &recv_item)
 Get the item at the front of the queue without deleting it, from within an ISR. More...
 
dataType ISR_peek (void)
 Return a copy of the item at the front of the queue without deleting it, from within an ISR. More...
 
bool any (void)
 Return true if the queue has contents which can be read. More...
 
void operator<< (dataType new_data)
 Operator which inserts data into the queue. More...
 
void operator>> (dataType &put_here)
 Read data from the queue. More...
 
bool ISR_any (void)
 Return true if the queue has items in it, from within an ISR. More...
 
unsigned portBASE_TYPE available (void)
 Return the number of items in the queue. More...
 
unsigned portBASE_TYPE ISR_available (void)
 Return the number of items in the queue, to an ISR. More...
 
void print_in_list (Print &print_dev)
 Print the queue's status to a serial device. More...
 
bool usable (void)
 Indicates whether this queue is usable. More...
 
QueueHandle_t get_handle (void)
 Return a handle to the FreeRTOS structure which runs this queue. More...
 
- Public Member Functions inherited from BaseShare
 BaseShare (const char *p_name=NULL)
 Construct a base shared data item. More...
 

Protected Attributes

QueueHandle_t handle
 Hhandle for the FreeTOS queue.
 
TickType_t ticks_to_wait
 RTOS ticks to wait for empty.
 
uint16_t buf_size
 Size of queue buffer in bytes.
 
uint16_t max_full
 Maximum number of bytes in queue.
 
- Protected Attributes inherited from BaseShare
char name [16]
 The name of the shared item. More...
 
BaseSharep_next
 Pointer to the next item in the linked list of shares. More...
 

Additional Inherited Members

- Static Protected Attributes inherited from BaseShare
static BaseSharep_newest = NULL
 Pointer to the most recently created shared data item. More...
 

Detailed Description

template<class dataType>
class Queue< dataType >

Implements a queue to transmit data from one RTOS task to another.

Since multithreaded tasks must not use unprotected shared data items for communication, queues are a primary means of intertask communication. Other means include shared data items (see taskshare.h) and carrier pigeons. The use of a C++ class template allows the compiler to check that you're putting the correct type of data into each queue and getting the correct type of data out, thus helping to prevent programming mistakes that can corrupt your data.

As a template class, Queue<dataType> can be used to make queues which hold data of many types. "Plain Old Data" types such as bool or uint16_t are supported, of course. But you can also use queues which hold compound data types. For example, if you have class my_data which holds several measurements together in an object, you can make a queue for my_data objects with Queue<my_data>. Each item in the queue will then hold several measurements.

The size of FreeRTOS queues is limited to 255 items in 8-bit microcontrollers whose portBASE_TYPE is an 8-bit number. This is a FreeRTOS feature.

Normal writing and reading are done with methods put() and get(). Normal writing means that the sending task must wait until there is empty space in the queue, and then it puts a data item into the "back" of the queue, where "back" means that the item in the back of the queue will be read after all items that were previously put into the queue have been read. Normal reading means that when an item is read from the front of the queue, it will then be removed, making space for more items at the back. This process is often used to synchronize tasks, as the reading task's get() method blocks, meaning that the reading task gets stuck waiting for an item to arrive in the queue; it won't do anything useful until new data has been read. Note that this is acceptable behavior in an RTOS because the RTOS scheduler will ensure that other tasks get to run even while the reading task is blocking itself waiting for data.

In some cases, one may need to use less normal reading and writing methods. Methods whose name begins with ISR_ are to be used only within a hardware interrupt service routine. If there is a need to put data at the front of the queue instead of the back, use butt_in() instead of put(). If one needs to read data from the queue without removing that data, the look_at() method allows this to be done. If something particularly unusual needs to be done with the queue, one can use the method get_handle() to retrieve the handle used by the C language functions in FreeRTOS to access the Queue object's underlying data structure directly.

Usage

The following bits of code show how to set up and use a queue to transfer data of type int16_t from one hypothetical task called task_A to another called task_B.

Near the top of the file which contains setup() we create a queue. The constructor of the Queue<int16_t> class is given the number of items in the queue (10 in this example) and an optional name for the queue:

#include "taskqueue.h"
...
/// This queue holds hockey puck accelerations
Queue<int16_t> hockey_queue (10, "Puckey");

In a location which is before we use the queue in any other file than the one in which the queue was created, we re-declare the queue with the keyword extern to make it accessible to any task within that file:

extern Queue<int16_t> hockey_queue;

In the sending task, data is put into the queue:

int16_t an_item = -3; ///< Local acceleration data
...
an_item = stick_sensor.get_data (2); // Read data from sensor
hockey_queue.put (a_data_item); // Put data into queue

In the receiving task, data is read from the queue. In typical usage, the call to get() will block the receiving task until data has been put into the queue by the sending task:

int16_t data_we_got; ///< Holds received data
...
hockey_queue.get (data_we_got); // Get data from the queue

Constructor & Destructor Documentation

◆ Queue()

template<class dataType >
Queue< dataType >::Queue ( BaseType_t  queue_size,
const char *  p_name = NULL,
TickType_t  wait_time = portMAX_DELAY 
)

Construct a queue object, allocating memory for the buffer.

This constructor creates the FreeRTOS queue which is wrapped by the Queue class.

Parameters
queue_sizeThe number of items which can be stored in the queue
p_nameA name to be shown in the list of task shares (default empty String)
wait_timeHow long, in RTOS ticks, to wait for a queue to become empty before a character can be sent. (Default: portMAX_DELAY, which causes the sending task to block until sending occurs.)

Member Function Documentation

◆ any()

template<class dataType >
bool Queue< dataType >::any ( void  )
inline

Return true if the queue has contents which can be read.

This method allows one to check if the queue has any contents. It must not be called from within an interrupt service routine.

Returns
true if there's something in the queue, false if not

◆ available()

template<class dataType >
unsigned portBASE_TYPE Queue< dataType >::available ( void  )
inline

Return the number of items in the queue.

This method returns the number of items waiting in the queue. It must not be called from within an interrupt service routine; the method ISR_num_items_in() can be called from within an ISR.

Returns
The number of items in the queue

◆ butt_in()

template<class dataType >
bool Queue< dataType >::butt_in ( const dataType  item)
inline

Put an item into the front of the queue to be retrieved first.

This method puts an item into the front of the queue so that it will be received first as long as nothing else is put in front of it. This is not the normal way to put things into a queue; using put() to put items into the back of the queue is. If you always use this method, you're making a stack rather than a queue, you weirdo. This method must not be used within an interrupt service routine.

Parameters
itemThe item which is going to be (rudely) put into the front of the queue
Returns
True if the item was successfully queued, false if not

◆ get() [1/2]

template<class dataType >
void Queue< dataType >::get ( dataType &  recv_item)
inline

Retrieve and remove the item at the head of the queue.

This method gets the item at the head of the queue and removes that item from the queue. If there's nothing in the queue, this method waits, blocking the calling task, for the number of RTOS ticks specified in the wait_time parameter to the queue constructor (the default is forever) or until something shows up.

Parameters
recv_itemA reference to the item to be filled with data from the queue

◆ get() [2/2]

template<class dataType >
dataType Queue< dataType >::get ( void  )
inline

Retrieve, remove, and return the item at the head of the queue.

This method gets the item at the head of the queue and removes it from the queue. A copy of the item's contents is returned. If there's nothing in the queue, this method waits, blocking the calling task, for the number of RTOS ticks specified in the wait_time parameter to the queue constructor (the default is forever) or until something shows up.

Returns
A copy of the contents of the queue item

◆ get_handle()

template<class dataType >
QueueHandle_t Queue< dataType >::get_handle ( void  )
inline

Return a handle to the FreeRTOS structure which runs this queue.

If somebody wants to do something which FreeRTOS queues can do but this class doesn't support, a handle for the queue wrapped by this class can be used to access the queue directly. This isn't commonly done.

Returns
The handle of the FreeRTOS queue which is wrapped within this C++ class

◆ is_empty()

template<class dataType >
bool Queue< dataType >::is_empty ( void  )
inline

Return true if the queue is empty.

This method checks if the queue is empty. It returns true if there are no items in the queue and false if there are items.

Returns
true if the queue is empty, false if it's not empty

◆ ISR_any()

template<class dataType >
bool Queue< dataType >::ISR_any ( void  )
inline

Return true if the queue has items in it, from within an ISR.

This method allows one to check if the queue has any contents from within an interrupt service routine. It must not be called from within normal, non-ISR code.

Returns
true if there's something in the queue, false if not

◆ ISR_available()

template<class dataType >
unsigned portBASE_TYPE Queue< dataType >::ISR_available ( void  )
inline

Return the number of items in the queue, to an ISR.

This method returns the number of items waiting in the queue; it must be called only from within an interrupt service routine.

Returns
The number of items in the queue

◆ ISR_butt_in()

template<class dataType >
bool Queue< dataType >::ISR_butt_in ( const dataType  item)
inline

Put an item into the front of the queue from within an ISR.

This method puts an item into the front of the queue from within an ISR. It must not be used within normal, non-ISR code.

Parameters
itemThe item which is going to be (rudely) put into the front of the queue
Returns
True if the item was successfully queued, false if not

◆ ISR_get() [1/2]

template<class dataType >
void Queue< dataType >::ISR_get ( dataType &  recv_item)
inline

Remove the item at the head of the queue from within an ISR.

This method gets and returns the item at the head of the queue from within an interrupt service routine. This method must not be called from within normal non-ISR code.

Parameters
recv_itemA reference to the item to be filled with data from the queue

◆ ISR_get() [2/2]

template<class dataType >
dataType Queue< dataType >::ISR_get ( void  )
inline

Retrieve, remove, and return the item at the head of the queue when called by ISR code.

This method gets the item at the head of the queue and removes it from the queue. A copy of the item's contents is returned. This method must not be called from within normal non-ISR code.

Returns
A copy of the contents of the queue item

◆ ISR_is_empty()

template<class dataType >
bool Queue< dataType >::ISR_is_empty ( void  )
inline

Return true if the queue is empty, from within an ISR.

This method checks if the queue is empty from within an interrupt service routine. It must not be used in normal non-ISR code.

Returns
true if the queue is empty, false if it's not empty

◆ ISR_peek() [1/2]

template<class dataType >
void Queue< dataType >::ISR_peek ( dataType &  recv_item)
inline

Get the item at the front of the queue without deleting it, from within an ISR.

This method returns the item at the head of the queue without removing that item from the queue. If there's nothing in the queue, this method doesn't change the value of the data given as its parameter. This method must only be called within an interrupt service routine.

Parameters
recv_itemA reference to the item to be filled with data from the queue

◆ ISR_peek() [2/2]

template<class dataType >
dataType Queue< dataType >::ISR_peek ( void  )
inline

Return a copy of the item at the front of the queue without deleting it, from within an ISR.

This method returns the item at the head of the queue without removing that item from the queue. If there's nothing in the queue, this method returns a default value of the type of data in the queue. This method must only be called within an interrupt service routine.

Returns
A copy of the data in the queue

◆ ISR_put()

template<class dataType >
bool Queue< dataType >::ISR_put ( const dataType  item)
inline

Put an item into the queue from within an ISR.

This method puts an item of data into the back of the queue from within an interrupt service routine. It must not be used within non-ISR code.

Parameters
itemThe item which is going to be put into the queue
Returns
True if the item was successfully queued, false if not

◆ operator<<()

template<class dataType >
void Queue< dataType >::operator<< ( dataType  new_data)
inline

Operator which inserts data into the queue.

This convenient operator puts data into the queue, protecting the data from corruption by thread switching. It checks if the processor is currently in an interupt service routine (ISR); if so, it calls ISR specific functions to prevent corruption, so this function may be used within an ISR or outside one. It runs a little more slowly than the put() method.

Parameters
new_dataThe data which is to be put into the queue

◆ operator>>()

template<class dataType >
void Queue< dataType >::operator>> ( dataType &  put_here)
inline

Read data from the queue.

This method is used to read data from the queue . The retrieved data is copied into the variable which is given as this method's parameter, replacing the previous contents. This method checks if the processor is currently in an interupt service routine (ISR) and if so, it calls ISR specific functions to prevent corruption, so this function may be used within an ISR or outside one. It runs a little more slowly than the get() method.

Parameters
put_hereA reference to the variable in which to put received data

◆ peek() [1/2]

template<class dataType >
void Queue< dataType >::peek ( dataType &  recv_item)
inline

Get the item at the queue head without removing it.

This method gets the item at the head of the queue without removing that item from the queue. If there's nothing in the queue this method waits, blocking the calling task, for for the number of RTOS ticks specified in the wait_time parameter to the queue constructor (the default is forever) or until something shows up. This method must not be called from within an interrupt service routine.

Parameters
recv_itemA reference to a variable to be filled with data from the queue item

◆ peek() [2/2]

template<class dataType >
dataType Queue< dataType >::peek ( void  )
inline

Return a copy of the item at the queue head without removing it.

This method returns the item at the head of the queue without removing that item from the queue. If there's nothing in the queue this method waits, blocking the calling task, for for the number of RTOS ticks specified in the wait_time parameter to the queue constructor (the default is forever) or until something shows up. This method must not be called from within an interrupt service routine.

Returns
A copy of the data in the item at the head of the queue

◆ print_in_list()

template<class dataType >
void Queue< dataType >::print_in_list ( Print &  print_dev)
virtual

Print the queue's status to a serial device.

This method makes a printout of the queue's status on the given serial device, then calls this same method for the next item of thread-safe data in the linked list of items.

Parameters
print_devReference to the serial device on which to print

Implements BaseShare.

◆ put()

template<class dataType >
bool Queue< dataType >::put ( const dataType  item)
inline

Put an item into the queue behind other items.

This method puts an item of data into the back of the queue, which is the normal way to put something into a queue. If you want to be rude and put an item into the front of the queue so it will be retrieved first, use butt_in() instead. This method must not be used within an Interrupt Service Routine.

Parameters
itemThe item which is going to be put into the queue
Returns
True if the item was successfully queued, false if not

◆ usable()

template<class dataType >
bool Queue< dataType >::usable ( void  )
inline

Indicates whether this queue is usable.

This method returns a value which is true if this queue has been successfully set up and can be used.

Returns
true if this queue is usable, false if not

The documentation for this class was generated from the following file:
taskqueue.h
Queue
Implements a queue to transmit data from one RTOS task to another.
Definition: taskqueue.h:128
Queue::put
bool put(const dataType item)
Put an item into the queue behind other items.
Definition: taskqueue.h:504