Mechatronic Zen Garden  0.1
This webpage contains documentation for the ME 507 term project: Mechatronic Zen Garden.
taskqueue.h
Go to the documentation of this file.
1 
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIB-
23  * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29  * THE POSSIBILITY OF SUCH DAMAGE. */
30 
31 // This define prevents this .h file from being included more than once
32 #ifndef _TASKQUEUE_H_
33 #define _TASKQUEUE_H_
34 
35 #include <Arduino.h>
36 #include "FreeRTOS.h" // Main header for FreeRTOS
37 #include "baseshare.h"
38 
39 
128 template <class dataType> class Queue : public BaseShare
129 {
130 // This protected data can only be accessed from this class or its
131 // descendents
132 protected:
133  QueueHandle_t handle;
134  TickType_t ticks_to_wait;
135  uint16_t buf_size;
136  uint16_t max_full;
137 
138 // Public methods can be called from anywhere in the program where there is
139 // a pointer or reference to an object of this class
140 public:
141  // The constructor creates a FreeRTOS queue
142  Queue (BaseType_t queue_size, const char* p_name = NULL,
143  TickType_t = portMAX_DELAY);
144 
145  // Put an item into the queue behind other items.
146  bool put (const dataType item);
147 
148  // This method puts an item of data into the back of the queue from
149  // within an interrupt service routine. It must not be used within
150  // non-ISR code.
151  bool ISR_put (const dataType item);
152 
167  bool butt_in (const dataType item)
168  {
169  return ((bool)(xQueueSendToFront (handle, &item, ticks_to_wait)));
170  }
171 
172  // This method puts an item into the front of the queue from within
173  // an ISR. It must not be used within normal, non-ISR code.
174  bool ISR_butt_in (const dataType item);
175 
182  bool is_empty (void)
183  {
184  return (uxQueueMessagesWaiting (handle) == 0);
185  }
186 
193  bool ISR_is_empty (void)
194  {
195  return (uxQueueMessagesWaitingFromISR (handle) == 0);
196  }
197 
208  void get (dataType& recv_item)
209  {
210  // If xQueueReceive doesn't return pdTrue, nothing was found in the
211  // queue, so no changes are made to the item
212  xQueueReceive (handle, &recv_item, ticks_to_wait);
213  }
214 
224  dataType get (void)
225  {
226  dataType return_this;
227  xQueueReceive (handle, &return_this, ticks_to_wait);
228  return return_this;
229  }
230 
238  void ISR_get (dataType& recv_item)
239  {
240  portBASE_TYPE task_awakened; // Checks if context switch needed
241 
242  // If xQueueReceive doesn't return pdTrue, nothing was found in the
243  // queue, so we won't change the data referenced in the parameter
244  xQueueReceiveFromISR (handle, &recv_item, &task_awakened);
245  }
246 
255  dataType ISR_get (void)
256  {
257  portBASE_TYPE task_awakened; // Checks if context switch needed
258 
259  dataType return_this;
260  xQueueReceiveFromISR (handle, &return_this, &task_awakened);
261  return return_this;
262  }
263 
275  void peek (dataType& recv_item)
276  {
277  // If xQueueReceive doesn't return pdTrue, nothing was found in the
278  // queue, so don't change the item
279  xQueuePeek (handle, &recv_item, ticks_to_wait);
280  }
281 
293  dataType peek (void)
294  {
295  dataType recv_item;
296  xQueuePeek (handle, &recv_item, ticks_to_wait);
297  return recv_item;
298  }
299 
310  void ISR_peek (dataType& recv_item)
311  {
312  portBASE_TYPE task_awakened; // Checks if a task will wake up
313 
314  // If xQueueReceive doesn't return pdTrue, nothing was found in the
315  // queue, so the value of recv_item is not changed
316  xQueuePeekFromISR (handle, &recv_item, &task_awakened);
317  }
318 
328  dataType ISR_peek (void)
329  {
330  portBASE_TYPE task_awakened; // Checks if a task will wake up
331  dataType recv_item;
332  xQueuePeekFromISR (handle, &recv_item, &task_awakened);
333  return recv_item;
334  }
335 
342  bool any (void)
343  {
344  return (uxQueueMessagesWaiting (handle) != 0);
345  }
346 
356  void operator << (dataType new_data)
357  {
358  if (CHECK_IF_IN_ISR ())
359  {
360  ISR_put (new_data);
361  }
362  else
363  {
364  put (new_data);
365  }
366  }
367 
380  void operator >> (dataType& put_here)
381  {
382  if (CHECK_IF_IN_ISR ())
383  {
384  portBASE_TYPE task_awakened; // Checks if context switch needed
385 
386  // Copy the data from the queue into the receiving variable
387  xQueueReceiveFromISR (handle, &put_here, &task_awakened);
388  }
389  else
390  {
391  xQueueReceive (handle, &put_here, ticks_to_wait);
392  }
393  }
394 
402  bool ISR_any (void)
403  {
404  return (uxQueueMessagesWaitingFromISR (handle) != 0);
405  }
406 
414  unsigned portBASE_TYPE available (void)
415  {
416  return (uxQueueMessagesWaiting (handle));
417  }
418 
425  unsigned portBASE_TYPE ISR_available (void)
426  {
427  return (uxQueueMessagesWaitingFromISR (handle));
428  }
429 
437  void print_in_list (Print& print_dev);
438 
444  bool usable (void)
445  {
446  return (bool)handle;
447  }
448 
458  QueueHandle_t get_handle (void)
459  {
460  return handle;
461  }
462 }; // class Queue
463 
464 
475 template <class dataType>
476 Queue<dataType>::Queue (BaseType_t queue_size, const char* p_name,
477  TickType_t wait_time)
478  : BaseShare (p_name)
479 {
480  // Create a FreeRTOS queue object with space for the data items
481  handle = xQueueCreate (queue_size, sizeof (dataType));
482 
483  // Store the wait time; it will be used when writing to the queue
484  ticks_to_wait = wait_time;
485 
486  // Save the buffer size
487  buf_size = queue_size;
488 
489  // We haven't stored any items in the queue yet
490  max_full = 0;
491 }
492 
493 
503 template <class dataType>
504 inline bool Queue<dataType>::put (const dataType item)
505 {
506  bool return_value = (bool)(xQueueSendToBack (handle, &item,
507  ticks_to_wait));
508 
509  // Keep track of the maximum fillage of the queue
510  uint16_t fillage = uxQueueMessagesWaiting (handle);
511  if (fillage > max_full)
512  {
513  max_full = fillage;
514  }
515 
516  return (return_value);
517 }
518 
519 
527 template <class dataType>
528 inline bool Queue<dataType>::ISR_put (const dataType item)
529 {
530  // This value is set true if a context switch should occur due to this data
531  signed portBASE_TYPE shouldSwitch = pdFALSE;
532 
533  bool return_value; // Value returned from this method
534 
535  // Call the FreeRTOS function and save its return value
536  return_value = (bool)(xQueueSendToBackFromISR (handle, &item,
537  &shouldSwitch));
538 
539  // Keep track of the maximum fillage of the queue. BUG: max_full isn't
540  // thread safe (but getting max_full corrupted shouldn't cause a calamity)
541  uint16_t fillage = uxQueueMessagesWaitingFromISR (handle);
542  if (fillage > max_full)
543  {
544  max_full = fillage;
545  }
546 
547  // Return the return value saved from the call to xQueueSendToBackFromISR()
548  return (return_value);
549 }
550 
551 
559 template <class dataType>
560 inline bool Queue<dataType>::ISR_butt_in (const dataType item)
561 {
562  // This value is set true if a context switch should occur due to this data
563  signed portBASE_TYPE shouldSwitch = pdFALSE;
564 
565  bool return_value; // Value returned from this method
566 
567  // Call the FreeRTOS function and save its return value
568  return_value = (bool)(xQueueSendToFrontFromISR (handle, &item,
569  &shouldSwitch));
570 
571  // Return the return value saved from the call to xQueueSendToBackFromISR()
572  return (return_value);
573 }
574 
575 
582 template <class dataType>
583 void Queue<dataType>::print_in_list (Print& print_dev)
584 {
585  // Print this task's name and pad it to 16 characters
586  print_dev.printf ("%-16squeue\t", name);
587 
588  // Print the free and total number of spaces in the queue or an error
589  // message if this queue can't be used (probably due to a memory error)
590  if (usable ())
591  {
592  print_dev << max_full << '/' << buf_size << endl;
593  }
594  else
595  {
596  print_dev << "UNUSABLE" << endl;
597  }
598 
599  // Call the next item
600  if (p_next != NULL)
601  {
602  p_next->print_in_list (print_dev);
603  }
604 }
605 
606 #endif // _TASKQUEUE_H_
Queue::ticks_to_wait
TickType_t ticks_to_wait
RTOS ticks to wait for empty.
Definition: taskqueue.h:134
Queue::ISR_any
bool ISR_any(void)
Return true if the queue has items in it, from within an ISR.
Definition: taskqueue.h:402
Queue::ISR_is_empty
bool ISR_is_empty(void)
Return true if the queue is empty, from within an ISR.
Definition: taskqueue.h:193
Queue::max_full
uint16_t max_full
Maximum number of bytes in queue.
Definition: taskqueue.h:136
Queue::ISR_put
bool ISR_put(const dataType item)
Put an item into the queue from within an ISR.
Definition: taskqueue.h:528
Queue::peek
void peek(dataType &recv_item)
Get the item at the queue head without removing it.
Definition: taskqueue.h:275
Queue::ISR_available
unsigned portBASE_TYPE ISR_available(void)
Return the number of items in the queue, to an ISR.
Definition: taskqueue.h:425
Queue::is_empty
bool is_empty(void)
Return true if the queue is empty.
Definition: taskqueue.h:182
Queue::get
dataType get(void)
Retrieve, remove, and return the item at the head of the queue.
Definition: taskqueue.h:224
Queue::any
bool any(void)
Return true if the queue has contents which can be read.
Definition: taskqueue.h:342
Queue::usable
bool usable(void)
Indicates whether this queue is usable.
Definition: taskqueue.h:444
Queue::ISR_peek
dataType ISR_peek(void)
Return a copy of the item at the front of the queue without deleting it, from within an ISR.
Definition: taskqueue.h:328
Queue::get_handle
QueueHandle_t get_handle(void)
Return a handle to the FreeRTOS structure which runs this queue.
Definition: taskqueue.h:458
Queue::available
unsigned portBASE_TYPE available(void)
Return the number of items in the queue.
Definition: taskqueue.h:414
Queue::operator<<
void operator<<(dataType new_data)
Operator which inserts data into the queue.
Definition: taskqueue.h:356
Queue::get
void get(dataType &recv_item)
Retrieve and remove the item at the head of the queue.
Definition: taskqueue.h:208
Queue::print_in_list
void print_in_list(Print &print_dev)
Print the queue's status to a serial device.
Definition: taskqueue.h:583
Queue::peek
dataType peek(void)
Return a copy of the item at the queue head without removing it.
Definition: taskqueue.h:293
Queue::butt_in
bool butt_in(const dataType item)
Put an item into the front of the queue to be retrieved first.
Definition: taskqueue.h:167
Queue::ISR_get
dataType ISR_get(void)
Retrieve, remove, and return the item at the head of the queue when called by ISR code.
Definition: taskqueue.h:255
Queue::handle
QueueHandle_t handle
Hhandle for the FreeTOS queue.
Definition: taskqueue.h:133
baseshare.h
Headers for a base class for type-safe, thread-safe task data exchange classes.
Queue::Queue
Queue(BaseType_t queue_size, const char *p_name=NULL, TickType_t=portMAX_DELAY)
Construct a queue object, allocating memory for the buffer.
Definition: taskqueue.h:476
Queue
Implements a queue to transmit data from one RTOS task to another.
Definition: taskqueue.h:129
Queue::buf_size
uint16_t buf_size
Size of queue buffer in bytes.
Definition: taskqueue.h:135
Queue::operator>>
void operator>>(dataType &put_here)
Read data from the queue.
Definition: taskqueue.h:380
Queue::ISR_butt_in
bool ISR_butt_in(const dataType item)
Put an item into the front of the queue from within an ISR.
Definition: taskqueue.h:560
Queue::ISR_get
void ISR_get(dataType &recv_item)
Remove the item at the head of the queue from within an ISR.
Definition: taskqueue.h:238
Queue::put
bool put(const dataType item)
Put an item into the queue behind other items.
Definition: taskqueue.h:504
Queue::ISR_peek
void ISR_peek(dataType &recv_item)
Get the item at the front of the queue without deleting it, from within an ISR.
Definition: taskqueue.h:310
BaseShare
Base class for classes that share data in a thread-safe manner between tasks.
Definition: baseshare.h:55