Merge branch 'mueller_framework' into front_branch

This commit is contained in:
Robin Müller 2020-06-15 17:59:59 +02:00
commit 555b7cc982
8 changed files with 103 additions and 56 deletions

View File

@ -1,5 +1,5 @@
#ifndef DEVICECOMMUNICATIONIF_H_ #ifndef FRAMEWORK_DEVICES_DEVICECOMMUNICATIONIF_H_
#define DEVICECOMMUNICATIONIF_H_ #define FRAMEWORK_DEVICES_DEVICECOMMUNICATIONIF_H_
#include <framework/devicehandlers/CookieIF.h> #include <framework/devicehandlers/CookieIF.h>
#include <framework/devicehandlers/DeviceHandlerIF.h> #include <framework/devicehandlers/DeviceHandlerIF.h>
@ -19,8 +19,8 @@
* the device handler to allow reuse of these components. * the device handler to allow reuse of these components.
* @details * @details
* Documentation: Dissertation Baetz p.138. * Documentation: Dissertation Baetz p.138.
* It works with the assumption that received data * It works with the assumption that received data is polled by a component.
* is polled by a component. There are four generic steps of device communication: * There are four generic steps of device communication:
* *
* 1. Send data to a device * 1. Send data to a device
* 2. Get acknowledgement for sending * 2. Get acknowledgement for sending
@ -77,8 +77,8 @@ public:
* - @c RETURN_OK for successfull send * - @c RETURN_OK for successfull send
* - Everything else triggers failure event with returnvalue as parameter 1 * - Everything else triggers failure event with returnvalue as parameter 1
*/ */
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData, virtual ReturnValue_t sendMessage(CookieIF *cookie,
size_t sendLen) = 0; const uint8_t * sendData, size_t sendLen) = 0;
/** /**
* Called by DHB in the GET_WRITE doGetWrite(). * Called by DHB in the GET_WRITE doGetWrite().
@ -103,7 +103,8 @@ public:
* - Everything else triggers failure event with * - Everything else triggers failure event with
* returnvalue as parameter 1 * returnvalue as parameter 1
*/ */
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) = 0; virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
size_t requestLen) = 0;
/** /**
* Called by DHB in the GET_WRITE doGetRead(). * Called by DHB in the GET_WRITE doGetRead().
@ -119,8 +120,8 @@ public:
* - Everything else triggers failure event with * - Everything else triggers failure event with
* returnvalue as parameter 1 * returnvalue as parameter 1
*/ */
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, virtual ReturnValue_t readReceivedMessage(CookieIF *cookie,
size_t *size) = 0; uint8_t **buffer, size_t *size) = 0;
}; };
#endif /* DEVICECOMMUNICATIONIF_H_ */ #endif /* DEVICECOMMUNICATIONIF_H_ */

View File

@ -3,9 +3,25 @@
HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message):
CommandMessageBase(message) { CommandMessageBase(message) {
if(message->getMaximumMessageSize() < HK_MESSAGE_SIZE) {
sif::error << "CommandMessage::ComandMessage: Passed message buffer"
" can not hold minimum "<< HK_MESSAGE_SIZE
<< " bytes!" << std::endl;
return;
}
message->setMessageSize(HK_MESSAGE_SIZE);
} }
HousekeepingMessage::~HousekeepingMessage() { HousekeepingMessage::~HousekeepingMessage() {}
void HousekeepingMessage::setParameter(uint32_t parameter) {
std::memcpy(getData(), &parameter, sizeof(parameter));
}
uint32_t HousekeepingMessage::getParameter() const {
uint32_t parameter;
std::memcpy(&parameter, getData(), sizeof(parameter));
return parameter;
} }
void HousekeepingMessage::setHkReportMessage(sid_t sid, void HousekeepingMessage::setHkReportMessage(sid_t sid,
@ -15,32 +31,45 @@ void HousekeepingMessage::setHkReportMessage(sid_t sid,
setParameter(storeId.raw); setParameter(storeId.raw);
} }
void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid,
store_address_t storeId) {
CommandMessageBase::setCommand(DIAGNOSTICS_REPORT);
setSid(sid);
setParameter(storeId.raw);
}
size_t HousekeepingMessage::getMinimumMessageSize() const { size_t HousekeepingMessage::getMinimumMessageSize() const {
return HK_MESSAGE_SIZE; return HK_MESSAGE_SIZE;
} }
size_t HousekeepingMessage::getMaximumMessageSize() const {
return MessageQueueMessage::MAX_MESSAGE_SIZE;
}
void HousekeepingMessage::clear() {
// clear IPC store where it is needed.
}
sid_t HousekeepingMessage::getSid() const { sid_t HousekeepingMessage::getSid() const {
sid_t sid; sid_t sid;
std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw)); std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw));
return sid; return sid;
} }
uint8_t* HousekeepingMessage::getData() {
return internalMessage->getBuffer() + sizeof(sid_t);
}
void HousekeepingMessage::setParameter(uint32_t parameter) { sid_t HousekeepingMessage::getHkReportMessage(
memcpy(getData(), &parameter, sizeof(parameter)); store_address_t *storeIdToSet) const {
if(storeIdToSet != nullptr) {
*storeIdToSet = getParameter();
}
return getSid();
} }
void HousekeepingMessage::setSid(sid_t sid) { void HousekeepingMessage::setSid(sid_t sid) {
std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw));
} }
uint8_t* HousekeepingMessage::getData() {
return CommandMessageBase::getData() + sizeof(sid_t);
}
const uint8_t* HousekeepingMessage::getData() const {
return CommandMessageBase::getData() + sizeof(sid_t);
}
void HousekeepingMessage::clear() {
// clear IPC store where it is needed.
}

