Mistake on this page?
Report an issue in GitHub or email us
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
40 using namespace rtos;
41 #endif
42 
43 #if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
44 
45 namespace 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  */
67 template<typename T, uint32_t queue_sz>
68 class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
69 public:
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 rel_time Timeout value (default: Kernel::wait_for_u32_forever).
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 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  */
338  T *try_get()
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 
373 private:
374  Queue<T, queue_sz> _queue;
376 };
377 
378 /** @}*/
379 /** @}*/
380 
381 }
382 
383 #endif
384 
385 #endif
386 
osStatus put(T *mptr)
Put a mail in the queue.
Definition: Mail.h:301
osEvent get(uint32_t millisec=osWaitForever)
Get a mail from the queue.
Definition: Mail.h:323
Mail()=default
Create and initialize Mail queue.
bool empty() const
Check if the mail queue is empty.
Definition: Mail.h:84
The Queue class represents a collection of objects that are stored first by order of priority...
Definition: Queue.h:66
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 from a memory pool, optionally blocking, and set memory block to zero...
Definition: MemoryPool.h:220
T * try_alloc_for(Kernel::Clock::duration_u32 rel_time)
Allocate a memory block from a memory pool, optionally blocking.
Definition: MemoryPool.h:128
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 * calloc_until(uint64_t millisec)
Allocate a memory block of type T, blocking, and set memory block to zero.
Definition: Mail.h:283
T * alloc(MBED_UNUSED uint32_t millisec=0)
Allocate a memory block of type T, without blocking.
Definition: Mail.h:113
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
T * try_calloc()
Allocate a memory block of type T, and set memory block to zero.
Definition: Mail.h:218
T * try_get()
Get a mail from the queue.
Definition: Mail.h:338
T * try_alloc()
Allocate a memory block of type T, without blocking.
Definition: Mail.h:125
T * alloc_until(uint64_t millisec)
Allocate a memory block of type T, blocking.
Definition: Mail.h:190
T * try_alloc_until(Kernel::Clock::time_point abs_time)
Allocate a memory block of type T, blocking.
Definition: Mail.h:170
The Mail class allows you to control, send, receive or wait for mail.
Definition: Mail.h:68
osStatus free(T *block)
Free a memory block.
Definition: MemoryPool.h:274
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:65
T * try_alloc_until(Kernel::Clock::time_point abs_time)
Allocate a memory block from a memory pool, blocking.
Definition: MemoryPool.h:161
osStatus free(T *mptr)
Free a memory block from a mail.
Definition: Mail.h:368
T * try_get_for(Kernel::Clock::duration_u32 rel_time)
Get a mail from the queue.
Definition: Mail.h:353
T * try_alloc()
Allocate a memory block from a memory pool, without blocking.
Definition: MemoryPool.h:104
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
T * alloc_for(uint32_t millisec)
Allocate a memory block of type T, optionally blocking.
Definition: Mail.h:153
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
bool full() const
Check if the mail queue is full.
Definition: Mail.h:97
T * try_alloc_for(Kernel::Clock::duration_u32 rel_time)
Allocate a memory block of type T, optionally blocking.
Definition: Mail.h:138
Definition: TaskBase.h:25
T * try_calloc()
Allocate a memory block from a memory pool, without blocking, and set memory block to zero...
Definition: MemoryPool.h:192
#define MBED_UNUSED
MBED_UNUSED Declare a function argument to be unused, suppressing compiler warnings.
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:257
#define MBED_DEPRECATED_SINCE(D, M)
MBED_DEPRECATED("message string") Mark a function declaration as deprecated, if it used then a warnin...
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.