Merge branch 'mueller_framework' into front_branch

This commit is contained in:
Robin Müller 2020-06-24 01:29:11 +02:00
commit 61370d43da
68 changed files with 726 additions and 828 deletions

View File

@ -33,15 +33,13 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
} }
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
queueToUse->sendMessage(reportTo, &reply); queueToUse->sendMessage(reportTo, &reply);
} }
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ActionMessage::setCompletionReply(&reply, commandId, result); ActionMessage::setCompletionReply(&reply, commandId, result);
queueToUse->sendMessage(reportTo, &reply); queueToUse->sendMessage(reportTo, &reply);
} }
@ -56,8 +54,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
size_t size = 0; size_t size = 0;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ActionMessage::setStepReply(&reply, actionId, 0, result); ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply); queueToUse->sendMessage(commandedBy, &reply);
return; return;
@ -65,8 +62,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
result = owner->executeAction(actionId, commandedBy, dataPtr, size); result = owner->executeAction(actionId, commandedBy, dataPtr, size);
ipcStore->deleteData(dataAddress); ipcStore->deleteData(dataAddress);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ActionMessage::setStepReply(&reply, actionId, 0, result); ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply); queueToUse->sendMessage(commandedBy, &reply);
return; return;
@ -75,8 +71,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
ActionId_t replyId, SerializeIF* data, bool hideSender) { ActionId_t replyId, SerializeIF* data, bool hideSender) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
store_address_t storeAddress; store_address_t storeAddress;
uint8_t *dataPtr; uint8_t *dataPtr;
size_t maxSize = data->getSerializedSize(); size_t maxSize = data->getSerializedSize();

View File

@ -53,8 +53,7 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId,
ActionId_t actionId, store_address_t storeId) { ActionId_t actionId, store_address_t storeId) {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ActionMessage::setCommand(&command, actionId, storeId); ActionMessage::setCommand(&command, actionId, storeId);
ReturnValue_t result = queueToUse->sendMessage(queueId, &command); ReturnValue_t result = queueToUse->sendMessage(queueId, &command);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -1,5 +1,5 @@
#ifndef HASACTIONSIF_H_ #ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_
#define HASACTIONSIF_H_ #define FRAMEWORK_ACTION_HASACTIONSIF_H_
#include <framework/action/ActionHelper.h> #include <framework/action/ActionHelper.h>
#include <framework/action/ActionMessage.h> #include <framework/action/ActionMessage.h>
@ -11,22 +11,26 @@
* Interface for component which uses actions * Interface for component which uses actions
* *
* @details * @details
* This interface is used to execute actions in the component. Actions, in the sense of this interface, are activities with a well-defined beginning and * This interface is used to execute actions in the component. Actions, in the
* end in time. They may adjust sub-states of components, but are not supposed to change * sense of this interface, are activities with a well-defined beginning and
* the main mode of operation, which is handled with the HasModesIF described below. * end in time. They may adjust sub-states of components, but are not supposed
* to change the main mode of operation, which is handled with the HasModesIF
* described below.
* *
* The HasActionsIF allows components to define such actions and make them available * The HasActionsIF allows components to define such actions and make them
* for other components to use. Implementing the interface is straightforward: Theres a * available for other components to use. Implementing the interface is
* single executeAction call, which provides an identifier for the action to execute, as well * straightforward: Theres a single executeAction call, which provides an
* as arbitrary parameters for input. Aside from direct, software-based * identifier for the action to execute, as well as arbitrary parameters for
* actions, it is used in device handler components as an interface to forward commands to * input.
* devices. * Aside from direct, software-based actions, it is used in device handler
* Implementing components of the interface are supposed to check identifier (ID) and * components as an interface to forward commands to devices.
* parameters and immediately start execution of the action. It is, however, not required to * Implementing components of the interface are supposed to check identifier
* immediately finish execution. Instead, this may be deferred to a later point in time, at * (ID) and parameters and immediately start execution of the action.
* which the component needs to inform the caller about finished or failed execution. * It is, however, not required to immediately finish execution.
* Instead, this may be deferred to a later point in time, at which the
* component needs to inform the caller about finished or failed execution.
* *
* \ingroup interfaces * @ingroup interfaces
*/ */
class HasActionsIF { class HasActionsIF {
public: public:
@ -43,13 +47,14 @@ public:
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;
/** /**
* Execute or initialize the execution of a certain function. * Execute or initialize the execution of a certain function.
* Returning #EXECUTION_FINISHED or a failure code, nothing else needs to be done. * Returning #EXECUTION_FINISHED or a failure code, nothing else needs to
* When needing more steps, return RETURN_OK and issue steps and completion manually. * be done. When needing more steps, return RETURN_OK and issue steps and
* completion manually.
* One "step failed" or completion report must be issued! * One "step failed" or completion report must be issued!
*/ */
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, virtual ReturnValue_t executeAction(ActionId_t actionId,
const uint8_t* data, size_t size) = 0; MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
}; };
#endif /* HASACTIONSIF_H_ */ #endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */

View File

@ -36,8 +36,7 @@ void SimpleActionHelper::resetHelper() {
void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
ActionId_t actionId, store_address_t dataAddress) { ActionId_t actionId, store_address_t dataAddress) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
if (isExecuting) { if (isExecuting) {
ipcStore->deleteData(dataAddress); ipcStore->deleteData(dataAddress);
ActionMessage::setStepReply(&reply, actionId, 0, ActionMessage::setStepReply(&reply, actionId, 0,

View File

@ -56,8 +56,7 @@ MessageQueueId_t ControllerBase::getCommandQueue() const {
} }
void ControllerBase::handleQueue() { void ControllerBase::handleQueue() {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result; ReturnValue_t result;
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
result = commandQueue->receiveMessage(&command)) { result = commandQueue->receiveMessage(&command)) {

View File

@ -21,8 +21,7 @@ ReturnValue_t HkSwitchHelper::initialize() {
} }
ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) { ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) { while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) {
ReturnValue_t result = commandActionHelper.handleReply(&command); ReturnValue_t result = commandActionHelper.handleReply(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {

View File

@ -66,8 +66,7 @@ ReturnValue_t DataPoolAdmin::getParameter(uint8_t domainId,
} }
void DataPoolAdmin::handleCommand() { void DataPoolAdmin::handleCommand() {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return; return;
@ -283,8 +282,7 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
return result; return result;
} }
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ParameterMessage::setParameterDumpReply(&reply, id, address); ParameterMessage::setParameterDumpReply(&reply, id, address);
@ -296,8 +294,7 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
//identical to ParameterHelper::rejectCommand() //identical to ParameterHelper::rejectCommand()
void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason,
Command_t initialCommand) { Command_t initialCommand) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
reply.setReplyRejected(reason, initialCommand); reply.setReplyRejected(reason, initialCommand);
commandQueue->sendMessage(to, &reply); commandQueue->sendMessage(to, &reply);
} }

View File

@ -45,8 +45,8 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
} }
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
HousekeepingMessage& message) { CommandMessage* message) {
Command_t command = message.getCommand(); Command_t command = message->getCommand();
switch(command) { switch(command) {
// I think those are the only commands which can be handled here.. // I think those are the only commands which can be handled here..
case(HousekeepingMessage::ADD_HK_REPORT_STRUCT): case(HousekeepingMessage::ADD_HK_REPORT_STRUCT):
@ -55,10 +55,10 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES):
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES):
return generateSetStructurePacket(message.getSid()); //return generateSetStructurePacket(message->getSid());
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT):
return generateHousekeepingPacket(message.getSid()); //return generateHousekeepingPacket(message->getSid());
default: default:
return CommandMessageIF::UNKNOWN_COMMAND; return CommandMessageIF::UNKNOWN_COMMAND;
} }
@ -105,19 +105,18 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) {
} }
// and now we set a HK message and send it the HK packet destination. // and now we set a HK message and send it the HK packet destination.
MessageQueueMessage message; //HousekeepingMessage hkMessage;
HousekeepingMessage hkMessage(&message); // hkMessage.setHkReportMessage(sid, storeId);
hkMessage.setHkReportMessage(sid, storeId); // if(hkQueue == nullptr) {
if(hkQueue == nullptr) { // return QUEUE_NOT_SET;
return QUEUE_NOT_SET; // }
} //
// if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) {
if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { // result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage);
result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); // }
} // else {
else { // result = hkQueue->sendToDefault(&hkMessage);
result = hkQueue->sendToDefault(&hkMessage); // }
}
return result; return result;
} }

View File

