FreeRTOScpp
Loading...
Searching...
No Matches
QueueCPP.h
Go to the documentation of this file.
1/**
2 * @file QueueCPP.h
3 * @brief FreeRTOS Queue Wrapper
4 *
5 * This file contains a set of lightweight wrappers for queues using FreeRTOS
6 *
7 * @copyright (c) 2007-2024 Richard Damon
8 * @author Richard Damon <richard.damon@gmail.com>
9 * @parblock
10 * MIT License:
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 * THE SOFTWARE.
29 *
30 * It is requested (but not required by license) that any bugs found or
31 * improvements made be shared, preferably to the author.
32 * @endparblock
33 *
34 * @ingroup FreeRTOSCpp
35 */
36#ifndef QUEUECPP_H
37#define QUEUECPP_H
38
39#include "FreeRTOScpp.h"
40#include "queue.h"
41
42#if FREERTOSCPP_USE_NAMESPACE
43namespace FreeRTOScpp {
44#endif
45
46//#include <type_traits>
47/**
48 * @brief Base Queue Wrapper
49 *
50 * This Base Class provides the Type Independent functionality for a Queue
51 * @ingroup FreeRTOSCpp
52 */
53
54class QueueBase {
55protected:
56 /**
57 * @brief Constructor
58 *
59 * Effectively Abstract class so protected base.
60 * @param handle_ The queueHandle for the queue/
61 */
62 QueueBase(QueueHandle_t handle_) : queueHandle(handle_) {};
63public:
64 /**
65 * @brief Destructor.
66 */
67 virtual ~QueueBase() {
68 vQueueDelete(queueHandle);
69 }
70
71 /**
72 * @brief Get number of items in the Queue.
73 * @return The number of item in the Queue.
74 */
75 unsigned waiting() const {
76 return uxQueueMessagesWaiting(queueHandle);
77 }
78
79 /**
80 * @brief Return number of spaces available in Queue
81 * @return the number of spaces available in the Queue.
82 */
83 unsigned available() const {
84 return uxQueueSpacesAvailable(queueHandle);
85 }
86
87 /**
88 * @brief Reset the Queue.
89 * Resets the Queue to an empty state.
90 */
91 void reset() {
92 xQueueReset(queueHandle);
93 }
94
95 /**
96 * @brief Check if Queue is Full.
97 * @return True if Queue is Full.
98 */
99 bool full() {
100 return 0 == uxQueueSpacesAvailable(queueHandle);
101 }
102
103 /**
104 * @brief Check if Queue is Empty
105 * @return True if Queue is Empty.
106 */
107 bool empty() {
108 return uxQueueMessagesWaiting(queueHandle) == 0;
109 }
110
111 /**
112 * @brief Is Queue Full.
113 * Note: Interrupt service routines should only call _ISR routines.
114 * @return True if Queue is Full.
115 */
116 bool full_ISR() {
117 return xQueueIsQueueFullFromISR(queueHandle);
118 }
119
120 /**
121 * @brief Is Queue Empty.
122 * Note: Interrupt service routines should only call _ISR routines.
123 * @return True if Queue is Empty.
124 */
125 bool empty_ISR() {
126 return xQueueIsQueueEmptyFromISR(queueHandle);
127 }
128
129 /**
130 * @brief Get number of message waiting.
131 * Note: Interrupt service routines should only call _ISR routines.
132 * @return The number of messages waiting.
133 */
134 unsigned waiting_ISR() {
135 return uxQueueMessagesWaitingFromISR(queueHandle);
136 }
137
138protected:
139 QueueHandle_t queueHandle;
140private:
141
142#if __cplusplus < 201101L
143 QueueBase(QueueBase const&); ///< We are not copyable.
144 void operator =(QueueBase const&); ///< We are not assignable.
145#else
146 QueueBase(QueueBase const&) = delete; ///< We are not copyable.
147 void operator =(QueueBase const&) = delete; ///< We are not assignable.
148#endif // __cplusplus
149
150};
151
152/**
153 * @brief Typed Queue Wrapper
154 *
155 * This Base Class provides the Type Dependent functionality for a Queue
156 * @ingroup FreeRTOSCpp
157 */
158
159template<class T> class QueueTypeBase : public QueueBase {
160protected:
161 QueueTypeBase(QueueHandle_t handle_) : QueueBase(handle_) {}
162
163public:
164 /**
165 * @brief Push an item onto the Queue.
166 * Puts an item onto the Queue so it will be the next item to remove.
167 * @param item The item to put on the Queue.
168 * @param time How long to wait for room if Queue is full.
169 * @return True if successful
170 */
171 bool push(T const& item, TickType_t time = portMAX_DELAY){
172 return xQueueSendToFront(queueHandle, &item, time);
173 }
174#if FREERTOSCPP_USE_CHRONO
175 /**
176 * @brief Push an item onto the Queue.
177 * Puts an item onto the Queue so it will be the next item to remove.
178 * @param item The item to put on the Queue.
179 * @param time How long to wait for room if Queue is full.
180 * @return True if successful
181 */
182 bool push(T const& item, Time_ms time){
183 return xQueueSendToFront(queueHandle, &item, ms2ticks(time));
184 }
185#endif
186 /**
187 * @brief add an item at end of the Queue.
188 * Puts an item onto the Queue so it will be the last item to remove.
189 * @param item The item to put on the Queue.
190 * @param time How long to wait for room if Queue is full.
191 * @return True if successful
192 */
193 bool add(T const& item, TickType_t time = portMAX_DELAY){
194 return xQueueSendToBack(queueHandle, &item, time);
195 }
196#if FREERTOSCPP_USE_CHRONO
197 /**
198 * @brief add an item at end of the Queue.
199 * Puts an item onto the Queue so it will be the last item to remove.
200 * @param item The item to put on the Queue.
201 * @param time How long to wait for room if Queue is full.
202 * @return True if successful
203 */
204 bool add(T const& item, Time_ms time){
205 return xQueueSendToBack(queueHandle, &item, ms2ticks(time));
206 }
207#endif
208 /**
209 * @brief Get an item from the Queue.
210 * Gets the first item from the Queue
211 * @param var Variable to place the item
212 * @param time How long to wait for an item to be available.
213 * @return True if an item returned.
214 */
215 bool pop(T& var, TickType_t time = portMAX_DELAY) {
216 return xQueueReceive(queueHandle, &var, time);
217 }
218#if FREERTOSCPP_USE_CHRONO
219 /**
220 * @brief Get an item from the Queue.
221 * Gets the first item from the Queue
222 * @param var Variable to place the item
223 * @param time How long to wait for an item to be available.
224 * @return True if an item returned.
225 */
226 bool pop(T& var, Time_ms time) {
227 return xQueueReceive(queueHandle, &var, ms2ticks(time));
228 }
229#endif
230
231 /**
232 * @brief Look at the first item in the Queue.
233 * Gets the first item from the Queue leaving it there.
234 * @param var Variable to place the item
235 * @param time How long to wait for an item to be available.
236 * @return True if an item returned.
237 */
238 bool peek(T& var, TickType_t time = 0) {
239 return xQueuePeek(queueHandle, &var, time);
240 }
241#if FREERTOSCPP_USE_CHRONO
242 /**
243 * @brief Look at the first item in the Queue.
244 * Gets the first item from the Queue leaving it there.
245 * @param var Variable to place the item
246 * @param time How long to wait for an item to be available.
247 * @return True if an item returned.
248 */
249 bool peek(T& var, Time_ms time) {
250 return xQueuePeek(queueHandle, &var, ms2ticks(time));
251 }
252#endif
253
254 /**
255 * @brief Push an item onto the Queue.
256 * Puts an item onto the Queue so it will be the next item to remove.
257 *
258 * Note: Interrupt service routines should only call _ISR routines.
259 * @param item The item to put on the Queue.
260 * @param waswoken Flag variable to determine if context switch is needed.
261 * @return True if successful
262 */
263 bool push_ISR(T const& item, portBASE_TYPE& waswoken){
264 return xQueueSendToFrontFromISR(queueHandle, &item, &waswoken);
265 }
266
267 /**
268 * @brief add an item at end of the Queue.
269 * Puts an item onto the Queue so it will be the last item to remove.
270 *
271 * Note: Interrupt service routines should only call _ISR routines.
272 * @param item The item to put on the Queue.
273 * @param waswoken Flag variable to determine if context switch is needed.
274 * @return True if successful
275 */
276 bool add_ISR(T const& item, portBASE_TYPE& waswoken){
277 return xQueueSendToBackFromISR(queueHandle, &item, &waswoken);
278 }
279
280 /**
281 * @brief Get an item from the Queue.
282 * Gets the first item from the Queue
283 *
284 * Note: Interrupt service routines should only call _ISR routines.
285 * @param var Variable to place the item
286 * @param waswoken Flag variable to determine if context switch is needed.
287 * @return True if an item returned.
288 */
289 bool pop_ISR(T& var, portBASE_TYPE& waswoken) {
290 return xQueueReceiveFromISR(queueHandle, &var, &waswoken);
291 }
292
293 /**
294 * @brief Look at the first item in the Queue.
295 * Gets the first item from the Queue leaving it there.
296 *
297 * Note: Interrupt service routines should only call _ISR routines.
298 * @param var Variable to place the item
299 * @param waswoken Flag variable to determine if context switch is needed.
300 * @return True if an item returned.
301 */
302 bool peek_ISR(T& var, portBASE_TYPE& waswoken) {
303 return xQueuePeekFromISR(queueHandle, &var);
304 }
305};
306
307/**
308 * @brief Queue Wrapper.
309 *
310 * Note, is a template on the type of object to place on the queue,
311 * which makes the Queue more typesafe.
312 *
313 * @tparam T The type of object to be placed on the queue.
314 * Note also, this type needs to be trivially copyable, and preferably a POD
315 * as the FreeRTOS queue code will copy it with memcpy().
316 * @tparam queuelength The number of elements to reserve space for in the queue.
317 * If 0 (which is the default value) then length will be provided to the constructor dynamically.
318 *
319 * @todo add Overwrite operation
320 * @todo add QueueSet Functionality
321 * @ingroup FreeRTOSCpp
322 */
323
324template<class T, unsigned queueLength
325#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
326 = 0
327#endif
328 > class Queue : public QueueTypeBase<T> {
329// static_assert(::std::is_pod<T>, "Queues only work with PODs"); ///@todo need to get later version of C++ compile working
330public:
331 /**
332 * @brief Constructor.
333 * @param name The name to register the Queue with.
334 */
335 Queue(char const* name = 0) :
336 QueueTypeBase<T>(
337
338#if( configSUPPORT_STATIC_ALLOCATION == 1 )
339 xQueueCreateStatic(queueLength, sizeof(T), reinterpret_cast<uint8_t*>(&queueStore), &queueBuff)
340#else
341 xQueueCreate(queueLength, sizeof(T))
342#endif
343 )
344 {
345#if configQUEUE_REGISTRY_SIZE > 0
346 if(name)
347 vQueueAddToRegistry(this->queueHandle, name);
348#endif
349
350 };
351private:
352#if( configSUPPORT_STATIC_ALLOCATION == 1 )
353 StaticQueue_t queueBuff;
354 T queueStore[queueLength];
355#endif
356};
357
358#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
359
360template<class T> class Queue<T, 0> : public QueueTypeBase<T> {
361// static_assert(::std::is_pod<T>, "Queues only work with PODs"); ///@todo need to get later version of C++ compile working
362public:
363 /**
364 * @brief Constructor.
365 * @param length How many object to make room for in the Queue.
366 * @param name The name to register the Queue with.
367 */
368 Queue(unsigned portBASE_TYPE length, char const* name = 0) :
369 QueueTypeBase<T>(xQueueCreate(length, sizeof(T)))
370 {
371#if configQUEUE_REGISTRY_SIZE > 0
372 if(name)
373 vQueueAddToRegistry(this->queueHandle, name);
374#endif
375
376 };
377
378};
379#endif
380
381#if FREERTOSCPP_USE_NAMESPACE
382} // namespace FreeRTOScpp
383#endif
384
385#endif
FreeRTOS Wrapper.
Base Queue Wrapper.
Definition QueueCPP.h:54
QueueBase(QueueBase const &)=delete
We are not copyable.
QueueBase(QueueHandle_t handle_)
Constructor.
Definition QueueCPP.h:62
unsigned waiting_ISR()
Get number of message waiting.
Definition QueueCPP.h:134
unsigned available() const
Return number of spaces available in Queue.
Definition QueueCPP.h:83
virtual ~QueueBase()
Destructor.
Definition QueueCPP.h:67
unsigned waiting() const
Get number of items in the Queue.
Definition QueueCPP.h:75
bool full()
Check if Queue is Full.
Definition QueueCPP.h:99
bool empty()
Check if Queue is Empty.
Definition QueueCPP.h:107
QueueHandle_t queueHandle
Definition QueueCPP.h:139
bool full_ISR()
Is Queue Full.
Definition QueueCPP.h:116
bool empty_ISR()
Is Queue Empty.
Definition QueueCPP.h:125
void reset()
Reset the Queue.
Definition QueueCPP.h:91
Queue Wrapper.
Definition QueueCPP.h:328
Queue(char const *name=0)
Constructor.
Definition QueueCPP.h:335
Typed Queue Wrapper.
Definition QueueCPP.h:159
bool peek(T &var, TickType_t time=0)
Look at the first item in the Queue.
Definition QueueCPP.h:238
QueueTypeBase(QueueHandle_t handle_)
Definition QueueCPP.h:161
bool push_ISR(T const &item, portBASE_TYPE &waswoken)
Push an item onto the Queue.
Definition QueueCPP.h:263
bool pop(T &var, TickType_t time=portMAX_DELAY)
Get an item from the Queue.
Definition QueueCPP.h:215
bool add_ISR(T const &item, portBASE_TYPE &waswoken)
add an item at end of the Queue.
Definition QueueCPP.h:276
bool add(T const &item, TickType_t time=portMAX_DELAY)
add an item at end of the Queue.
Definition QueueCPP.h:193
bool push(T const &item, TickType_t time=portMAX_DELAY)
Push an item onto the Queue.
Definition QueueCPP.h:171
bool peek_ISR(T &var, portBASE_TYPE &waswoken)
Look at the first item in the Queue.
Definition QueueCPP.h:302
bool pop_ISR(T &var, portBASE_TYPE &waswoken)
Get an item from the Queue.
Definition QueueCPP.h:289
Definition FreeRTOScpp.h:74