From b673e13892cf7aac425569709a140dc4b589ec70 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 16 May 2020 20:58:48 +0200 Subject: [PATCH] some refactoring --- ipc/MessageQueueIF.h | 24 ++++--- ipc/MessageQueueMessage.cpp | 28 ++++---- ipc/MessageQueueMessage.h | 126 +++++++++++++++++++-------------- ipc/QueueFactory.h | 6 +- osal/FreeRTOS/MessageQueue.cpp | 10 +-- osal/FreeRTOS/QueueFactory.cpp | 16 +++-- osal/linux/MessageQueue.cpp | 12 ++-- osal/linux/MessageQueue.h | 32 +++++---- osal/linux/QueueFactory.cpp | 16 +++-- 9 files changed, 156 insertions(+), 114 deletions(-) diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 47da694c..c67f3870 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -36,8 +36,8 @@ public: * lastParnter information as destination. If there was no message received yet * (i.e. lastPartner is zero), an error code is returned. * @param message A pointer to a previously created message, which is sent. - * \return RETURN_OK if ok - * \return NO_REPLY_PARTNER Should return NO_REPLY_PARTNER if partner was found + * @return RETURN_OK if ok + * @return NO_REPLY_PARTNER Should return NO_REPLY_PARTNER if partner was found */ virtual ReturnValue_t reply( MessageQueueMessage* message ) = 0; @@ -53,10 +53,12 @@ public: /** * @brief This function reads available messages from the message queue. - * @details If data is available it is stored in the passed message pointer. The message's - * original content is overwritten and the sendFrom information is stored in the - * lastPartner attribute. Else, the lastPartner information remains untouched, the - * message's content is cleared and the function returns immediately. + * @details + * If data is available it is stored in the passed message pointer. + * The message's original content is overwritten and the sendFrom + * information is stored in theblastPartner attribute. Else, the lastPartner + * information remains untouched, the message's content is cleared and the + * function returns immediately. * @param message A pointer to a message in which the received data is stored. * @return -@c RETURN_OK on success * -@c MessageQueueIF::EMPTY if queue is empty @@ -90,7 +92,9 @@ public: * @return -@c RETURN_OK on success * -@c MessageQueueIF::FULL if queue is full */ - virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; + virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault = false ) = 0; /** * @brief This operation sends a message to the given destination. @@ -100,7 +104,8 @@ public: * @param message A pointer to a previously created message, which is sent. * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ - virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo, MessageQueueMessage* message, bool ignoreFault = false ) = 0; + virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo, + MessageQueueMessage* message, bool ignoreFault = false ) = 0; /** * @brief The sendToDefaultFrom method sends a queue message to the default destination. @@ -111,7 +116,8 @@ public: * @return -@c RETURN_OK on success * -@c MessageQueueIF::FULL if queue is full */ - virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; + virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, + MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; /** * @brief This operation sends a message to the default destination. * @details As in the sendMessage method, this function uses the sendToDefault call of the diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index 30e0325c..544d18e8 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -8,6 +8,20 @@ MessageQueueMessage::MessageQueueMessage() : memset(this->internalBuffer, 0, sizeof(this->internalBuffer)); } +MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size) : + messageSize(this->HEADER_SIZE + size) { + if (size <= this->MAX_DATA_SIZE) { + memcpy(this->getData(), data, size); + this->messageSize = this->HEADER_SIZE + size; + } + else { + sif::warning << "MessageQueueMessage: Passed size larger than maximum" + "allowed size! Setting content to 0" << std::endl; + memset(this->internalBuffer, 0, sizeof(this->internalBuffer)); + this->messageSize = this->HEADER_SIZE; + } +} + MessageQueueMessage::~MessageQueueMessage() { } @@ -37,23 +51,13 @@ void MessageQueueMessage::setSender(MessageQueueId_t setId) { memcpy(this->internalBuffer, &setId, sizeof(MessageQueueId_t)); } -MessageQueueMessage::MessageQueueMessage(uint8_t* data, uint32_t size) : - messageSize(this->HEADER_SIZE + size) { - if (size <= this->MAX_DATA_SIZE) { - memcpy(this->getData(), data, size); - } else { - memset(this->internalBuffer, 0, sizeof(this->internalBuffer)); - this->messageSize = this->HEADER_SIZE; - } -} - size_t MessageQueueMessage::getMinimumMessageSize() { return this->HEADER_SIZE; } void MessageQueueMessage::print() { - sif::debug << "MessageQueueMessage has size: " << this->messageSize << std::hex - << std::endl; + sif::debug << "MessageQueueMessage has size: " << this->messageSize << + std::hex << std::endl; for (uint8_t count = 0; count < this->messageSize; count++) { sif::debug << (uint32_t) this->internalBuffer[count] << ":"; } diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 8c4ec947..4d82bd88 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -5,111 +5,129 @@ #include /** - * \brief This class is the representation and data organizer for interprocess messages. + * @brief This class is the representation and data organizer + * for interprocess messages. * - * \details To facilitate and standardize interprocess communication, this class was created - * to handle a lightweight "interprocess message protocol". It adds a header with the - * sender's queue id to every sent message and defines the maximum total message size. - * Specialized messages, such as device commanding messages, can be created by inheriting - * from this class and filling the buffer provided by getData with additional content. - * If larger amounts of data must be sent between processes, the data shall be stored in - * the IPC Store object and only the storage id is passed in a queue message. - * The class is used both to generate and send messages and to receive messages from - * other tasks. - * \ingroup message_queue + * @details + * To facilitate and standardize interprocess communication, this class was + * created to handle a lightweight "interprocess message protocol". + * + * It adds a header with the sender's queue id to every sent message and + * defines the maximum total message size. Specialized messages, such as + * device commanding messages, can be created by inheriting from this class + * and filling the buffer provided by getData with additional content. + * + * If larger amounts of data must be sent between processes, the data shall + * be stored in the IPC Store object and only the storage id is passed in a + * queue message.The class is used both to generate and send messages and to + * receive messages from other tasks. + * @ingroup message_queue */ class MessageQueueMessage { public: /** - * \brief This constant defines the maximum size of the data content, excluding the header. - * \details It may be changed if necessary, but in general should be kept as small as possible. + * @brief The class is initialized empty with this constructor. + * @details The messageSize attribute is set to the header's size and the + * whole content is set to zero. + */ + MessageQueueMessage(); + /** + * @brief With this constructor the class is initialized with the given content. + * @details + * If the passed message size fits into the buffer, the passed data is + * copied to the internal buffer and the messageSize information is set. + * Otherwise, messageSize is set to the header's size and the whole + * content is set to zero. + * @param data The data to be put in the message. + * @param size Size of the data to be copied. Must be smaller than + * MAX_MESSAGE_SIZE and larger than MIN_MESSAGE_SIZE. + */ + MessageQueueMessage(uint8_t* data, size_t size); + /** + * @brief The size information of each message is stored in this attribute. + * @details + * It is public to simplify usage and to allow for passing the size + * address as a pointer. Care must be taken when inheriting from this class, + * as every child class is responsible for managing the size information by + * itself. When using the class to receive a message, the size information + * is updated automatically. + * + * Please note that the minimum size is limited by the size of the header + * while the maximum size is limited by the maximum allowed message size. + */ + size_t messageSize; + /** + * @brief This constant defines the maximum size of the data content, excluding the header. + * @details It may be changed if necessary, but in general should be kept as small as possible. */ static const size_t MAX_DATA_SIZE = 24; /** - * \brief This constants defines the size of the header, which is added to every message. + * @brief This constants defines the size of the header, which is added to every message. */ static const size_t HEADER_SIZE = sizeof(MessageQueueId_t); /** - * \brief This constant defines the maximum total size in bytes of a sent message. - * \details It is the sum of the maximum data and the header size. Be aware that this constant + * @brief This constant defines the maximum total size in bytes of a sent message. + * @details It is the sum of the maximum data and the header size. Be aware that this constant * is used to define the buffer sizes for every message queue in the system. So, a change * here may have significant impact on the required resources. */ static const size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE; + /** + * @brief Defines the minimum size of a message where only the + * header is included + */ + static const size_t MIN_MESSAGE_SIZE = HEADER_SIZE; private: /** - * \brief This is the internal buffer that contains the actual message data. + * @brief This is the internal buffer that contains the actual message data. */ uint8_t internalBuffer[MAX_MESSAGE_SIZE]; public: /** - * \brief The size information of each message is stored in this attribute. - * \details It is public to simplify usage and to allow for passing the variable's address as a - * pointer. Care must be taken when inheriting from this class, as every child class is - * responsible for managing the size information by itself. When using the class to - * receive a message, the size information is updated automatically. - */ - size_t messageSize; - /** - * \brief The class is initialized empty with this constructor. - * \details The messageSize attribute is set to the header's size and the whole content is set to - * zero. - */ - MessageQueueMessage(); - /** - * \brief With this constructor the class is initialized with the given content. - * \details If the passed message size fits into the buffer, the passed data is copied to the - * internal buffer and the messageSize information is set. Otherwise, messageSize - * is set to the header's size and the whole content is set to zero. - * \param data The data to be put in the message. - * \param size Size of the data to be copied. Must be smaller than MAX_MESSAGE_SIZE. - */ - MessageQueueMessage(uint8_t* data, uint32_t size); - /** - * \brief As no memory is allocated in this class, the destructor is empty. + * @brief As no memory is allocated in this class, the destructor is empty. */ virtual ~MessageQueueMessage(); /** - * \brief This method is used to get the complete data of the message. + * @brief This method is used to get the complete data of the message. */ const uint8_t* getBuffer() const; /** - * \brief This method is used to get the complete data of the message. + * @brief This method is used to get the complete data of the message. */ uint8_t* getBuffer(); /** - * \brief This method is used to fetch the data content of the message. - * \details It shall be used by child classes to add data at the right position. + * @brief This method is used to fetch the data content of the message. + * @details It shall be used by child classes to add data at the right position. */ const uint8_t* getData() const; /** - * \brief This method is used to fetch the data content of the message. - * \details It shall be used by child classes to add data at the right position. + * @brief This method is used to fetch the data content of the message. + * @details It shall be used by child classes to add data at the right position. */ uint8_t* getData(); /** - * \brief This method is used to extract the sender's message queue id information from a + * @brief This method is used to extract the sender's message queue id information from a * received message. */ MessageQueueId_t getSender() const; /** - * \brief With this method, the whole content and the message size is set to zero. + * @brief With this method, the whole content and the message size is set to zero. */ void clear(); /** - * \brief This is a debug method that prints the content (till messageSize) to the debug output. + * @brief This is a debug method that prints the content (till messageSize) to the debug output. */ void print(); /** - * \brief This method is used to set the sender's message queue id information prior to + * @brief This method is used to set the sender's message queue id information prior to * sending the message. - * \param setId The message queue id that identifies the sending message queue. + * @param setId The message queue id that identifies the sending message queue. */ void setSender(MessageQueueId_t setId); /** - * \brief This helper function is used by the MessageQueue class to check the size of an + * @brief This helper function is used by the MessageQueue class to check the size of an * incoming message. - * \details The method must be overwritten by child classes if size checks shall be more strict. + * @details The method must be overwritten by child classes if size checks shall be more strict. * @return The default implementation returns HEADER_SIZE. */ virtual size_t getMinimumMessageSize(); diff --git a/ipc/QueueFactory.h b/ipc/QueueFactory.h index c385b15d..9a883fd8 100644 --- a/ipc/QueueFactory.h +++ b/ipc/QueueFactory.h @@ -2,7 +2,7 @@ #define FRAMEWORK_IPC_QUEUEFACTORY_H_ #include -#include +#include /** * Creates message queues. * This class is a "singleton" interface, i.e. it provides an @@ -18,8 +18,8 @@ public: */ static QueueFactory* instance(); - MessageQueueIF* createMessageQueue(uint32_t message_depth = 3, - uint32_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE); + MessageQueueIF* createMessageQueue(size_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); void deleteMessageQueue(MessageQueueIF* queue); private: diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index aedf4831..38f425a4 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -2,12 +2,14 @@ #include -// TODO I guess we should have a way of checking if we are in an ISR and then use the "fromISR" versions of all calls -// As a first step towards this, introduces system context variable which needs to be switched manually +// TODO I guess we should have a way of checking if we are in an ISR and then +// use the "fromISR" versions of all calls +// As a first step towards this, introduces system context variable which needs +// to be switched manually // Haven't found function to find system context. -MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) : defaultDestination(0),lastPartner(0), callContext(CallContext::task) { - handle = xQueueCreate(message_depth, max_message_size); + handle = xQueueCreate(messageDepth, maxMessageSize); if (handle == NULL) { sif::error << "MessageQueue creation failed" << std::endl; } diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index eaf245d3..a4ee5cf3 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -3,16 +3,18 @@ #include -QueueFactory* QueueFactory::factoryInstance = NULL; +QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { - return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, + sentFrom,ignoreFault); } QueueFactory* QueueFactory::instance() { - if (factoryInstance == NULL) { + if (factoryInstance == nullptr) { factoryInstance = new QueueFactory; } return factoryInstance; @@ -24,9 +26,9 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); +MessageQueueIF* QueueFactory::createMessageQueue(size_t messageDepth, + size_t maxMessageSize) { + return new MessageQueue(messageDepth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index edabe946..96d9fb4d 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -7,15 +7,15 @@ #include -MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) : id(0), lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; //Set attributes attributes.mq_curmsgs = 0; - attributes.mq_maxmsg = message_depth; - attributes.mq_msgsize = max_message_size; + attributes.mq_maxmsg = messageDepth; + attributes.mq_msgsize = maxMessageSize; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open //Set the name of the queue sprintf(name, "/Q%u\n", queueCounter++); @@ -265,7 +265,11 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ case EMSGSIZE: - //The msg_len is greater than the msgsize associated with the specified queue. + // The msg_len is greater than the msgsize associated with + //the specified queue. + sif::error << "MessageQueue::sendMessage: Size error [" << + strerror(errno) << "] in mq_send" << std::endl; + /*NO BREAK*/ default: return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index b8285dc5..fdc8dab1 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -5,20 +5,23 @@ #include #include /** - * @brief This class manages sending and receiving of message queue messages. + * @brief This class manages sending and receiving of message queue messages. * - * @details Message queues are used to pass asynchronous messages between processes. - * They work like post boxes, where all incoming messages are stored in FIFO - * order. This class creates a new receiving queue and provides methods to fetch - * received messages. Being a child of MessageQueueSender, this class also provides - * methods to send a message to a user-defined or a default destination. In addition - * it also provides a reply method to answer to the queue it received its last message - * from. - * The MessageQueue should be used as "post box" for a single owning object. So all - * message queue communication is "n-to-one". - * For creating the queue, as well as sending and receiving messages, the class makes - * use of the operating system calls provided. - * \ingroup message_queue + * @details + * Message queues are used to pass asynchronous messages between processes. + * They work like post boxes, where all incoming messages are stored in FIFO + * order. This class creates a new receiving queue and provides methods to fetch + * received messages. Being a child of MessageQueueSender, this class also + * provides methods to send a message to a user-defined or a default destination. + * In addition it also provides a reply method to answer to the queue it + * received its last message from. + * + * The MessageQueue should be used as "post box" for a single owning object. + * So all message queue communication is "n-to-one". + * + * The creation of message queues, as well as sending and receiving messages, + * makes use of the operating system calls provided. + * @ingroup message_queue */ class MessageQueue : public MessageQueueIF { friend class MessageQueueSenderIF; @@ -35,7 +38,8 @@ public: * @param max_message_size With this parameter, the maximum message size can be adjusted. * This should be left default. */ - MessageQueue( size_t message_depth = 3, size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE ); + MessageQueue(size_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE ); /** * @brief The destructor deletes the formerly created message queue. * @details This is accomplished by using the delete call provided by the operating system. diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index fc4c9026..2bacb815 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -5,16 +5,18 @@ #include #include -QueueFactory* QueueFactory::factoryInstance = NULL; +QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { - return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, + sentFrom,ignoreFault); } QueueFactory* QueueFactory::instance() { - if (factoryInstance == NULL) { + if (factoryInstance == nullptr) { factoryInstance = new QueueFactory; } return factoryInstance; @@ -26,9 +28,9 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); +MessageQueueIF* QueueFactory::createMessageQueue(size_t messageDepth, + size_t maxMessageSize) { + return new MessageQueue(messageDepth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {