From 140aa3ab422cc220dbbcf16f1d24242a73b3c933 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 12 Oct 2020 18:18:41 +0200 Subject: [PATCH 1/4] form improvements DHB --- devicehandlers/AcceptsDeviceResponsesIF.h | 22 +-- devicehandlers/AssemblyBase.cpp | 13 +- devicehandlers/AssemblyBase.h | 90 ++++++--- devicehandlers/ChildHandlerBase.cpp | 10 +- devicehandlers/ChildHandlerBase.h | 14 +- devicehandlers/ChildHandlerFDIR.cpp | 3 +- devicehandlers/ChildHandlerFDIR.h | 4 +- devicehandlers/CookieIF.h | 10 +- devicehandlers/DeviceCommunicationIF.h | 43 ++-- devicehandlers/DeviceHandlerBase.cpp | 183 ++++++++++++------ devicehandlers/DeviceHandlerBase.h | 170 ++++++++-------- .../DeviceHandlerFailureIsolation.cpp | 8 + devicehandlers/DeviceHandlerIF.h | 20 +- devicehandlers/DeviceHandlerMessage.cpp | 19 +- devicehandlers/DeviceHandlerMessage.h | 78 +++----- devicehandlers/DeviceTmReportingWrapper.cpp | 1 - devicehandlers/DeviceTmReportingWrapper.h | 6 +- devicehandlers/HealthDevice.cpp | 6 +- devicehandlers/HealthDevice.h | 6 +- 19 files changed, 403 insertions(+), 303 deletions(-) diff --git a/devicehandlers/AcceptsDeviceResponsesIF.h b/devicehandlers/AcceptsDeviceResponsesIF.h index 8dc69de4..8e13ba0c 100644 --- a/devicehandlers/AcceptsDeviceResponsesIF.h +++ b/devicehandlers/AcceptsDeviceResponsesIF.h @@ -1,23 +1,19 @@ -/** - * @file AcceptsDeviceResponsesIF.h - * @brief This file defines the AcceptsDeviceResponsesIF class. - * @date 15.05.2013 - * @author baetz - */ - -#ifndef ACCEPTSDEVICERESPONSESIF_H_ -#define ACCEPTSDEVICERESPONSESIF_H_ +#ifndef FSFW_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ +#define FSFW_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ #include "../ipc/MessageQueueSenderIF.h" +/** + * This interface is used by the device handler to send a device response + * to the queue ID, which is returned in the implemented abstract method. + */ class AcceptsDeviceResponsesIF { public: /** * Default empty virtual destructor. */ - virtual ~AcceptsDeviceResponsesIF() { -} -virtual MessageQueueId_t getDeviceQueue() = 0; + virtual ~AcceptsDeviceResponsesIF() {} + virtual MessageQueueId_t getDeviceQueue() = 0; }; -#endif /* ACCEPTSDEVICERESPONSESIF_H_ */ +#endif /* FSFW_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ */ diff --git a/devicehandlers/AssemblyBase.cpp b/devicehandlers/AssemblyBase.cpp index 8b3f7f4d..46b2211a 100644 --- a/devicehandlers/AssemblyBase.cpp +++ b/devicehandlers/AssemblyBase.cpp @@ -2,10 +2,10 @@ AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth) : - SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth), internalState( - STATE_NONE), recoveryState(RECOVERY_IDLE), recoveringDevice( - childrenMap.end()), targetMode(MODE_OFF), targetSubmode( - SUBMODE_NONE) { + SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth), + internalState(STATE_NONE), recoveryState(RECOVERY_IDLE), + recoveringDevice(childrenMap.end()), targetMode(MODE_OFF), + targetSubmode(SUBMODE_NONE) { recoveryOffTimer.setTimeout(POWER_OFF_TIME_MS); } @@ -165,9 +165,8 @@ ReturnValue_t AssemblyBase::checkChildrenState() { } ReturnValue_t AssemblyBase::checkChildrenStateOff() { - for (std::map::iterator iter = childrenMap.begin(); - iter != childrenMap.end(); iter++) { - if (checkChildOff(iter->first) != RETURN_OK) { + for (const auto& childIter: childrenMap) { + if (checkChildOff(childIter.first) != RETURN_OK) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } } diff --git a/devicehandlers/AssemblyBase.h b/devicehandlers/AssemblyBase.h index bd2e8fad..353d5f89 100644 --- a/devicehandlers/AssemblyBase.h +++ b/devicehandlers/AssemblyBase.h @@ -1,10 +1,30 @@ -#ifndef ASSEMBLYBASE_H_ -#define ASSEMBLYBASE_H_ +#ifndef FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ +#define FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ -#include "../container/FixedArrayList.h" #include "DeviceHandlerBase.h" +#include "../container/FixedArrayList.h" #include "../subsystem/SubsystemBase.h" +/** + * @brief Base class to implement reconfiguration and failure handling for + * redundant devices by monitoring their modes health states. + * @details + * Documentation: Dissertation Baetz p.156, 157. + * + * This class reduces the complexity of controller components which would + * otherwise be needed for the handling of redundant devices. + * + * The template class monitors mode and health state of its children + * and checks availability of devices on every detected change. + * AssemblyBase does not implement any redundancy logic by itself, but provides + * adaptation points for implementations to do so. Since most monitoring + * activities rely on mode and health state only and are therefore + * generic, it is sufficient for subclasses to provide: + * + * 1. check logic when active-> checkChildrenStateOn + * 2. transition logic to change the mode -> commandChildren + * + */ class AssemblyBase: public SubsystemBase { public: static const uint8_t INTERFACE_ID = CLASS_ID::ASSEMBLY_BASE; @@ -16,10 +36,41 @@ public: static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE = MAKE_RETURN_CODE(0xa1); - AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth = 8); + AssemblyBase(object_id_t objectId, object_id_t parentId, + uint16_t commandQueueDepth = 8); virtual ~AssemblyBase(); protected: + + // SHOULDDO: Change that OVERWRITE_HEALTH may be returned + // (or return internalState directly?) + /** + * Command children to reach [mode,submode] combination + * Can be done by setting #commandsOutstanding correctly, + * or using executeTable() + * @param mode + * @param submode + * @return + * - @c RETURN_OK if ok + * - @c NEED_SECOND_STEP if children need to be commanded again + */ + virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0; + + /** + * Check whether desired assembly mode was achieved by checking the modes + * or/and health states of child device handlers. + * The assembly template class will also call this function if a health + * or mode change of a child device handler was detected. + * @param wantedMode + * @param wantedSubmode + * @return + */ + virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, + Submode_t wantedSubmode) = 0; + + virtual ReturnValue_t isModeCombinationValid(Mode_t mode, + Submode_t submode) = 0; + enum InternalState { STATE_NONE, STATE_OVERWRITE_HEALTH, @@ -36,6 +87,7 @@ protected: RECOVERY_WAIT } recoveryState; //!< Indicates if one of the children requested a recovery. ChildrenMap::iterator recoveringDevice; + /** * the mode the current transition is trying to achieve. * Can be different from the modehelper.commandedMode! @@ -61,8 +113,8 @@ protected: bool handleChildrenChanged(); /** - * This method is called if the children changed its mode in a way that the current - * mode can't be kept. + * This method is called if the children changed its mode in a way that + * the current mode can't be kept. * Default behavior is to go to MODE_OFF. * @param result The failure code which was returned by checkChildrenState. */ @@ -75,9 +127,6 @@ protected: ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - virtual ReturnValue_t isModeCombinationValid(Mode_t mode, - Submode_t submode) = 0; - virtual void startTransition(Mode_t mode, Submode_t submode); virtual void doStartTransition(Mode_t mode, Submode_t submode); @@ -90,24 +139,6 @@ protected: void sendHealthCommand(MessageQueueId_t sendTo, HealthState health); - //SHOULDDO: Change that OVERWRITE_HEALTH may be returned (or return internalState directly?) - /** - * command children to reach mode,submode - * - * set #commandsOutstanding correctly, or use executeTable() - * - * @param mode - * @param submode - * @return - * - @c RETURN_OK if ok - * - @c NEED_SECOND_STEP if children need to be commanded again - */ - virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0; - - //SHOULDDO: Remove wantedMode, wantedSubmode, as targetMode/submode is available? - virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, - Submode_t wantedSubmode) = 0; - virtual ReturnValue_t checkChildrenStateOff(); ReturnValue_t checkChildrenState(); @@ -125,8 +156,9 @@ protected: * Also sets state to STATE_OVERWRITE_HEATH. * @param objectId Must be a registered child. */ - void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth); + void overwriteDeviceHealth(object_id_t objectId, + HasHealthIF::HealthState oldHealth); }; -#endif /* ASSEMBLYBASE_H_ */ +#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */ diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index e800cd56..d4ef67ad 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -1,16 +1,18 @@ +#include "ChildHandlerBase.h" #include "../subsystem/SubsystemBase.h" -#include "../devicehandlers/ChildHandlerBase.h" #include "../subsystem/SubsystemBase.h" ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * cookie, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - object_id_t parent, FailureIsolationBase* customFdir, - size_t cmdQueueSize) : + object_id_t hkDestination, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, + object_id_t parent, + FailureIsolationBase* customFdir, size_t cmdQueueSize) : DeviceHandlerBase(setObjectId, deviceCommunication, cookie, (customFdir == nullptr? &childHandlerFdir : customFdir), cmdQueueSize), parentId(parent), childHandlerFdir(setObjectId) { + this->setHkDestination(hkDestination); this->setThermalStateRequestPoolIds(thermalStatePoolId, thermalRequestPoolId); diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index f6bf318a..eed4c95e 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -1,17 +1,18 @@ -#ifndef FSFW_DEVICES_CHILDHANDLERBASE_H_ -#define FSFW_DEVICES_CHILDHANDLERBASE_H_ +#ifndef FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_ +#define FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_ -#include "ChildHandlerFDIR.h" #include "DeviceHandlerBase.h" +#include "ChildHandlerFDIR.h" class ChildHandlerBase: public DeviceHandlerBase { public: ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * cookie, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, + CookieIF * cookie, object_id_t hkDestination, + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT, FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20); + virtual ~ChildHandlerBase(); virtual ReturnValue_t initialize(); @@ -22,5 +23,4 @@ protected: }; -#endif /* FSFW_DEVICES_CHILDHANDLERBASE_H_ */ - +#endif /* FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_ */ diff --git a/devicehandlers/ChildHandlerFDIR.cpp b/devicehandlers/ChildHandlerFDIR.cpp index 14043a77..cb4c75ea 100644 --- a/devicehandlers/ChildHandlerFDIR.cpp +++ b/devicehandlers/ChildHandlerFDIR.cpp @@ -1,6 +1,7 @@ #include "ChildHandlerFDIR.h" -ChildHandlerFDIR::ChildHandlerFDIR(object_id_t owner, object_id_t faultTreeParent, uint32_t recoveryCount) : +ChildHandlerFDIR::ChildHandlerFDIR(object_id_t owner, + object_id_t faultTreeParent, uint32_t recoveryCount) : DeviceHandlerFailureIsolation(owner, faultTreeParent) { recoveryCounter.setFailureThreshold(recoveryCount); } diff --git a/devicehandlers/ChildHandlerFDIR.h b/devicehandlers/ChildHandlerFDIR.h index ce844518..13d1345c 100644 --- a/devicehandlers/ChildHandlerFDIR.h +++ b/devicehandlers/ChildHandlerFDIR.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_DEVICEHANDLERS_CHILDHANDLERFDIR_H_ -#define FRAMEWORK_DEVICEHANDLERS_CHILDHANDLERFDIR_H_ +#ifndef FSFW_DEVICEHANDLERS_CHILDHANDLERFDIR_H_ +#define FSFW_DEVICEHANDLERS_CHILDHANDLERFDIR_H_ #include "DeviceHandlerFailureIsolation.h" diff --git a/devicehandlers/CookieIF.h b/devicehandlers/CookieIF.h index 496cf0d2..5911bfdb 100644 --- a/devicehandlers/CookieIF.h +++ b/devicehandlers/CookieIF.h @@ -1,11 +1,12 @@ -#ifndef COOKIE_H_ -#define COOKIE_H_ +#ifndef FSFW_DEVICEHANDLER_COOKIE_H_ +#define FSFW_DEVICEHANDLER_COOKIE_H_ + #include /** * @brief Physical address type */ -typedef std::uint32_t address_t; +using address_t = uint32_t; /** * @brief This datatype is used to identify different connection over a @@ -16,7 +17,6 @@ typedef std::uint32_t address_t; * calling @code{.cpp} CookieIF* childCookie = new ChildCookie(...) * @endcode . * - * [not implemented yet] * This cookie is then passed to the child device handlers, which stores the * pointer and passes it to the communication interface functions. * @@ -31,4 +31,4 @@ public: virtual ~CookieIF() {}; }; -#endif /* COOKIE_H_ */ +#endif /* FSFW_DEVICEHANDLER_COOKIE_H_ */ diff --git a/devicehandlers/DeviceCommunicationIF.h b/devicehandlers/DeviceCommunicationIF.h index 11960d8e..e0b473d3 100644 --- a/devicehandlers/DeviceCommunicationIF.h +++ b/devicehandlers/DeviceCommunicationIF.h @@ -1,9 +1,10 @@ -#ifndef DEVICECOMMUNICATIONIF_H_ -#define DEVICECOMMUNICATIONIF_H_ +#ifndef FSFW_DEVICES_DEVICECOMMUNICATIONIF_H_ +#define FSFW_DEVICES_DEVICECOMMUNICATIONIF_H_ #include "CookieIF.h" +#include "DeviceHandlerIF.h" + #include "../returnvalues/HasReturnvaluesIF.h" -#include /** * @defgroup interfaces Interfaces * @brief Interfaces for flight software objects @@ -19,8 +20,8 @@ * the device handler to allow reuse of these components. * @details * Documentation: Dissertation Baetz p.138. - * It works with the assumption that received data - * is polled by a component. There are four generic steps of device communication: + * It works with the assumption that received data is polled by a component. + * There are four generic steps of device communication: * * 1. Send data to a device * 2. Get acknowledgement for sending @@ -38,24 +39,20 @@ class DeviceCommunicationIF: public HasReturnvaluesIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF; - //! Standard Error Codes + //! This is returned in readReceivedMessage() if no reply was reived. + static const ReturnValue_t NO_REPLY_RECEIVED = MAKE_RETURN_CODE(0x01); + //! General protocol error. Define more concrete errors in child handler - static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x01); + static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x02); //! If cookie is a null pointer - static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x02); - static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x03); + static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x03); + static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x04); // is this needed if there is no open/close call? static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05); - static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x06); - static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x07); - static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x08); - - //! Can be used in readReceivedMessage() if no reply was received. - static const ReturnValue_t NO_REPLY_RECEIVED = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x06); virtual ~DeviceCommunicationIF() {} - /** * @brief Device specific initialization, using the cookie. * @details @@ -76,13 +73,13 @@ public: * by implementing and calling related drivers or wrapper functions. * @param cookie * @param data - * @param len + * @param len If this is 0, nothing shall be sent. * @return * - @c RETURN_OK for successfull send * - Everything else triggers failure event with returnvalue as parameter 1 */ - virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData, - size_t sendLen) = 0; + virtual ReturnValue_t sendMessage(CookieIF *cookie, + const uint8_t * sendData, size_t sendLen) = 0; /** * Called by DHB in the GET_WRITE doGetWrite(). @@ -108,7 +105,7 @@ public: * returnvalue as parameter 1 */ virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, - size_t requestLen) = 0; + size_t requestLen) = 0; /** * Called by DHB in the GET_WRITE doGetRead(). @@ -124,8 +121,8 @@ public: * - Everything else triggers failure event with * returnvalue as parameter 1 */ - virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, - size_t *size) = 0; + virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, + uint8_t **buffer, size_t *size) = 0; }; -#endif /* DEVICECOMMUNICATIONIF_H_ */ +#endif /* FSFW_DEVICES_DEVICECOMMUNICATIONIF_H_ */ diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 017ea8d2..227d5b6d 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -2,15 +2,17 @@ #include "AcceptsDeviceResponsesIF.h" #include "DeviceTmReportingWrapper.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../datapoolglob/GlobalDataSet.h" +#include "../datapoolglob/GlobalPoolVariable.h" #include "../objectmanager/ObjectManager.h" #include "../storagemanager/StorageManagerIF.h" #include "../thermal/ThermalComponentIF.h" -#include "../datapool/DataSet.h" -#include "../datapool/PoolVariable.h" #include "../globalfunctions/CRC.h" -#include "../subsystem/SubsystemBase.h" +#include "../housekeeping/HousekeepingMessage.h" +#include "../ipc/MessageQueueMessage.h" #include "../ipc/QueueFactory.h" -#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../subsystem/SubsystemBase.h" #include @@ -25,10 +27,11 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), deviceCommunicationId(deviceCommunication), comCookie(comCookie), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), - actionHelper(this, nullptr), childTransitionFailure(RETURN_OK), - fdirInstance(fdirInstance), hkSwitcher(this), - defaultFDIRUsed(fdirInstance == nullptr), switchOffWasReported(false), - childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), + actionHelper(this, nullptr), hkManager(this, nullptr), + childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), + hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), + switchOffWasReported(false), childTransitionDelay(5000), + transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); @@ -48,6 +51,10 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, } } +void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) { + this->hkDestination = hkDestination; +} + void DeviceHandlerBase::setThermalStateRequestPoolIds( uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) { this->deviceThermalRequestPoolId = thermalStatePoolId; @@ -74,6 +81,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { decrementDeviceReplyMap(); fdirInstance->checkForFailures(); hkSwitcher.performOperation(); + hkManager.performHkOperation(); performOperationHook(); } if (mode == MODE_OFF) { @@ -120,7 +128,9 @@ ReturnValue_t DeviceHandlerBase::initialize() { result = communicationInterface->initializeInterface(comCookie); if (result != RETURN_OK) { - return result; + sif::error << "DeviceHandlerBase::initialize: Initializing " + "communication interface failed!" << std::endl; + return result; } IPCStore = objectManager->get(objects::IPC_STORE); @@ -183,11 +193,16 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } + result = hkManager.initialize(commandQueue); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + fillCommandAndReplyMap(); //Set temperature target state to NON_OP. - DataSet mySet; - db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_WRITE); mySet.read(); thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; @@ -245,10 +260,10 @@ void DeviceHandlerBase::readCommandQueue() { return; } -// result = hkManager.handleHousekeepingMessage(&command); -// if (result == RETURN_OK) { -// return; -// } + result = hkManager.handleHousekeepingMessage(&command); + if (result == RETURN_OK) { + return; + } result = handleDeviceHandlerMessage(&command); if (result == RETURN_OK) { @@ -376,24 +391,28 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, - size_t replyLen, bool periodic, bool hasDifferentReplyId, - DeviceCommandId_t replyId) { + LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic, + bool hasDifferentReplyId, DeviceCommandId_t replyId) { //No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand); if (hasDifferentReplyId) { - return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic); + return insertInReplyMap(replyId, maxDelayCycles, + replyDataSet, replyLen, periodic); } else { - return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic); + return insertInReplyMap(deviceCommand, maxDelayCycles, + replyDataSet, replyLen, periodic); } } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, - uint16_t maxDelayCycles, size_t replyLen, bool periodic) { + uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet, + size_t replyLen, bool periodic) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; info.periodic = periodic; info.delayCycles = 0; info.replyLen = replyLen; + info.dataSet = dataSet; info.command = deviceCommandMap.end(); auto resultPair = deviceReplyMap.emplace(replyId, info); if (resultPair.second) { @@ -419,13 +438,12 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap( ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { - std::map::iterator iter = - deviceReplyMap.find(deviceReply); - if (iter == deviceReplyMap.end()) { + auto replyIter = deviceReplyMap.find(deviceReply); + if (replyIter == deviceReplyMap.end()) { triggerEvent(INVALID_DEVICE_COMMAND, deviceReply); return RETURN_FAILED; } else { - DeviceReplyInfo *info = &(iter->second); + DeviceReplyInfo *info = &(replyIter->second); if (maxDelayCycles != 0) { info->maxDelayCycles = maxDelayCycles; } @@ -435,6 +453,17 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep } } + +ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId, + LocalPoolDataSetBase *dataSet) { + auto replyIter = deviceReplyMap.find(replyId); + if(replyIter == deviceReplyMap.end()) { + return HasReturnvaluesIF::RETURN_FAILED; + } + replyIter->second.dataSet = dataSet; + return HasReturnvaluesIF::RETURN_OK; +} + void DeviceHandlerBase::callChildStatemachine() { if (mode == _MODE_START_UP) { doStartUp(); @@ -469,8 +498,8 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { Clock::getUptime(&timeoutStart); if (mode == MODE_OFF) { - DataSet mySet; - db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -649,7 +678,7 @@ void DeviceHandlerBase::doGetRead() { void DeviceHandlerBase::parseReply(const uint8_t* receivedData, size_t receivedDataLen) { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - DeviceCommandId_t foundId = 0xFFFFFFFF; + DeviceCommandId_t foundId = 0xffffffff; size_t foundLen = 0; // The loop may not execute more often than the number of received bytes // (worst case). This approach avoids infinite loops due to buggy @@ -661,18 +690,26 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData, switch (result) { case RETURN_OK: handleReply(receivedData, foundId, foundLen); + if(foundLen == 0) { + sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!" + " Packet parsing will be stuck." << std::endl; + } break; case APERIODIC_REPLY: { result = interpretDeviceReply(foundId, receivedData); if (result != RETURN_OK) { - replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, - foundId); + replyRawReplyIfnotWiretapped(receivedData, foundLen); + triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, + foundId); + } + if(foundLen == 0) { + sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!" + " Packet parsing will be stuck." << std::endl; } - } - break; - case IGNORE_REPLY_DATA: break; + } + case IGNORE_REPLY_DATA: + continue; case IGNORE_FULL_PACKET: return; default: @@ -704,16 +741,19 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceReplyInfo *info = &(iter->second); if (info->delayCycles != 0) { + result = interpretDeviceReply(foundId, receivedData); - if (info->periodic != false) { + if(result == IGNORE_REPLY_DATA) { + return; + } + + if (info->periodic) { info->delayCycles = info->maxDelayCycles; } else { info->delayCycles = 0; } - result = interpretDeviceReply(foundId, receivedData); - if (result != RETURN_OK) { // Report failed interpretation to FDIR. replyRawReplyIfnotWiretapped(receivedData, foundLen); @@ -926,10 +966,10 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, if ((commandedMode == MODE_ON) && (mode == MODE_OFF) && (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) { - DataSet mySet; - db_int8_t thermalState(deviceThermalStatePoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t thermalState(deviceThermalStatePoolId, &mySet, PoolVariableIF::VAR_READ); - db_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, + gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -956,8 +996,8 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, MODE_ON); triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); - DataSet mySet; - db_int8_t thermalRequest(deviceThermalRequestPoolId, + GlobDataSet mySet; + gp_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -1089,19 +1129,6 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( } replyReturnvalueToCommand(RETURN_OK); return RETURN_OK; -// case DeviceHandlerMessage::CMD_SWITCH_IOBOARD: -// if (mode != MODE_OFF) { -// replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND); -// } else { -// result = switchCookieChannel( -// DeviceHandlerMessage::getIoBoardObjectId(message)); -// if (result == RETURN_OK) { -// replyReturnvalueToCommand(RETURN_OK); -// } else { -// replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS); -// } -// } -// return RETURN_OK; case DeviceHandlerMessage::CMD_RAW: if ((mode != MODE_RAW)) { DeviceHandlerMessage::clear(message); @@ -1185,7 +1212,7 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, } //Try to cast to GlobDataSet and commit data. if (!neverInDataPool) { - DataSet* dataSet = dynamic_cast(data); + GlobDataSet* dataSet = dynamic_cast(data); if (dataSet != NULL) { dataSet->commit(PoolVariableIF::VALID); } @@ -1248,10 +1275,14 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { + //so we can track misconfigurations sif::debug << std::hex << getObjectId() << ": DHB::buildInternalCommand: Command " - << deviceCommandId << " isExecuting" << std::endl; //so we can track misconfigurations - return; //this is an internal command, no need to report a failure here, missed reply will track if a reply is too late, otherwise, it's ok + << deviceCommandId << " isExecuting" << std::dec + << std::endl; + // this is an internal command, no need to report a failure here, + // missed reply will track if a reply is too late, otherwise, it's ok + return; } else { iter->second.sendReplyTo = NO_COMMANDER; iter->second.isExecuting = true; @@ -1340,12 +1371,50 @@ void DeviceHandlerBase::debugInterface(uint8_t positionTracker, void DeviceHandlerBase::performOperationHook() { } +ReturnValue_t DeviceHandlerBase::initializeLocalDataPool( + LocalDataPool &localDataPoolMap, + LocalDataPoolManager& poolManager) { + return RETURN_OK; +} + +LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { + return &hkManager; +} + + ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { // In this function, the task handle should be valid if the task // was implemented correctly. We still check to be 1000 % sure :-) if(executingTask != nullptr) { pstIntervalMs = executingTask->getPeriodMs(); } + this->hkManager.initializeAfterTaskCreation(); + + if(setStartupImmediately) { + startTransition(MODE_ON, SUBMODE_NONE); + } return HasReturnvaluesIF::RETURN_OK; } +LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) { + auto iter = deviceReplyMap.find(sid.ownerSetId); + if(iter != deviceReplyMap.end()) { + return iter->second.dataSet; + } + else { + return nullptr; + } +} + +object_id_t DeviceHandlerBase::getObjectId() const { + return SystemObject::getObjectId(); +} + +void DeviceHandlerBase::setStartUpImmediately() { + this->setStartupImmediately = true; +} + +dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { + return pstIntervalMs; +} + diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 5666f35e..eda318cb 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,12 +1,11 @@ -#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ -#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ #include "DeviceHandlerIF.h" #include "DeviceCommunicationIF.h" #include "DeviceHandlerFailureIsolation.h" #include "../objectmanager/SystemObject.h" -#include "../tasks/PeriodicTaskIF.h" #include "../tasks/ExecutableObjectIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../action/HasActionsIF.h" @@ -14,10 +13,13 @@ #include "../modes/HasModesIF.h" #include "../power/PowerSwitchIF.h" #include "../ipc/MessageQueueIF.h" +#include "../tasks/PeriodicTaskIF.h" #include "../action/ActionHelper.h" #include "../health/HealthHelper.h" #include "../parameters/ParameterHelper.h" #include "../datapool/HkSwitchHelper.h" +#include "../datapoollocal/HasLocalDataPoolIF.h" +#include "../datapoollocal/LocalDataPoolManager.h" #include @@ -38,17 +40,16 @@ class StorageManagerIF; * Documentation: Dissertation Baetz p.138,139, p.141-149 * * It features handling of @link DeviceHandlerIF::Mode_t Modes @endlink, - * communication with physical devices, using the @link DeviceCommunicationIF @endlink, - * and communication with commanding objects. - * It inherits SystemObject and thus can be created by the ObjectManagerIF. + * communication with physical devices, using the + * @link DeviceCommunicationIF @endlink, and communication with commanding + * objects. It inherits SystemObject and thus can be created by the + * ObjectManagerIF. * - * This class uses the opcode of ExecutableObjectIF to perform a step-wise execution. - * For each step an RMAP action is selected and executed. - * If data has been received (GET_READ), the data will be interpreted. - * The action for each step can be defined by the child class but as most - * device handlers share a 4-call (sendRead-getRead-sendWrite-getWrite) structure, - * a default implementation is provided. - * NOTE: RMAP is a standard which is used for FLP. + * This class uses the opcode of ExecutableObjectIF to perform a + * step-wise execution. For each step a different action is selected and + * executed. Currently, the device handler base performs a 4-step + * execution related to 4 communication steps (based on RMAP). + * NOTE: RMAP is a standard which is used for Flying Laptop. * RMAP communication is not mandatory for projects implementing the FSFW. * However, the communication principles are similar to RMAP as there are * two write and two send calls involved. @@ -69,9 +70,6 @@ class StorageManagerIF; * * Other important virtual methods with a default implementation * are the getTransitionDelayMs() function and the getSwitches() function. - * Please ensure that getSwitches() returns DeviceHandlerIF::NO_SWITCHES if - * power switches are not implemented yet. Otherwise, the device handler will - * not transition to MODE_ON, even if setMode(MODE_ON) is called. * If a transition to MODE_ON is desired without commanding, override the * intialize() function and call setMode(_MODE_START_UP) before calling * DeviceHandlerBase::initialize(). @@ -85,20 +83,18 @@ class DeviceHandlerBase: public DeviceHandlerIF, public HasModesIF, public HasHealthIF, public HasActionsIF, - public ReceivesParameterMessagesIF { + public ReceivesParameterMessagesIF, + public HasLocalDataPoolIF { friend void (Factory::setStaticFrameworkObjectIds)(); public: /** * The constructor passes the objectId to the SystemObject(). * * @param setObjectId the ObjectId to pass to the SystemObject() Constructor - * @param maxDeviceReplyLen the length the RMAP getRead call will be sent with - * @param setDeviceSwitch the switch the device is connected to, - * for devices using two switches, overwrite getSwitches() * @param deviceCommuncation Communcation Interface object which is used * to implement communication functions - * @param thermalStatePoolId - * @param thermalRequestPoolId + * @param comCookie This object will be passed to the communication inter- + * face and can contain user-defined information about the communication. * @param fdirInstance * @param cmdQueueSize */ @@ -106,8 +102,21 @@ public: CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr, size_t cmdQueueSize = 20); + void setHkDestination(object_id_t hkDestination); void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId); + /** + * @brief Helper function to ease device handler development. + * This will instruct the transition to MODE_ON immediately + * (leading to doStartUp() being called for the transition to the ON mode), + * so external mode commanding is not necessary anymore. + * + * This has to be called before the task is started! + * (e.g. in the task factory). This is only a helper function for + * development. Regular mode commanding should be performed by commanding + * the AssemblyBase or Subsystem objects resposible for the device handler. + */ + void setStartUpImmediately(); /** * @brief This function is the device handler base core component and is @@ -153,6 +162,14 @@ public: * @return */ virtual ReturnValue_t initialize(); + + /** + * @brief Intialization steps performed after all tasks have been created. + * This function will be called by the executing task. + * @return + */ + virtual ReturnValue_t initializeAfterTaskCreation() override; + /** Destructor. */ virtual ~DeviceHandlerBase(); @@ -320,6 +337,8 @@ protected: * @param packet * @return * - @c RETURN_OK when the reply was interpreted. + * - @c IGNORE_REPLY_DATA Ignore the reply and don't reset reply cycle + * counter. * - @c RETURN_FAILED when the reply could not be interpreted, * e.g. logical errors or range violations occurred */ @@ -347,22 +366,10 @@ protected: * set to the maximum expected number of PST cycles between two replies * (also a tolerance should be added, as an FDIR message will be * generated if it is missed). - * - * (Robin) This part confuses me. "must do as soon as" implies that - * the developer must do something somewhere else in the code. Is - * that really the case? If I understood correctly, DHB performs - * almost everything (e.g. in erirm function) as long as the commands - * are inserted correctly. - * - * As soon as the replies are enabled, DeviceCommandInfo.periodic must - * be set to true, DeviceCommandInfo.delayCycles to - * DeviceCommandInfo.maxDelayCycles. * From then on, the base class handles the reception. * Then, scanForReply returns the id of the reply or the placeholder id * and the base class will take care of checking that all replies are * received and the interval is correct. - * When the replies are disabled, DeviceCommandInfo.periodic must be set - * to 0, DeviceCommandInfo.delayCycles to 0; * * - Aperiodic, unrequested replies. These are replies that are sent * by the device without any preceding command and not in a defined @@ -376,13 +383,17 @@ protected: * @param deviceCommand Identifier of the command to add. * @param maxDelayCycles The maximum number of delay cycles the command * waits until it times out. + * @param replyLen Will be supplied to the requestReceiveMessage call of + * the communication interface. * @param periodic Indicates if the command is periodic (i.e. it is sent * by the device repeatedly without request) or not. Default is aperiodic (0) * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false, + uint16_t maxDelayCycles, + LocalPoolDataSetBase* replyDataSet = nullptr, + size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); /** @@ -396,7 +407,8 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false); + uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, + size_t replyLen = 0, bool periodic = false); /** * @brief A simple command to add a command to the commandList. @@ -424,6 +436,9 @@ protected: uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic = false); + ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, + LocalPoolDataSetBase* dataset); + /** * @brief Can be implemented by child handler to * perform debugging @@ -477,18 +492,22 @@ protected: * @param localDataPoolMap * @return */ - //virtual ReturnValue_t initializePoolEntries( - // LocalDataPool& localDataPoolMap) override; + virtual ReturnValue_t initializeLocalDataPool(LocalDataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; /** Get the HK manager object handle */ - //virtual LocalDataPoolManager* getHkManagerHandle() override; + virtual LocalDataPoolManager* getHkManagerHandle() override; /** * @brief Hook function for child handlers which is called once per * performOperation(). Default implementation is empty. */ virtual void performOperationHook(); + public: + /** Explicit interface implementation of getObjectId */ + virtual object_id_t getObjectId() const override; + /** * @param parentQueueId */ @@ -608,7 +627,7 @@ protected: /** Action helper for HasActionsIF */ ActionHelper actionHelper; /** Housekeeping Manager */ - //LocalDataPoolManager hkManager; + LocalDataPoolManager hkManager; /** * @brief Information about commands @@ -647,7 +666,7 @@ protected: //! The dataset used to access housekeeping data related to the //! respective device reply. Will point to a dataset held by //! the child handler (if one is specified) - // DataSetIF* dataSet = nullptr; + LocalPoolDataSetBase* dataSet; //! The command that expects this reply. DeviceCommandMap::iterator command; }; @@ -689,14 +708,18 @@ protected: uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER; /** - * Optional Error code - * Can be set in doStartUp(), doShutDown() and doTransition() to signal cause for Transition failure. + * Optional Error code. Can be set in doStartUp(), doShutDown() and + * doTransition() to signal cause for Transition failure. */ ReturnValue_t childTransitionFailure; - uint32_t ignoreMissedRepliesCount = 0; //!< Counts if communication channel lost a reply, so some missed replys can be ignored. + /** Counts if communication channel lost a reply, so some missed + * replys can be ignored. */ + uint32_t ignoreMissedRepliesCount = 0; - FailureIsolationBase* fdirInstance; //!< Pointer to the used FDIR instance. If not provided by child, default class is instantiated. + /** Pointer to the used FDIR instance. If not provided by child, + * default class is instantiated. */ + FailureIsolationBase* fdirInstance; HkSwitchHelper hkSwitcher; @@ -944,14 +967,17 @@ protected: virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - virtual void startTransition(Mode_t mode, Submode_t submode); - virtual void setToExternalControl(); - virtual void announceMode(bool recursive); + + /* HasModesIF overrides */ + virtual void startTransition(Mode_t mode, Submode_t submode) override; + virtual void setToExternalControl() override; + virtual void announceMode(bool recursive) override; virtual ReturnValue_t letChildHandleMessage(CommandMessage *message); /** - * Overwrites SystemObject::triggerEvent in order to inform FDIR"Helper" faster about executed events. + * Overwrites SystemObject::triggerEvent in order to inform FDIR"Helper" + * faster about executed events. * This is a bit sneaky, but improves responsiveness of the device FDIR. * @param event The event to be thrown * @param parameter1 Optional parameter 1 @@ -1034,12 +1060,17 @@ private: /** the object used to set power switches */ PowerSwitchIF *powerSwitcher = nullptr; + /** HK destination can also be set individually */ + object_id_t hkDestination = objects::NO_OBJECT; + /** * @brief Used for timing out mode transitions. * Set when setMode() is called. */ uint32_t timeoutStart = 0; + bool setStartupImmediately = false; + /** * Delay for the current mode transition, used for time out */ @@ -1080,11 +1111,6 @@ private: void buildRawDeviceCommand(CommandMessage* message); void buildInternalCommand(void); -// /** -// * Send a reply with the current mode and submode. -// */ -// void announceMode(void); - /** * Decrement the counter for the timout of replies. * @@ -1111,10 +1137,14 @@ private: /** * Build and send a command to the device. * - * This routine checks whether a raw or direct command has been received, checks the content of the received command and - * calls buildCommandFromCommand() for direct commands or sets #rawpacket to the received raw packet. - * If no external command is received or the received command is invalid and the current mode is @c MODE_NORMAL or a transitional mode, - * it asks the child class to build a command (via getNormalDeviceCommand() or getTransitionalDeviceCommand() and buildCommand()) and + * This routine checks whether a raw or direct command has been received, + * checks the content of the received command and calls + * buildCommandFromCommand() for direct commands or sets #rawpacket + * to the received raw packet. + * If no external command is received or the received command is invalid and + * the current mode is @c MODE_NORMAL or a transitional mode, it asks the + * child class to build a command (via getNormalDeviceCommand() or + * getTransitionalDeviceCommand() and buildCommand()) and * sends the command via RMAP. */ void doSendWrite(void); @@ -1159,7 +1189,6 @@ private: ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, uint32_t *len); - /** * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!! */ @@ -1170,25 +1199,14 @@ private: */ void callChildStatemachine(); - /** - * Switches the channel of the cookie used for the communication - * - * - * @param newChannel the object Id of the channel to switch to - * @return - * - @c RETURN_OK when cookie was changed - * - @c RETURN_FAILED when cookies could not be changed, eg because the newChannel is not enabled - * - @c returnvalues of RMAPChannelIF::isActive() - */ - ReturnValue_t switchCookieChannel(object_id_t newChannelId); - ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); - virtual ReturnValue_t initializeAfterTaskCreation() override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; - void parseReply(const uint8_t* receivedData, - size_t receivedDataLen); + virtual dur_millis_t getPeriodicOperationFrequency() const override; + + void parseReply(const uint8_t* receivedData, + size_t receivedDataLen); }; -#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ - +#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ diff --git a/devicehandlers/DeviceHandlerFailureIsolation.cpp b/devicehandlers/DeviceHandlerFailureIsolation.cpp index 9fbe71d8..24fe15a0 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.cpp +++ b/devicehandlers/DeviceHandlerFailureIsolation.cpp @@ -247,6 +247,14 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty( } return true; } + + if (owner == nullptr) { + // Configuration error. + sif::error << "DeviceHandlerFailureIsolation::" + << "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl; + return false; + } + if (owner->getHealth() == HasHealthIF::FAULTY || owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) { //Ignore all events in case device is already faulty. diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index 52a3be4d..9c8eb098 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -1,12 +1,19 @@ -#ifndef DEVICEHANDLERIF_H_ -#define DEVICEHANDLERIF_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ +#define FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ + +#include "DeviceHandlerMessage.h" #include "../action/HasActionsIF.h" -#include "DeviceHandlerMessage.h" #include "../events/Event.h" #include "../modes/HasModesIF.h" #include "../ipc/MessageQueueSenderIF.h" +/** + * This is used to uniquely identify commands that are sent to a device + * The values are defined in the device-specific implementations + */ +using DeviceCommandId_t = uint32_t; + /** * @brief This is the Interface used to communicate with a device handler. * @details Includes all expected return values, events and modes. @@ -15,6 +22,7 @@ class DeviceHandlerIF { public: + static const uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20; static const uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10; @@ -47,6 +55,8 @@ public: //! This is a transitional state which can not be commanded. //! The device handler performs all actions and commands to get the device //! shut down. When the device is off, the mode changes to @c MODE_OFF. + //! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off + //! transition if available. static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; //! It is possible to set the mode to _MODE_TO_ON to use the to on //! transition if available. @@ -96,7 +106,7 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; // Standard codes used when building commands. - static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If the command size is 0. Checked in DHB + static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If no command data was given when expected. static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3); @@ -150,4 +160,4 @@ public: }; -#endif /* DEVICEHANDLERIF_H_ */ +#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ */ diff --git a/devicehandlers/DeviceHandlerMessage.cpp b/devicehandlers/DeviceHandlerMessage.cpp index 564fae21..cb9043db 100644 --- a/devicehandlers/DeviceHandlerMessage.cpp +++ b/devicehandlers/DeviceHandlerMessage.cpp @@ -1,10 +1,6 @@ -#include "../objectmanager/ObjectManagerIF.h" #include "DeviceHandlerMessage.h" #include "../objectmanager/ObjectManagerIF.h" -DeviceHandlerMessage::DeviceHandlerMessage() { -} - store_address_t DeviceHandlerMessage::getStoreAddress( const CommandMessage* message) { return store_address_t(message->getParameter2()); @@ -25,14 +21,6 @@ uint8_t DeviceHandlerMessage::getWiretappingMode( return message->getParameter(); } -//void DeviceHandlerMessage::setDeviceHandlerDirectCommandMessage( -// CommandMessage* message, DeviceCommandId_t deviceCommand, -// store_address_t commandParametersStoreId) { -// message->setCommand(CMD_DIRECT); -// message->setParameter(deviceCommand); -// message->setParameter2(commandParametersStoreId.raw); -//} - void DeviceHandlerMessage::setDeviceHandlerRawCommandMessage( CommandMessage* message, store_address_t rawPacketStoreId) { message->setCommand(CMD_RAW); @@ -47,7 +35,7 @@ void DeviceHandlerMessage::setDeviceHandlerWiretappingMessage( void DeviceHandlerMessage::setDeviceHandlerSwitchIoBoardMessage( CommandMessage* message, uint32_t ioBoardIdentifier) { - message->setCommand(CMD_SWITCH_IOBOARD); + message->setCommand(CMD_SWITCH_ADDRESS); message->setParameter(ioBoardIdentifier); } @@ -79,18 +67,17 @@ void DeviceHandlerMessage::setDeviceHandlerDirectCommandReply( void DeviceHandlerMessage::clear(CommandMessage* message) { switch (message->getCommand()) { case CMD_RAW: -// case CMD_DIRECT: case REPLY_RAW_COMMAND: case REPLY_RAW_REPLY: case REPLY_DIRECT_COMMAND_DATA: { StorageManagerIF *ipcStore = objectManager->get( objects::IPC_STORE); - if (ipcStore != NULL) { + if (ipcStore != nullptr) { ipcStore->deleteData(getStoreAddress(message)); } } /* NO BREAK falls through*/ - case CMD_SWITCH_IOBOARD: + case CMD_SWITCH_ADDRESS: case CMD_WIRETAPPING: message->setCommand(CommandMessage::CMD_NONE); message->setParameter(0); diff --git a/devicehandlers/DeviceHandlerMessage.h b/devicehandlers/DeviceHandlerMessage.h index 8d1c94f4..e5da01c8 100644 --- a/devicehandlers/DeviceHandlerMessage.h +++ b/devicehandlers/DeviceHandlerMessage.h @@ -1,69 +1,56 @@ -#ifndef DEVICEHANDLERMESSAGE_H_ -#define DEVICEHANDLERMESSAGE_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ +#define FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ #include "../action/ActionMessage.h" #include "../ipc/CommandMessage.h" #include "../objectmanager/SystemObjectIF.h" #include "../storagemanager/StorageManagerIF.h" -//SHOULDDO: rework the static constructors to name the type of command they are building, maybe even hide setting the commandID. +// SHOULDDO: rework the static constructors to name the type of command +// they are building, maybe even hide setting the commandID. + /** - * This is used to uniquely identify commands that are sent to a device - * - * The values are defined in the device-specific implementations - */ -typedef uint32_t DeviceCommandId_t; - -/** - * The DeviceHandlerMessage is used to send Commands to a DeviceHandlerIF + * @brief The DeviceHandlerMessage is used to send commands to classes + * implementing DeviceHandlerIF */ class DeviceHandlerMessage { -private: - DeviceHandlerMessage(); public: + /** + * Instantiation forbidden. Instead, use static functions to operate + * on messages. + */ + DeviceHandlerMessage() = delete; + virtual ~DeviceHandlerMessage() {} /** * These are the commands that can be sent to a DeviceHandlerBase */ static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND; - static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send -// static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command - static const Command_t CMD_SWITCH_IOBOARD = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier - static const Command_t CMD_WIRETAPPING = MAKE_COMMAND_ID( 4 ); //!< (De)Activates the monitoring of all raw traffic in DeviceHandlers, setParameter is 0 to deactivate, 1 to activate + //! Sends a raw command, setParameter is a storeId containing the + //! raw packet to send + static const Command_t CMD_RAW = MAKE_COMMAND_ID(1); + //! Requests a IO-Board switch, setParameter() is the IO-Board identifier + static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID(3); + //! (De)Activates the monitoring of all raw traffic in DeviceHandlers, + //! setParameter is 0 to deactivate, 1 to activate + static const Command_t CMD_WIRETAPPING = MAKE_COMMAND_ID(4); - /*static const Command_t REPLY_SWITCHED_IOBOARD = MAKE_COMMAND_ID(1 );//!< Reply to a @c CMD_SWITCH_IOBOARD, indicates switch was successful, getParameter() contains the board switched to (0: nominal, 1: redundant) - static const Command_t REPLY_CANT_SWITCH_IOBOARD = MAKE_COMMAND_ID( 2); //!< Reply to a @c CMD_SWITCH_IOBOARD, indicating the switch could not be performed, getParameter() contains the error message - static const Command_t REPLY_WIRETAPPING = MAKE_COMMAND_ID( 3); //!< Reply to a @c CMD_WIRETAPPING, getParameter() is the current state, 1 enabled, 0 disabled - - static const Command_t REPLY_COMMAND_WAS_SENT = MAKE_COMMAND_ID(4 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates the command was successfully sent to the device, getParameter() contains the ::DeviceCommandId_t - static const Command_t REPLY_COMMAND_NOT_SUPPORTED = MAKE_COMMAND_ID(5 );//!< Reply to a @c CMD_DIRECT, the requested ::DeviceCommand_t is not supported, getParameter() contains the requested ::DeviceCommand_t, getParameter2() contains the ::DeviceCommandId_t - static const Command_t REPLY_COMMAND_WAS_NOT_SENT = MAKE_COMMAND_ID(6 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates the command was not sent, getParameter contains the RMAP Return code (@see rmap.h), getParameter2() contains the ::DeviceCommandId_t - - static const Command_t REPLY_COMMAND_ALREADY_SENT = MAKE_COMMAND_ID(7 );//!< Reply to a @c CMD_DIRECT, the requested ::DeviceCommand_t has already been sent to the device and not ye been answered - static const Command_t REPLY_WRONG_MODE_FOR_CMD = MAKE_COMMAND_ID(8 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates that the requested command can not be sent in the curent mode, getParameter() contains the DeviceHandlerCommand_t - static const Command_t REPLY_NO_DATA = MAKE_COMMAND_ID(9 ); //!< Reply to a CMD_RAW or @c CMD_DIRECT, indicates that the ::store_id_t was invalid, getParameter() contains the ::DeviceCommandId_t, getPrameter2() contains the error code - */ - static const Command_t REPLY_DIRECT_COMMAND_SENT = ActionMessage::STEP_SUCCESS; //!< Signals that a direct command was sent - static const Command_t REPLY_RAW_COMMAND = MAKE_COMMAND_ID(0x11 ); //!< Contains a raw command sent to the Device - static const Command_t REPLY_RAW_REPLY = MAKE_COMMAND_ID( 0x12); //!< Contains a raw reply from the Device, getParameter() is the ObjcetId of the sender, getParameter2() is a ::store_id_t containing the raw packet received + //! Signals that a direct command was sent + static const Command_t REPLY_DIRECT_COMMAND_SENT = ActionMessage::STEP_SUCCESS; + //! Contains a raw command sent to the Device + static const Command_t REPLY_RAW_COMMAND = MAKE_COMMAND_ID(0x11); + //! Contains a raw reply from the Device, getParameter() is the ObjcetId + //! of the sender, getParameter2() is a ::store_id_t containing the + //! raw packet received + static const Command_t REPLY_RAW_REPLY = MAKE_COMMAND_ID(0x12); static const Command_t REPLY_DIRECT_COMMAND_DATA = ActionMessage::DATA_REPLY; - /** - * Default Destructor - */ - virtual ~DeviceHandlerMessage() { - } - static store_address_t getStoreAddress(const CommandMessage* message); static uint32_t getDeviceCommandId(const CommandMessage* message); static object_id_t getDeviceObjectId(const CommandMessage *message); static object_id_t getIoBoardObjectId(const CommandMessage* message); static uint8_t getWiretappingMode(const CommandMessage* message); -// static void setDeviceHandlerDirectCommandMessage(CommandMessage* message, -// DeviceCommandId_t deviceCommand, -// store_address_t commandParametersStoreId); - static void setDeviceHandlerDirectCommandReply(CommandMessage* message, object_id_t deviceObjectid, store_address_t commandParametersStoreId); @@ -75,11 +62,6 @@ public: object_id_t deviceObjectid, store_address_t rawPacketStoreId, bool isCommand); -// static void setDeviceHandlerMessage(CommandMessage* message, -// Command_t command, DeviceCommandId_t deviceCommand, -// store_address_t commandParametersStoreId); -// static void setDeviceHandlerMessage(CommandMessage* message, -// Command_t command, store_address_t rawPacketStoreId); static void setDeviceHandlerWiretappingMessage(CommandMessage* message, uint8_t wiretappingMode); static void setDeviceHandlerSwitchIoBoardMessage(CommandMessage* message, @@ -88,4 +70,4 @@ public: static void clear(CommandMessage* message); }; -#endif /* DEVICEHANDLERMESSAGE_H_ */ +#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ */ diff --git a/devicehandlers/DeviceTmReportingWrapper.cpp b/devicehandlers/DeviceTmReportingWrapper.cpp index 84f926f0..c70f57d6 100644 --- a/devicehandlers/DeviceTmReportingWrapper.cpp +++ b/devicehandlers/DeviceTmReportingWrapper.cpp @@ -1,4 +1,3 @@ -#include "../serialize/SerializeAdapter.h" #include "DeviceTmReportingWrapper.h" #include "../serialize/SerializeAdapter.h" diff --git a/devicehandlers/DeviceTmReportingWrapper.h b/devicehandlers/DeviceTmReportingWrapper.h index a14c4261..447e95f2 100644 --- a/devicehandlers/DeviceTmReportingWrapper.h +++ b/devicehandlers/DeviceTmReportingWrapper.h @@ -1,5 +1,5 @@ -#ifndef DEVICETMREPORTINGWRAPPER_H_ -#define DEVICETMREPORTINGWRAPPER_H_ +#ifndef FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_ +#define FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_ #include "../action/HasActionsIF.h" #include "../objectmanager/SystemObjectIF.h" @@ -24,4 +24,4 @@ private: SerializeIF *data; }; -#endif /* DEVICETMREPORTINGWRAPPER_H_ */ +#endif /* FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_ */ diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index b15e5d2b..418ed257 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -13,10 +13,10 @@ HealthDevice::~HealthDevice() { } ReturnValue_t HealthDevice::performOperation(uint8_t opCode) { - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + CommandMessage command; + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - healthHelper.handleHealthCommand(&message); + healthHelper.handleHealthCommand(&command); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/devicehandlers/HealthDevice.h b/devicehandlers/HealthDevice.h index 53b0ab09..738f0c7e 100644 --- a/devicehandlers/HealthDevice.h +++ b/devicehandlers/HealthDevice.h @@ -1,5 +1,5 @@ -#ifndef HEALTHDEVICE_H_ -#define HEALTHDEVICE_H_ +#ifndef FSFW_DEVICEHANDLERS_HEALTHDEVICE_H_ +#define FSFW_DEVICEHANDLERS_HEALTHDEVICE_H_ #include "../health/HasHealthIF.h" #include "../health/HealthHelper.h" @@ -37,4 +37,4 @@ public: HealthHelper healthHelper; }; -#endif /* HEALTHDEVICE_H_ */ +#endif /* FSFW_DEVICEHANDLERS_HEALTHDEVICE_H_ */ From dbcd06527ef728c2620c4141eab58bbf40994339 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 12 Oct 2020 18:28:07 +0200 Subject: [PATCH 2/4] separate step for performOp now --- devicehandlers/DeviceHandlerBase.cpp | 39 ++++++++++++++++++---------- devicehandlers/DeviceHandlerBase.h | 3 ++- devicehandlers/DeviceHandlerIF.h | 3 ++- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 227d5b6d..d67e47d8 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -72,8 +72,13 @@ DeviceHandlerBase::~DeviceHandlerBase() { ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { this->pstStep = counter; + this->lastStep = this->pstStep; - if (getComAction() == SEND_WRITE) { + if (getComAction() == CommunicationAction::NOTHING) { + return HasReturnvaluesIF::RETURN_OK; + } + + if (getComAction() == CommunicationAction::PERFORM_OPERATION) { cookieInfo.state = COOKIE_UNUSED; readCommandQueue(); doStateMachine(); @@ -83,26 +88,29 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { hkSwitcher.performOperation(); hkManager.performHkOperation(); performOperationHook(); + return RETURN_OK; } + if (mode == MODE_OFF) { return RETURN_OK; } + switch (getComAction()) { - case SEND_WRITE: - if ((cookieInfo.state == COOKIE_UNUSED)) { + case CommunicationAction::SEND_WRITE: + if (cookieInfo.state == COOKIE_UNUSED) { + // if no external command was specified, build internal command. buildInternalCommand(); } doSendWrite(); break; - case GET_WRITE: + case CommunicationAction::GET_WRITE: doGetWrite(); break; - case SEND_READ: + case CommunicationAction::SEND_READ: doSendRead(); break; - case GET_READ: + case CommunicationAction::GET_READ: doGetRead(); - cookieInfo.state = COOKIE_UNUSED; break; default: break; @@ -821,24 +829,27 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, } //Default child implementations -DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() { +DeviceHandlerIF::CommunicationAction DeviceHandlerBase::getComAction() { switch (pstStep) { case 0: - return SEND_WRITE; + return CommunicationAction::PERFORM_OPERATION; break; case 1: - return GET_WRITE; - break; + return CommunicationAction::SEND_WRITE; + break; case 2: - return SEND_READ; + return CommunicationAction::GET_WRITE; break; case 3: - return GET_READ; + return CommunicationAction::SEND_READ; + break; + case 4: + return CommunicationAction::GET_READ; break; default: break; } - return NOTHING; + return CommunicationAction::NOTHING; } MessageQueueId_t DeviceHandlerBase::getCommandQueue() const { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index eda318cb..627a6423 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -577,6 +577,7 @@ protected: /** This is the counter value from performOperation(). */ uint8_t pstStep = 0; + uint8_t lastStep = 0; uint32_t pstIntervalMs = 0; /** @@ -841,7 +842,7 @@ protected: * @return The Rmap action to execute in this step */ - virtual CommunicationAction_t getComAction(); + virtual CommunicationAction getComAction(); /** * Build the device command to send for raw mode. diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index 9c8eb098..088c1b45 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -139,7 +139,8 @@ public: * * This is used by the child class to tell the base class what to do. */ - enum CommunicationAction_t: uint8_t { + enum CommunicationAction: uint8_t { + PERFORM_OPERATION, SEND_WRITE,//!< Send write GET_WRITE, //!< Get write SEND_READ, //!< Send read From c9bfc0bbfd87797d75b6d1049e066e649e1714dd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 15:22:18 +0100 Subject: [PATCH 3/4] change log update --- CHANGELOG | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 4937b5f8..c0c826a7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,3 +5,8 @@ - vRequestContextSwitchFromISR is declared extern "C" so it can be defined in a C file without issues + +### Device Handler Base + +- There is an additional `PERFORM_OPERATION` step for the device handler base. It is important +that DHB users adapt their polling sequence tables to perform this step. This steps allows for aclear distinction between operation and communication steps From ec3c83bcc1e9cbf587b4602fa3d65d9f797c781e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 18:24:51 +0100 Subject: [PATCH 4/4] monitoring update --- monitoring/AbsLimitMonitor.h | 28 +++++++----- monitoring/HasMonitorsIF.h | 12 ++--- monitoring/LimitMonitor.h | 27 ++++++----- monitoring/MonitorBase.h | 64 +++++++++++++++++---------- monitoring/MonitorReporter.h | 37 +++++++++------- monitoring/MonitoringIF.h | 8 ++-- monitoring/MonitoringMessageContent.h | 37 ++++++++++------ monitoring/TriplexMonitor.h | 2 +- 8 files changed, 127 insertions(+), 88 deletions(-) diff --git a/monitoring/AbsLimitMonitor.h b/monitoring/AbsLimitMonitor.h index 2e60f6f8..5feb369c 100644 --- a/monitoring/AbsLimitMonitor.h +++ b/monitoring/AbsLimitMonitor.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ -#define FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ +#ifndef FSFW_MONITORING_ABSLIMITMONITOR_H_ +#define FSFW_MONITORING_ABSLIMITMONITOR_H_ #include "MonitorBase.h" #include @@ -7,9 +7,14 @@ template class AbsLimitMonitor: public MonitorBase { public: - AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, uint32_t parameterId, - uint16_t confirmationLimit, T limit, Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE, bool aboveIsViolation = true) : - MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), limit(limit), violationEvent(violationEvent), aboveIsViolation(aboveIsViolation) { + AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, + gp_id_t globalPoolId, uint16_t confirmationLimit, T limit, + Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE, + bool aboveIsViolation = true) : + MonitorBase(reporterId, monitorId, globalPoolId, + confirmationLimit), + limit(limit), violationEvent(violationEvent), + aboveIsViolation(aboveIsViolation) { } virtual ~AbsLimitMonitor() { } @@ -32,8 +37,9 @@ public: const ParameterWrapper *newValues, uint16_t startAtIndex) { ReturnValue_t result = this->MonitorBase::getParameter(domainId, parameterId, parameterWrapper, newValues, startAtIndex); - //We'll reuse the DOMAIN_ID of MonitorReporter, as we know the parameterIds used there. - if (result != this->INVALID_MATRIX_ID) { + // We'll reuse the DOMAIN_ID of MonitorReporter, + // as we know the parameterIds used there. + if (result != this->INVALID_IDENTIFIER_ID) { return result; } switch (parameterId) { @@ -41,7 +47,7 @@ public: parameterWrapper->set(this->limit); break; default: - return this->INVALID_MATRIX_ID; + return this->INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } @@ -59,7 +65,9 @@ protected: void sendTransitionEvent(T currentValue, ReturnValue_t state) { switch (state) { case MonitoringIF::OUT_OF_RANGE: - EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, + violationEvent, this->globalPoolId.objectId, + this->globalPoolId.localPoolId); break; default: break; @@ -70,4 +78,4 @@ protected: const bool aboveIsViolation; }; -#endif /* FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ */ +#endif /* FSFW_MONITORING_ABSLIMITMONITOR_H_ */ diff --git a/monitoring/HasMonitorsIF.h b/monitoring/HasMonitorsIF.h index 85d92b6b..04f63437 100644 --- a/monitoring/HasMonitorsIF.h +++ b/monitoring/HasMonitorsIF.h @@ -1,11 +1,5 @@ -/** - * @file HasMonitorsIF.h - * @brief This file defines the HasMonitorsIF class. - * @date 28.07.2014 - * @author baetz - */ -#ifndef HASMONITORSIF_H_ -#define HASMONITORSIF_H_ +#ifndef FSFW_MONITORING_HASMONITORSIF_H_ +#define FSFW_MONITORING_HASMONITORSIF_H_ #include "../events/EventReportingProxyIF.h" #include "../objectmanager/ObjectManagerIF.h" @@ -27,4 +21,4 @@ public: } }; -#endif /* HASMONITORSIF_H_ */ +#endif /* FSFW_MONITORING_HASMONITORSIF_H_ */ diff --git a/monitoring/LimitMonitor.h b/monitoring/LimitMonitor.h index 66e6725e..c4448ced 100644 --- a/monitoring/LimitMonitor.h +++ b/monitoring/LimitMonitor.h @@ -12,13 +12,15 @@ template class LimitMonitor: public MonitorBase { public: - LimitMonitor(object_id_t reporterId, uint8_t monitorId, uint32_t parameterId, - uint16_t confirmationLimit, T lowerLimit, T upperLimit, - Event belowLowEvent = MonitoringIF::VALUE_BELOW_LOW_LIMIT, + LimitMonitor(object_id_t reporterId, uint8_t monitorId, + gp_id_t globalPoolId, uint16_t confirmationLimit, T lowerLimit, + T upperLimit, Event belowLowEvent = + MonitoringIF::VALUE_BELOW_LOW_LIMIT, Event aboveHighEvent = MonitoringIF::VALUE_ABOVE_HIGH_LIMIT) : - MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), lowerLimit( - lowerLimit), upperLimit(upperLimit), belowLowEvent( - belowLowEvent), aboveHighEvent(aboveHighEvent) { + MonitorBase(reporterId, monitorId, globalPoolId, + confirmationLimit), + lowerLimit(lowerLimit), upperLimit(upperLimit), + belowLowEvent(belowLowEvent), aboveHighEvent(aboveHighEvent) { } virtual ~LimitMonitor() { } @@ -41,7 +43,7 @@ public: ReturnValue_t result = this->MonitorBase::getParameter(domainId, parameterId, parameterWrapper, newValues, startAtIndex); //We'll reuse the DOMAIN_ID of MonitorReporter, as we know the parameterIds used there. - if (result != this->INVALID_MATRIX_ID) { + if (result != this->INVALID_IDENTIFIER_ID) { return result; } switch (parameterId) { @@ -52,12 +54,13 @@ public: parameterWrapper->set(this->upperLimit); break; default: - return this->INVALID_MATRIX_ID; + return this->INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } bool isOutOfLimits() { - if (this->oldState == MonitoringIF::ABOVE_HIGH_LIMIT || this->oldState == MonitoringIF::BELOW_LOW_LIMIT) { + if (this->oldState == MonitoringIF::ABOVE_HIGH_LIMIT or + this->oldState == MonitoringIF::BELOW_LOW_LIMIT) { return true; } else { return false; @@ -76,10 +79,12 @@ protected: void sendTransitionEvent(T currentValue, ReturnValue_t state) { switch (state) { case MonitoringIF::BELOW_LOW_LIMIT: - EventManagerIF::triggerEvent(this->reportingId, belowLowEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, belowLowEvent, + this->globalPoolId.objectId, this->globalPoolId.localPoolId); break; case MonitoringIF::ABOVE_HIGH_LIMIT: - EventManagerIF::triggerEvent(this->reportingId, aboveHighEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, aboveHighEvent, + this->globalPoolId.objectId, this->globalPoolId.localPoolId); break; default: break; diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index b2d0e6cb..530a3840 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -1,39 +1,50 @@ -#ifndef MONITORBASE_H_ -#define MONITORBASE_H_ +#ifndef FSFW_MONITORING_MONITORBASE_H_ +#define FSFW_MONITORING_MONITORBASE_H_ -#include "../datapool/DataSet.h" -#include "../datapool/PIDReader.h" #include "LimitViolationReporter.h" #include "MonitoringIF.h" #include "MonitoringMessageContent.h" #include "MonitorReporter.h" +#include "../datapoollocal/LocalPoolVariable.h" + + /** - * Base class for monitoring of parameters. - * Can be used anywhere, specializations need to implement checkSample and should override sendTransitionEvent. - * Manages state handling, enabling and disabling of events/reports and forwarding of transition - * reports via MonitorReporter. In addition, it provides default implementations for fetching the parameter sample from - * the data pool and a simple confirmation counter. + * @brief Base class for monitoring of parameters. + * @details + * Can be used anywhere, specializations need to implement checkSample and + * should override sendTransitionEvent. + * Manages state handling, enabling and disabling of events/reports and + * forwarding of transition reports via MonitorReporter. + * + * In addition, it provides default implementations for fetching the + * parameter sample from the data pool and a simple confirmation counter. */ template class MonitorBase: public MonitorReporter { public: + MonitorBase(object_id_t reporterId, uint8_t monitorId, - uint32_t parameterId, uint16_t confirmationLimit) : - MonitorReporter(reporterId, monitorId, parameterId, confirmationLimit) { + gp_id_t globalPoolId, uint16_t confirmationLimit): + MonitorReporter(reporterId, monitorId, globalPoolId, + confirmationLimit), + poolVariable(globalPoolId) { } + virtual ~MonitorBase() { } + virtual ReturnValue_t check() { - //1. Fetch sample of type T, return validity. + // 1. Fetch sample of type T, return validity. T sample = 0; ReturnValue_t validity = fetchSample(&sample); - //2. If returning from fetch != OK, parameter is invalid. Report (if oldState is != invalidity). + // 2. If returning from fetch != OK, parameter is invalid. + // Report (if oldState is != invalidity). if (validity != HasReturnvaluesIF::RETURN_OK) { this->monitorStateIs(validity, sample, 0); - //3. Otherwise, check sample. } else { + //3. Otherwise, check sample. this->oldState = doCheck(sample); } return this->oldState; @@ -43,20 +54,25 @@ public: ReturnValue_t currentState = checkSample(sample, &crossedLimit); return this->monitorStateIs(currentState,sample, crossedLimit); } - //Abstract or default. + + // Abstract or default. virtual ReturnValue_t checkSample(T sample, T* crossedLimit) = 0; protected: + virtual ReturnValue_t fetchSample(T* sample) { - DataSet mySet; - PIDReader parameter(this->parameterId, &mySet); - mySet.read(); - if (!parameter.isValid()) { - return MonitoringIF::INVALID; - } - *sample = parameter.value; - return HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = poolVariable.read(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (not poolVariable.isValid()) { + return MonitoringIF::INVALID; + } + *sample = poolVariable.value; + return HasReturnvaluesIF::RETURN_OK; } + + LocalPoolVar poolVariable; }; -#endif /* MONITORBASE_H_ */ +#endif /* FSFW_MONITORING_MONITORBASE_H_ */ diff --git a/monitoring/MonitorReporter.h b/monitoring/MonitorReporter.h index ca2b534b..9028e7e4 100644 --- a/monitoring/MonitorReporter.h +++ b/monitoring/MonitorReporter.h @@ -1,10 +1,12 @@ -#ifndef FRAMEWORK_MONITORING_MONITORREPORTER_H_ -#define FRAMEWORK_MONITORING_MONITORREPORTER_H_ +#ifndef FSFW_MONITORING_MONITORREPORTER_H_ +#define FSFW_MONITORING_MONITORREPORTER_H_ -#include "../events/EventManagerIF.h" #include "LimitViolationReporter.h" #include "MonitoringIF.h" #include "MonitoringMessageContent.h" + +#include "../datapoollocal/locPoolDefinitions.h" +#include "../events/EventManagerIF.h" #include "../parameters/HasParametersIF.h" template @@ -14,11 +16,14 @@ public: static const uint8_t ENABLED = 1; static const uint8_t DISABLED = 0; - MonitorReporter(object_id_t reportingId, uint8_t monitorId, uint32_t parameterId, uint16_t confirmationLimit) : - monitorId(monitorId), parameterId(parameterId), reportingId( - reportingId), oldState(MonitoringIF::UNCHECKED), reportingEnabled( - ENABLED), eventEnabled(ENABLED), currentCounter(0), confirmationLimit( - confirmationLimit) { + // TODO: Adapt to use SID instead of parameter ID. + + MonitorReporter(object_id_t reportingId, uint8_t monitorId, + gp_id_t globalPoolId, uint16_t confirmationLimit) : + monitorId(monitorId), globalPoolId(globalPoolId), + reportingId(reportingId), oldState(MonitoringIF::UNCHECKED), + reportingEnabled(ENABLED), eventEnabled(ENABLED), currentCounter(0), + confirmationLimit(confirmationLimit) { } virtual ~MonitorReporter() { @@ -63,7 +68,7 @@ public: parameterWrapper->set(this->eventEnabled); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } @@ -91,7 +96,7 @@ public: protected: const uint8_t monitorId; - const uint32_t parameterId; + const gp_id_t globalPoolId; object_id_t reportingId; ReturnValue_t oldState; @@ -148,7 +153,8 @@ protected: case HasReturnvaluesIF::RETURN_OK: break; default: - EventManagerIF::triggerEvent(reportingId, MonitoringIF::MONITOR_CHANGED_STATE, state); + EventManagerIF::triggerEvent(reportingId, + MonitoringIF::MONITOR_CHANGED_STATE, state); break; } } @@ -159,14 +165,15 @@ protected: * @param crossedLimit The limit crossed (if applicable). * @param state Current state the monitor is in. */ - virtual void sendTransitionReport(T parameterValue, T crossedLimit, ReturnValue_t state) { - MonitoringReportContent report(parameterId, + virtual void sendTransitionReport(T parameterValue, T crossedLimit, + ReturnValue_t state) { + MonitoringReportContent report(globalPoolId, parameterValue, crossedLimit, oldState, state); LimitViolationReporter::sendLimitViolationReport(&report); } ReturnValue_t setToState(ReturnValue_t state) { if (oldState != state && reportingEnabled) { - MonitoringReportContent report(parameterId, 0, 0, oldState, + MonitoringReportContent report(globalPoolId, 0, 0, oldState, state); LimitViolationReporter::sendLimitViolationReport(&report); oldState = state; @@ -175,4 +182,4 @@ protected: } }; -#endif /* FRAMEWORK_MONITORING_MONITORREPORTER_H_ */ +#endif /* FSFW_MONITORING_MONITORREPORTER_H_ */ diff --git a/monitoring/MonitoringIF.h b/monitoring/MonitoringIF.h index 44218c36..aa266f33 100644 --- a/monitoring/MonitoringIF.h +++ b/monitoring/MonitoringIF.h @@ -1,8 +1,8 @@ -#ifndef MONITORINGIF_H_ -#define MONITORINGIF_H_ +#ifndef FSFW_MONITORING_MONITORINGIF_H_ +#define FSFW_MONITORING_MONITORINGIF_H_ -#include "../memory/HasMemoryIF.h" #include "MonitoringMessage.h" +#include "../memory/HasMemoryIF.h" #include "../serialize/SerializeIF.h" class MonitoringIF : public SerializeIF { @@ -64,4 +64,4 @@ public: -#endif /* MONITORINGIF_H_ */ +#endif /* FSFW_MONITORING_MONITORINGIF_H_ */ diff --git a/monitoring/MonitoringMessageContent.h b/monitoring/MonitoringMessageContent.h index c82506f3..44d32656 100644 --- a/monitoring/MonitoringMessageContent.h +++ b/monitoring/MonitoringMessageContent.h @@ -3,6 +3,7 @@ #include "HasMonitorsIF.h" #include "MonitoringIF.h" +#include "../datapoollocal/locPoolDefinitions.h" #include "../objectmanager/ObjectManagerIF.h" #include "../serialize/SerialBufferAdapter.h" #include "../serialize/SerialFixedArrayListAdapter.h" @@ -16,12 +17,17 @@ void setStaticFrameworkObjectIds(); } //PID(uint32_t), TYPE, LIMIT_ID, value,limitValue, previous, later, timestamp +/** + * @brief Does magic. + * @tparam T + */ template class MonitoringReportContent: public SerialLinkedListAdapter { friend void (Factory::setStaticFrameworkObjectIds)(); public: SerializeElement monitorId; - SerializeElement parameterId; + SerializeElement parameterObjectId; + SerializeElement localPoolId; SerializeElement parameterValue; SerializeElement limitValue; SerializeElement oldState; @@ -30,20 +36,23 @@ public: SerializeElement> timestampSerializer; TimeStamperIF* timeStamper; MonitoringReportContent() : - SerialLinkedListAdapter( - LinkedElement::Iterator(¶meterId)), monitorId(0), parameterId( - 0), parameterValue(0), limitValue(0), oldState(0), newState( - 0), rawTimestamp( { 0 }), timestampSerializer(rawTimestamp, + SerialLinkedListAdapter(¶meterObjectId), + monitorId(0), parameterObjectId(0), + localPoolId(0), parameterValue(0), + limitValue(0), oldState(0), newState(0), + rawTimestamp( { 0 }), timestampSerializer(rawTimestamp, sizeof(rawTimestamp)), timeStamper(NULL) { setAllNext(); } - MonitoringReportContent(uint32_t setPID, T value, T limitValue, + MonitoringReportContent(gp_id_t globalPoolId, T value, T limitValue, ReturnValue_t oldState, ReturnValue_t newState) : - SerialLinkedListAdapter( - LinkedElement::Iterator(¶meterId)), monitorId(0), parameterId( - setPID), parameterValue(value), limitValue(limitValue), oldState( - oldState), newState(newState), timestampSerializer(rawTimestamp, - sizeof(rawTimestamp)), timeStamper(NULL) { + SerialLinkedListAdapter(¶meterObjectId), + monitorId(0), parameterObjectId(globalPoolId.objectId), + localPoolId(globalPoolId.localPoolId), + parameterValue(value), limitValue(limitValue), + oldState(oldState), newState(newState), + timestampSerializer(rawTimestamp, sizeof(rawTimestamp)), + timeStamper(NULL) { setAllNext(); if (checkAndSetStamper()) { timeStamper->addTimeStamp(rawTimestamp, sizeof(rawTimestamp)); @@ -53,16 +62,16 @@ private: static object_id_t timeStamperId; void setAllNext() { - parameterId.setNext(¶meterValue); + parameterObjectId.setNext(¶meterValue); parameterValue.setNext(&limitValue); limitValue.setNext(&oldState); oldState.setNext(&newState); newState.setNext(×tampSerializer); } bool checkAndSetStamper() { - if (timeStamper == NULL) { + if (timeStamper == nullptr) { timeStamper = objectManager->get( timeStamperId ); - if ( timeStamper == NULL ) { + if ( timeStamper == nullptr ) { sif::error << "MonitoringReportContent::checkAndSetStamper: " "Stamper not found!" << std::endl; return false; diff --git a/monitoring/TriplexMonitor.h b/monitoring/TriplexMonitor.h index 9b60aeb6..c4b3c537 100644 --- a/monitoring/TriplexMonitor.h +++ b/monitoring/TriplexMonitor.h @@ -82,7 +82,7 @@ public: parameterWrapper->set(limit); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; }