@ -58,7 +58,7 @@ public:
ReturnValue_t generateHousekeepingPacket(sid_t sid); ReturnValue_t generateHousekeepingPacket(sid_t sid);
ReturnValue_t generateSetStructurePacket(sid_t sid); ReturnValue_t generateSetStructurePacket(sid_t sid);
ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& message); ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
/** /**
* This function is used to fill the local data pool map with pool * This function is used to fill the local data pool map with pool

View File

@ -148,8 +148,7 @@ void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) {
void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo, void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo,
HealthState health) { HealthState health) {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET, HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET,
health); health);
if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) { if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) {

View File

@ -214,12 +214,7 @@ void DeviceHandlerBase::readCommandQueue() {
return; return;
} }
// This is not ideal. What if it is not a command message? (e.g. another CommandMessage command;
// message with 3 parameters). The full buffer is filled anyway
// and I could just copy the content into the other message but
// all I need are few additional functions the other message type offers.
MessageQueueMessage message;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return; return;
@ -247,8 +242,7 @@ void DeviceHandlerBase::readCommandQueue() {
return; return;
} }
HousekeepingMessage hkMessage(&message); result = hkManager.handleHousekeepingMessage(&command);
result = hkManager.handleHousekeepingMessage(hkMessage);
if (result == RETURN_OK) { if (result == RETURN_OK) {
return; return;
} }
@ -484,13 +478,12 @@ void DeviceHandlerBase::setMode(Mode_t newMode) {
void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status, void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status,
uint32_t parameter) { uint32_t parameter) {
MessageQueueMessage message;
//This is actually the reply protocol for raw and misc DH commands. //This is actually the reply protocol for raw and misc DH commands.
if (status == RETURN_OK) { if (status == RETURN_OK) {
CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, parameter); CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, parameter);
commandQueue->reply(&reply); commandQueue->reply(&reply);
} else { } else {
CommandMessage reply(&message, CommandMessage::REPLY_REJECTED, status, parameter); CommandMessage reply(CommandMessage::REPLY_REJECTED, status, parameter);
commandQueue->reply(&reply); commandQueue->reply(&reply);
} }
} }
@ -760,8 +753,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
return; return;
} }
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command,
getObjectId(), address, isCommand); getObjectId(), address, isCommand);

View File

@ -137,7 +137,7 @@ void DeviceHandlerFailureIsolation::decrementFaultCounters() {
void DeviceHandlerFailureIsolation::handleRecovery(Event reason) { void DeviceHandlerFailureIsolation::handleRecovery(Event reason) {
clearFaultCounters(); clearFaultCounters();
if (!recoveryCounter.incrementAndCheck()) { if (not recoveryCounter.incrementAndCheck()) {
startRecovery(reason); startRecovery(reason);
} else { } else {
setFaulty(reason); setFaulty(reason);

View File

@ -31,6 +31,7 @@ protected:
bool hasPowerConfirmation = false; bool hasPowerConfirmation = false;
MessageQueueId_t powerConfirmation; MessageQueueId_t powerConfirmation;
static object_id_t powerConfirmationId; static object_id_t powerConfirmationId;
// TODO: Are those hardcoded value? How can they be changed.
static const uint32_t MAX_REBOOT = 1; static const uint32_t MAX_REBOOT = 1;
static const uint32_t REBOOT_TIME_MS = 180000; static const uint32_t REBOOT_TIME_MS = 180000;
static const uint32_t MAX_STRANGE_REPLIES = 10; static const uint32_t MAX_STRANGE_REPLIES = 10;

View File

@ -13,8 +13,7 @@ HealthDevice::~HealthDevice() {
} }
ReturnValue_t HealthDevice::performOperation(uint8_t opCode) { ReturnValue_t HealthDevice::performOperation(uint8_t opCode) {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
healthHelper.handleHealthCommand(&command); healthHelper.handleHealthCommand(&command);

View File

@ -52,7 +52,7 @@ void EventManager::notifyListeners(EventMessage* message) {
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) { for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
if (iter->second.match(message)) { if (iter->second.match(message)) {
MessageQueueSenderIF::sendMessage(iter->first, message, MessageQueueSenderIF::sendMessage(iter->first, message,
message->getSender()); message->getSender());
} }
} }
unlockMutex(); unlockMutex();

View File

@ -4,6 +4,7 @@
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/ipc/MessageQueueSenderIF.h> #include <framework/ipc/MessageQueueSenderIF.h>
// TODO: Documentation.
class ConfirmsFailuresIF { class ConfirmsFailuresIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::HANDLES_FAILURES_IF; static const uint8_t INTERFACE_ID = CLASS_ID::HANDLES_FAILURES_IF;

View File

@ -9,7 +9,8 @@ FailureIsolationBase::FailureIsolationBase(object_id_t owner,
object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) : object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) :
eventQueue(NULL), ownerId(owner), owner(NULL), eventQueue(NULL), ownerId(owner), owner(NULL),
faultTreeParent(parent), parameterDomainBase(parameterDomainBase) { faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE); eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
EventMessage::EVENT_MESSAGE_SIZE);
} }
FailureIsolationBase::~FailureIsolationBase() { FailureIsolationBase::~FailureIsolationBase() {

View File

@ -65,12 +65,11 @@ void HealthHelper::informParent(HasHealthIF::HealthState health,
if (parentQueue == MessageQueueMessageIF::NO_QUEUE) { if (parentQueue == MessageQueueMessageIF::NO_QUEUE) {
return; return;
} }
MessageQueueMessage message; CommandMessage information;
CommandMessage information(&message);
HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO,
health, oldHealth); health, oldHealth);
if (MessageQueueSenderIF::sendMessage(parentQueue, &information, if (MessageQueueSenderIF::sendMessage(parentQueue, &information,
owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) {
sif::debug << "HealthHelper::informParent: sending health reply failed." sif::debug << "HealthHelper::informParent: sending health reply failed."
<< std::endl; << std::endl;
} }
@ -81,8 +80,7 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) {
if (command->getSender() == MessageQueueMessageIF::NO_QUEUE) { if (command->getSender() == MessageQueueMessageIF::NO_QUEUE) {
return; return;
} }
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
HealthMessage::setHealthMessage(&reply, HealthMessage::setHealthMessage(&reply,
HealthMessage::REPLY_HEALTH_SET); HealthMessage::REPLY_HEALTH_SET);
@ -90,7 +88,7 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) {
reply.setReplyRejected(result, command->getCommand()); reply.setReplyRejected(result, command->getCommand());
} }
if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply, if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply,
owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) {
sif::debug << "HealthHelper::handleHealthCommand: sending health " sif::debug << "HealthHelper::handleHealthCommand: sending health "
"reply failed." << std::endl; "reply failed." << std::endl;

View File

@ -1,5 +1,5 @@
#ifndef HEALTHTABLE_H_ #ifndef FRAMEWORK_HEALTH_HEALTHTABLE_H_
#define HEALTHTABLE_H_ #define FRAMEWORK_HEALTH_HEALTHTABLE_H_
#include <framework/health/HealthTableIF.h> #include <framework/health/HealthTableIF.h>
#include <framework/objectmanager/SystemObject.h> #include <framework/objectmanager/SystemObject.h>

View File

@ -1,5 +1,5 @@
#ifndef HEALTHTABLEIF_H_ #ifndef FRAMEWORK_HEALTH_HEALTHTABLEIF_H_
#define HEALTHTABLEIF_H_ #define FRAMEWORK_HEALTH_HEALTHTABLEIF_H_
#include <framework/health/ManagesHealthIF.h> #include <framework/health/ManagesHealthIF.h>
#include <framework/objectmanager/ObjectManagerIF.h> #include <framework/objectmanager/ObjectManagerIF.h>
@ -8,6 +8,8 @@
class HealthTableIF: public ManagesHealthIF { class HealthTableIF: public ManagesHealthIF {
// TODO: This is in the mission folder and not in the framework folder.
// delete it?
friend class HealthCommandingService; friend class HealthCommandingService;
public: public:
virtual ~HealthTableIF() { virtual ~HealthTableIF() {
@ -23,4 +25,4 @@ protected:
virtual ReturnValue_t iterate(std::pair<object_id_t,HasHealthIF::HealthState> *value, bool reset = false) = 0; virtual ReturnValue_t iterate(std::pair<object_id_t,HasHealthIF::HealthState> *value, bool reset = false) = 0;
}; };
#endif /* HEALTHTABLEIF_H_ */ #endif /* FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ */

View File

@ -1,15 +1,7 @@
#include <framework/housekeeping/HousekeepingMessage.h> #include <framework/housekeeping/HousekeepingMessage.h>
#include <cstring> #include <cstring>
HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): HousekeepingMessage::HousekeepingMessage(): CommandMessage() {
CommandMessageBase(message) {
if(message->getMaximumMessageSize() < HK_MESSAGE_SIZE) {
sif::error << "HousekeepingMessage::HousekeepingMessage: Passed "
"message buffer can not hold minimum " << HK_MESSAGE_SIZE
<< " bytes!" << std::endl;
return;
}
message->setMessageSize(HK_MESSAGE_SIZE);
} }
HousekeepingMessage::~HousekeepingMessage() {} HousekeepingMessage::~HousekeepingMessage() {}
@ -26,25 +18,25 @@ uint32_t HousekeepingMessage::getParameter() const {
void HousekeepingMessage::setHkReportMessage(sid_t sid, void HousekeepingMessage::setHkReportMessage(sid_t sid,
store_address_t storeId) { store_address_t storeId) {
CommandMessageBase::setCommand(HK_REPORT); CommandMessage::setCommand(HK_REPORT);
setSid(sid); setSid(sid);
setParameter(storeId.raw); setParameter(storeId.raw);
} }
void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid,
store_address_t storeId) { store_address_t storeId) {
CommandMessageBase::setCommand(DIAGNOSTICS_REPORT); CommandMessage::setCommand(DIAGNOSTICS_REPORT);
setSid(sid); setSid(sid);
setParameter(storeId.raw); setParameter(storeId.raw);
} }
size_t HousekeepingMessage::getMinimumMessageSize() const { //size_t HousekeepingMessage::getMinimumMessageSize() const {
return HK_MESSAGE_SIZE; // return HK_MESSAGE_SIZE;
} //}
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, CommandMessage::getData(), sizeof(sid.raw));
return sid; return sid;
} }
@ -58,16 +50,16 @@ sid_t HousekeepingMessage::getHkReportMessage(
} }
void HousekeepingMessage::setSid(sid_t sid) { void HousekeepingMessage::setSid(sid_t sid) {
std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); std::memcpy(CommandMessage::getData(), &sid.raw, sizeof(sid.raw));
} }
uint8_t* HousekeepingMessage::getData() { uint8_t* HousekeepingMessage::getData() {
return CommandMessageBase::getData() + sizeof(sid_t); return CommandMessage::getData() + sizeof(sid_t);
} }
const uint8_t* HousekeepingMessage::getData() const { const uint8_t* HousekeepingMessage::getData() const {
return CommandMessageBase::getData() + sizeof(sid_t); return CommandMessage::getData() + sizeof(sid_t);
} }
void HousekeepingMessage::clear() { void HousekeepingMessage::clear() {

View File

@ -1,6 +1,7 @@
#ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_
#define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_
#include <framework/ipc/CommandMessageBase.h>
#include <framework/ipc/CommandMessage.h>
#include <framework/ipc/FwMessageTypes.h> #include <framework/ipc/FwMessageTypes.h>
#include <framework/objectmanager/SystemObjectIF.h> #include <framework/objectmanager/SystemObjectIF.h>
#include <framework/storagemanager/StorageManagerIF.h> #include <framework/storagemanager/StorageManagerIF.h>
@ -33,7 +34,7 @@ union sid_t {
* This message is slightly larger than regular command messages to accomodate * This message is slightly larger than regular command messages to accomodate
* the uint64_t structure ID (SID). * the uint64_t structure ID (SID).
*/ */
class HousekeepingMessage : public CommandMessageBase { class HousekeepingMessage : public CommandMessage {
public: public:
static constexpr size_t HK_MESSAGE_SIZE = CommandMessageIF::HEADER_SIZE + static constexpr size_t HK_MESSAGE_SIZE = CommandMessageIF::HEADER_SIZE +
@ -44,7 +45,7 @@ public:
* the message data, see CommandMessageIF and getInternalMessage(). * the message data, see CommandMessageIF and getInternalMessage().
* @param message * @param message
*/ */
HousekeepingMessage(MessageQueueMessageIF* message); HousekeepingMessage();
virtual ~HousekeepingMessage(); virtual ~HousekeepingMessage();
static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING;
@ -104,7 +105,7 @@ public:
//! to distinguish between diagnostics and regular HK packets //! to distinguish between diagnostics and regular HK packets
sid_t getHkReportMessage(store_address_t * storeIdToSet) const; sid_t getHkReportMessage(store_address_t * storeIdToSet) const;
virtual size_t getMinimumMessageSize() const override; //virtual size_t getMinimumMessageSize() const override;
virtual void clear() override; virtual void clear() override;
private: private:

View File

@ -1,64 +1,97 @@
#include <framework/ipc/CommandMessage.h> #include <framework/ipc/CommandMessage.h>
#include <framework/ipc/CommandMessageCleaner.h>
#include <cstring> #include <cstring>
CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): CommandMessage::CommandMessage() {
CommandMessageBase(receiverMessage) { MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE);
if(receiverMessage == nullptr) { setCommand(CMD_NONE);
sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr"
" as the message queue message, pass the address of an actual"
" message!" << std::endl;
return;
}
if(receiverMessage->getMaximumMessageSize() <
getMinimumMessageSize()) {
sif::error << "CommandMessage::ComandMessage: Passed message buffer"
" can not hold minimum "<< getMinimumMessageSize()
<< " bytes!" << std::endl;
return;
}
internalMessage->setMessageSize(getMinimumMessageSize());
} }
CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, CommandMessage::CommandMessage(Command_t command, uint32_t parameter1,
Command_t command, uint32_t parameter1, uint32_t parameter2): uint32_t parameter2) {
CommandMessage(messageToSet) { MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE);
setCommand(command); setCommand(command);
setParameter(parameter1); setParameter(parameter1);
setParameter2(parameter2); setParameter2(parameter2);
}
Command_t CommandMessage::getCommand() const {
Command_t command;
std::memcpy(&command, MessageQueueMessage::getData(), sizeof(Command_t));
return command;
}
void CommandMessage::setCommand(Command_t command) {
std::memcpy(MessageQueueMessage::getData(), &command, sizeof(Command_t));
}
uint8_t CommandMessage::getMessageType() const {
// first byte of command ID.
return getCommand() >> 8 & 0xff;
} }
uint32_t CommandMessage::getParameter() const { uint32_t CommandMessage::getParameter() const {
uint32_t parameter1; uint32_t parameter1;
std::memcpy(&parameter1, CommandMessageBase::getData(), sizeof(parameter1)); std::memcpy(&parameter1, this->getData(), sizeof(parameter1));
return parameter1; return parameter1;
} }
void CommandMessage::setParameter(uint32_t parameter1) { void CommandMessage::setParameter(uint32_t parameter1) {
std::memcpy(CommandMessageBase::getData(), &parameter1, sizeof(parameter1)); std::memcpy(this->getData(), &parameter1, sizeof(parameter1));
} }
uint32_t CommandMessage::getParameter2() const { uint32_t CommandMessage::getParameter2() const {
uint32_t parameter2; uint32_t parameter2;
std::memcpy(&parameter2, CommandMessageBase::getData() + sizeof(uint32_t), std::memcpy(&parameter2, this->getData() + sizeof(uint32_t),
sizeof(parameter2)); sizeof(parameter2));
return parameter2; return parameter2;
} }
void CommandMessage::setParameter2(uint32_t parameter2) { void CommandMessage::setParameter2(uint32_t parameter2) {
std::memcpy(CommandMessageBase::getData() + sizeof(uint32_t), &parameter2, std::memcpy(this->getData() + sizeof(uint32_t), &parameter2,
sizeof(parameter2)); sizeof(parameter2));
} }
size_t CommandMessage::getMinimumMessageSize() const { size_t CommandMessage::getMinimumMessageSize() const {
return MINIMUM_COMMAND_MESSAGE_SIZE; return MINIMUM_COMMAND_MESSAGE_SIZE;
}
void CommandMessage::clear() {
CommandMessageCleaner::clearCommandMessage(this);
} }
bool CommandMessage::isClearedCommandMessage() { bool CommandMessage::isClearedCommandMessage() {
return getCommand() == CMD_NONE; return getCommand() == CMD_NONE;
} }
void CommandMessage::setToUnknownCommand() { void CommandMessage::setToUnknownCommand() {
Command_t initialCommand = getCommand(); Command_t initialCommand = getCommand();
this->clear(); this->clear();
setReplyRejected(UNKNOWN_COMMAND, initialCommand); setReplyRejected(UNKNOWN_COMMAND, initialCommand);
}
void CommandMessage::setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) {
std::memcpy(getData(), &reason, sizeof(reason));
std::memcpy(getData() + sizeof(reason), &initialCommand,
sizeof(initialCommand));
}
ReturnValue_t CommandMessage::getReplyRejectedReason(
Command_t *initialCommand) const {
ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED;
std::memcpy(&reason, getData(), sizeof(reason));
if(initialCommand != nullptr) {
std::memcpy(initialCommand, getData() + sizeof(reason),
sizeof(Command_t));
}
return reason;
}
uint8_t* CommandMessage::getData() {
return MessageQueueMessage::getData() + sizeof(Command_t);
}
const uint8_t* CommandMessage::getData() const {
return MessageQueueMessage::getData() + sizeof(Command_t);
} }

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ #ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_
#define FRAMEWORK_IPC_COMMANDMESSAGE_H_ #define FRAMEWORK_IPC_COMMANDMESSAGE_H_
#include <framework/ipc/CommandMessageBase.h> #include <framework/ipc/CommandMessageIF.h>
#include <framework/ipc/MessageQueueMessage.h> #include <framework/ipc/MessageQueueMessage.h>
#include <framework/ipc/FwMessageTypes.h> #include <framework/ipc/FwMessageTypes.h>
@ -20,23 +20,21 @@
* currently has an internal message size of 28 bytes. * currently has an internal message size of 28 bytes.
* @author Bastian Baetz * @author Bastian Baetz
*/ */
class CommandMessage: public CommandMessageBase { class CommandMessage: public MessageQueueMessage, public CommandMessageIF {
public: public:
/** /**
* This is the size of a message as it is seen by the MessageQueue. * Default size can accomodate 2 4-byte parameters.
* It can hold the CommandMessage header plus 2 4-byte parameters. */
* 14 of the 24 available MessageQueueMessage bytes are used. static constexpr size_t DEFAULT_COMMAND_MESSAGE_SIZE =
*/ CommandMessageIF::MINIMUM_COMMAND_MESSAGE_SIZE + sizeof(uint32_t);
static const size_t MINIMUM_COMMAND_MESSAGE_SIZE =
CommandMessageIF::HEADER_SIZE + 2 * sizeof(uint32_t);
/** /**
* Default Constructor, does not initialize anything. * @brief Default Constructor, does not initialize anything.
* * @details
* This constructor should be used when receiving a Message, as the * This constructor should be used when receiving a Message, as the
* content is filled by the MessageQueue. * content is filled by the MessageQueue.
*/ */
CommandMessage(MessageQueueMessageIF* receiverMessage); CommandMessage();
/** /**
* This constructor creates a new message with all message content * This constructor creates a new message with all message content
* initialized * initialized
@ -45,17 +43,29 @@ public:
* @param parameter1 The first parameter * @param parameter1 The first parameter
* @param parameter2 The second parameter * @param parameter2 The second parameter
*/ */
CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, CommandMessage(Command_t command, uint32_t parameter1, uint32_t parameter2);
uint32_t parameter1, uint32_t parameter2);
/** /**
* @brief Default Destructor * @brief Default Destructor
*/ */
virtual ~CommandMessage() {} virtual ~CommandMessage() {}
/** MessageQueueMessageIF functions used for minimum size check. */ /**
size_t getMinimumMessageSize() const override; * Read the DeviceHandlerCommand_t that is stored in the message,
* usually used after receiving.
*
* @return the Command stored in the Message
*/
virtual Command_t getCommand() const override;
/**
* Set the command type of the message. Default implementation also
* sets the message type, which will be the first byte of the command ID.
* @param the Command to be sent
*/
virtual void setCommand(Command_t command);
virtual uint8_t* getData() override;
virtual const uint8_t* getData() const override;
/** /**
* Get the first parameter of the message * Get the first parameter of the message
* @return the first Parameter of the message * @return the first Parameter of the message
@ -91,8 +101,35 @@ public:
* Sets the command to REPLY_REJECTED with parameter UNKNOWN_COMMAND. * Sets the command to REPLY_REJECTED with parameter UNKNOWN_COMMAND.
* Is needed quite often, so we better code it once only. * Is needed quite often, so we better code it once only.
*/ */
void setToUnknownCommand(); void setToUnknownCommand() override;
/**
* A command message can be rejected and needs to offer a function
* to set a rejected reply
* @param reason
* @param initialCommand
*/
void setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) override;
/**
* Corrensonding getter function.
* @param initialCommand
* @return
*/
ReturnValue_t getReplyRejectedReason(
Command_t* initialCommand = nullptr) const override;
virtual void clear() override;
/**
* Extract message ID, which is the first byte of the command ID for the
* default implementation.
* @return
*/
virtual uint8_t getMessageType() const override;
/** MessageQueueMessageIF functions used for minimum size check. */
size_t getMinimumMessageSize() const override;
}; };
#endif /* COMMANDMESSAGE_H_ */ #endif /* COMMANDMESSAGE_H_ */

