Mbed OS Reference
Loading...
Searching...
No Matches
Mail.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 MAIL_H
24#define MAIL_H
25
26#include <stdint.h>
27#include <string.h>
28
29#include "rtos/Queue.h"
30#include "rtos/MemoryPool.h"
31#include "rtos/mbed_rtos_types.h"
32#include "rtos/internal/mbed_rtos_storage.h"
33#include "rtos/internal/mbed_rtos1_types.h"
34
35#include "platform/mbed_toolchain.h"
36#include "platform/mbed_assert.h"
37#include "platform/NonCopyable.h"
38
39#ifndef MBED_NO_GLOBAL_USING_DIRECTIVE
40using namespace rtos;
41#endif
42
43#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
44
45namespace rtos {
46/** \addtogroup rtos-public-api */
47/** @{*/
48
49/**
50 * \defgroup rtos_Mail Mail class
51 * @{
52 */
53
54/** The Mail class allows you to control, send, receive or wait for mail.
55 * A mail is a memory block that is sent to a thread or interrupt service routine (ISR).
56 * @tparam T Data type of a single mail message element.
57 * @tparam queue_sz Maximum number of mail messages in queue.
58 *
59 * @note
60 * Memory considerations: The mail data store and control structures are part of this class - they do not (themselves)
61 * allocate memory on the heap, both for the Mbed OS and underlying RTOS objects (static or dynamic RTOS memory
62 * pools are not being used).
63 *
64 * @note
65 * Bare metal profile: This class is not supported.
66 */
67template<typename T, uint32_t queue_sz>
68class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
69public:
70 /** Create and initialize Mail queue.
71 *
72 * @note You cannot call this function from ISR context.
73 */
74 Mail() = default;
75
76 /** Check if the mail queue is empty.
77 *
78 * @return State of queue.
79 * @retval true Mail queue is empty.
80 * @retval false Mail queue contains mail.
81 *
82 * @note You may call this function from ISR context.
83 */
84 bool empty() const
85 {
86 return _queue.empty();
87 }
88
89 /** Check if the mail queue is full.
90 *
91 * @return State of queue.
92 * @retval true Mail queue is full.
93 * @retval false Mail queue is not full.
94 *
95 * @note You may call this function from ISR context.
96 */
97 bool full() const
98 {
99 return _queue.full();
100 }
101
102 /** Allocate a memory block of type T, without blocking.
103 *
104 * @param millisec Not used (see note).
105 *
106 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
107 *
108 * @note You may call this function from ISR context.
109 * @note If blocking is required, use Mail::try_alloc_for or Mail::try_alloc_until
110 * @deprecated Replaced with try_alloc. In future alloc() will be an untimed blocking call.
111 */
112 MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_alloc. In future alloc() will be an untimed blocking call.")
113 T *alloc(MBED_UNUSED uint32_t millisec = 0)
114 {
115 return try_alloc();
116 }
117
118 /** Allocate a memory block of type T, without blocking.
119 *
120 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
121 *
122 * @note You may call this function from ISR context.
123 * @note If blocking is required, use Mail::try_alloc_for or Mail::try_alloc_until
124 */
126 {
127 return _pool.try_alloc();
128 }
129
130 /** Allocate a memory block of type T, optionally blocking.
131 *
132 * @param rel_time Timeout value, or Kernel::wait_for_u32_forever.
133 *
134 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
135 *
136 * @note You may call this function from ISR context if the millisec parameter is set to 0.
137 */
138 T *try_alloc_for(Kernel::Clock::duration_u32 rel_time)
139 {
140 return _pool.try_alloc_for(rel_time);
141 }
142
143 /** Allocate a memory block of type T, optionally blocking.
144 *
145 * @param millisec Timeout value, or osWaitForever.
146 *
147 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
148 *
149 * @note You may call this function from ISR context if the millisec parameter is set to 0.
150 * @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
151 */
152 MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
153 T *alloc_for(uint32_t millisec)
154 {
155 return try_alloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
156 }
157
158 /** Allocate a memory block of type T, blocking.
159 *
160 * @param abs_time Absolute timeout time, referenced to Kernel::Clock.
161 *
162 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
163 *
164 * @note You cannot call this function from ISR context.
165 * @note the underlying RTOS may have a limit to the maximum wait time
166 * due to internal 32-bit computations, but this is guaranteed to work if the
167 * wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
168 * the wait will time out earlier than specified.
169 */
170 T *try_alloc_until(Kernel::Clock::time_point abs_time)
171 {
172 return _pool.try_alloc_until(abs_time);
173 }
174
175 /** Allocate a memory block of type T, blocking.
176 *
177 * @param millisec Absolute timeout time, referenced to Kernel::get_ms_count().
178 *
179 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
180 *
181 * @note You cannot call this function from ISR context.
182 * @note the underlying RTOS may have a limit to the maximum wait time
183 * due to internal 32-bit computations, but this is guaranteed to work if the
184 * wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
185 * the wait will time out earlier than specified.
186 * @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
187 * rather than `Kernel::get_ms_count() + 5000`.
188 */
189 MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
190 T *alloc_until(uint64_t millisec)
191 {
192 return try_alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
193 }
194
195 /** Allocate a memory block of type T, and set memory block to zero.
196 *
197 * @param millisec Not used (see note).
198 *
199 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
200 *
201 * @note You may call this function from ISR context.
202 * @note If blocking is required, use Mail::try_calloc_for or Mail::try_calloc_until
203 * @deprecated Replaced with try_calloc. In future calloc() will be an untimed blocking call.
204 */
205 MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_calloc. In future calloc() will be an untimed blocking call.")
206 T *calloc(MBED_UNUSED uint32_t millisec = 0)
207 {
208 return try_calloc();
209 }
210
211 /** Allocate a memory block of type T, and set memory block to zero.
212 *
213 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
214 *
215 * @note You may call this function from ISR context.
216 * @note If blocking is required, use Mail::try_calloc_for or Mail::try_calloc_until
217 */
219 {
220 return _pool.try_calloc();
221 }
222
223 /** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
224 *
225 * @param rel_time Timeout value, or Kernel::wait_for_u32_forever.
226 *
227 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
228 *
229 * @note You may call this function from ISR context if the rel_time parameter is set to 0.
230 */
231 T *try_calloc_for(Kernel::Clock::duration_u32 rel_time)
232 {
233 return _pool.try_calloc_for(rel_time);
234 }
235
236 /** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
237 *
238 * @param millisec Timeout value, or osWaitForever.
239 *
240 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
241 *
242 * @note You may call this function from ISR context if the millisec parameter is set to 0.
243 * @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
244 */
245 MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
246 T *calloc_for(uint32_t millisec)
247 {
248 return try_calloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
249 }
250
251 /** Allocate a memory block of type T, blocking, and set memory block to zero.
252 *
253 * @param abs_time Absolute timeout time, referenced to Kernel::Clock.
254 *
255 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
256 *
257 * @note You cannot call this function from ISR context.
258 * @note the underlying RTOS may have a limit to the maximum wait time
259 * due to internal 32-bit computations, but this is guaranteed to work if the
260 * wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
261 * the wait will time out earlier than specified.
262 */
263 T *try_calloc_until(Kernel::Clock::time_point abs_time)
264 {
265 return _pool.try_calloc_until(abs_time);
266 }
267
268 /** Allocate a memory block of type T, blocking, and set memory block to zero.
269 *
270 * @param millisec Absolute timeout time, referenced to Kernel::get_ms_count().
271 *
272 * @return Pointer to memory block that you can fill with mail or nullptr in case error.
273 *
274 * @note You cannot call this function from ISR context.
275 * @note the underlying RTOS may have a limit to the maximum wait time
276 * due to internal 32-bit computations, but this is guaranteed to work if the
277 * wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
278 * the wait will time out earlier than specified.
279 * @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
280 * rather than `Kernel::get_ms_count() + 5000`.
281 */
282 MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
283 T *calloc_until(uint64_t millisec)
284 {
285 return try_calloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
286 }
287
288 /** Put a mail in the queue.
289 *
290 * @param mptr Memory block previously allocated with Mail::alloc or Mail::calloc.
291 *
292 * @return Status code that indicates the execution status of the function (osOK on success).
293 * See note.
294 *
295 * @note You may call this function from ISR context.
296 * @note As the mail should have already been allocated, and the memory pool is the same size
297 * as the queue, the put operation should always succeed, despite being implemented with
298 * Queue::try_put - there is room in the queue for every mail from the pool. Therefore
299 * use of the return value is deprecated, and the function will return void in future.
300 */
301 osStatus put(T *mptr)
302 {
303 bool ok = _queue.try_put(mptr);
304 MBED_ASSERT(ok);
305 return ok ? osOK : osErrorResource;
306 }
307
308 /** Get a mail from the queue.
309 *
310 * @param millisec Timeout value (default: osWaitForever).
311 *
312 * @return Event that contains mail information and status code. The status code
313 * is stored in the status member:
314 * @a osEventMail Mail successfully received.
315 * @a osOK No mail is available (and no timeout was specified).
316 * @a osEventTimeout No mail has arrived during the given timeout period.
317 * @a osErrorParameter A parameter is invalid or outside of a permitted range.
318 *
319 * @note You may call this function from ISR context if the \c millisec parameter is set to 0.
320 * @deprecated Replaced with try_get and try_get_for. In future get will be an untimed blocking call.
321 */
322 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.")
323 osEvent get(uint32_t millisec = osWaitForever)
324 {
325 osEvent evt = _queue.get(millisec);
326 if (evt.status == osEventMessage) {
327 evt.status = osEventMail;
328 }
329 return evt;
330 }
331
332 /** Get a mail from the queue.
333 *
334 * @return Pointer to received mail, or nullptr if none was received.
335 *
336 * @note You may call this function from ISR context.
337 */
339 {
340 T *mptr = nullptr;
341 _queue.try_get(&mptr);
342 return mptr;
343 }
344
345 /** Get a mail from the queue.
346 *
347 * @param rel_time Timeout value or Kernel::wait_for_u32_forever.
348 *
349 * @return Pointer to received mail, or nullptr if none was received.
350 *
351 * @note You may call this function from ISR context if the millisec parameter is set to 0.
352 */
353 T *try_get_for(Kernel::Clock::duration_u32 rel_time)
354 {
355 T *mptr = nullptr;
356 _queue.try_get_for(rel_time, &mptr);
357 return mptr;
358 }
359
360 /** Free a memory block from a mail.
361 *
362 * @param mptr Pointer to the memory block that was obtained with Mail::get.
363 *
364 * @return Status code that indicates the execution status of the function (osOK on success).
365 *
366 * @note You may call this function from ISR context.
367 */
368 osStatus free(T *mptr)
369 {
370 return _pool.free(mptr);
371 }
372
373private:
374 Queue<T, queue_sz> _queue;
376};
377
378/** @}*/
379/** @}*/
380
381}
382
383#endif
384
385#endif
386
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
The Mail class allows you to control, send, receive or wait for mail.
Definition: Mail.h:68
T * calloc_for(uint32_t millisec)
Allocate a memory block of type T, optionally blocking, and set memory block to zero.
Definition: Mail.h:246
T * try_calloc_for(Kernel::Clock::duration_u32 rel_time)
Allocate a memory block of type T, optionally blocking, and set memory block to zero.
Definition: Mail.h:231
T * try_calloc_until(Kernel::Clock::time_point abs_time)
Allocate a memory block of type T, blocking, and set memory block to zero.
Definition: Mail.h:263
T * try_get()
Get a mail from the queue.
Definition: Mail.h:338
osStatus free(T *mptr)
Free a memory block from a mail.
Definition: Mail.h:368
T * try_alloc_until(Kernel::Clock::time_point abs_time)
Allocate a memory block of type T, blocking.
Definition: Mail.h:170
T * alloc_for(uint32_t millisec)
Allocate a memory block of type T, optionally blocking.
Definition: Mail.h:153
bool empty() const
Check if the mail queue is empty.
Definition: Mail.h:84
osStatus put(T *mptr)
Put a mail in the queue.
Definition: Mail.h:301
bool full() const
Check if the mail queue is full.
Definition: Mail.h:97
Mail()=default
Create and initialize Mail queue.
T * alloc(MBED_UNUSED uint32_t millisec=0)
Allocate a memory block of type T, without blocking.
Definition: Mail.h:113
T * try_alloc()
Allocate a memory block of type T, without blocking.
Definition: Mail.h:125
T * try_alloc_for(Kernel::Clock::duration_u32 rel_time)
Allocate a memory block of type T, optionally blocking.
Definition: Mail.h:138
T * calloc_until(uint64_t millisec)
Allocate a memory block of type T, blocking, and set memory block to zero.
Definition: Mail.h:283
osEvent get(uint32_t millisec=osWaitForever)
Get a mail from the queue.
Definition: Mail.h:323
T * try_get_for(Kernel::Clock::duration_u32 rel_time)
Get a mail from the queue.
Definition: Mail.h:353
T * try_calloc()
Allocate a memory block of type T, and set memory block to zero.
Definition: Mail.h:218
T * alloc_until(uint64_t millisec)
Allocate a memory block of type T, blocking.
Definition: Mail.h:190
T * calloc(MBED_UNUSED uint32_t millisec=0)
Allocate a memory block of type T, and set memory block to zero.
Definition: Mail.h:206
Define and manage fixed-size memory pools of objects of a given type.
Definition: MemoryPool.h:59
T * try_calloc_for(Kernel::Clock::duration_u32 rel_time)
Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
Definition: MemoryPool.h:235
T * try_calloc_until(Kernel::Clock::time_point abs_time)
Allocate a memory block from a memory pool, blocking, and set memory block to zero.
Definition: MemoryPool.h:272
T * try_alloc_until(Kernel::Clock::time_point abs_time)
Allocate a memory block from a memory pool, blocking.
Definition: MemoryPool.h:176
osStatus free(T *block)
Free a memory block.
Definition: MemoryPool.h:300
T * try_alloc()
Allocate a memory block from a memory pool, without blocking.
Definition: MemoryPool.h:117
T * try_alloc_for(Kernel::Clock::duration_u32 rel_time)
Allocate a memory block from a memory pool, optionally blocking.
Definition: MemoryPool.h:142
T * try_calloc()
Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
Definition: MemoryPool.h:207
The Queue class represents a collection of objects that are stored first by order of priority,...
Definition: Queue.h:66
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:66
#define MBED_DEPRECATED_SINCE(D, M)
MBED_DEPRECATED("message string") Mark a function declaration as deprecated, if it used then a warnin...
#define MBED_UNUSED
MBED_UNUSED Declare a function argument to be unused, suppressing compiler warnings.