ME507 Utility Library
0.2.1
Mechatronics Course Support Software for ARM/Arduino/FreeRTOS
|
Implements a queue to transmit data from one RTOS task to another. More...
#include <taskqueue.h>
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... | |
![]() | |
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. | |
![]() | |
char | name [16] |
The name of the shared item. More... | |
BaseShare * | p_next |
Pointer to the next item in the linked list of shares. More... | |
Additional Inherited Members | |
![]() | |
static BaseShare * | p_newest = NULL |
Pointer to the most recently created shared data item. More... | |
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.
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:
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:
In the sending task, data is put into the 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:
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.
queue_size | The number of items which can be stored in the queue |
p_name | A name to be shown in the list of task shares (default empty String) |
wait_time | How 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.) |
|
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.
true
if there's something in the queue, false
if not
|
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.
|
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.
item | The item which is going to be (rudely) put into the front of the queue |
True
if the item was successfully queued, false if not
|
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.
recv_item | A reference to the item to be filled with data from the queue |
|
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.
|
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.
|
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.
true
if the queue is empty, false
if it's not empty
|
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.
true
if there's something in the queue, false
if not
|
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.
|
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.
item | The item which is going to be (rudely) put into the front of the queue |
|
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.
recv_item | A reference to the item to be filled with data from the queue |
|
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.
|
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.
true
if the queue is empty, false
if it's not empty
|
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.
recv_item | A reference to the item to be filled with data from the queue |
|
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.
|
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.
item | The item which is going to be put into the queue |
|
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.
new_data | The data which is to be put into the queue |
|
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.
put_here | A reference to the variable in which to put received data |
|
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.
recv_item | A reference to a variable to be filled with data from the queue item |
|
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.
|
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.
print_dev | Reference to the serial device on which to print |
Implements BaseShare.
|
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.
item | The item which is going to be put into the queue |
|
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.
true
if this queue is usable, false
if not