View File

@ -1,90 +0,0 @@
#include <framework/ipc/CommandMessageBase.h>
#include <framework/ipc/CommandMessageCleaner.h>
#include <cstring>
CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message):
internalMessage(message) {
}
Command_t CommandMessageBase::getCommand() const {
Command_t command;
std::memcpy(&command, internalMessage->getData(), sizeof(Command_t));
return command;
}
void CommandMessageBase::setCommand(Command_t command) {
std::memcpy(internalMessage->getData(), &command, sizeof(Command_t));
}
uint8_t CommandMessageBase::getMessageType() const {
// first byte of command ID.
return getCommand() >> 8 & 0xff;
}
MessageQueueId_t CommandMessageBase::getSender() const {
return internalMessage->getSender();
}
uint8_t* CommandMessageBase::getBuffer() {
return internalMessage->getBuffer();
}
void CommandMessageBase::setSender(MessageQueueId_t setId) {
internalMessage->setSender(setId);
}
const uint8_t* CommandMessageBase::getBuffer() const {
return internalMessage->getBuffer();
}
// Header includes command ID.
uint8_t* CommandMessageBase::getData() {
return internalMessage->getData() + sizeof(Command_t);
}
// Header includes command ID.
const uint8_t* CommandMessageBase::getData() const {
return internalMessage->getData() + sizeof(Command_t);
}
void CommandMessageBase::setMessageSize(size_t messageSize) {
internalMessage->setMessageSize(messageSize);
}
size_t CommandMessageBase::getMessageSize() const {
return internalMessage->getMessageSize();
}
size_t CommandMessageBase::getMaximumMessageSize() const {
return internalMessage->getMaximumMessageSize();
}
MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const {
return internalMessage;
}
size_t CommandMessageBase::getMinimumMessageSize() const {
return MINIMUM_COMMAND_MESSAGE_BASE_SIZE;
}
void CommandMessageBase::setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) {
std::memcpy(getData(), &reason, sizeof(reason));
std::memcpy(getData() + sizeof(reason), &initialCommand,
sizeof(initialCommand));
}
ReturnValue_t CommandMessageBase::getReplyRejectedReason(
Command_t *initialCommand) const {
ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED;
std::memcpy(&reason, getData(), sizeof(reason));
if(initialCommand != nullptr) {
std::memcpy(initialCommand, getData() + sizeof(reason),
sizeof(Command_t));
}
return reason;
}
void CommandMessageBase::clear() {
CommandMessageCleaner::clearCommandMessage(this);
}

View File

@ -1,106 +0,0 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_
#define FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_
#include <framework/ipc/CommandMessageIF.h>
#include <framework/ipc/MessageQueueMessage.h>
/**
* @brief Base implementation of a generic command message, which has
* a Command_t ID and message type ID in the header in addition
* to the sender message queue ID.
* @details
* This is the base implementation serves as a base for other command messages
* and which implements most functions required for MessageQueueMessageIF.
* The only functions which have to be supplied by a specific command message
* impelementations are the size related functions which are used for
* size checks:
*
* 1. getMinimumMessageSize()
*
* 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
* commandmessage implementation!
*/
class CommandMessageBase: public CommandMessageIF {
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);
/**
* Read the DeviceHandlerCommand_t that is stored in the message,
* usually used after receiving.
*
* @return the Command stored in the Message
*/
virtual Command_t getCommand() const override;
/**
* Set the command type of the message. Default implementation also
* sets the message type, which will be the first byte of the command ID.
* @param the Command to be sent
*/
virtual void setCommand(Command_t command);
/**
* Extract message ID, which is the first byte of the command ID for the
* default implementation.
* @return
*/
virtual uint8_t getMessageType() const override;
/*
* MessageQueueMessageIF functions, which generally just call the
* respective functions of the internal message queue message.
*/
virtual uint8_t * getBuffer() override;
virtual const uint8_t * getBuffer() const override;
virtual void setSender(MessageQueueId_t setId) override;
virtual MessageQueueId_t getSender() const override;
virtual uint8_t * getData() override;
virtual const uint8_t* getData() const override;
virtual void setMessageSize(size_t messageSize) 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
* to set a rejected reply
* @param reason
* @param initialCommand
*/
void setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) override;
/**
* Corrensonding getter function.
* @param initialCommand
* @return
*/
ReturnValue_t getReplyRejectedReason(
Command_t* initialCommand = nullptr) const override;
virtual MessageQueueMessageIF* getInternalMessage() const override;
virtual void clear() override;
protected:
/**
* @brief Pointer to the message containing the data.
* @details
* The command message does not actually own the memory containing a
* message, it just oprates on it via a pointer to a message queue message.
*/
MessageQueueMessageIF* internalMessage = nullptr;
};
#endif /* FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ */

View File

