13#ifndef CMSIS_PLUS_RTOS_OS_MQUEUE_H_
14#define CMSIS_PLUS_RTOS_OS_MQUEUE_H_
18#if defined(__cplusplus)
22#if defined(OS_USE_OS_APP_CONFIG_H)
23#include <cmsis-plus/os-app-config.h>
33#pragma GCC diagnostic push
35#pragma clang diagnostic ignored "-Wc++98-compat"
36#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
48#pragma GCC diagnostic push
50#pragma clang diagnostic ignored "-Wpadded"
51#elif defined(__GNUC__)
52#pragma GCC diagnostic ignored "-Wpadded"
61#pragma GCC diagnostic push
63#elif defined(__GNUC__)
64#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
65#pragma GCC diagnostic ignored "-Wsuggest-final-types"
81#if defined(OS_BOOL_RTOS_MESSAGE_QUEUE_SIZE_16BITS)
232 template<
typename T, std::
size_t msgs, std::
size_t msg_size_
bytes>
236 T
queue[(msgs * msg_size_bytes +
sizeof(T) - 1) /
sizeof(T)];
249 constexpr std::size_t
251 std::size_t msg_size_bytes)
254 return (msgs * ((msg_size_bytes + (
sizeof(T) - 1)) & ~(
sizeof(T) - 1)))
256 + ((2 * msgs *
sizeof(
index_t) + (
sizeof(T) - 1))
259 + ((msgs *
sizeof(
priority_t) + (
sizeof(T) - 1))
292 std::size_t msg_size_bytes,
const attributes& attr =
418 timed_send (
const void* msg, std::size_t nbytes,
573 internal_construct_ (std::size_t msgs, std::size_t msg_size_bytes,
574 const attributes& attr,
void* queue_address,
575 std::size_t queue_size_bytes);
585 internal_init_ (
void);
587#if !defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
599 internal_try_send_ (
const void* msg, std::size_t nbytes,
613 internal_try_receive_ (
void* msg, std::size_t nbytes,
priority_t* mprio);
637#if !defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
649 clock* clock_ =
nullptr;
656 volatile index_t* prev_array_ =
nullptr;
660 volatile index_t* next_array_ =
nullptr;
675 void*
volatile first_free_ =
nullptr;
682 void* queue_addr_ =
nullptr;
687 void* allocated_queue_addr_ =
nullptr;
691 const void* allocator_ =
nullptr;
693#if defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
694 friend class port::message_queue;
695 os_mqueue_port_data_t port_;
702 std::size_t queue_size_bytes_ = 0;
706 std::size_t allocated_queue_size_elements_ = 0;
721#if !defined(OS_USE_RTOS_PORT_MESSAGE_QUEUE)
737#pragma GCC diagnostic pop
746 template<
typename Allocator = memory::allocator<
void*>>
784 std::size_t msg_size_bytes,
827#pragma GCC diagnostic push
828#if defined(__clang__)
829#elif defined(__GNUC__)
830#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
831#pragma GCC diagnostic ignored "-Wsuggest-final-types"
833 template<
typename T,
typename Allocator = memory::allocator<
void*>>
1035#pragma GCC diagnostic pop
1045 template<
typename T, std::
size_t N>
1261#pragma GCC diagnostic pop
1290 return this == &rhs;
1326 return msg_size_bytes_;
1381 template<
typename Allocator>
1384 std::size_t msgs, std::size_t msg_size_bytes,
const attributes& attr,
1387 {
nullptr, msgs, msg_size_bytes, attr, allocator }
1417 template<
typename Allocator>
1419 const char* name, std::size_t msgs, std::size_t msg_size_bytes,
1424#if defined(OS_TRACE_RTOS_MQUEUE)
1425 trace::printf (
"%s() @%p %s %d %d\n", __func__,
this, this->name (),
1426 msgs, msg_size_bytes);
1429 if (attr.mq_queue_address !=
nullptr)
1432 internal_construct_ (msgs, msg_size_bytes, attr,
nullptr, 0);
1436 allocator_ = &allocator;
1440 allocated_queue_size_elements_ = (compute_allocated_size_bytes<
1441 typename allocator_type::value_type> (msgs, msg_size_bytes)
1442 +
sizeof(
typename allocator_type::value_type) - 1)
1443 /
sizeof(
typename allocator_type::value_type);
1445 allocated_queue_addr_ =
1446 const_cast<allocator_type&
> (allocator).allocate (
1447 allocated_queue_size_elements_);
1449 internal_construct_ (
1453 allocated_queue_addr_,
1454 allocated_queue_size_elements_
1455 *
sizeof(
typename allocator_type::value_type));
1473 template<
typename Allocator>
1476#if defined(OS_TRACE_RTOS_MQUEUE)
1479 typedef typename std::allocator_traits<allocator_type>::pointer pointer;
1481 if (allocated_queue_addr_ !=
nullptr)
1483 static_cast<allocator_type*
> (
const_cast<void*
> (allocator_))->deallocate (
1484 static_cast<pointer
> (allocated_queue_addr_),
1485 allocated_queue_size_elements_);
1487 allocated_queue_addr_ =
nullptr;
1522 template<
typename T,
typename Allocator>
1528 { msgs,
sizeof(
value_type), attr, allocator }
1561 template<
typename T,
typename Allocator>
1564 const char* name, std::size_t msgs,
1588#pragma GCC diagnostic push
1589#if defined(__clang__)
1590#elif defined(__GNUC__)
1591#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
1593 template<
typename T,
typename Allocator>
1597#pragma GCC diagnostic pop
1606 template<
typename T,
typename Allocator>
1612 reinterpret_cast<const char*
> (msg),
sizeof(
value_type), mprio);
1622 template<
typename T,
typename Allocator>
1628 reinterpret_cast<const char*
> (msg),
sizeof(
value_type), mprio);
1638 template<
typename T,
typename Allocator>
1645 reinterpret_cast<const char*
> (msg),
sizeof(
value_type), timeout,
1656 template<
typename T,
typename Allocator>
1662 reinterpret_cast<char*
> (msg),
sizeof(
value_type), mprio);
1672 template<
typename T,
typename Allocator>
1678 reinterpret_cast<char*
> (msg),
sizeof(
value_type), mprio);
1688 template<
typename T,
typename Allocator>
1695 reinterpret_cast<char*
> (msg),
sizeof(
value_type), timeout, mprio);
1734 template<
typename T, std::
size_t N>
1777 template<
typename T, std::
size_t N>
1782 static_assert(
sizeof(T) >=
sizeof(
void*),
"Messages of message_queue need to have at least the size of a pointer");
1801 template<
typename T, std::
size_t N>
1813 template<
typename T, std::
size_t N>
1829 template<
typename T, std::
size_t N>
1845 template<
typename T, std::
size_t N>
1862 template<
typename T, std::
size_t N>
1878 template<
typename T, std::
size_t N>
1894 template<
typename T, std::
size_t N>
1907#pragma GCC diagnostic pop
Base class for attributes.
Base class for named system objects.
const char * name(void) const
Get object name.
Priority ordered list of threads.
Standard allocator based on the RTOS system default memory manager.
Storage for a static message queue.
T prios[(msgs *sizeof(priority_t)+sizeof(T) - 1)/sizeof(T)]
T queue[(msgs *msg_size_bytes+sizeof(T) - 1)/sizeof(T)]
T links[((2 *msgs) *sizeof(index_t)+sizeof(T) - 1)/sizeof(T)]
Message queue attributes.
attributes(attributes &&)=default
attributes(const attributes &)=default
constexpr attributes()
Construct a message queue attributes object instance.
void * mq_queue_address
Address of the user defined storage for the message queue.
std::size_t mq_queue_size_bytes
Size of the user defined storage for the message queue.
attributes & operator=(const attributes &)=default
~attributes()=default
Destruct the message queue attributes object instance.
Template of a POSIX compliant message queue with allocator.
message_queue_allocated(std::size_t msgs, std::size_t msg_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
Construct a message queue object instance.
message_queue_allocated(const char *name, std::size_t msgs, std::size_t msg_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
Construct a named message queue object instance.
virtual ~message_queue_allocated() override
Destruct the message queue.
Allocator allocator_type
Standard allocator type definition.
Template of a POSIX compliant message queue with message type and local storage.
T value_type
Local type of message.
result_t send(const value_type *msg, priority_t mprio=default_priority)
Send a typed message to the queue.
virtual ~message_queue_inclusive() override
Destruct the typed message queue object instance.
result_t try_send(const value_type *msg, priority_t mprio=default_priority)
Try to send a typed message to the queue.
result_t timed_send(const value_type *msg, clock::duration_t timeout, priority_t mprio=default_priority)
Send a typed message to the queue with timeout.
message_queue_inclusive(const attributes &attr=initializer)
Construct a typed message queue object instance.
static const std::size_t msgs
Local constant based on template definition.
result_t receive(value_type *msg, priority_t *mprio=nullptr)
Receive a typed message from the queue.
result_t timed_receive(value_type *msg, clock::duration_t timeout, priority_t *mprio=nullptr)
Receive a typed message from the queue with timeout.
result_t try_receive(value_type *msg, priority_t *mprio=nullptr)
Try to receive a typed message from the queue.
Template of a POSIX compliant message queue with message type and allocator.
T value_type
Standard allocator type definition.
result_t send(const value_type *msg, message_queue::priority_t mprio=message_queue::default_priority)
Send a typed message to the queue.
result_t try_send(const value_type *msg, message_queue::priority_t mprio=message_queue::default_priority)
Try to send a typed message to the queue.
Allocator allocator_type
Standard allocator type definition.
result_t try_receive(value_type *msg, message_queue::priority_t *mprio=nullptr)
Try to receive a typed message from the queue.
result_t receive(value_type *msg, message_queue::priority_t *mprio=nullptr)
Receive a typed message from the queue.
result_t timed_receive(value_type *msg, clock::duration_t timeout, message_queue::priority_t *mprio=nullptr)
Receive a typed message from the queue with timeout.
message_queue_typed(std::size_t msgs, const message_queue::attributes &attr=message_queue::initializer, const allocator_type &allocator=allocator_type())
Construct a typed message queue object instance.
virtual ~message_queue_typed() override
Destruct the typed message queue object instance.
result_t timed_send(const value_type *msg, clock::duration_t timeout, message_queue::priority_t mprio=message_queue::default_priority)
Send a typed message to the queue with timeout.
POSIX compliant message queue, using the default RTOS allocator.
bool empty(void) const
Check if the queue is empty.
result_t receive(void *msg, std::size_t nbytes, priority_t *mprio=nullptr)
Receive a message from the queue.
result_t reset(void)
Reset the message queue.
result_t try_send(const void *msg, std::size_t nbytes, priority_t mprio=default_priority)
Try to send a message to the queue.
result_t try_receive(void *msg, std::size_t nbytes, priority_t *mprio=nullptr)
Try to receive a message from the queue.
result_t send(const void *msg, std::size_t nbytes, priority_t mprio=default_priority)
Send a message to the queue.
virtual ~message_queue()
Destruct the message queue object instance.
result_t timed_receive(void *msg, std::size_t nbytes, clock::duration_t timeout, priority_t *mprio=nullptr)
Receive a message from the queue with timeout.
std::size_t capacity(void) const
Get queue capacity.
std::size_t msg_size(void) const
Get message size.
result_t timed_send(const void *msg, std::size_t nbytes, clock::duration_t timeout, priority_t mprio=default_priority)
Send a message to the queue with timeout.
constexpr std::size_t compute_allocated_size_bytes(std::size_t msgs, std::size_t msg_size_bytes)
Calculator for queue storage requirements.
bool full(void) const
Check if the queue is full.
std::size_t length(void) const
Get queue length.
bool operator==(const message_queue &rhs) const
Compare memory queues.
int printf(const char *format,...)
Write a formatted string to the trace device.
port::clock::duration_t duration_t
Type of variables holding clock durations.
static constexpr msg_size_t max_msg_size
Maximum message size.
static constexpr priority_t max_priority
Maximum message priority.
uint8_t priority_t
Type of message priority storage.
message_queue::size_t index_t
Type of list index storage.
static constexpr priority_t default_priority
Default message priority.
static const attributes initializer
Default message queue initialiser.
uint8_t size_t
Type of a queue size storage.
memory::allocator< thread::stack::allocation_element_t > allocator_type
Default RTOS allocator.
uint16_t msg_size_t
Type of message size storage.
static constexpr index_t no_index
Index value to represent an illegal index.
static constexpr message_queue::size_t max_size
Maximum queue size.
uint32_t result_t
Type of values returned by RTOS functions.