ME507 Utility Library
0.2.1
Mechatronics Course Support Software for ARM/Arduino/FreeRTOS
|
Class for data to be shared in a thread-safe manner between tasks. More...
#include <taskshare.h>
Public Member Functions | |
Share (const char *p_name=NULL) | |
Construct a shared data item. More... | |
void | put (DataType new_data) |
Put data into the shared data item. More... | |
void | ISR_put (DataType new_data) |
Put data into the shared data item from within an ISR. More... | |
void | operator<< (DataType new_data) |
Operator which inserts data into the share. More... | |
void | operator>> (DataType put_here) |
Read data from the shared data item. More... | |
void | get (DataType &recv_data) |
Read data from the shared data item into a variable. More... | |
DataType | get (void) |
Read and return data from the shared data item. More... | |
void | ISR_get (DataType &recv_data) |
Read data from the shared data item, from within an ISR. More... | |
DataType | ISR_get (void) |
Read and return data from the shared data item, from within an ISR. More... | |
void | print_in_list (Print &printer) |
Print the name and type (share) of this data item. More... | |
![]() | |
BaseShare (const char *p_name=NULL) | |
Construct a base shared data item. More... | |
Protected Attributes | |
QueueHandle_t | queue |
A queue is used to hold the data, as it's portable to different CPU's. | |
![]() | |
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... | |
Class for data to be shared in a thread-safe manner between tasks.
This class implements an item of data which can be shared between tasks without the risk of data corruption associated with global variables. Unlike queues, shares do not use a buffer for many data items; there is only a one-item buffer in which the most recent value of the data is kept. Shares therefore do not provide the task synchronization or incur the overhead associated with queues.
The data is protected by using critical code sections (see the FreeRTOS documentation of portENTER_CRITICAL()
) so that tasks can't interrupt each other when reading or writing the data is taking place. This prevents data corruption due to thread switching. The C++ template mechanism is used to ensure that only data of the correct type is put into or taken from a shared data item. A TaskShare<DataType>
object keeps its own separate copy of the data. This uses some memory, but it is necessary to reliably prevent data corruption; it prevents possible side effects from causing the sender's copy of the data from being inadvertently changed.
The following bits of code show how to set up and use a share to transfer data of type uint16_t
from one hypothetical task called task_A
to another called task_B
.
In the file which contains setup()
we create a shared data object. The constructor of the Share<uint16_t>
class is given a name for the share; the name will be shown on system diagnostic printouts. If it is desired to print diagnostic information to a serial monitor, a pointer to an output stream may also be given:
If there are any tasks which use this share in other source files, we must re-declare this share with the keyword extern
near the top of those files to make it accessible to those task(s). This copy of the share does not need a Doxygen comment:
In the sending task, data is put into the share:
In the receiving task, data is read from the share:
The Easy Way It's also possible to use overloaded stream insertion and extraction operators to interact with the share. These operators contain code which checks if they're running in an interrupt service routine (ISR) or not and use the appropriate method to interact with the internal queue which holds the data, so they're a little slower than put()
and get()
. Usage is as follows, assuming that the share and local variable have been set up above:
Construct a shared data item.
This constructor for a shared data item creates a queue in which to hold one item of data. Note that the data is not initialized.
p_name | A name to be shown in the list of task shares (default NULL ) |
|
inline |
Read data from the shared data item into a variable.
This method is used to read data from the shared data item with protection to ensure that the data cannot be corrupted by a task switch. The shared data is copied into the variable which is given as this method's parameter, replacing the previous contents of that variable.
recv_data | A reference to the variable in which to put received data |
|
inline |
Read and return data from the shared data item.
This method is used to read data from the shared data item with protection to ensure that the data cannot be corrupted by a task switch. A copy of the shared data is returned.
|
inline |
Read data from the shared data item, from within an ISR.
This method is used to enable code within an ISR to read data from the shared data item. It must only be called from within an interrupt service routine, not a normal task.
recv_data | A reference to the variable in which to put received data |
|
inline |
Read and return data from the shared data item, from within an ISR.
This method is used to enable code within an ISR to read data from the shared data item. It must only be called from within an interrupt service routine, not a normal task.
|
inline |
Put data into the shared data item from within an ISR.
This method writes data from an ISR into the shared data item. It must only be called from within an interrupt service routine, not a normal task.
new_data | The data to be written into the shared data item |
|
inline |
Operator which inserts data into the share.
This convenient operator puts data into the share, 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 share |
|
inline |
Read data from the shared data item.
This method is used to read data from the shared data item with critical section protection to ensure that the data cannot be corrupted by a task switch. The shared 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 because of the run-time ISR check.
put_here | A reference to the variable in which to put received data |
|
virtual |
Print the name and type (share) of this data item.
This method prints the share's name and a word indicating that it is a shared data item, as opposed to a queue, formatted to match similar printouts from other task shares such as queues. After printing this share's information, it looks in the linked list of shares for the next one and asks it to print its information too.
printer | Reference to a serial device on which to print the status |
Implements BaseShare.
|
inline |
Put data into the shared data item.
This method is used to write data into the shared data item.
new_data | The data which is to be written |