@ -9,34 +9,34 @@
#include <framework/tmstorage/TmStoreMessage.h> #include <framework/tmstorage/TmStoreMessage.h>
#include <framework/parameters/ParameterMessage.h> #include <framework/parameters/ParameterMessage.h>
void CommandMessageCleaner::clearCommandMessage(CommandMessageIF* message) { void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) {
switch(message->getMessageType()){ switch(message->getMessageType()){
case messagetypes::MODE_COMMAND: case messagetypes::MODE_COMMAND:
ModeMessage::clear(dynamic_cast<CommandMessage*>(message)); ModeMessage::clear(message);
break; break;
case messagetypes::HEALTH_COMMAND: case messagetypes::HEALTH_COMMAND:
HealthMessage::clear(dynamic_cast<CommandMessage*>(message)); HealthMessage::clear(message);
break; break;
case messagetypes::MODE_SEQUENCE: case messagetypes::MODE_SEQUENCE:
ModeSequenceMessage::clear(dynamic_cast<CommandMessage*>(message)); ModeSequenceMessage::clear(message);
break; break;
case messagetypes::ACTION: case messagetypes::ACTION:
ActionMessage::clear(dynamic_cast<CommandMessage*>(message)); ActionMessage::clear(message);
break; break;
case messagetypes::DEVICE_HANDLER_COMMAND: case messagetypes::DEVICE_HANDLER_COMMAND:
DeviceHandlerMessage::clear(dynamic_cast<CommandMessage*>(message)); DeviceHandlerMessage::clear(message);
break; break;
case messagetypes::MEMORY: case messagetypes::MEMORY:
MemoryMessage::clear(dynamic_cast<CommandMessage*>(message)); MemoryMessage::clear(message);
break; break;
case messagetypes::MONITORING: case messagetypes::MONITORING:
MonitoringMessage::clear(dynamic_cast<CommandMessage*>(message)); MonitoringMessage::clear(message);
break; break;
case messagetypes::TM_STORE: case messagetypes::TM_STORE:
TmStoreMessage::clear(dynamic_cast<CommandMessage*>(message)); TmStoreMessage::clear(message);
break; break;
case messagetypes::PARAMETER: case messagetypes::PARAMETER:
ParameterMessage::clear(dynamic_cast<CommandMessage*>(message)); ParameterMessage::clear(message);
break; break;
default: default:
messagetypes::clearMissionMessage(message); messagetypes::clearMissionMessage(message);

View File

@ -1,15 +1,15 @@
#ifndef FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ #ifndef FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_
#define FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ #define FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_
#include <framework/ipc/CommandMessageIF.h> #include <framework/ipc/CommandMessage.h>
namespace messagetypes { namespace messagetypes {
// Implemented in config. // Implemented in config.
void clearMissionMessage(CommandMessageIF* message); void clearMissionMessage(CommandMessage* message);
} }
class CommandMessageCleaner { class CommandMessageCleaner {
public: public:
static void clearCommandMessage(CommandMessageIF* message); static void clearCommandMessage(CommandMessage* message);
}; };

View File

@ -5,20 +5,24 @@
#include <framework/ipc/FwMessageTypes.h> #include <framework/ipc/FwMessageTypes.h>
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number))
typedef uint16_t Command_t; typedef uint16_t Command_t;
// TODO: actually, this interface propably does not have to implement class CommandMessageIF {
// MQM IF, because there is a getter function for the internal message..
// But it is also convenient to have the full access to all MQM IF functions.
// That way, I can just pass CommandMessages to functions expecting a MQM IF.
// The command message implementations just forwards the calls. Maybe
// we should just leave it like that.
class CommandMessageIF: public MessageQueueMessageIF {
public: public:
static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) + /**
* Header consists of sender ID and command ID.
*/
static constexpr size_t HEADER_SIZE = MessageQueueMessageIF::HEADER_SIZE +
sizeof(Command_t); sizeof(Command_t);
/**
* 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_SIZE =
CommandMessageIF::HEADER_SIZE + sizeof(ReturnValue_t) +
sizeof(Command_t);
static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE;
static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01);
@ -60,15 +64,9 @@ public:
virtual ReturnValue_t getReplyRejectedReason( virtual ReturnValue_t getReplyRejectedReason(
Command_t* initialCommand = nullptr) const = 0; Command_t* initialCommand = nullptr) const = 0;
/** virtual void setToUnknownCommand() = 0;
* This function is used to get a pointer to the internal message, as
* the command message implementations always operate on the memory virtual void clear() = 0;
* contained in the message queue message implementation.
* This pointer can be used to set the internal message of different
* command message implementations.
* @return
*/
virtual MessageQueueMessageIF* getInternalMessage() const = 0;
}; };

View File

@ -1,10 +1,10 @@
#include <framework/ipc/MessageQueueMessage.h> #include <framework/ipc/MessageQueueMessage.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/globalfunctions/arrayprinter.h>
#include <string.h> #include <cstring>
MessageQueueMessage::MessageQueueMessage() : MessageQueueMessage::MessageQueueMessage() :
messageSize(this->HEADER_SIZE) { messageSize(getMinimumMessageSize()) {
memset(this->internalBuffer, 0, sizeof(this->internalBuffer)); memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
} }
@ -51,17 +51,15 @@ void MessageQueueMessage::setSender(MessageQueueId_t setId) {
memcpy(this->internalBuffer, &setId, sizeof(MessageQueueId_t)); memcpy(this->internalBuffer, &setId, sizeof(MessageQueueId_t));
} }
size_t MessageQueueMessage::getMinimumMessageSize() const { void MessageQueueMessage::print(bool printWholeMessage) {
return this->HEADER_SIZE; sif::debug << "MessageQueueMessage content: " << std::endl;
} if(printWholeMessage) {
arrayprinter::print(getData(), getMaximumMessageSize());
void MessageQueueMessage::print() {
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] << ":";
} }
sif::debug << std::dec << std::endl; else {
arrayprinter::print(getData(), getMessageSize());
}
} }
void MessageQueueMessage::clear() { void MessageQueueMessage::clear() {
@ -72,10 +70,15 @@ size_t MessageQueueMessage::getMessageSize() const {
return this->messageSize; return this->messageSize;
} }
size_t MessageQueueMessage::getMaximumMessageSize() const {
return this->MAX_MESSAGE_SIZE;
}
void MessageQueueMessage::setMessageSize(size_t messageSize) { void MessageQueueMessage::setMessageSize(size_t messageSize) {
this->messageSize = messageSize; this->messageSize = messageSize;
} }
size_t MessageQueueMessage::getMinimumMessageSize() const {
return this->MIN_MESSAGE_SIZE;
}
size_t MessageQueueMessage::getMaximumMessageSize() const {
return this->MAX_MESSAGE_SIZE;
}

View File

@ -74,11 +74,7 @@ public:
* as small as possible. * as small as possible.
*/ */
static const size_t MAX_DATA_SIZE = 24; static const size_t MAX_DATA_SIZE = 24;
/**
* @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 * @brief This constant defines the maximum total size in bytes
* of a sent message. * of a sent message.
@ -139,26 +135,16 @@ public:
* The message queue id that identifies the sending message queue. * The message queue id that identifies the sending message queue.
*/ */
void setSender(MessageQueueId_t setId) override; void setSender(MessageQueueId_t setId) override;
/**
* @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.
* @return The default implementation returns HEADER_SIZE.
*/
virtual size_t getMinimumMessageSize() const override;
virtual size_t getMessageSize() const override; virtual size_t getMessageSize() const override;
virtual void setMessageSize(size_t messageSize) override; virtual void setMessageSize(size_t messageSize) override;
virtual size_t getMinimumMessageSize() const override;
virtual size_t getMaximumMessageSize() const override; virtual size_t getMaximumMessageSize() const override;
/** /**
* @brief This is a debug method that prints the content * @brief This is a debug method that prints the content.
* (till messageSize) to the debug output.
*/ */
void print(); void print(bool printWholeMessage);
}; };
#endif /* MESSAGEQUEUEMESSAGE_H_ */ #endif /* MESSAGEQUEUEMESSAGE_H_ */

View File

@ -18,7 +18,12 @@ typedef uint32_t MessageQueueId_t;
class MessageQueueMessageIF { class MessageQueueMessageIF {
public: public:
static const MessageQueueId_t NO_QUEUE = 0xffffffff; static const MessageQueueId_t NO_QUEUE = -1;
/**
* @brief This constants defines the size of the header,
* which is added to every message.
*/
static const size_t HEADER_SIZE = sizeof(MessageQueueId_t);
virtual ~MessageQueueMessageIF() {}; virtual ~MessageQueueMessageIF() {};
@ -68,23 +73,15 @@ public:
virtual uint8_t* getData() = 0; virtual uint8_t* getData() = 0;
/** /**
* @brief This helper function is used by the MessageQueue class to * Get constant message size of current message implementation.
* check the size of an incoming message.
*/
virtual size_t getMinimumMessageSize() const = 0;
/**
* Get message size of current message implementation.
* @return * @return
*/ */
virtual size_t getMessageSize() const = 0; virtual size_t getMessageSize() const = 0;
virtual void setMessageSize(size_t messageSize) = 0;
/** virtual void setMessageSize(size_t messageSize) = 0;
* Get maximum allowed size of current message implementation. virtual size_t getMinimumMessageSize() const = 0;
* @return virtual size_t getMaximumMessageSize() const = 0;
*/
virtual size_t getMaximumMessageSize() const = 0;
}; };

View File

@ -10,18 +10,16 @@ public:
virtual ~MessageQueueSenderIF() {} virtual ~MessageQueueSenderIF() {}
/** /**
* Allows sending messages without actually "owing" a message queue. * Allows sending messages without actually "owning" a message queue.
* Not sure whether this is actually a good idea. * Not sure whether this is actually a good idea.
* Must be implemented by a subclass.
*/ */
static ReturnValue_t sendMessage(MessageQueueId_t sendTo, static ReturnValue_t sendMessage(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueMessageIF* message,
MessageQueueId_t sentFrom = MessageQueueMessageIF::NO_QUEUE, MessageQueueId_t sentFrom = MessageQueueMessageIF::NO_QUEUE,
bool ignoreFault=false); bool ignoreFault = false);
private: private:
MessageQueueSenderIF() {} MessageQueueSenderIF() {}
}; };
#endif /* FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ */ #endif /* FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ */

View File

@ -51,16 +51,14 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode,
break; break;
default: default:
ipcStore->deleteData(ipcAddress); ipcStore->deleteData(ipcAddress);
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
MemoryMessage::setMemoryReplyFailed(&reply, errorCode, MemoryMessage::setMemoryReplyFailed(&reply, errorCode,
MemoryMessage::CMD_MEMORY_LOAD); MemoryMessage::CMD_MEMORY_LOAD);
queueToUse->sendMessage(lastSender, &reply); queueToUse->sendMessage(lastSender, &reply);
return; return;
} }
//Only reached on success //Only reached on success
MessageQueueMessage message; CommandMessage reply( CommandMessage::REPLY_COMMAND_OK, 0, 0);
CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, 0);
queueToUse->sendMessage(lastSender, &reply); queueToUse->sendMessage(lastSender, &reply);
ipcStore->deleteData(ipcAddress); ipcStore->deleteData(ipcAddress);
} }
@ -68,8 +66,7 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode,
void MemoryHelper::completeDump(ReturnValue_t errorCode, void MemoryHelper::completeDump(ReturnValue_t errorCode,
const uint8_t* dataToCopy, const uint32_t size) { const uint8_t* dataToCopy, const uint32_t size) {
busy = false; busy = false;
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
MemoryMessage::setMemoryReplyFailed(&reply, errorCode, lastCommand); MemoryMessage::setMemoryReplyFailed(&reply, errorCode, lastCommand);
switch (errorCode) { switch (errorCode) {
case HasMemoryIF::DO_IT_MYSELF: case HasMemoryIF::DO_IT_MYSELF:
@ -154,8 +151,7 @@ void MemoryHelper::handleMemoryLoad(CommandMessage* message) {
completeLoad(returnCode, p_data, size, dataPointer); completeLoad(returnCode, p_data, size, dataPointer);
} else { } else {
//At least inform sender. //At least inform sender.
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
MemoryMessage::setMemoryReplyFailed(&reply, returnCode, MemoryMessage::setMemoryReplyFailed(&reply, returnCode,
MemoryMessage::CMD_MEMORY_LOAD); MemoryMessage::CMD_MEMORY_LOAD);
queueToUse->sendMessage(lastSender, &reply); queueToUse->sendMessage(lastSender, &reply);
@ -173,8 +169,7 @@ void MemoryHelper::handleMemoryCheckOrDump(CommandMessage* message) {
reservedSpaceInIPC); reservedSpaceInIPC);
completeDump(returnCode, dataPointer, size); completeDump(returnCode, dataPointer, size);
} else { } else {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
MemoryMessage::setMemoryReplyFailed(&reply, returnCode, lastCommand); MemoryMessage::setMemoryReplyFailed(&reply, returnCode, lastCommand);
queueToUse->sendMessage(lastSender, &reply); queueToUse->sendMessage(lastSender, &reply);
} }

View File

@ -12,8 +12,7 @@ ModeHelper::~ModeHelper() {
} }
ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
Mode_t mode; Mode_t mode;
Submode_t submode; Submode_t submode;
switch (command->getCommand()) { switch (command->getCommand()) {
@ -28,7 +27,7 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) {
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
ModeMessage::cantReachMode(&reply, result); ModeMessage::cantReachMode(&reply, result);
MessageQueueSenderIF::sendMessage(command->getSender(), &reply, MessageQueueSenderIF::sendMessage(command->getSender(), &reply,
owner->getCommandQueue()); owner->getCommandQueue());
break; break;
} }
//Free to start transition //Free to start transition
@ -50,7 +49,7 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, mode, ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, mode,
submode); submode);
MessageQueueSenderIF::sendMessage(command->getSender(), &reply, MessageQueueSenderIF::sendMessage(command->getSender(), &reply,
owner->getCommandQueue()); owner->getCommandQueue());
} }
break; break;
case ModeMessage::CMD_MODE_ANNOUNCE: case ModeMessage::CMD_MODE_ANNOUNCE:
@ -79,8 +78,7 @@ void ModeHelper::modeChanged(Mode_t ownerMode, Submode_t ownerSubmode) {
void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, void ModeHelper::sendModeReplyMessage(Mode_t ownerMode,
Submode_t ownerSubmode) { Submode_t ownerSubmode) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
if (theOneWhoCommandedAMode != MessageQueueMessageIF::NO_QUEUE) if (theOneWhoCommandedAMode != MessageQueueMessageIF::NO_QUEUE)
{ {
if (ownerMode != commandedMode or ownerSubmode != commandedSubmode) if (ownerMode != commandedMode or ownerSubmode != commandedSubmode)
@ -95,21 +93,20 @@ void ModeHelper::sendModeReplyMessage(Mode_t ownerMode,
ownerMode, ownerSubmode); ownerMode, ownerSubmode);
} }
MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply, MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply,
owner->getCommandQueue()); owner->getCommandQueue());
} }
} }
void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, void ModeHelper::sendModeInfoMessage(Mode_t ownerMode,
Submode_t ownerSubmode) { Submode_t ownerSubmode) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
if (theOneWhoCommandedAMode != parentQueueId if (theOneWhoCommandedAMode != parentQueueId
and parentQueueId != MessageQueueMessageIF::NO_QUEUE) and parentQueueId != MessageQueueMessageIF::NO_QUEUE)
{ {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO,
ownerMode, ownerSubmode); ownerMode, ownerSubmode);
MessageQueueSenderIF::sendMessage(parentQueueId, &reply, MessageQueueSenderIF::sendMessage(parentQueueId, &reply,
owner->getCommandQueue()); owner->getCommandQueue());
} }
} }