View File

@ -27,14 +27,22 @@ union sid_t {
}; };
/**
* @brief Special command message type for housekeeping messages
* @details
* This message is slightly larger than regular command messages to accomodate
* the uint64_t structure ID (SID).
*/
class HousekeepingMessage : public CommandMessageBase { class HousekeepingMessage : public CommandMessageBase {
public: public:
static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t) static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t)
+ sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t); + sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t);
/** /**
* No instances of a message shall be created, instead * The HK message is initialized with a pointer to a message which holds
* a CommandMessage instance is manipulated. * the message data, see CommandMessageIF and getInternalMessage().
* @param message
*/ */
HousekeepingMessage(MessageQueueMessageIF* message); HousekeepingMessage(MessageQueueMessageIF* message);
virtual ~HousekeepingMessage(); virtual ~HousekeepingMessage();
@ -85,18 +93,24 @@ public:
static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL =
MAKE_COMMAND_ID(32); MAKE_COMMAND_ID(32);
void setHkReportMessage(sid_t sid, store_address_t storeId);
void setParameter(uint32_t parameter); void setParameter(uint32_t parameter);
uint32_t getParameter() const;
void setHkReportMessage(sid_t sid, store_address_t storeId);
void setHkDiagnosticsMessage(sid_t sid, store_address_t storeId);
//! Get the respective SID and store ID. Command ID can be used beforehand
//! to distinguish between diagnostics and regular HK packets
sid_t getHkReportMessage(store_address_t * storeIdToSet) const;
virtual void clear() override;
virtual size_t getMinimumMessageSize() const override; virtual size_t getMinimumMessageSize() const override;
virtual size_t getMaximumMessageSize() const override; virtual void clear() override;
virtual uint8_t* getData() override;
private: private:
sid_t getSid() const; sid_t getSid() const;
void setSid(sid_t sid); void setSid(sid_t sid);
virtual uint8_t* getData() override;
virtual const uint8_t* getData() const override;
}; };

View File

@ -10,31 +10,18 @@ CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage):
return; return;
} }
if(receiverMessage->getMaximumMessageSize() < if(receiverMessage->getMaximumMessageSize() <
MINIMUM_COMMAND_MESSAGE_SIZE) { getMinimumMessageSize()) {
sif::error << "CommandMessage::ComandMessage: Passed message buffer" sif::error << "CommandMessage::ComandMessage: Passed message buffer"
" can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE
<< " bytes!" << std::endl; << " bytes!" << std::endl;
return; return;
} }
internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); internalMessage->setMessageSize(getMinimumMessageSize());
} }
CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet,
Command_t command, uint32_t parameter1, uint32_t parameter2): Command_t command, uint32_t parameter1, uint32_t parameter2):
CommandMessageBase(messageToSet) { CommandMessage(messageToSet) {
if(messageToSet == nullptr) {
sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr"
" as the message queue message, pass the address of an actual"
" message!" << std::endl;
}
if(messageToSet->getMaximumMessageSize() <
MINIMUM_COMMAND_MESSAGE_SIZE) {
sif::error << "CommandMessage::ComandMessage: Passed message buffer"
" can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE
<< " bytes!" << std::endl;
return;
}
internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE);
setCommand(command); setCommand(command);
setParameter(parameter1); setParameter(parameter1);
setParameter2(parameter2); setParameter2(parameter2);
@ -66,10 +53,6 @@ size_t CommandMessage::getMinimumMessageSize() const {
return MINIMUM_COMMAND_MESSAGE_SIZE; return MINIMUM_COMMAND_MESSAGE_SIZE;
} }
size_t CommandMessage::getMaximumMessageSize() const {
return MessageQueueMessage::MAX_MESSAGE_SIZE;
}
bool CommandMessage::isClearedCommandMessage() { bool CommandMessage::isClearedCommandMessage() {
return getCommand() == CMD_NONE; return getCommand() == CMD_NONE;
} }

