Mistake on this page?
Report an issue in GitHub or email us
Queue.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2019 ARM Limited
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 #ifndef QUEUE_H
24 #define QUEUE_H
25 
26 #include "rtos/mbed_rtos_types.h"
27 #include "rtos/internal/mbed_rtos1_types.h"
28 #include "rtos/internal/mbed_rtos_storage.h"
29 #include "rtos/Kernel.h"
30 #include "platform/mbed_error.h"
31 #include "platform/NonCopyable.h"
32 #include "platform/mbed_assert.h"
33 
34 #if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
35 
36 namespace rtos {
37 /** \addtogroup rtos-public-api */
38 /** @{*/
39 
40 /**
41  * \defgroup rtos_Queue Queue class
42  * @{
43  */
44 
45 /** The Queue class represents a collection of objects that are stored first by
46  * order of priority, and then in first-in, first-out (FIFO) order.
47  *
48  * You can use a queue when you need to store data and then access it in the same
49  * order that it has been stored. The order in which you retrieve the data is in
50  * order of descending priority. If multiple elements have the same priority,
51  * they are retrieved in FIFO order.
52  *
53  * The object type stored in the queue can be an integer, pointer or a generic
54  * type given by the template parameter T.
55  *
56  * @tparam T Specifies the type of elements stored in the queue.
57  * @tparam queue_sz Maximum number of messages that you can store in the queue.
58  *
59  * @note Memory considerations: The queue control structures are created on the
60  * current thread's stack, both for the Mbed OS and underlying RTOS
61  * objects (static or dynamic RTOS memory pools are not being used).
62  *
63  * @note Bare metal profile: This class is not supported.
64  */
65 template<typename T, uint32_t queue_sz>
66 class Queue : private mbed::NonCopyable<Queue<T, queue_sz> > {
67 public:
68  /** Create and initialize a message Queue of objects of the parameterized
69  * type `T` and maximum capacity specified by `queue_sz`.
70  *
71  * @note You cannot call this function from ISR context.
72  */
74  {
75  osMessageQueueAttr_t attr = { 0 };
76  attr.mq_mem = _queue_mem;
77  attr.mq_size = sizeof(_queue_mem);
78  attr.cb_mem = &_obj_mem;
79  attr.cb_size = sizeof(_obj_mem);
80  _id = osMessageQueueNew(queue_sz, sizeof(T *), &attr);
81  MBED_ASSERT(_id);
82  }
83 
84  /** Queue destructor
85  *
86  * @note You cannot call this function from ISR context.
87  */
89  {
90  osMessageQueueDelete(_id);
91  }
92 
93  /** Check if the queue is empty.
94  *
95  * @return True if the queue is empty, false if not
96  *
97  * @note You may call this function from ISR context.
98  */
99  bool empty() const
100  {
101  return osMessageQueueGetCount(_id) == 0;
102  }
103 
104  /** Check if the queue is full.
105  *
106  * @return True if the queue is full, false if not
107  *
108  * @note You may call this function from ISR context.
109  */
110  bool full() const
111  {
112  return osMessageQueueGetSpace(_id) == 0;
113  }
114 
115  /** Get number of queued messages in the queue.
116  *
117  * @return Number of items in the queue
118  *
119  * @note You may call this function from ISR context.
120  */
121  uint32_t count() const
122  {
123  return osMessageQueueGetCount(_id);
124  }
125 
126  /** Inserts the given element to the end of the queue.
127  *
128  * This function puts the message pointed to by `data` into the queue. The
129  * parameter `prio` is used to sort the message according to their priority
130  * (higher numbers indicate higher priority) on insertion.
131  *
132  * The function does not block, and returns immediately if the queue is full.
133  *
134  * @param data Pointer to the element to insert into the queue.
135  * @param prio Priority of the operation or 0 in case of default.
136  * (default: 0)
137  *
138  * @return true if the element was inserted, false otherwise.
139  *
140  * @note You may call this function from ISR context.
141  */
142  bool try_put(T *data, uint8_t prio = 0)
143  {
144  return try_put_for(Kernel::Clock::duration_u32::zero(), data, prio);
145  }
146 
147  /** Inserts the given element to the end of the queue.
148  *
149  * This function puts the message pointed to by `data` into the queue. The
150  * parameter `prio` is used to sort the message according to their priority
151  * (higher numbers indicate higher priority) on insertion.
152  *
153  * The timeout indicated by the parameter `rel_time` specifies how long the
154  * function blocks waiting for the message to be inserted into the
155  * queue.
156  *
157  * The parameter `rel_time` can have the following values:
158  * - When the duration is 0, the function returns instantly. You could use
159  * `try_put` instead.
160  * - When the duration is Kernel::wait_for_u32_forever, the function waits for an
161  * infinite time.
162  * - For all other values, the function waits for the given duration.
163  *
164  * @param rel_time Timeout for the operation to be executed.
165  * @param data Pointer to the element to insert into the queue.
166  * @param prio Priority of the operation or 0 in case of default.
167  * (default: 0)
168  *
169  * @return true if the element was inserted, false otherwise.
170  *
171  * @note You may call this function from ISR context if the rel_time
172  * parameter is set to 0.
173  *
174  */
175  bool try_put_for(Kernel::Clock::duration_u32 rel_time, T *data, uint8_t prio = 0)
176  {
177  osStatus status = osMessageQueuePut(_id, &data, prio, rel_time.count());
178  return status == osOK;
179  }
180 
181  /** Inserts the given element to the end of the queue.
182  *
183  * This function puts the message pointed to by `data` into the queue. The
184  * parameter `prio` is used to sort the message according to their priority
185  * (higher numbers indicate higher priority) on insertion.
186  *
187  * The timeout indicated by the parameter `millisec` specifies how long the
188  * function blocks waiting for the message to be inserted into the
189  * queue.
190  *
191  * The parameter `millisec` can have the following values:
192  * - When the timeout is 0, the function returns instantly.
193  * - When the timeout is osWaitForever, the function waits for an
194  * infinite time.
195  * - For all other values, the function waits for the given number of
196  * milliseconds.
197  *
198  * @param data Pointer to the element to insert into the queue.
199  * @param millisec Timeout for the operation to be executed, or 0 in case
200  * of no timeout.
201  * @param prio Priority of the operation or 0 in case of default.
202  * (default: 0)
203  *
204  * @return Status code that indicates the execution status of the function:
205  * @a osOK The message has been successfully inserted
206  * into the queue.
207  * @a osErrorTimeout The message could not be inserted into the
208  * queue in the given time.
209  * @a osErrorResource The message could not be inserted because
210  * the queue is full.
211  * @a osErrorParameter Internal error or nonzero timeout specified
212  * in an ISR.
213  *
214  * @note You may call this function from ISR context if the millisec
215  * parameter is set to 0.
216  * @deprecated Replaced with try_put and try_put_for. In future put will be an untimed blocking call.
217  */
218  MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_put and try_put_for. In future put will be an untimed blocking call.")
219  osStatus put(T *data, uint32_t millisec = 0, uint8_t prio = 0)
220  {
221  return osMessageQueuePut(_id, &data, prio, millisec);
222  }
223 
224  /** Get a message from the queue.
225  *
226  * This function retrieves a message from the queue. The message is stored
227  * in the location pointed to be the parameter `data_out`.
228  *
229  * The function does not block, and returns immediately if the queue is empty.
230  *
231  * @param[out] data_out Pointer to location to write the element retrieved from the queue.
232  *
233  * @return true if an element was received and written to data_out.
234  *
235  * @note You may call this function from ISR context.
236  */
237  bool try_get(T **data_out)
238  {
239  return try_get_for(Kernel::Clock::duration_u32::zero(), data_out);
240  }
241 
242  /** Get a message or wait for a message from the queue.
243  *
244  * This function retrieves a message from the queue. The message is stored
245  * in the location pointed to be the parameter `data_out`.
246  *
247  * The timeout specified by the parameter `rel_time` specifies how long the
248  * function waits to retrieve the message from the queue.
249  *
250  * The timeout parameter can have the following values:
251  * - When the timeout is 0, the function returns instantly.
252  * - When the timeout is Kernel::wait_for_u32_forever, the function waits
253  * infinite time until the message is retrieved.
254  * - When the timeout is any other value, the function waits for the
255  * specified time before returning a timeout error.
256  *
257  * Messages are retrieved in descending priority order. If two messages
258  * share the same priority level, they are retrieved in first-in, first-out
259  * (FIFO) order.
260  *
261  * @param rel_time Timeout value.
262  * @param[out] data_out Pointer to location to write the element retrieved from the queue.
263  *
264  * @return true if an element was received and written to data_out.
265  *
266  * @note You may call this function from ISR context if the rel_time
267  * parameter is set to 0.
268  */
269  bool try_get_for(Kernel::Clock::duration_u32 rel_time, T **data_out)
270  {
271  osStatus status = osMessageQueueGet(_id, data_out, nullptr, rel_time.count());
272  return status == osOK;
273  }
274 
275  /** Get a message or wait for a message from the queue.
276  *
277  * This function retrieves a message from the queue. The message is stored
278  * in the value field of the returned `osEvent` object.
279  *
280  * The timeout specified by the parameter `millisec` specifies how long the
281  * function waits to retrieve the message from the queue.
282  *
283  * The timeout parameter can have the following values:
284  * - When the timeout is 0, the function returns instantly.
285  * - When the timeout is osWaitForever (default), the function waits
286  * infinite time until the message is retrieved.
287  * - When the timeout is any other value, the function waits for the
288  * specified time before returning a timeout error.
289  *
290  * Messages are retrieved in descending priority order. If two messages
291  * share the same priority level, they are retrieved in first-in, first-out
292  * (FIFO) order.
293  *
294  * @param millisec Timeout value.
295  *
296  * @return Event information that includes the message in event. Message
297  * value and the status code in event.status:
298  * @a osEventMessage Message successfully received.
299  * @a osOK No message is available in the queue, and no
300  * timeout was specified.
301  * @a osEventTimeout No message was received before a timeout
302  * event occurred.
303  * @a osErrorParameter A parameter is invalid or outside of a
304  * permitted range.
305  *
306  * @note You may call this function from ISR context if the millisec
307  * parameter is set to 0.
308  * @deprecated Replaced with try_get and try_get_for. In future get will be an untimed blocking call.
309  */
310  MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_get and try_get_for. In future get will be an untimed blocking call.")
311  osEvent get(uint32_t millisec = osWaitForever)
312  {
313  osEvent event;
314  T *data = nullptr;
315  osStatus_t res = osMessageQueueGet(_id, &data, nullptr, millisec);
316 
317  switch (res) {
318  case osOK:
319  event.status = (osStatus)osEventMessage;
320  event.value.p = data;
321  break;
322  case osErrorResource:
323  event.status = osOK;
324  break;
325  case osErrorTimeout:
326  event.status = (osStatus)osEventTimeout;
327  break;
328  case osErrorParameter:
329  default:
330  event.status = osErrorParameter;
331  break;
332  }
333  event.def.message_id = _id;
334 
335  return event;
336  }
337 private:
338  osMessageQueueId_t _id;
339  char _queue_mem[queue_sz * (sizeof(T *) + sizeof(mbed_rtos_storage_message_t))];
340  mbed_rtos_storage_msg_queue_t _obj_mem;
341 };
342 /** @}*/
343 /** @}*/
344 
345 } // namespace rtos
346 
347 #endif
348 
349 #endif // QUEUE_H
bool full() const
Check if the queue is full.
Definition: Queue.h:110
~Queue()
Queue destructor.
Definition: Queue.h:88
The Queue class represents a collection of objects that are stored first by order of priority...
Definition: Queue.h:66
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
bool try_get_for(Kernel::Clock::duration_u32 rel_time, T **data_out)
Get a message or wait for a message from the queue.
Definition: Queue.h:269
osEvent get(uint32_t millisec=osWaitForever)
Get a message or wait for a message from the queue.
Definition: Queue.h:311
bool try_get(T **data_out)
Get a message from the queue.
Definition: Queue.h:237
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:65
bool try_put(T *data, uint8_t prio=0)
Inserts the given element to the end of the queue.
Definition: Queue.h:142
bool try_put_for(Kernel::Clock::duration_u32 rel_time, T *data, uint8_t prio=0)
Inserts the given element to the end of the queue.
Definition: Queue.h:175
Queue()
Create and initialize a message Queue of objects of the parameterized type T and maximum capacity spe...
Definition: Queue.h:73
Definition: TaskBase.h:25
bool empty() const
Check if the queue is empty.
Definition: Queue.h:99
uint32_t count() const
Get number of queued messages in the queue.
Definition: Queue.h:121
#define MBED_DEPRECATED_SINCE(D, M)
MBED_DEPRECATED("message string") Mark a function declaration as deprecated, if it used then a warnin...
osStatus put(T *data, uint32_t millisec=0, uint8_t prio=0)
Inserts the given element to the end of the queue.
Definition: Queue.h:219
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.