View File

@ -31,8 +31,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
MessageQueueMessage message; CommandMessage report;
CommandMessage report(&message);
MonitoringMessage::setLimitViolationReport(&report, storeId); MonitoringMessage::setLimitViolationReport(&report, storeId);
return MessageQueueSenderIF::sendMessage(reportQueue, &report); return MessageQueueSenderIF::sendMessage(reportQueue, &report);
} }

View File

@ -82,7 +82,7 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const {
void FixedTimeslotTask::taskFunctionality() { void FixedTimeslotTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the // A local iterator for the Polling Sequence Table is created to find the
// start time for the first entry. // start time for the first entry.
SlotListIter slotListIter = pst.current; auto slotListIter = pst.current;
//The start time for the first entry is read. //The start time for the first entry is read.
uint32_t intervalMs = slotListIter->pollingTimeMs; uint32_t intervalMs = slotListIter->pollingTimeMs;
@ -90,9 +90,9 @@ void FixedTimeslotTask::taskFunctionality() {
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* The xLastWakeTime variable needs to be initialized with the current tick /* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to explicitly. count. Note that this is the only time the variable is written to
After this assignment, xLastWakeTime is updated automatically internally within explicitly. After this assignment, xLastWakeTime is updated automatically
vTaskDelayUntil(). */ internally within vTaskDelayUntil(). */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
// wait for first entry's start time // wait for first entry's start time
@ -105,31 +105,53 @@ void FixedTimeslotTask::taskFunctionality() {
//The component for this slot is executed and the next one is chosen. //The component for this slot is executed and the next one is chosen.
this->pst.executeAndAdvance(); this->pst.executeAndAdvance();
if (not pst.slotFollowsImmediately()) { if (not pst.slotFollowsImmediately()) {
/* If all operations are finished and the difference of the // Get the interval till execution of the next slot.
* current time minus the last wake time is larger than the
* expected wait period, a deadline was missed. */
if(xTaskGetTickCount() - xLastWakeTime >=
pdMS_TO_TICKS(this->pst.getIntervalToPreviousSlotMs())) {
#ifdef DEBUG
sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
// Continue immediately, no need to wait.
break;
}
// we need to wait before executing the current slot
//this gives us the time to wait:
intervalMs = this->pst.getIntervalToPreviousSlotMs(); intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs); interval = pdMS_TO_TICKS(intervalMs);
checkMissedDeadline(xLastWakeTime, interval);
// Wait for the interval. This exits immediately if a deadline was
// missed while also updating the last wake time.
vTaskDelayUntil(&xLastWakeTime, interval); vTaskDelayUntil(&xLastWakeTime, interval);
} }
} }
} }
void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown
if(currentTickCount < xLastWakeTime) {
// Time to wake has overflown as well. If the tick count
// is larger than the time to wake, a deadline was missed.
if(timeToWake < xLastWakeTime and
currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
// No tick count overflow. If the timeToWake has not overflown
// and the current tick count is larger than the time to wake,
// a deadline was missed.
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
void FixedTimeslotTask::handleMissedDeadline() {
#ifdef DEBUG
sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}
ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
vTaskDelay(pdMS_TO_TICKS(ms)); vTaskDelay(pdMS_TO_TICKS(ms));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;

View File

@ -12,7 +12,7 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF {
public: public:
/** /**
* Keep in Mind that you need to call before this vTaskStartScheduler()! * Keep in mind that you need to call before vTaskStartScheduler()!
* A lot of task parameters are set in "FreeRTOSConfig.h". * A lot of task parameters are set in "FreeRTOSConfig.h".
* @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN * @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN
* @param setPriority Number of priorities specified by * @param setPriority Number of priorities specified by
@ -89,6 +89,10 @@ protected:
* OS's System Calls to keep the timing of the periods. * OS's System Calls to keep the timing of the periods.
*/ */
void taskFunctionality(void); void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
}; };
#endif /* POLLINGTASK_H_ */ #endif /* POLLINGTASK_H_ */

View File

@ -7,7 +7,8 @@
// As a first step towards this, introduces system context variable which needs // As a first step towards this, introduces system context variable which needs
// to be switched manually // to be switched manually
// Haven't found function to find system context. // Haven't found function to find system context.
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) { MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
maxMessageSize(maxMessageSize) {
handle = xQueueCreate(messageDepth, maxMessageSize); handle = xQueueCreate(messageDepth, maxMessageSize);
if (handle == NULL) { if (handle == NULL) {
sif::error << "MessageQueue: Creation failed" << std::endl; sif::error << "MessageQueue: Creation failed" << std::endl;
@ -49,8 +50,8 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) { bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo, message, sentFrom, return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault,
ignoreFault, callContext); callContext);
} }
@ -120,10 +121,11 @@ bool MessageQueue::isDefaultDestinationSet() const {
// static core function to send messages. // static core function to send messages.
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF *message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault, CallContext callContext) { bool ignoreFault, CallContext callContext) {
message->setSender(sentFrom); message->setSender(sentFrom);
BaseType_t result; BaseType_t result;
if(callContext == CallContext::TASK) { if(callContext == CallContext::TASK) {
result = xQueueSendToBack(reinterpret_cast<QueueHandle_t>(sendTo), result = xQueueSendToBack(reinterpret_cast<QueueHandle_t>(sendTo),
static_cast<const void*>(message->getBuffer()), 0); static_cast<const void*>(message->getBuffer()), 0);

View File

@ -204,6 +204,7 @@ private:
QueueHandle_t handle; QueueHandle_t handle;
MessageQueueId_t defaultDestination = 0; MessageQueueId_t defaultDestination = 0;
MessageQueueId_t lastPartner = 0; MessageQueueId_t lastPartner = 0;
const size_t maxMessageSize;
//!< Stores the current system context //!< Stores the current system context
CallContext callContext = CallContext::TASK; CallContext callContext = CallContext::TASK;
}; };

View File

@ -74,18 +74,7 @@ void PeriodicTask::taskFunctionality() {
object->performOperation(); object->performOperation();
} }
/* If all operations are finished and the difference of the checkMissedDeadline(xLastWakeTime, xPeriod);
* current time minus the last wake time is larger than the
* wait period, a deadline was missed. */
if(xTaskGetTickCount() - xLastWakeTime >= xPeriod) {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}
vTaskDelayUntil(&xLastWakeTime, xPeriod); vTaskDelayUntil(&xLastWakeTime, xPeriod);
@ -100,13 +89,48 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) {
"it implement ExecutableObjectIF" << std::endl; "it implement ExecutableObjectIF" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if(setTaskIF) {
newObject->setTaskIF(this);
}
objectList.push_back(newObject); objectList.push_back(newObject);
if(setTaskIF) {
newObject->setTaskIF(this);
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t PeriodicTask::getPeriodMs() const { uint32_t PeriodicTask::getPeriodMs() const {
return period * 1000; return period * 1000;
} }
void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown
if(currentTickCount < xLastWakeTime) {
// Time to wake has overflown as well. If the tick count
// is larger than the time to wake, a deadline was missed.
if(timeToWake < xLastWakeTime and
currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
// No tick count overflow. If the timeToWake has not overflown
// and the current tick count is larger than the time to wake,
// a deadline was missed.
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
void PeriodicTask::handleMissedDeadline() {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}

View File

@ -116,6 +116,10 @@ protected:
* On missing the deadline, the deadlineMissedFunction is executed. * On missing the deadline, the deadlineMissedFunction is executed.
*/ */
void taskFunctionality(void); void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
}; };
#endif /* PERIODICTASK_H_ */ #endif /* PERIODICTASK_H_ */

View File

@ -11,7 +11,8 @@
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize):
id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE),
defaultDestination(MessageQueueIF::NO_QUEUE) { defaultDestination(MessageQueueIF::NO_QUEUE),
maxMessageSize(maxMessageSize) {
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
mq_attr attributes; mq_attr attributes;
this->id = 0; this->id = 0;
@ -142,6 +143,19 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
} }
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
if(message == nullptr) {
sif::error << "MessageQueue::receiveMessage: Message is "
"nullptr!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if(message->getMaximumMessageSize() < maxMessageSize) {
sif::error << "MessageQueue::receiveMessage: Message size "
<< message->getMaximumMessageSize() <<
" too small to receive data!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
unsigned int messagePriority = 0; unsigned int messagePriority = 0;
int status = mq_receive(id,reinterpret_cast<char*>(message->getBuffer()), int status = mq_receive(id,reinterpret_cast<char*>(message->getBuffer()),
message->getMaximumMessageSize(),&messagePriority); message->getMaximumMessageSize(),&messagePriority);
@ -258,18 +272,19 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
this->defaultDestination = defaultDestination; this->defaultDestination = defaultDestination;
} }
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault);
}
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
MessageQueueId_t sentFrom, bool ignoreFault) { MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
} }
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault);
}
MessageQueueId_t MessageQueue::getDefaultDestination() const { MessageQueueId_t MessageQueue::getDefaultDestination() const {
return this->defaultDestination; return this->defaultDestination;
} }
@ -283,6 +298,12 @@ uint16_t MessageQueue::queueCounter = 0;
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF *message, MessageQueueId_t sentFrom, MessageQueueMessageIF *message, MessageQueueId_t sentFrom,
bool ignoreFault) { bool ignoreFault) {
if(message == nullptr) {
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is "
"nullptr!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
message->setSender(sentFrom); message->setSender(sentFrom);
int result = mq_send(sendTo, int result = mq_send(sendTo,
reinterpret_cast<const char*>(message->getBuffer()), reinterpret_cast<const char*>(message->getBuffer()),

View File

@ -176,9 +176,10 @@ private:
/** /**
* The name of the message queue, stored for unlinking * The name of the message queue, stored for unlinking
*/ */
char name[5]; char name[16];
static uint16_t queueCounter; static uint16_t queueCounter;
const size_t maxMessageSize;
ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth); ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth);
}; };

View File