View File

@ -24,11 +24,11 @@ class CommandMessage: public CommandMessageBase {
public: public:
/** /**
* This is the size of a message as it is seen by the MessageQueue. * This is the size of a message as it is seen by the MessageQueue.
* It can hold the CommandMessage header plus 2 4-byte parameters.
* 14 of the 24 available MessageQueueMessage bytes are used. * 14 of the 24 available MessageQueueMessage bytes are used.
*/ */
static const size_t MINIMUM_COMMAND_MESSAGE_SIZE = static const size_t MINIMUM_COMMAND_MESSAGE_SIZE =
MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) + CommandMessageIF::HEADER_SIZE + 2 * sizeof(uint32_t);
2 * sizeof(uint32_t);
/** /**
* Default Constructor, does not initialize anything. * Default Constructor, does not initialize anything.
@ -55,8 +55,6 @@ public:
/** MessageQueueMessageIF functions used for minimum size check. */ /** MessageQueueMessageIF functions used for minimum size check. */
size_t getMinimumMessageSize() const override; size_t getMinimumMessageSize() const override;
/** MessageQueueMessageIF functions used for maximum size check. */
size_t getMaximumMessageSize() const override;
/** /**
* Get the first parameter of the message * Get the first parameter of the message

View File

@ -55,10 +55,18 @@ size_t CommandMessageBase::getMessageSize() const {
return internalMessage->getMessageSize(); return internalMessage->getMessageSize();
} }
size_t CommandMessageBase::getMaximumMessageSize() const {
return internalMessage->getMaximumMessageSize();
}
MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const {
return internalMessage; return internalMessage;
} }
size_t CommandMessageBase::getMinimumMessageSize() const {
return MINIMUM_COMMAND_MESSAGE_BASE_SIZE;
}
void CommandMessageBase::setReplyRejected(ReturnValue_t reason, void CommandMessageBase::setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) { Command_t initialCommand) {
std::memcpy(getData(), &reason, sizeof(reason)); std::memcpy(getData(), &reason, sizeof(reason));

View File

@ -15,13 +15,21 @@
* size checks: * size checks:
* *
* 1. getMinimumMessageSize() * 1. getMinimumMessageSize()
* 2. getMaximumMessageSize()
* *
* The maximum message size generally depends on the buffer size of the passed
* internal message.
* Don't forget to set the message size of the passed message in the concrete * Don't forget to set the message size of the passed message in the concrete
* commandmessage implementation! * commandmessage implementation!
*/ */
class CommandMessageBase: public CommandMessageIF { class CommandMessageBase: public CommandMessageIF {
public: public:
//! This minimum size is derived from the interface requirement to be able
//! to set a rejected reply, which contains a returnvalue and the initial
//! command.
static constexpr size_t MINIMUM_COMMAND_MESSAGE_BASE_SIZE =
CommandMessageIF::HEADER_SIZE + sizeof(ReturnValue_t) +
sizeof(Command_t);
CommandMessageBase(MessageQueueMessageIF* message); CommandMessageBase(MessageQueueMessageIF* message);
/** /**
@ -58,6 +66,12 @@ public:
virtual void setMessageSize(size_t messageSize) override; virtual void setMessageSize(size_t messageSize) override;
virtual size_t getMessageSize() const override; virtual size_t getMessageSize() const override;
//! This depends on the maximum message size of the passed internal message.
virtual size_t getMaximumMessageSize() const override;
//! Return the constant minimum message size.
virtual size_t getMinimumMessageSize() const override;
/** /**
* A command message can be rejected and needs to offer a function * A command message can be rejected and needs to offer a function
* to set a rejected reply * to set a rejected reply

View File

@ -10,7 +10,7 @@ public:
internalMutex(mutex) { internalMutex(mutex) {
ReturnValue_t status = mutex->lockMutex(timeoutMs); ReturnValue_t status = mutex->lockMutex(timeoutMs);
if(status == MutexIF::MUTEX_TIMEOUT) { if(status == MutexIF::MUTEX_TIMEOUT) {
sif::error << "MutexHelper: Lock of mutex failed with timeout of" sif::error << "MutexHelper: Lock of mutex failed with timeout of "
<< timeoutMs << " milliseconds!" << std::endl; << timeoutMs << " milliseconds!" << std::endl;
} }
else if(status != HasReturnvaluesIF::RETURN_OK){ else if(status != HasReturnvaluesIF::RETURN_OK){