2013-02-18 15:32:11 +00:00
/* mbed Microcontroller Library
2019-07-11 15:23:39 +00:00
* Copyright ( c ) 2006 - 2019 ARM Limited
2020-02-20 08:45:04 +00:00
* SPDX - License - Identifier : MIT
*
2013-02-18 15:32:11 +00:00
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*/
# ifndef MAIL_H
# define MAIL_H
# include <stdint.h>
# include <string.h>
2019-03-14 11:36:02 +00:00
# include "rtos/Queue.h"
# include "rtos/MemoryPool.h"
# include "rtos/mbed_rtos_types.h"
# include "rtos/mbed_rtos_storage.h"
# include "rtos/mbed_rtos1_types.h"
2017-05-15 14:55:45 +00:00
2019-03-26 08:48:58 +00:00
# include "platform/mbed_toolchain.h"
2020-04-21 11:39:50 +00:00
# include "platform/mbed_assert.h"
2017-06-20 12:00:20 +00:00
# include "platform/NonCopyable.h"
2018-10-25 15:45:29 +00:00
# ifndef MBED_NO_GLOBAL_USING_DIRECTIVE
2017-05-15 14:55:45 +00:00
using namespace rtos ;
2018-10-25 15:45:29 +00:00
# endif
2013-02-18 15:32:11 +00:00
2019-03-14 11:36:02 +00:00
# if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
2013-02-18 15:32:11 +00:00
namespace rtos {
2019-07-11 15:23:39 +00:00
/** \addtogroup rtos-public-api */
2016-10-04 20:02:44 +00:00
/** @{*/
2019-09-06 21:58:57 +00:00
2017-10-24 15:05:45 +00:00
/**
* \ defgroup rtos_Mail Mail class
* @ {
*/
2018-11-12 10:33:38 +00:00
2018-10-25 19:20:40 +00:00
/** The Mail class allows you to control, send, receive or wait for mail.
* A mail is a memory block that is sent to a thread or interrupt service routine ( ISR ) .
2018-10-24 13:43:49 +00:00
* @ tparam T Data type of a single mail message element .
* @ tparam queue_sz Maximum number of mail messages in queue .
*
* @ note
* Memory considerations : The mail data store and control structures are part of this class - they do not ( themselves )
2018-10-25 19:20:40 +00:00
* allocate memory on the heap , both for the Mbed OS and underlying RTOS objects ( static or dynamic RTOS memory
2018-10-24 13:43:49 +00:00
* pools are not being used ) .
2020-04-16 14:11:09 +00:00
*
* @ note
* Bare metal profile : This class is not supported .
2018-10-24 13:43:49 +00:00
*/
2013-02-18 15:32:11 +00:00
template < typename T , uint32_t queue_sz >
2017-06-20 12:00:20 +00:00
class Mail : private mbed : : NonCopyable < Mail < T , queue_sz > > {
2013-02-18 15:32:11 +00:00
public :
2018-10-24 13:43:49 +00:00
/** Create and initialize Mail queue.
2017-12-27 14:46:00 +00:00
*
2018-01-08 23:41:37 +00:00
* @ note You cannot call this function from ISR context .
2018-10-24 13:43:49 +00:00
*/
2020-02-13 09:07:12 +00:00
Mail ( ) = default ;
2014-05-29 13:36:51 +00:00
2018-10-24 13:43:49 +00:00
/** Check if the mail queue is empty.
2017-09-21 10:09:45 +00:00
*
2018-10-24 13:43:49 +00:00
* @ return State of queue .
* @ retval true Mail queue is empty .
* @ retval false Mail queue contains mail .
2017-12-27 14:46:00 +00:00
*
2018-01-08 23:41:37 +00:00
* @ note You may call this function from ISR context .
2017-09-21 10:09:45 +00:00
*/
2018-10-09 19:59:02 +00:00
bool empty ( ) const
{
2017-09-21 10:09:45 +00:00
return _queue . empty ( ) ;
}
2018-10-24 13:43:49 +00:00
/** Check if the mail queue is full.
2017-09-21 10:09:45 +00:00
*
2018-10-24 13:43:49 +00:00
* @ return State of queue .
* @ retval true Mail queue is full .
* @ retval false Mail queue is not full .
2017-12-27 14:46:00 +00:00
*
2018-01-08 23:41:37 +00:00
* @ note You may call this function from ISR context .
2017-09-21 10:09:45 +00:00
*/
2018-10-09 19:59:02 +00:00
bool full ( ) const
{
2017-09-21 10:09:45 +00:00
return _queue . full ( ) ;
}
2019-03-26 08:48:58 +00:00
/** Allocate a memory block of type T, without blocking.
2018-10-24 13:43:49 +00:00
*
2019-03-26 08:48:58 +00:00
* @ param millisec Not used ( see note ) .
2018-10-24 13:43:49 +00:00
*
2019-07-04 12:37:47 +00:00
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
2018-10-24 13:43:49 +00:00
*
* @ note You may call this function from ISR context .
2020-04-21 10:12:28 +00:00
* @ note If blocking is required , use Mail : : try_alloc_for or Mail : : try_alloc_until
* @ deprecated Replaced with try_alloc . In future alloc ( ) will be an untimed blocking call .
2018-10-24 13:43:49 +00:00
*/
2020-04-21 10:12:28 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Replaced with try_alloc. In future alloc() will be an untimed blocking call. " )
2019-03-26 08:48:58 +00:00
T * alloc ( MBED_UNUSED uint32_t millisec = 0 )
2018-11-12 10:33:38 +00:00
{
2020-04-21 10:12:28 +00:00
return try_alloc ( ) ;
}
/** Allocate a memory block of type T, without blocking.
*
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
*
* @ note You may call this function from ISR context .
* @ note If blocking is required , use Mail : : try_alloc_for or Mail : : try_alloc_until
*/
T * try_alloc ( )
{
return _pool . try_alloc ( ) ;
2013-02-18 15:32:11 +00:00
}
2014-05-29 13:36:51 +00:00
2020-02-13 09:07:12 +00:00
/** Allocate a memory block of type T, optionally blocking.
*
* @ param rel_time Timeout value , or Kernel : : wait_for_u32_forever .
*
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
*
* @ note You may call this function from ISR context if the millisec parameter is set to 0.
*/
2020-04-21 10:12:28 +00:00
T * try_alloc_for ( Kernel : : Clock : : duration_u32 rel_time )
2020-02-13 09:07:12 +00:00
{
2020-04-21 10:12:28 +00:00
return _pool . try_alloc_for ( rel_time ) ;
2020-02-13 09:07:12 +00:00
}
2019-03-26 08:48:58 +00:00
/** Allocate a memory block of type T, optionally blocking.
*
* @ param millisec Timeout value , or osWaitForever .
*
2019-07-04 12:37:47 +00:00
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
2019-03-26 08:48:58 +00:00
*
* @ note You may call this function from ISR context if the millisec parameter is set to 0.
2020-02-13 09:07:12 +00:00
* @ deprecated Pass a chrono duration , not an integer millisecond count . For example use ` 5 s ` rather than ` 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. " )
2019-03-26 08:48:58 +00:00
T * alloc_for ( uint32_t millisec )
{
2020-04-21 10:12:28 +00:00
return try_alloc_for ( std : : chrono : : duration < uint32_t , std : : milli > ( millisec ) ) ;
2020-02-13 09:07:12 +00:00
}
/** Allocate a memory block of type T, blocking.
*
* @ param abs_time Absolute timeout time , referenced to Kernel : : Clock .
*
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
*
* @ note You cannot call this function from ISR context .
* @ note the underlying RTOS may have a limit to the maximum wait time
* due to internal 32 - bit computations , but this is guaranteed to work if the
* wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
* the wait will time out earlier than specified .
*/
2020-04-21 10:12:28 +00:00
T * try_alloc_until ( Kernel : : Clock : : time_point abs_time )
2020-02-13 09:07:12 +00:00
{
2020-04-21 10:12:28 +00:00
return _pool . try_alloc_until ( abs_time ) ;
2019-03-26 08:48:58 +00:00
}
/** Allocate a memory block of type T, blocking.
*
* @ param millisec Absolute timeout time , referenced to Kernel : : get_ms_count ( ) .
*
2019-07-04 12:37:47 +00:00
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
2019-03-26 08:48:58 +00:00
*
* @ note You cannot call this function from ISR context .
* @ note the underlying RTOS may have a limit to the maximum wait time
* due to internal 32 - bit computations , but this is guaranteed to work if the
* wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
* the wait will time out earlier than specified .
2020-02-13 09:07:12 +00:00
* @ deprecated Pass a chrono time_point , not an integer millisecond count . For example use ` Kernel : : Clock : : now ( ) + 5 s `
* rather than ` Kernel : : get_ms_count ( ) + 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
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`. " )
2019-03-26 08:48:58 +00:00
T * alloc_until ( uint64_t millisec )
{
2020-04-21 10:12:28 +00:00
return try_alloc_until ( Kernel : : Clock : : time_point ( std : : chrono : : duration < uint64_t , std : : milli > ( millisec ) ) ) ;
2019-03-26 08:48:58 +00:00
}
2018-10-25 19:20:40 +00:00
/** Allocate a memory block of type T, and set memory block to zero.
2018-10-24 13:43:49 +00:00
*
2019-03-26 08:48:58 +00:00
* @ param millisec Not used ( see note ) .
2018-10-24 13:43:49 +00:00
*
2019-07-04 12:37:47 +00:00
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
2018-10-24 13:43:49 +00:00
*
2020-04-21 10:12:28 +00:00
* @ note You may call this function from ISR context .
* @ note If blocking is required , use Mail : : try_calloc_for or Mail : : try_calloc_until
* @ deprecated Replaced with try_calloc . In future calloc ( ) will be an untimed blocking call .
2018-10-24 13:43:49 +00:00
*/
2020-04-21 10:12:28 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Replaced with try_calloc. In future calloc() will be an untimed blocking call. " )
2019-03-26 08:48:58 +00:00
T * calloc ( MBED_UNUSED uint32_t millisec = 0 )
2018-11-12 10:33:38 +00:00
{
2020-04-21 10:12:28 +00:00
return try_calloc ( ) ;
}
/** Allocate a memory block of type T, and set memory block to zero.
*
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
*
* @ note You may call this function from ISR context .
* @ note If blocking is required , use Mail : : try_calloc_for or Mail : : try_calloc_until
*/
T * try_calloc ( )
{
return _pool . try_calloc ( ) ;
2013-02-18 15:32:11 +00:00
}
2014-05-29 13:36:51 +00:00
2020-02-13 09:07:12 +00:00
/** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
*
* @ param rel_time Timeout value , or Kernel : : wait_for_u32_forever .
*
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
*
* @ note You may call this function from ISR context if the rel_time parameter is set to 0.
*/
2020-04-21 10:12:28 +00:00
T * try_calloc_for ( Kernel : : Clock : : duration_u32 rel_time )
2020-02-13 09:07:12 +00:00
{
2020-04-21 10:12:28 +00:00
return _pool . try_calloc_for ( rel_time ) ;
2020-02-13 09:07:12 +00:00
}
2019-03-26 08:48:58 +00:00
/** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
*
* @ param millisec Timeout value , or osWaitForever .
*
2019-07-04 12:37:47 +00:00
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
2019-03-26 08:48:58 +00:00
*
* @ note You may call this function from ISR context if the millisec parameter is set to 0.
2020-02-13 09:07:12 +00:00
* @ deprecated Pass a chrono duration , not an integer millisecond count . For example use ` 5 s ` rather than ` 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. " )
2019-03-26 08:48:58 +00:00
T * calloc_for ( uint32_t millisec )
{
2020-04-21 10:12:28 +00:00
return try_calloc_for ( std : : chrono : : duration < uint32_t , std : : milli > ( millisec ) ) ;
2020-02-13 09:07:12 +00:00
}
/** Allocate a memory block of type T, blocking, and set memory block to zero.
*
* @ param abs_time Absolute timeout time , referenced to Kernel : : Clock .
*
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
*
* @ note You cannot call this function from ISR context .
* @ note the underlying RTOS may have a limit to the maximum wait time
* due to internal 32 - bit computations , but this is guaranteed to work if the
* wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
* the wait will time out earlier than specified .
*/
2020-04-21 10:12:28 +00:00
T * try_calloc_until ( Kernel : : Clock : : time_point abs_time )
2020-02-13 09:07:12 +00:00
{
2020-04-21 10:12:28 +00:00
return _pool . try_calloc_until ( abs_time ) ;
2019-03-26 08:48:58 +00:00
}
/** Allocate a memory block of type T, blocking, and set memory block to zero.
*
* @ param millisec Absolute timeout time , referenced to Kernel : : get_ms_count ( ) .
*
2019-07-04 12:37:47 +00:00
* @ return Pointer to memory block that you can fill with mail or nullptr in case error .
2019-03-26 08:48:58 +00:00
*
* @ note You cannot call this function from ISR context .
* @ note the underlying RTOS may have a limit to the maximum wait time
* due to internal 32 - bit computations , but this is guaranteed to work if the
* wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
* the wait will time out earlier than specified .
2020-02-13 09:07:12 +00:00
* @ deprecated Pass a chrono time_point , not an integer millisecond count . For example use ` Kernel : : Clock : : now ( ) + 5 s `
* rather than ` Kernel : : get_ms_count ( ) + 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
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`. " )
2019-03-26 08:48:58 +00:00
T * calloc_until ( uint64_t millisec )
{
2020-04-21 10:12:28 +00:00
return try_calloc_until ( Kernel : : Clock : : time_point ( std : : chrono : : duration < uint64_t , std : : milli > ( millisec ) ) ) ;
2019-03-26 08:48:58 +00:00
}
2013-02-18 15:32:11 +00:00
/** Put a mail in the queue.
2018-10-24 13:43:49 +00:00
*
* @ param mptr Memory block previously allocated with Mail : : alloc or Mail : : calloc .
*
* @ return Status code that indicates the execution status of the function ( osOK on success ) .
2020-04-21 11:39:50 +00:00
* See note .
2018-10-24 13:43:49 +00:00
*
* @ note You may call this function from ISR context .
2020-04-21 11:39:50 +00:00
* @ note As the mail should have already been allocated , and the memory pool is the same size
* as the queue , the put operation should always succeed , despite being implemented with
* Queue : : try_put - there is room in the queue for every mail from the pool . Therefore
* use of the return value is deprecated , and the function will return void in future .
2018-10-24 13:43:49 +00:00
*/
2018-11-12 10:33:38 +00:00
osStatus put ( T * mptr )
{
2020-04-21 11:39:50 +00:00
bool ok = _queue . try_put ( mptr ) ;
MBED_ASSERT ( ok ) ;
return ok ? osOK : osErrorResource ;
2020-02-13 09:07:12 +00:00
}
/** Get a mail from the queue.
*
* @ param rel_time Timeout value ( default : Kernel : : wait_for_u32_forever ) .
2018-10-24 13:43:49 +00:00
*
2020-03-11 16:25:11 +00:00
* @ return Event that contains mail information and status code . The status code
* is stored in the status member :
* @ a osEventMail Mail successfully received .
* @ a osOK No mail is available ( and no timeout was specified ) .
* @ a osEventTimeout No mail has arrived during the given timeout period .
* @ a osErrorParameter A parameter is invalid or outside of a permitted range .
2018-10-24 13:43:49 +00:00
*
* @ note You may call this function from ISR context if the millisec parameter is set to 0.
2020-04-21 11:39:50 +00:00
* @ deprecated Replaced with try_get and try_get_for . In future get will be an untimed blocking call .
2018-10-24 13:43:49 +00:00
*/
2020-04-21 11:39:50 +00:00
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. " )
osEvent get ( uint32_t millisec = osWaitForever )
2018-11-12 10:33:38 +00:00
{
2020-04-21 11:39:50 +00:00
osEvent evt = _queue . get ( millisec ) ;
2017-05-15 14:55:45 +00:00
if ( evt . status = = osEventMessage ) {
evt . status = osEventMail ;
}
return evt ;
2013-02-18 15:32:11 +00:00
}
2014-05-29 13:36:51 +00:00
2020-04-21 11:39:50 +00:00
/** Get a mail from the queue.
*
* @ return Pointer to received mail , or nullptr if none was received .
*
* @ note You may call this function from ISR context .
*/
T * try_get ( )
{
T * mptr = nullptr ;
_queue . try_get ( & mptr ) ;
return mptr ;
}
/** Get a mail from the queue.
*
* @ param rel_time Timeout value or Kernel : : wait_for_u32_forever .
*
* @ return Pointer to received mail , or nullptr if none was received .
*
* @ note You may call this function from ISR context if the millisec parameter is set to 0.
*/
T * try_get_for ( Kernel : : Clock : : duration_u32 rel_time )
{
T * mptr = nullptr ;
_queue . try_get_for ( rel_time , & mptr ) ;
return mptr ;
}
2013-02-18 15:32:11 +00:00
/** Free a memory block from a mail.
2018-10-24 13:43:49 +00:00
*
* @ param mptr Pointer to the memory block that was obtained with Mail : : get .
*
* @ return Status code that indicates the execution status of the function ( osOK on success ) .
*
* @ note You may call this function from ISR context .
*/
2018-11-12 10:33:38 +00:00
osStatus free ( T * mptr )
{
2017-05-15 14:55:45 +00:00
return _pool . free ( mptr ) ;
2013-02-18 15:32:11 +00:00
}
private :
2017-05-15 14:55:45 +00:00
Queue < T , queue_sz > _queue ;
MemoryPool < T , queue_sz > _pool ;
2013-02-18 15:32:11 +00:00
} ;
2017-10-24 15:05:45 +00:00
/** @}*/
/** @}*/
2013-02-18 15:32:11 +00:00
}
# endif
2019-03-14 11:36:02 +00:00
# endif
2017-10-24 15:05:45 +00:00