@ -31,10 +31,11 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object,
"it implements ExecutableObjectIF" << std::endl; "it implements ExecutableObjectIF" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject);
if(setTaskIF) { if(setTaskIF) {
newObject->setTaskIF(this); newObject->setTaskIF(this);
} }
objectList.push_back(newObject);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -43,14 +44,14 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
} }
ReturnValue_t PeriodicPosixTask::startTask(void){ ReturnValue_t PeriodicPosixTask::startTask(void) {
started = true; started = true;
//sif::info << stackSize << std::endl; //sif::info << stackSize << std::endl;
PosixThread::createTask(&taskEntryPoint,this); PosixThread::createTask(&taskEntryPoint,this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void PeriodicPosixTask::taskFunctionality(void){ void PeriodicPosixTask::taskFunctionality(void) {
if(!started){ if(!started){
suspend(); suspend();
} }
@ -64,14 +65,15 @@ void PeriodicPosixTask::taskFunctionality(void){
if(!PosixThread::delayUntil(&lastWakeTime,periodMs)){ if(!PosixThread::delayUntil(&lastWakeTime,periodMs)){
char name[20] = {0}; char name[20] = {0};
int status = pthread_getname_np(pthread_self(),name,sizeof(name)); int status = pthread_getname_np(pthread_self(),name,sizeof(name));
if(status==0){ if(status == 0){
sif::error << "PeriodicPosixTask " << name << ": Deadline " sif::error << "PeriodicPosixTask " << name << ": Deadline "
"missed." << std::endl; "missed." << std::endl;
}else{ }
else {
sif::error << "PeriodicPosixTask X: Deadline missed. " << sif::error << "PeriodicPosixTask X: Deadline missed. " <<
status << std::endl; status << std::endl;
} }
if (this->deadlineMissedFunc != NULL) { if (this->deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();
} }
} }

View File

@ -32,7 +32,7 @@ public:
* The address of the task object is passed as an argument * The address of the task object is passed as an argument
* to the system call. * to the system call.
*/ */
ReturnValue_t startTask(void); ReturnValue_t startTask(void) override;
/** /**
* Adds an object to the list of objects to be executed. * Adds an object to the list of objects to be executed.
* The objects are executed in the order added. * The objects are executed in the order added.
@ -42,9 +42,9 @@ public:
ReturnValue_t addComponent(object_id_t object, ReturnValue_t addComponent(object_id_t object,
bool setTaskIF = true) override; bool setTaskIF = true) override;
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms) override;
private: private:
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects. typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.

View File

@ -49,9 +49,9 @@ QueueFactory::QueueFactory() {
QueueFactory::~QueueFactory() { QueueFactory::~QueueFactory() {
} }
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth,
uint32_t max_message_size) { size_t maxMessageSize) {
return new MessageQueue(message_depth, max_message_size); return new MessageQueue(messageDepth, maxMessageSize);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {

View File

@ -102,8 +102,7 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id,
return result; return result;
} }
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ParameterMessage::setParameterDumpReply(&reply, id, address); ParameterMessage::setParameterDumpReply(&reply, id, address);
@ -126,8 +125,7 @@ ReturnValue_t ParameterHelper::initialize() {
void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason,
Command_t initialCommand) { Command_t initialCommand) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
reply.setReplyRejected(reason, initialCommand); reply.setReplyRejected(reason, initialCommand);
MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId);
} }

View File

@ -163,8 +163,7 @@ void Fuse::setAllMonitorsToUnchecked() {
} }
void Fuse::checkCommandQueue() { void Fuse::checkCommandQueue() {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return; return;

View File

@ -74,8 +74,7 @@ void PowerSensor::setAllMonitorsToUnchecked() {
} }
void PowerSensor::checkCommandQueue() { void PowerSensor::checkCommandQueue() {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return; return;

View File

@ -1,5 +1,5 @@
#ifndef HASRETURNVALUESIF_H_ #ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
#define HASRETURNVALUESIF_H_ #define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
#include <framework/returnvalues/FwClassIds.h> #include <framework/returnvalues/FwClassIds.h>
#include <config/returnvalues/classIds.h> #include <config/returnvalues/classIds.h>
@ -12,8 +12,13 @@ typedef uint16_t ReturnValue_t;
class HasReturnvaluesIF { class HasReturnvaluesIF {
public: public:
static const ReturnValue_t RETURN_OK = 0; static const ReturnValue_t RETURN_OK = 0;
static const ReturnValue_t RETURN_FAILED = 0xFFFF; //! This will be the all-ones value irrespective of used unsigned datatype.
static const ReturnValue_t RETURN_FAILED = -1;
virtual ~HasReturnvaluesIF() {} virtual ~HasReturnvaluesIF() {}
static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) {
return (interfaceId << 8) + number;
}
}; };
#endif /* HASRETURNVALUESIF_H_ */ #endif /* HASRETURNVALUESIF_H_ */

View File

@ -0,0 +1,87 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/storagemanager/ConstStorageAccessor.h>
#include <framework/storagemanager/StorageManagerIF.h>
#include <framework/globalfunctions/arrayprinter.h>
ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId):
storeId(storeId) {}
ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId,
StorageManagerIF* store):
storeId(storeId), store(store) {
internalState = AccessState::ASSIGNED;
}
ConstStorageAccessor::~ConstStorageAccessor() {
if(deleteData and store != nullptr) {
sif::debug << "deleting store data" << std::endl;
store->deleteData(storeId);
}
}
ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other):
constDataPointer(other.constDataPointer), storeId(other.storeId),
size_(other.size_), store(other.store), deleteData(other.deleteData),
internalState(other.internalState) {
// This prevent premature deletion
other.store = nullptr;
}
ConstStorageAccessor& ConstStorageAccessor::operator=(
ConstStorageAccessor&& other) {
constDataPointer = other.constDataPointer;
storeId = other.storeId;
store = other.store;
size_ = other.size_;
deleteData = other.deleteData;
this->store = other.store;
// This prevents premature deletion
other.store = nullptr;
return *this;
}
const uint8_t* ConstStorageAccessor::data() const {
return constDataPointer;
}
size_t ConstStorageAccessor::size() const {
if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl;
}
return size_;
}
ReturnValue_t ConstStorageAccessor::getDataCopy(uint8_t *pointer,
size_t maxSize) {
if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if(size_ > maxSize) {
sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
std::copy(constDataPointer, constDataPointer + size_, pointer);
return HasReturnvaluesIF::RETURN_OK;
}
void ConstStorageAccessor::release() {
deleteData = false;
}
store_address_t ConstStorageAccessor::getId() const {
return storeId;
}
void ConstStorageAccessor::print() const {
if(internalState == AccessState::UNINIT or constDataPointer == nullptr) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return;
}
arrayprinter::print(constDataPointer, size_);
}
void ConstStorageAccessor::assignStore(StorageManagerIF* store) {
internalState = AccessState::ASSIGNED;
this->store = store;
}

View File

@ -0,0 +1,116 @@
#ifndef FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_
#define FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_
#include <framework/storagemanager/storeAddress.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <cstddef>
class StorageManagerIF;
/**
* @brief Helper classes to facilitate safe access to storages which is also
* conforming to RAII principles
* @details
* Accessor class which can be returned by pool manager or passed and set by
* pool managers to have safe access to the pool resources.
*
* These helper can be used together with the StorageManager classes to manage
* access to a storage. It can take care of thread-safety while also providing
* mechanisms to automatically clear storage data.
*/
class ConstStorageAccessor {
//! StorageManager classes have exclusive access to private variables.
template<uint8_t NUMBER_OF_POOLS>
friend class PoolManager;
template<uint8_t NUMBER_OF_POOLS>
friend class LocalPool;
public:
/**
* @brief Simple constructor which takes the store ID of the storage
* entry to access.
* @param storeId
*/
ConstStorageAccessor(store_address_t storeId);
ConstStorageAccessor(store_address_t storeId, StorageManagerIF* store);
/**
* @brief The destructor in default configuration takes care of
* deleting the accessed pool entry and unlocking the mutex
*/
virtual ~ConstStorageAccessor();
/**
* @brief Returns a pointer to the read-only data
* @return
*/
const uint8_t* data() const;
/**
* @brief Copies the read-only data to the supplied pointer
* @param pointer
*/
virtual ReturnValue_t getDataCopy(uint8_t *pointer, size_t maxSize);
/**
* @brief Calling this will prevent the Accessor from deleting the data
* when the destructor is called.
*/
void release();
/**
* Get the size of the data
* @return
*/
size_t size() const;
/**
* Get the storage ID.
* @return
*/
store_address_t getId() const;
void print() const;
/**
* @brief Move ctor and move assignment allow returning accessors as
* a returnvalue. They prevent resource being free prematurely.
* Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/
* move-constructors-and-move-assignment-operators-cpp.md
* @param
* @return
*/
ConstStorageAccessor& operator= (ConstStorageAccessor&&);
ConstStorageAccessor (ConstStorageAccessor&&);
//! The copy ctor and copy assignemnt should be deleted implicitely
//! according to https://foonathan.net/2019/02/special-member-functions/
//! but I still deleted them to make it more explicit. (remember rule of 5).
ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete;
ConstStorageAccessor (ConstStorageAccessor&) = delete;
protected:
const uint8_t* constDataPointer = nullptr;
store_address_t storeId;
size_t size_ = 0;
//! Managing pool, has to assign itself.
StorageManagerIF* store = nullptr;
bool deleteData = true;
enum class AccessState {
UNINIT,
ASSIGNED
};
//! Internal state for safety reasons.
AccessState internalState = AccessState::UNINIT;
/**
* Used by the pool manager instances to assign themselves to the
* accessor. This is necessary to delete the data when the acessor
* exits the scope ! The internal state will be considered read
* when this function is called, so take care all data is set properly as
* well.
* @param
*/
void assignStore(StorageManagerIF*);
};
#endif /* FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ */

View File

@ -35,7 +35,7 @@ public:
/** /**
* @brief This is the default constructor for a pool manager instance. * @brief This is the default constructor for a pool manager instance.
* @details By passing two arrays of size NUMBER_OF_POOLS, the constructor * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor
* allocates memory (with \c new) for store and size_list. These * allocates memory (with @c new) for store and size_list. These
* regions are all set to zero on start up. * regions are all set to zero on start up.
* @param setObjectId The object identifier to be set. This allows for * @param setObjectId The object identifier to be set. This allows for
* multiple instances of LocalPool in the system. * multiple instances of LocalPool in the system.
@ -87,7 +87,7 @@ public:
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
protected: protected:
/** /**
* With this helper method, a free element of \c size is reserved. * With this helper method, a free element of @c size is reserved.
* @param size The minimum packet size that shall be reserved. * @param size The minimum packet size that shall be reserved.
* @param[out] address Storage ID of the reserved data. * @param[out] address Storage ID of the reserved data.
* @return - #RETURN_OK on success, * @return - #RETURN_OK on success,
@ -100,7 +100,8 @@ protected:
private: private:
/** /**
* Indicates that this element is free. * Indicates that this element is free.
* This value limits the maximum size of a pool. Change to larger data type if increase is required. * This value limits the maximum size of a pool. Change to larger data type
* if increase is required.
*/ */
static const uint32_t STORAGE_FREE = 0xFFFFFFFF; static const uint32_t STORAGE_FREE = 0xFFFFFFFF;
/** /**
@ -126,7 +127,9 @@ private:
* is also dynamically allocated there. * is also dynamically allocated there.
*/ */
uint32_t* size_list[NUMBER_OF_POOLS]; uint32_t* size_list[NUMBER_OF_POOLS];
bool spillsToHigherPools; //!< A variable to determine whether higher n pools are used if the store is full. //! A variable to determine whether higher n pools are used if
//! the store is full.
bool spillsToHigherPools;
/** /**
* @brief This method safely stores the given data in the given packet_id. * @brief This method safely stores the given data in the given packet_id.
* @details It also sets the size in size_list. The method does not perform * @details It also sets the size in size_list. The method does not perform

View File

@ -29,6 +29,9 @@ public:
store_address_t* storeId = nullptr) override; store_address_t* storeId = nullptr) override;
protected: protected:
//! Default mutex timeout value to prevent permanent blocking.
static constexpr uint32_t mutexTimeout = 50;
ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address,
bool ignoreFault) override; bool ignoreFault) override;

View File

@ -21,7 +21,7 @@ inline PoolManager<NUMBER_OF_POOLS>::~PoolManager(void) {
template<uint8_t NUMBER_OF_POOLS> template<uint8_t NUMBER_OF_POOLS>
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::reserveSpace( inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::reserveSpace(
const uint32_t size, store_address_t* address, bool ignoreFault) { const uint32_t size, store_address_t* address, bool ignoreFault) {
MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); MutexHelper mutexHelper(mutex, mutexTimeout);
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::reserveSpace(size, ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::reserveSpace(size,
address,ignoreFault); address,ignoreFault);
return status; return status;
@ -33,7 +33,7 @@ inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(
// debug << "PoolManager( " << translateObject(getObjectId()) << // debug << "PoolManager( " << translateObject(getObjectId()) <<
// " )::deleteData from store " << packet_id.pool_index << // " )::deleteData from store " << packet_id.pool_index <<
// ". id is "<< packet_id.packet_index << std::endl; // ". id is "<< packet_id.packet_index << std::endl;
MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); MutexHelper mutexHelper(mutex, mutexTimeout);
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(packet_id); ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(packet_id);
return status; return status;
} }
@ -41,7 +41,7 @@ inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(
template<uint8_t NUMBER_OF_POOLS> template<uint8_t NUMBER_OF_POOLS>
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(uint8_t* buffer, inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(uint8_t* buffer,
size_t size, store_address_t* storeId) { size_t size, store_address_t* storeId) {
MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); MutexHelper mutexHelper(mutex, mutexTimeout);
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(buffer, ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(buffer,
size, storeId); size, storeId);
return status; return status;

View File

@ -1,96 +1,6 @@
#include <framework/storagemanager/StorageAccessor.h> #include <framework/storagemanager/StorageAccessor.h>
#include <framework/storagemanager/StorageManagerIF.h> #include <framework/storagemanager/StorageManagerIF.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId):
storeId(storeId) {}
ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId,
StorageManagerIF* store):
storeId(storeId), store(store) {
internalState = AccessState::ASSIGNED;
}
ConstStorageAccessor::~ConstStorageAccessor() {
if(deleteData and store != nullptr) {
sif::debug << "deleting store data" << std::endl;
store->deleteData(storeId);
}
}
ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other):
constDataPointer(other.constDataPointer), storeId(other.storeId),
size_(other.size_), store(other.store), deleteData(other.deleteData),
internalState(other.internalState) {
// This prevent premature deletion
other.store = nullptr;
}
ConstStorageAccessor& ConstStorageAccessor::operator=(
ConstStorageAccessor&& other) {
constDataPointer = other.constDataPointer;
storeId = other.storeId;
store = other.store;
size_ = other.size_;
deleteData = other.deleteData;
this->store = other.store;
// This prevents premature deletion
other.store = nullptr;
return *this;
}
const uint8_t* ConstStorageAccessor::data() const {
return constDataPointer;
}
size_t ConstStorageAccessor::size() const {
if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl;
}
return size_;
}
ReturnValue_t ConstStorageAccessor::getDataCopy(uint8_t *pointer,
size_t maxSize) {
if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if(size_ > maxSize) {
sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
std::copy(constDataPointer, constDataPointer + size_, pointer);
return HasReturnvaluesIF::RETURN_OK;
}
void ConstStorageAccessor::release() {
deleteData = false;
}
store_address_t ConstStorageAccessor::getId() const {
return storeId;
}
void ConstStorageAccessor::print() const {
if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return;
}
sif::info << "StorageAccessor: Printing data: [";
for(uint16_t iPool = 0; iPool < size_; iPool++) {
sif::info << std::hex << (int)constDataPointer[iPool];
if(iPool < size_ - 1){
sif::info << " , ";
}
}
sif::info << " ] " << std::endl;
}
void ConstStorageAccessor::assignStore(StorageManagerIF* store) {
internalState = AccessState::ASSIGNED;
this->store = store;
}
StorageAccessor::StorageAccessor(store_address_t storeId): StorageAccessor::StorageAccessor(store_address_t storeId):
ConstStorageAccessor(storeId) { ConstStorageAccessor(storeId) {
@ -120,7 +30,8 @@ ReturnValue_t StorageAccessor::getDataCopy(uint8_t *pointer, size_t maxSize) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if(size_ > maxSize) { if(size_ > maxSize) {
sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl; sif::error << "StorageAccessor: Supplied buffer not large "
"enough" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
std::copy(dataPointer, dataPointer + size_, pointer); std::copy(dataPointer, dataPointer + size_, pointer);
@ -141,7 +52,8 @@ ReturnValue_t StorageAccessor::write(uint8_t *data, size_t size,
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if(offset + size > size_) { if(offset + size > size_) {
sif::error << "StorageAccessor: Data too large for pool entry!" << std::endl; sif::error << "StorageAccessor: Data too large for pool "
"entry!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
std::copy(data, data + size, dataPointer + offset); std::copy(data, data + size, dataPointer + offset);

View File

@ -1,117 +1,10 @@
#ifndef FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_ #ifndef FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_
#define FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_ #define FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_
#include <framework/ipc/MutexHelper.h> #include <framework/storagemanager/ConstStorageAccessor.h>
#include <framework/storagemanager/storeAddress.h>
class StorageManagerIF; class StorageManagerIF;
/**
* @brief Helper classes to facilitate safe access to storages which is also
* conforming to RAII principles
* @details
* Accessor class which can be returned by pool manager or passed and set by
* pool managers to have safe access to the pool resources.
*
* These helper can be used together with the StorageManager classes to manage
* access to a storage. It can take care of thread-safety while also providing
* mechanisms to automatically clear storage data.
*/
class ConstStorageAccessor {
//! StorageManager classes have exclusive access to private variables.
template<uint8_t NUMBER_OF_POOLS>
friend class PoolManager;
template<uint8_t NUMBER_OF_POOLS>
friend class LocalPool;
public:
/**
* @brief Simple constructor which takes the store ID of the storage
* entry to access.
* @param storeId
*/
ConstStorageAccessor(store_address_t storeId);
ConstStorageAccessor(store_address_t storeId, StorageManagerIF* store);
/**
* @brief The destructor in default configuration takes care of
* deleting the accessed pool entry and unlocking the mutex
*/
virtual ~ConstStorageAccessor();
/**
* @brief Returns a pointer to the read-only data
* @return
*/
const uint8_t* data() const;
/**
* @brief Copies the read-only data to the supplied pointer
* @param pointer
*/
virtual ReturnValue_t getDataCopy(uint8_t *pointer, size_t maxSize);
/**
* @brief Calling this will prevent the Accessor from deleting the data
* when the destructor is called.
*/
void release();
/**
* Get the size of the data
* @return
*/
size_t size() const;
/**
* Get the storage ID.
* @return
*/
store_address_t getId() const;
void print() const;
/**
* @brief Move ctor and move assignment allow returning accessors as
* a returnvalue. They prevent resource being free prematurely.
* Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/
* move-constructors-and-move-assignment-operators-cpp.md
* @param
* @return
*/
ConstStorageAccessor& operator= (ConstStorageAccessor&&);
ConstStorageAccessor (ConstStorageAccessor&&);
//! The copy ctor and copy assignemnt should be deleted implicitely
//! according to https://foonathan.net/2019/02/special-member-functions/
//! but I still deleted them to make it more explicit. (remember rule of 5).
ConstStorageAccessor& operator= (const ConstStorageAccessor&) = delete;
ConstStorageAccessor (const ConstStorageAccessor&) = delete;
protected:
const uint8_t* constDataPointer = nullptr;
store_address_t storeId;
size_t size_ = 0;
//! Managing pool, has to assign itself.
StorageManagerIF* store = nullptr;
bool deleteData = true;
enum class AccessState {
UNINIT,
ASSIGNED
};
//! Internal state for safety reasons.
AccessState internalState = AccessState::UNINIT;
/**
* Used by the pool manager instances to assign themselves to the
* accessor. This is necessary to delete the data when the acessor
* exits the scope ! The internal state will be considered read
* when this function is called, so take care all data is set properly as
* well.
* @param
*/
void assignStore(StorageManagerIF*);
};
/** /**
* @brief Child class for modifyable data. Also has a normal pointer member. * @brief Child class for modifyable data. Also has a normal pointer member.
*/ */

View File

@ -309,8 +309,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
break; break;
case ModeSequenceMessage::READ_FREE_SEQUENCE_SLOTS: { case ModeSequenceMessage::READ_FREE_SEQUENCE_SLOTS: {
uint32_t freeSlots = modeSequences.maxSize() - modeSequences.size(); uint32_t freeSlots = modeSequences.maxSize() - modeSequences.size();
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ModeSequenceMessage::setModeSequenceMessage(&reply, ModeSequenceMessage::setModeSequenceMessage(&reply,
ModeSequenceMessage::FREE_SEQUENCE_SLOTS, freeSlots); ModeSequenceMessage::FREE_SEQUENCE_SLOTS, freeSlots);
commandQueue->reply(&reply); commandQueue->reply(&reply);
@ -318,8 +317,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
break; break;
case ModeSequenceMessage::READ_FREE_TABLE_SLOTS: { case ModeSequenceMessage::READ_FREE_TABLE_SLOTS: {
uint32_t free = modeTables.maxSize() - modeTables.size(); uint32_t free = modeTables.maxSize() - modeTables.size();
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ModeSequenceMessage::setModeSequenceMessage(&reply, ModeSequenceMessage::setModeSequenceMessage(&reply,
ModeSequenceMessage::FREE_TABLE_SLOTS, free); ModeSequenceMessage::FREE_TABLE_SLOTS, free);
commandQueue->reply(&reply); commandQueue->reply(&reply);
@ -332,12 +330,11 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
} }
void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) { void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) {
MessageQueueMessage message;
if (status == RETURN_OK) { if (status == RETURN_OK) {
CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, 0); CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, 0);
commandQueue->reply(&reply); commandQueue->reply(&reply);
} else { } else {
CommandMessage reply(&message, CommandMessage::REPLY_REJECTED, status, 0); CommandMessage reply(CommandMessage::REPLY_REJECTED, status, 0);
commandQueue->reply(&reply); commandQueue->reply(&reply);
} }
} }
@ -620,8 +617,7 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command,
for (uint8_t i = 0; i < count; i++) { for (uint8_t i = 0; i < count; i++) {
elements[i]->serialize(&storeBuffer, &size, maxSize, true); elements[i]->serialize(&storeBuffer, &size, maxSize, true);
} }
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ModeSequenceMessage::setModeSequenceMessage(&reply, command, address); ModeSequenceMessage::setModeSequenceMessage(&reply, command, address);
if (commandQueue->reply(&reply) != RETURN_OK) { if (commandQueue->reply(&reply) != RETURN_OK) {
IPCStore->deleteData(address); IPCStore->deleteData(address);

View File

@ -77,8 +77,7 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable(
} }
void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submode_t targetSubmode) { void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submode_t targetSubmode) {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
std::map<object_id_t, ChildInfo>::iterator iter; std::map<object_id_t, ChildInfo>::iterator iter;
@ -129,7 +128,7 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
continue; //don't send redundant mode commands (produces event spam), but still command if mode is forced to reach lower levels continue; //don't send redundant mode commands (produces event spam), but still command if mode is forced to reach lower levels
} }
ReturnValue_t result = commandQueue->sendMessage( ReturnValue_t result = commandQueue->sendMessage(
iter->second.commandQueue, &message); iter->second.commandQueue, &command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
++commandsOutstanding; ++commandsOutstanding;
} }
@ -297,8 +296,7 @@ void SubsystemBase::setToExternalControl() {
void SubsystemBase::announceMode(bool recursive) { void SubsystemBase::announceMode(bool recursive) {
triggerEvent(MODE_INFO, mode, submode); triggerEvent(MODE_INFO, mode, submode);
if (recursive) { if (recursive) {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ModeMessage::setModeMessage(&command, ModeMessage::setModeMessage(&command,
ModeMessage::CMD_MODE_ANNOUNCE_RECURSIVELY, 0, 0); ModeMessage::CMD_MODE_ANNOUNCE_RECURSIVELY, 0, 0);
commandAllChildren(&command); commandAllChildren(&command);
@ -307,8 +305,7 @@ void SubsystemBase::announceMode(bool recursive) {
void SubsystemBase::checkCommandQueue() { void SubsystemBase::checkCommandQueue() {
ReturnValue_t result; ReturnValue_t result;
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
result = commandQueue->receiveMessage(&command)) { result = commandQueue->receiveMessage(&command)) {
@ -330,8 +327,7 @@ void SubsystemBase::checkCommandQueue() {
result = handleCommandMessage(&command); result = handleCommandMessage(&command);
if (result != RETURN_OK) { if (result != RETURN_OK) {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND,
command.getCommand()); command.getCommand());
replyToCommand(&reply); replyToCommand(&reply);

View File

@ -44,8 +44,7 @@ ReturnValue_t AbstractTemperatureSensor::performHealthOp() {
} }
void AbstractTemperatureSensor::handleCommandQueue() { void AbstractTemperatureSensor::handleCommandQueue() {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
result = healthHelper.handleHealthCommand(&command); result = healthHelper.handleHealthCommand(&command);
@ -57,7 +56,7 @@ void AbstractTemperatureSensor::handleCommandQueue() {
return; return;
} }
command.setToUnknownCommand(); command.setToUnknownCommand();
commandQueue->reply(&message); commandQueue->reply(&command);
} }
} }

View File

@ -279,8 +279,7 @@ ReturnValue_t Heater::initialize() {
} }
void Heater::handleQueue() { void Heater::handleQueue() {
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
ReturnValue_t result = commandQueue->receiveMessage(&command); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
result = healthHelper.handleHealthCommand(&command); result = healthHelper.handleHealthCommand(&command);

View File

@ -117,7 +117,8 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination,
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
TmTcMessage tmMessage(getStoreAddress()); TmTcMessage tmMessage(getStoreAddress());
ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, &tmMessage, sentFrom); ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination,
&tmMessage, sentFrom);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
deletePacket(); deletePacket();
if (doErrorReporting) { if (doErrorReporting) {

View File

@ -76,28 +76,18 @@ ReturnValue_t CommandingServiceBase::initialize() {
} }
void CommandingServiceBase::handleCommandQueue() { void CommandingServiceBase::handleCommandQueue() {
MessageQueueMessage message; CommandMessage reply;
CommandMessage reply(&message);
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK;
result = commandQueue->receiveMessage(&reply)) { result = commandQueue->receiveMessage(&reply)) {
if(reply.getInternalMessage() == nullptr) {
// This should never happen unless the passed message maximum size
// is too small!
sif::error << "CommandingServiceBase::handleCommandMessage: Reply"
"does not satisfy minimum requirements for a command "
"message!" << std::endl;
continue;
}
handleCommandMessage(&reply); handleCommandMessage(&reply);
} }
} }
void CommandingServiceBase::handleCommandMessage(CommandMessageIF* reply) { void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) {
bool isStep = false; bool isStep = false;
MessageQueueMessage message; CommandMessage nextCommand;
CommandMessage nextCommand(&message);
CommandMapIter iter = commandMap.find(reply->getSender()); CommandMapIter iter = commandMap.find(reply->getSender());
// handle unrequested reply first // handle unrequested reply first
@ -156,8 +146,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessageIF* reply) {
} }
void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result,
CommandMapIter iter, CommandMessageIF* nextCommand, CommandMapIter iter, CommandMessage* nextCommand,
CommandMessageIF* reply, bool& isStep) { CommandMessage* reply, bool& isStep) {
iter->command = nextCommand->getCommand(); iter->command = nextCommand->getCommand();
// In case a new command is to be sent immediately, this is performed here. // In case a new command is to be sent immediately, this is performed here.
@ -303,8 +293,7 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice,
void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, void CommandingServiceBase::startExecution(TcPacketStored *storedPacket,
CommandMapIter iter) { CommandMapIter iter) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
MessageQueueMessage message; CommandMessage command;
CommandMessage command(&message);
iter->subservice = storedPacket->getSubService(); iter->subservice = storedPacket->getSubService();
result = prepareCommand(&command, iter->subservice, result = prepareCommand(&command, iter->subservice,
storedPacket->getApplicationData(), storedPacket->getApplicationData(),
@ -316,7 +305,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket,
case RETURN_OK: case RETURN_OK:
if (command.getCommand() != CommandMessage::CMD_NONE) { if (command.getCommand() != CommandMessage::CMD_NONE) {
sendResult = commandQueue->sendMessage(iter.value->first, sendResult = commandQueue->sendMessage(iter.value->first,
&message); &command);
} }
if (sendResult == RETURN_OK) { if (sendResult == RETURN_OK) {
Clock::getUptime(&iter->uptimeOfStart); Clock::getUptime(&iter->uptimeOfStart);
@ -338,7 +327,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket,
if (command.getCommand() != CommandMessage::CMD_NONE) { if (command.getCommand() != CommandMessage::CMD_NONE) {
//Fire-and-forget command. //Fire-and-forget command.
sendResult = commandQueue->sendMessage(iter.value->first, sendResult = commandQueue->sendMessage(iter.value->first,
&message); &command);
} }
if (sendResult == RETURN_OK) { if (sendResult == RETURN_OK) {
verificationReporter.sendSuccessReport(TC_VERIFY::START_SUCCESS, verificationReporter.sendSuccessReport(TC_VERIFY::START_SUCCESS,
@ -384,9 +373,8 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) {
} }
void CommandingServiceBase::handleUnrequestedReply(CommandMessageIF* reply) { void CommandingServiceBase::handleUnrequestedReply(CommandMessage* reply) {
CommandMessage commandReply(reply->getInternalMessage()); reply->clear();
commandReply.clear();
} }

View File

@ -139,7 +139,7 @@ protected:
* @param objectId Target object ID * @param objectId Target object ID
* @return * @return
*/ */
virtual ReturnValue_t prepareCommand(CommandMessageIF *message, virtual ReturnValue_t prepareCommand(CommandMessage* message,
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) = 0; uint32_t *state, object_id_t objectId) = 0;
@ -168,9 +168,9 @@ protected:
* a failure verification message with the reason as the error parameter * a failure verification message with the reason as the error parameter
* and the initial command as failure parameter 1. * and the initial command as failure parameter 1.
*/ */
virtual ReturnValue_t handleReply(const CommandMessageIF *reply, virtual ReturnValue_t handleReply(const CommandMessage* reply,
Command_t previousCommand, uint32_t *state, Command_t previousCommand, uint32_t *state,
CommandMessageIF *optionalNextCommand, object_id_t objectId, CommandMessage* optionalNextCommand, object_id_t objectId,
bool *isStep) = 0; bool *isStep) = 0;
/** /**
@ -182,7 +182,7 @@ protected:
* Reply which is non-const so the default implementation can clear the * Reply which is non-const so the default implementation can clear the
* message. * message.
*/ */
virtual void handleUnrequestedReply(CommandMessageIF *reply); virtual void handleUnrequestedReply(CommandMessage* reply);
virtual void doPeriodicOperation(); virtual void doPeriodicOperation();
@ -310,9 +310,9 @@ private:
void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); void startExecution(TcPacketStored *storedPacket, CommandMapIter iter);
void handleCommandMessage(CommandMessageIF* reply); void handleCommandMessage(CommandMessage* reply);
void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter,
CommandMessageIF* nextCommand,CommandMessageIF* reply, bool& isStep); CommandMessage* nextCommand, CommandMessage* reply, bool& isStep);
void checkTimeout(); void checkTimeout();
}; };

View File

@ -3,6 +3,7 @@
#include <framework/ipc/QueueFactory.h> #include <framework/ipc/QueueFactory.h>
#include <framework/tmtcservices/AcceptsTelecommandsIF.h> #include <framework/tmtcservices/AcceptsTelecommandsIF.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/globalfunctions/arrayprinter.h>
TmTcBridge::TmTcBridge(object_id_t objectId_, TmTcBridge::TmTcBridge(object_id_t objectId_,
object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), object_id_t ccsdsPacketDistributor_): SystemObject(objectId_),
@ -85,7 +86,7 @@ ReturnValue_t TmTcBridge::handleTm() {
return RETURN_FAILED; return RETURN_FAILED;
} }
if(tmStored && communicationLinkUp) { if(tmStored and communicationLinkUp) {
result = handleStoredTm(); result = handleStoredTm();
} }
return result; return result;
@ -141,11 +142,11 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) {
ReturnValue_t TmTcBridge::handleStoredTm() { ReturnValue_t TmTcBridge::handleStoredTm() {
uint8_t counter = 0; uint8_t counter = 0;
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
while(not tmFifo.empty() && counter < sentPacketsPerCycle) { while(not tmFifo.empty() and counter < sentPacketsPerCycle) {
//info << "TMTC Bridge: Sending stored TM data. There are " //info << "TMTC Bridge: Sending stored TM data. There are "
// << (int) fifo.size() << " left to send\r\n" << std::flush; // << (int) fifo.size() << " left to send\r\n" << std::flush;
store_address_t storeId; store_address_t storeId;
const uint8_t* data = NULL; const uint8_t* data = nullptr;
size_t size = 0; size_t size = 0;
tmFifo.retrieve(&storeId); tmFifo.retrieve(&storeId);
result = tmStore->getData(storeId, &data, &size); result = tmStore->getData(storeId, &data, &size);
@ -186,14 +187,6 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) {
} }
void TmTcBridge::printData(uint8_t * data, size_t dataLen) { void TmTcBridge::printData(uint8_t * data, size_t dataLen) {
sif::info << "TMTC Bridge: Printing data: ["; arrayprinter::print(data, dataLen);
for(uint32_t i = 0; i < dataLen; i++) {
sif::info << std::hex << (int)data[i];
if(i < dataLen-1){
sif::info << " , ";
}
}
sif::info << " ] " << std::endl;
} }

View File

@ -43,26 +43,27 @@ public:
*/ */
ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored); ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored);
void registerCommConnect(); virtual void registerCommConnect();
void registerCommDisconnect(); virtual void registerCommDisconnect();
/** /**
* Initializes necessary FSFW components for the TMTC Bridge * Initializes necessary FSFW components for the TMTC Bridge
* @return * @return
*/ */
ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
/** /**
* @brief Handles TMTC reception * @brief Handles TMTC reception
*/ */
ReturnValue_t performOperation(uint8_t operationCode = 0) override; virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
/** /**
* Return TMTC Reception Queue * Return TMTC Reception Queue
* @param virtualChannel * @param virtualChannel
* @return * @return
*/ */
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override; MessageQueueId_t getReportReceptionQueue(
uint8_t virtualChannel = 0) override;
protected: protected:
//! Used to send and receive TMTC messages. //! Used to send and receive TMTC messages.
//! TmTcMessage is used to transport messages between tasks. //! TmTcMessage is used to transport messages between tasks.

View File

@ -22,7 +22,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id,
current_packet->getAcknowledgeFlags(), current_packet->getAcknowledgeFlags(),
current_packet->getPacketId(), current_packet->getPacketId(),
current_packet->getPacketSequenceControl(), 0, set_step); current_packet->getPacketSequenceControl(), 0, set_step);
ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue,
&message);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
sif::error << "VerificationReporter::sendSuccessReport: Error writing " sif::error << "VerificationReporter::sendSuccessReport: Error writing "
"to queue. Code: " << std::hex << (uint16_t) status << std::endl; "to queue. Code: " << std::hex << (uint16_t) status << std::endl;
@ -37,7 +38,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id,
} }
PusVerificationMessage message(set_report_id, ackFlags, tcPacketId, PusVerificationMessage message(set_report_id, ackFlags, tcPacketId,
tcSequenceControl, 0, set_step); tcSequenceControl, 0, set_step);
ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue,
&message);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
sif::error << "VerificationReporter::sendSuccessReport: Error writing " sif::error << "VerificationReporter::sendSuccessReport: Error writing "
"to queue. Code: " << std::hex << (uint16_t) status << std::endl; "to queue. Code: " << std::hex << (uint16_t) status << std::endl;
@ -55,7 +57,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id,
current_packet->getPacketId(), current_packet->getPacketId(),
current_packet->getPacketSequenceControl(), error_code, step, current_packet->getPacketSequenceControl(), error_code, step,
parameter1, parameter2); parameter1, parameter2);
ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue,
&message);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
sif::error sif::error
<< "VerificationReporter::sendFailureReport Error writing to queue. Code: " << "VerificationReporter::sendFailureReport Error writing to queue. Code: "
@ -72,7 +75,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id,
} }
PusVerificationMessage message(report_id, ackFlags, tcPacketId, PusVerificationMessage message(report_id, ackFlags, tcPacketId,
tcSequenceControl, error_code, step, parameter1, parameter2); tcSequenceControl, error_code, step, parameter1, parameter2);
ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue,
&message);
if (status != HasReturnvaluesIF::RETURN_OK) { if (status != HasReturnvaluesIF::RETURN_OK) {
sif::error sif::error
<< "VerificationReporter::sendFailureReport Error writing to queue. Code: " << "VerificationReporter::sendFailureReport Error writing to queue. Code: "