FreeRTOS-Cpp
Queue.hpp
1 /*
2  * FreeRTOS-Cpp
3  * Copyright (C) 2021 Jon Enz. All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * https://github.com/jonenz/FreeRTOS-Cpp
26  */
27 
28 #ifndef FREERTOS_QUEUE_HPP
29 #define FREERTOS_QUEUE_HPP
30 
31 #include <optional>
32 
33 #include "FreeRTOS.h"
34 #include "queue.h"
35 
36 namespace FreeRTOS {
37 
49 template <class T>
50 class QueueBase {
51  public:
52  template <class>
53  friend class Queue;
54 
55  template <class, UBaseType_t>
56  friend class StaticQueue;
57 
58  QueueBase(const QueueBase&) = delete;
59  QueueBase& operator=(const QueueBase&) = delete;
60 
61  static void* operator new(size_t, void* ptr) { return ptr; }
62  static void* operator new[](size_t, void* ptr) { return ptr; }
63  static void* operator new(size_t) = delete;
64  static void* operator new[](size_t) = delete;
65 
75  inline bool isValid() const { return (handle != NULL); }
76 
102  inline bool sendToBack(const T& item,
103  const TickType_t ticksToWait = portMAX_DELAY) const {
104  return (xQueueSendToBack(handle, &item, ticksToWait) == pdTRUE);
105  }
106 
125  inline bool sendToBackFromISR(bool& higherPriorityTaskWoken,
126  const T& item) const {
127  BaseType_t taskWoken = pdFALSE;
128  bool result =
129  (xQueueSendToBackFromISR(handle, &item, &taskWoken) == pdPASS);
130  if (taskWoken == pdTRUE) {
131  higherPriorityTaskWoken = true;
132  }
133  return result;
134  }
135 
146  inline bool sendToBackFromISR(const T& item) const {
147  return (xQueueSendToBackFromISR(handle, &item, NULL) == pdPASS);
148  }
149 
170  inline bool sendToFront(const T& item,
171  const TickType_t ticksToWait = portMAX_DELAY) const {
172  return (xQueueSendToFront(handle, &item, ticksToWait) == pdTRUE);
173  }
174 
193  inline bool sendToFrontFromISR(bool& higherPriorityTaskWoken,
194  const T& item) const {
195  BaseType_t taskWoken = pdFALSE;
196  bool result =
197  (xQueueSendToFrontFromISR(handle, &item, &taskWoken) == pdPASS);
198  if (taskWoken == pdTRUE) {
199  higherPriorityTaskWoken = true;
200  }
201  return result;
202  }
203 
214  inline bool sendToFrontFromISR(const T& item) const {
215  return (xQueueSendToFrontFromISR(handle, &item, NULL) == pdPASS);
216  }
217 
242  inline std::optional<T> receive(
243  const TickType_t ticksToWait = portMAX_DELAY) const {
244  T buffer;
245  return (xQueueReceive(handle, &buffer, ticksToWait) == pdTRUE)
246  ? std::optional<T>(buffer)
247  : std::nullopt;
248  }
249 
271  inline std::optional<T> receiveFromISR(bool& higherPriorityTaskWoken) const {
272  T buffer;
273  BaseType_t taskWoken = pdFALSE;
274  bool result = (xQueueReceiveFromISR(handle, &buffer, &taskWoken) == pdTRUE);
275  if (taskWoken == pdTRUE) {
276  higherPriorityTaskWoken = true;
277  }
278  return result ? std::optional<T>(buffer) : std::nullopt;
279  }
280 
292  inline std::optional<T> receiveFromISR() const {
293  T buffer;
294  return (xQueueReceiveFromISR(handle, &buffer, NULL) == pdTRUE)
295  ? std::optional<T>(buffer)
296  : std::nullopt;
297  }
298 
311  inline UBaseType_t messagesWaiting() const {
312  return uxQueueMessagesWaiting(handle);
313  }
314 
328  inline UBaseType_t messagesWaitingFromISR() const {
329  return uxQueueMessagesWaitingFromISR(handle);
330  }
331 
344  inline UBaseType_t spacesAvailable() const {
345  return uxQueueSpacesAvailable(handle);
346  }
347 
358  inline void reset() const { xQueueReset(handle); }
359 
382  inline void overwrite(const T& item) const { xQueueOverwrite(handle, &item); }
383 
410  inline void overwriteFromISR(bool& higherPriorityTaskWoken,
411  const T& item) const {
412  BaseType_t taskWoken = pdFALSE;
413  xQueueOverwriteFromISR(handle, &item, &taskWoken);
414  if (taskWoken == pdTRUE) {
415  higherPriorityTaskWoken = true;
416  }
417  }
418 
430  inline void overwriteFromISR(const T& item) const {
431  xQueueOverwriteFromISR(handle, &item, NULL);
432  }
433 
463  inline std::optional<T> peek(
464  const TickType_t ticksToWait = portMAX_DELAY) const {
465  T buffer;
466  return (xQueuePeek(handle, &buffer, ticksToWait) == pdTRUE)
467  ? std::optional<T>(buffer)
468  : std::nullopt;
469  }
470 
490  inline std::optional<T> peekFromISR() const {
491  T buffer;
492  return (xQueuePeekFromISR(handle, &buffer) == pdTRUE)
493  ? std::optional<T>(buffer)
494  : std::nullopt;
495  }
496 
526  inline void addToRegistry(const char* name) const {
527  vQueueAddToRegistry(handle, name);
528  }
529 
545  inline void unregister() const { vQueueUnregisterQueue(handle); }
546 
562  inline const char* getName() const { return pcQueueGetName(handle); }
563 
578  inline bool isFullFromISR() const {
579  return (xQueueIsQueueFullFromISR(handle) == pdTRUE);
580  }
581 
596  inline bool isEmptyFromISR() const {
597  return (xQueueIsQueueEmptyFromISR(handle) == pdTRUE);
598  }
599 
600  private:
610  QueueBase() = default;
611 
623  ~QueueBase() { vQueueDelete(this->handle); }
624 
625  QueueBase(QueueBase&&) noexcept = default;
626  QueueBase& operator=(QueueBase&&) noexcept = default;
627 
631  QueueHandle_t handle = NULL;
632 };
633 
634 #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
635 
648 template <class T>
649 class Queue : public QueueBase<T> {
650  public:
669  explicit Queue(const UBaseType_t length) {
670  this->handle = xQueueCreate(length, sizeof(T));
671  }
672  ~Queue() = default;
673 
674  Queue(const Queue&) = delete;
675  Queue& operator=(const Queue&) = delete;
676 
677  Queue(Queue&&) noexcept = default;
678  Queue& operator=(Queue&&) noexcept = default;
679 };
680 
681 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
682 
683 #if (configSUPPORT_STATIC_ALLOCATION == 1)
684 
697 template <class T, UBaseType_t N>
698 class StaticQueue : public QueueBase<T> {
699  public:
718  this->handle = xQueueCreateStatic(N, sizeof(T), storage, &staticQueue);
719  }
720  ~StaticQueue() = default;
721 
722  StaticQueue(const StaticQueue&) = delete;
723  StaticQueue& operator=(const StaticQueue&) = delete;
724 
725  StaticQueue(StaticQueue&&) noexcept = default;
726  StaticQueue& operator=(StaticQueue&&) noexcept = default;
727 
728  private:
729  StaticQueue_t staticQueue;
730  uint8_t storage[N * sizeof(T)];
731 };
732 
733 #endif /* configSUPPORT_STATIC_ALLOCATION */
734 
735 } // namespace FreeRTOS
736 
737 #endif // FREERTOS_QUEUE_HPP
Base class that provides the standard queue interface to FreeRTOS::Queue and FreeRTOS::StaticQueue.
Definition: Queue.hpp:50
bool sendToBackFromISR(bool &higherPriorityTaskWoken, const T &item) const
Function that calls xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
Definition: Queue.hpp:125
const char * getName() const
Function that calls const char *pcQueueGetName( QueueHandle_t xQueue )
Definition: Queue.hpp:562
bool isFullFromISR() const
Function that calls BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
Definition: Queue.hpp:578
bool sendToFrontFromISR(const T &item) const
Function that calls xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
Definition: Queue.hpp:214
std::optional< T > peekFromISR() const
Function that calls BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void *pvBuffer )
Definition: Queue.hpp:490
void overwriteFromISR(bool &higherPriorityTaskWoken, const T &item) const
Function that calls BaseType_t xQueueOverwriteFromISR( QueueHandle_t xQueue, const void * pvItemToQue...
Definition: Queue.hpp:410
QueueHandle_t handle
Handle used to refer to the queue when using the FreeRTOS interface.
Definition: Queue.hpp:631
bool sendToBackFromISR(const T &item) const
Function that calls xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
Definition: Queue.hpp:146
void reset() const
Function that calls BaseType_t xQueueReset( QueueHandle_t xQueue )
Definition: Queue.hpp:358
UBaseType_t messagesWaitingFromISR() const
Function that calls UBaseType_t uxQueueMessagesWaitingFromISR( QueueHandle_t xQueue )
Definition: Queue.hpp:328
UBaseType_t messagesWaiting() const
Function that calls UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue )
Definition: Queue.hpp:311
UBaseType_t spacesAvailable() const
Function that calls UBaseType_t uxQueueSpacesAvailable( QueueHandle_t xQueue )
Definition: Queue.hpp:344
std::optional< T > peek(const TickType_t ticksToWait=portMAX_DELAY) const
Function that calls BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer,...
Definition: Queue.hpp:463
QueueBase()=default
Construct a new QueueBase object.
void addToRegistry(const char *name) const
Function that calls void vQueueAddToRegistry( QueueHandle_t xQueue, char *pcQueueName )
Definition: Queue.hpp:526
void unregister() const
Function that calls void vQueueUnregisterQueue( QueueHandle_t xQueue )
Definition: Queue.hpp:545
void overwriteFromISR(const T &item) const
Function that calls BaseType_t xQueueOverwriteFromISR( QueueHandle_t xQueue, const void * pvItemToQue...
Definition: Queue.hpp:430
bool sendToBack(const T &item, const TickType_t ticksToWait=portMAX_DELAY) const
Function that calls xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait )
Definition: Queue.hpp:102
std::optional< T > receiveFromISR() const
Function that calls BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer,...
Definition: Queue.hpp:292
void overwrite(const T &item) const
Function that calls BaseType_t xQueueOverwrite( QueueHandle_t xQueue, const void * pvItemToQueue )
Definition: Queue.hpp:382
bool sendToFrontFromISR(bool &higherPriorityTaskWoken, const T &item) const
Function that calls xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
Definition: Queue.hpp:193
bool isEmptyFromISR() const
Function that calls BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue )
Definition: Queue.hpp:596
std::optional< T > receive(const TickType_t ticksToWait=portMAX_DELAY) const
Function that calls BaseType_t xQueueReceive( QueueHandle_t xQueue, void *pvBuffer,...
Definition: Queue.hpp:242
bool sendToFront(const T &item, const TickType_t ticksToWait=portMAX_DELAY) const
Function that calls xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait )
Definition: Queue.hpp:170
bool isValid() const
Function that checks if the underlying queue handle is not NULL. This should be used to ensure a queu...
Definition: Queue.hpp:75
~QueueBase()
Destroy the QueueBase object by calling void vQueueDelete( QueueHandle_t xQueue )
Definition: Queue.hpp:623
std::optional< T > receiveFromISR(bool &higherPriorityTaskWoken) const
Function that calls BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer,...
Definition: Queue.hpp:271
Class that encapsulates the functionality of a FreeRTOS queue.
Definition: Queue.hpp:649
Queue(const UBaseType_t length)
Construct a new Queue object by calling QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,...
Definition: Queue.hpp:669
Class that encapsulates the functionality of a FreeRTOS queue.
Definition: Queue.hpp:698
StaticQueue()
Construct a new StaticQueue object by calling QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLe...
Definition: Queue.hpp:717