Abstraction of message queue message and command message #106
Labels
No Label
API Change
Breaking API Change
bug
build
cosmetics
Documentation
duplicate
feature
help wanted
hotfix
invalid
question
Refactor
Tests
wontfix
No Milestone
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: fsfw/fsfw#106
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
To support variable sized packets and different kind of command messages, I suggest changes to the way message queues are used. These changes achieve dependency inversion by making the message queue implementation depending on an abstraction instead of a concrete implementation but this comes at a price: More size checking is required. Advantages are that message queue messages are not fixed to 24 bytes. I think this could be useful for certain cases and make the message queue code more generic and flexible (comes at a price, of course..).
This basically includes following changes:
New
MessageQueueMessageIF
Interface for the class which holds the actual data of the message (has an internal buffer). It has following abstract functions, which are used by the the message queue implementations.
virtual void clear() = 0;
virtual const uint8_t* getBuffer() const = 0
virtual uint8_t* getBuffer() = 0
virtual void setSender(MessageQueueId_t setId) = 0
virtual MessageQueueId_t getSender() const = 0
virtual const uint8_t* getData() const = 0
virtual uint8_t* getData() = 0
virtual size_t getMinimumMessageSize() const = 0
virtual size_t getMessageSize() const = 0
virtual void setMessageSize(size_t messageSize) = 0
virtual size_t getMaximumMessageSize() const = 0
MessageQueueMessage implements all the functions above and a few more (like
print
).NO_QUEUE
value is 0xffffffff now (Of course, could also be 0, but I think this would be a more fitting value of an invalid value). While trying this out, I found out that some places in the code, the hardcoded number 0 was used to initialize queue IDs instead ofNO_QUEUE
, I replaced those where I found them.All MessageQueue implementations take a MQM IF pointer instead of a concrete MQM pointer now
and can perform size checking by calling the interface functions. This enables new message types which can have more or less than 24 bytes (but the default MQM message will still have 24 bytes).
Of course, new size checks are required for the message queue implementations: The maximum message size has to be checked against the message queue size (which is cached by the constructor) before a message is sent.
Interesting ways this could be used: If the size of a message which is passed between objects is fixed at for example 32 bytes, a message queue could be used instead of the IPC store to exchange the data in form of messages instead of using the IPC store. Of course, for variable sized data or for huge data blocks, it propably would be better to use the IPC store, but maybe an informative comment in MQM IF would be good for that.
New
CommandMessageIF
Interface for command messages. Header gets 2 additional bytes for command ID.
Minimal size is size of header (6).
Implements MQM IF to allow passing command messages directly. Holds a pointer to the message holding the actual data. The ctor of the command message implementation has to check the maximum size against the minimum size of the message queue message (something I don't like but becomes necessary).
virtual Command_t getCommand() const = 0
virtual uint8_t getMessageType() const = 0
virtual void setReplyRejected(ReturnValue_t reason, Command_t initialCommand) = 0
virtual ReturnValue_t getReplyRejectedReason(Command_t* initialCommand = nullptr) const = 0;
virtual MessageQueueMessageIF* getInternalMessage() const = 0
New
CommandMessageBase
Base class for command messages, which implements all common functions to avoid boilerplate code. Minimal size is CommandMessageIF header (6) + space required to set rejected reply (4), so 10 bytes total.
New
CommandMessageCleaner
Extraction of clean-up code into separate class. Dynamic dispatch is used to differentiate between the clean() operation of a MQM (set all bytes to 0) or a command message (look up whether special cleanup needs to be performed).
CommandMessage
The command message now only offers the functions getParameter / setParameter 1/2 and setUnknownReply (although this could propably be moved to base too..). The rest is provided by CommandMessageBase (it implements CommandMessageBase)
HousekeepingMessage
Another form of a command message, implements command message base. Offers get/setSid (for 64 bit SID consisting of object and set ID) and one uint32_t parameter (for example for float collection interval).
Abstraction of message queueto Abstraction of message queue messageAbstraction of message queue messageto Abstraction of message queue message and command messageUPDATE:
After discussions and some thinking I scrapped the CommandMessageBase.
The command message will now expose more parameters (for example with a new
getParameter3()
function), which should be enough for housekeeping messages, which then can be implemented like other command messages.The CommandMessageIF might still have its uses and I still think the MessageQueueMessageIF would be a nice feature.