diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..669283c7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.13) + +set(LIB_FSFW_NAME fsfw) +add_library(${LIB_FSFW_NAME}) + +# Set options for FSFW OSAL selection. +if(UNIX) +set(OS_FSFW "linux" CACHE STRING "OS abstraction layer used in the FSFW") +elseif(WIN32) +set(OS_FSFW "host" CACHE STRING "OS abstraction layer used in the FSFW") +endif() + +set_property(CACHE OS_FSFW PROPERTY STRINGS host linux rtems freertos) + +if(${OS_FSFW} STREQUAL host) +set(OS_FSFW_NAME "Host") +elseif(${OS_FSFW} STREQUAL linux) +set(OS_FSFW_NAME "Linux") +elseif(${OS_FSFW} STREQUAL freertos) +set(OS_FSFW_NAME "FreeRTOS") +elseif(${OS_FSFW} STREQUAL rtems) +set(OS_FSFW_NAME "RTEMS") +else() +message(WARNING "Invalid operating system for FSFW specified! Setting to host..") +set(OS_FSFW_NAME "Host") +set(OS_FSFW "host") +endif() + +message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system") + +# Options to exclude parts of the FSFW from compilation. +option(FSFW_USE_RMAP "Compile with RMAP" ON) +option(FSFW_USE_DATALINKLAYER "Compile with Data Link Layer" ON) + +add_subdirectory(action) +add_subdirectory(container) +add_subdirectory(controller) +add_subdirectory(coordinates) +add_subdirectory(datalinklayer) +add_subdirectory(datapool) +add_subdirectory(devicehandlers) +add_subdirectory(events) +add_subdirectory(fdir) +add_subdirectory(globalfunctions) +add_subdirectory(health) +add_subdirectory(internalError) +add_subdirectory(ipc) +add_subdirectory(memory) +add_subdirectory(modes) +add_subdirectory(monitoring) +add_subdirectory(objectmanager) +add_subdirectory(osal) +add_subdirectory(parameters) +add_subdirectory(power) +add_subdirectory(pus) + +if(FSFW_USE_RMAP) +add_subdirectory(rmap) +endif() + +add_subdirectory(serialize) +add_subdirectory(serviceinterface) +add_subdirectory(storagemanager) +add_subdirectory(subsystem) +add_subdirectory(tasks) +add_subdirectory(tcdistribution) +add_subdirectory(thermal) +add_subdirectory(timemanager) +add_subdirectory(tmstorage) +add_subdirectory(tmtcpacket) +add_subdirectory(tmtcservices) + +# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. +# If this is not given, we include the default configuration and emit a warning. +if(NOT FSFW_CONFIG_PATH) +message(WARNING "Flight Software Framework configuration path not set!") +message(WARNING "Setting default configuration!") +add_subdirectory(defaultcfg/fsfwconfig) +endif() + +# Required include paths to compile the FSFW +target_include_directories(${LIB_FSFW_NAME} + INTERFACE + ${FSFW_CONFIG_PATH} +) diff --git a/action/CMakeLists.txt b/action/CMakeLists.txt new file mode 100644 index 00000000..a62d4044 --- /dev/null +++ b/action/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ActionHelper.cpp + ActionMessage.cpp + CommandActionHelper.cpp + SimpleActionHelper.cpp +) \ No newline at end of file diff --git a/container/CMakeLists.txt b/container/CMakeLists.txt new file mode 100644 index 00000000..904cde55 --- /dev/null +++ b/container/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + SharedRingBuffer.cpp + SimpleRingBuffer.cpp +) \ No newline at end of file diff --git a/controller/CMakeLists.txt b/controller/CMakeLists.txt new file mode 100644 index 00000000..6f660738 --- /dev/null +++ b/controller/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ControllerBase.cpp +) \ No newline at end of file diff --git a/coordinates/CMakeLists.txt b/coordinates/CMakeLists.txt new file mode 100644 index 00000000..a1fa1e52 --- /dev/null +++ b/coordinates/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CoordinateTransformations.cpp + Sgp4Propagator.cpp +) \ No newline at end of file diff --git a/datalinklayer/CMakeLists.txt b/datalinklayer/CMakeLists.txt new file mode 100644 index 00000000..148e7c5d --- /dev/null +++ b/datalinklayer/CMakeLists.txt @@ -0,0 +1,12 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + Clcw.cpp + DataLinkLayer.cpp + Farm1StateLockout.cpp + Farm1StateOpen.cpp + Farm1StateWait.cpp + MapPacketExtraction.cpp + TcTransferFrame.cpp + TcTransferFrameLocal.cpp + VirtualChannelReception.cpp +) \ No newline at end of file diff --git a/datapool/CMakeLists.txt b/datapool/CMakeLists.txt new file mode 100644 index 00000000..e741f6a1 --- /dev/null +++ b/datapool/CMakeLists.txt @@ -0,0 +1,11 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ControllerSet.cpp + DataPool.cpp + DataPoolAdmin.cpp + DataPoolParameterWrapper.cpp + DataSet.cpp + HkSwitchHelper.cpp + PoolEntry.cpp + PoolRawAccess.cpp +) \ No newline at end of file diff --git a/defaultcfg/fsfwconfig/CMakeLists.txt b/defaultcfg/fsfwconfig/CMakeLists.txt new file mode 100644 index 00000000..b8b41c93 --- /dev/null +++ b/defaultcfg/fsfwconfig/CMakeLists.txt @@ -0,0 +1,15 @@ +target_sources(${TARGET_NAME} + PRIVATE +) + +# Add include paths for the executable +target_include_directories(${TARGET_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) + +# Add include paths for the FSFW library +target_include_directories(${LIB_FSFW_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) \ No newline at end of file diff --git a/devicehandlers/CMakeLists.txt b/devicehandlers/CMakeLists.txt new file mode 100644 index 00000000..50c1008f --- /dev/null +++ b/devicehandlers/CMakeLists.txt @@ -0,0 +1,11 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + AssemblyBase.cpp + ChildHandlerBase.cpp + ChildHandlerFDIR.cpp + DeviceHandlerBase.cpp + DeviceHandlerFailureIsolation.cpp + DeviceHandlerMessage.cpp + DeviceTmReportingWrapper.cpp + HealthDevice.cpp +) \ No newline at end of file diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index b5d43d77..f095834e 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -3,8 +3,6 @@ #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" @@ -13,9 +11,11 @@ #include "../ipc/MessageQueueMessage.h" #include "../ipc/QueueFactory.h" #include "../subsystem/SubsystemBase.h" +#include "../datapoollocal/LocalPoolVariable.h" #include + object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; @@ -56,9 +56,10 @@ void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) { } void DeviceHandlerBase::setThermalStateRequestPoolIds( - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) { - this->deviceThermalRequestPoolId = thermalStatePoolId; - this->deviceThermalRequestPoolId = thermalRequestPoolId; + lp_id_t thermalStatePoolId, lp_id_t heaterRequestPoolId, + uint32_t thermalSetId) { + thermalSet = new DeviceHandlerThermalSet(this, thermalSetId, + thermalStatePoolId, heaterRequestPoolId); } @@ -86,7 +87,6 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { decrementDeviceReplyMap(); fdirInstance->checkForFailures(); hkSwitcher.performOperation(); - hkManager.performHkOperation(); performOperationHook(); return RETURN_OK; } @@ -111,6 +111,9 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { break; case CommunicationAction::GET_READ: doGetRead(); + // This will be performed after datasets have been updated by the + // custom device implementation. + hkManager.performHkOperation(); break; default: break; @@ -208,16 +211,18 @@ ReturnValue_t DeviceHandlerBase::initialize() { fillCommandAndReplyMap(); - //Set temperature target state to NON_OP. - GlobDataSet mySet; - gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_WRITE); - mySet.read(); - thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; - mySet.commit(PoolVariableIF::VALID); + if(thermalSet != nullptr) { + //Set temperature target state to NON_OP. + result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + thermalSet->heaterRequest.value = + ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; + thermalSet->commit(PoolVariableIF::VALID); + } + + } return RETURN_OK; - } void DeviceHandlerBase::decrementDeviceReplyMap() { @@ -505,15 +510,17 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { } Clock::getUptime(&timeoutStart); - if (mode == MODE_OFF) { - GlobDataSet mySet; - gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - mySet.read(); - if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { - thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; + if (mode == MODE_OFF and thermalSet != nullptr) { + ReturnValue_t result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if (thermalSet->heaterRequest.value != + ThermalComponentIF::STATE_REQUEST_IGNORE) { + thermalSet->heaterRequest.value = ThermalComponentIF:: + STATE_REQUEST_NON_OPERATIONAL; + } + thermalSet->heaterRequest.commit(PoolVariableIF::VALID); } - mySet.commit(PoolVariableIF::VALID); + } changeHK(mode, submode, true); } @@ -976,17 +983,15 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, } if ((commandedMode == MODE_ON) && (mode == MODE_OFF) - && (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) { - GlobDataSet mySet; - gp_uint8_t thermalState(deviceThermalStatePoolId, &mySet, - PoolVariableIF::VAR_READ); - gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_READ); - mySet.read(); - if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { - if (!ThermalComponentIF::isOperational(thermalState)) { + and (thermalSet != nullptr)) { + ReturnValue_t result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if((thermalSet->heaterRequest.value != + ThermalComponentIF::STATE_REQUEST_IGNORE) and (not + ThermalComponentIF::isOperational( + thermalSet->thermalState.value))) { triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, - thermalState); + thermalSet->thermalState.value); return NON_OP_TEMPERATURE; } } @@ -999,32 +1004,15 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) { switch (commandedMode) { case MODE_ON: - if (mode == MODE_OFF) { - transitionSourceMode = _MODE_POWER_DOWN; - transitionSourceSubMode = SUBMODE_NONE; - setMode(_MODE_POWER_ON, commandedSubmode); - //already set the delay for the child transition so we don't need to call it twice - childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, - MODE_ON); - triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); - GlobDataSet mySet; - gp_int8_t thermalRequest(deviceThermalRequestPoolId, - &mySet, PoolVariableIF::VAR_READ_WRITE); - mySet.read(); - if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { - thermalRequest = ThermalComponentIF::STATE_REQUEST_OPERATIONAL; - mySet.commit(PoolVariableIF::VALID); - } - } else { - setTransition(MODE_ON, commandedSubmode); - } + handleTransitionToOnMode(commandedMode, commandedSubmode); break; case MODE_OFF: if (mode == MODE_OFF) { triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); setMode(_MODE_POWER_DOWN, commandedSubmode); } else { - //already set the delay for the child transition so we don't need to call it twice + // already set the delay for the child transition + // so we don't need to call it twice childTransitionDelay = getTransitionDelayMs(mode, _MODE_POWER_DOWN); transitionSourceMode = _MODE_POWER_DOWN; transitionSourceSubMode = commandedSubmode; @@ -1050,6 +1038,33 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, } } +void DeviceHandlerBase::handleTransitionToOnMode(Mode_t commandedMode, + Submode_t commandedSubmode) { + if (mode == MODE_OFF) { + transitionSourceMode = _MODE_POWER_DOWN; + transitionSourceSubMode = SUBMODE_NONE; + setMode(_MODE_POWER_ON, commandedSubmode); + // already set the delay for the child transition so we don't + // need to call it twice + childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, + MODE_ON); + triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); + if(thermalSet != nullptr) { + ReturnValue_t result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if(thermalSet->heaterRequest != + ThermalComponentIF::STATE_REQUEST_IGNORE) { + thermalSet->heaterRequest = + ThermalComponentIF::STATE_REQUEST_OPERATIONAL; + thermalSet->commit(); + } + } + } + } else { + setTransition(MODE_ON, commandedSubmode); + } +} + void DeviceHandlerBase::getMode(Mode_t* mode, Submode_t* submode) { *mode = this->mode; *submode = this->submode; @@ -1222,10 +1237,12 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, } } //Try to cast to GlobDataSet and commit data. - if (!neverInDataPool) { - GlobDataSet* dataSet = dynamic_cast(data); - if (dataSet != NULL) { - dataSet->commit(PoolVariableIF::VALID); + if (not neverInDataPool) { + LocalPoolDataSetBase* dataSet = + dynamic_cast(data); + if (dataSet != nullptr) { + dataSet->setValidity(true, true); + dataSet->commit(); } } } @@ -1262,7 +1279,8 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (result == BUSY) { //so we can track misconfigurations sif::debug << std::hex << getObjectId() - << ": DHB::buildInternalCommand: Busy" << std::dec << std::endl; + << ": DHB::buildInternalCommand: Busy" << std::dec + << std::endl; result = NOTHING_TO_SEND; //no need to report this } } @@ -1371,8 +1389,8 @@ bool DeviceHandlerBase::commandIsExecuting(DeviceCommandId_t commandId) { void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { } -void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ - executingTask = task_; +void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task){ + executingTask = task; } // Default implementations empty. @@ -1385,6 +1403,12 @@ void DeviceHandlerBase::performOperationHook() { ReturnValue_t DeviceHandlerBase::initializeLocalDataPool( LocalDataPool &localDataPoolMap, LocalDataPoolManager& poolManager) { + if(thermalSet != nullptr) { + localDataPoolMap.emplace(thermalSet->thermalStatePoolId, + new PoolEntry); + localDataPoolMap.emplace(thermalSet->heaterRequestPoolId, + new PoolEntry); + } return RETURN_OK; } @@ -1429,3 +1453,9 @@ dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { return pstIntervalMs; } +DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const { + if(cookieInfo.pendingCommand != deviceCommandMap.end()) { + return cookieInfo.pendingCommand->first; + } + return DeviceHandlerIF::NO_COMMAND; +} diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 627a6423..9a5287e0 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -4,6 +4,7 @@ #include "DeviceHandlerIF.h" #include "DeviceCommunicationIF.h" #include "DeviceHandlerFailureIsolation.h" +#include "DeviceHandlerThermalSet.h" #include "../objectmanager/SystemObject.h" #include "../tasks/ExecutableObjectIF.h" @@ -103,8 +104,21 @@ public: size_t cmdQueueSize = 20); void setHkDestination(object_id_t hkDestination); - void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId); + + /** + * If the device handler is controlled by the FSFW thermal building blocks, + * this function should be called to initialize all required components. + * The device handler will then take care of creating local pool entries + * for the device thermal state and device heating request. + * Custom local pool IDs can be assigned as well. + * @param thermalStatePoolId + * @param thermalRequestPoolId + */ + void setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId = + DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID, + lp_id_t thermalRequestPoolId = + DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID, + uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID); /** * @brief Helper function to ease device handler development. * This will instruct the transition to MODE_ON immediately @@ -694,19 +708,7 @@ protected: //! and to send replies. MessageQueueIF* commandQueue = nullptr; - /** - * this is the datapool variable with the thermal state of the device - * - * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking - */ - uint32_t deviceThermalStatePoolId = PoolVariableIF::NO_PARAMETER; - - /** - * this is the datapool variable with the thermal request of the device - * - * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking - */ - uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER; + DeviceHandlerThermalSet* thermalSet = nullptr; /** * Optional Error code. Can be set in doStartUp(), doShutDown() and @@ -732,15 +734,28 @@ protected: //! before setTaskIF was called. PeriodicTaskIF* executingTask = nullptr; - static object_id_t powerSwitcherId; //!< Object which switches power on and off. + //!< Object which switches power on and off. + static object_id_t powerSwitcherId; - static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default. + //!< Object which receives RAW data by default. + static object_id_t rawDataReceiverId; + + //!< Object which may be the root cause of an identified fault. + static object_id_t defaultFdirParentId; + + /** + * Helper function to get pending command. This is useful for devices + * like SPI sensors to identify the last sent command. + * This only returns the command sent in the last SEND_WRITE cycle. + * @return + */ + DeviceCommandId_t getPendingCommand() const; - static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault. /** * Helper function to report a missed reply * - * Can be overwritten by children to act on missed replies or to fake reporting Id. + * Can be overwritten by children to act on missed replies or to fake + * reporting Id. * * @param id of the missed reply */ @@ -847,15 +862,18 @@ protected: /** * Build the device command to send for raw mode. * - * This is only called in @c MODE_RAW. It is for the rare case that in raw mode packets - * are to be sent by the handler itself. It is NOT needed for the raw commanding service. - * Its only current use is in the STR handler which gets its raw packets from a different - * source. - * Also it can be used for transitional commands, to get the device ready for @c MODE_RAW + * This is only called in @c MODE_RAW. It is for the rare case that in + * raw mode packets are to be sent by the handler itself. It is NOT needed + * for the raw commanding service. Its only current use is in the STR + * handler which gets its raw packets from a different source. + * Also it can be used for transitional commands, to get the device ready + * for @c MODE_RAW * - * As it is almost never used, there is a default implementation returning @c NOTHING_TO_SEND. + * As it is almost never used, there is a default implementation + * returning @c NOTHING_TO_SEND. * - * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. + * #rawPacket and #rawPacketLen must be set by this method to the packet + * to be sent. * * @param[out] id the device command id built * @return @@ -868,7 +886,9 @@ protected: * Returns the delay cycle count of a reply. * A count != 0 indicates that the command is already executed. * @param deviceCommand The command to look for - * @return The current delay count. If the command does not exist (should never happen) it returns 0. + * @return + * The current delay count. If the command does not exist (should never + * happen) it returns 0. */ uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); @@ -878,20 +898,22 @@ protected: * It gets space in the #IPCStore, copies data there, then sends a raw reply * containing the store address. * - * This method is virtual, as the STR has a different channel to send raw replies - * and overwrites it accordingly. + * This method is virtual, as the STR has a different channel to send + * raw replies and overwrites it accordingly. * * @param data data to send * @param len length of @c data * @param sendTo the messageQueueId of the one to send to - * @param isCommand marks the raw data as a command, the message then will be of type raw_command + * @param isCommand marks the raw data as a command, the message then + * will be of type raw_command */ virtual void replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand = false); /** - * Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping is active and if so, - * does not send the Data as the wiretapping will have sent it already + * Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping + * is active and if so, does not send the data as the wiretapping will have + * sent it already */ void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len); @@ -903,17 +925,19 @@ protected: /** * Enable the reply checking for a command * - * Is only called, if the command was sent (ie the getWriteReply was successful). - * Must ensure that all replies are activated and correctly linked to the command that initiated it. - * The default implementation looks for a reply with the same id as the command id in the replyMap or - * uses the alternativeReplyId if flagged so. - * When found, copies maxDelayCycles to delayCycles in the reply information and sets the command to - * expect one reply. + * Is only called, if the command was sent (i.e. the getWriteReply was + * successful). Must ensure that all replies are activated and correctly + * linked to the command that initiated it. + * The default implementation looks for a reply with the same id as the + * command id in the replyMap or uses the alternativeReplyId if flagged so. + * When found, copies maxDelayCycles to delayCycles in the reply information + * and sets the command to expect one reply. * * Can be overwritten by the child, if a command activates multiple replies * or replyId differs from commandId. * Notes for child implementations: - * - If the command was not found in the reply map, NO_REPLY_EXPECTED MUST be returned. + * - If the command was not found in the reply map, + * NO_REPLY_EXPECTED MUST be returned. * - A failure code may be returned if something went fundamentally wrong. * * @param deviceCommand @@ -929,17 +953,20 @@ protected: * get the state of the PCDU switches in the datapool * * @return - * - @c PowerSwitchIF::SWITCH_ON if all switches specified by #switches are on - * - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by #switches are off - * - @c PowerSwitchIF::RETURN_FAILED if an error occured + * - @c PowerSwitchIF::SWITCH_ON if all switches specified + * by #switches are on + * - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by + * #switches are off + * - @c PowerSwitchIF::RETURN_FAILED if an error occured */ ReturnValue_t getStateOfSwitches(void); /** - * set all datapool variables that are update periodically in normal mode invalid - * - * Child classes should provide an implementation which sets all those variables invalid - * which are set periodically during any normal mode. + * @brief Set all datapool variables that are update periodically in + * normal mode invalid + * @details TODO: Use local pools + * Child classes should provide an implementation which sets all those + * variables invalid which are set periodically during any normal mode. */ virtual void setNormalDatapoolEntriesInvalid() = 0; @@ -949,11 +976,12 @@ protected: virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); /** - * Children can overwrite this function to suppress checking of the command Queue + * Children can overwrite this function to suppress checking of the + * command Queue * - * This can be used when the child does not want to receive a command in a certain - * situation. Care must be taken that checking is not permanentely disabled as this - * would render the handler unusable. + * This can be used when the child does not want to receive a command in + * a certain situation. Care must be taken that checking is not + * permanentely disabled as this would render the handler unusable. * * @return whether checking the queue should NOT be done */ @@ -992,17 +1020,20 @@ protected: virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const; /** - * Checks state of switches in conjunction with mode and triggers an event if they don't fit. + * Checks state of switches in conjunction with mode and triggers an event + * if they don't fit. */ virtual void checkSwitchState(); /** - * Reserved for the rare case where a device needs to perform additional operation cyclically in OFF mode. + * Reserved for the rare case where a device needs to perform additional + * operation cyclically in OFF mode. */ virtual void doOffActivity(); /** - * Reserved for the rare case where a device needs to perform additional operation cyclically in ON mode. + * Reserved for the rare case where a device needs to perform additional + * operation cyclically in ON mode. */ virtual void doOnActivity(); @@ -1043,9 +1074,10 @@ private: /** * Information about a cookie. * - * This is stored in a map for each cookie, to not only track the state, but also information - * about the sent command. Tracking this information is needed as - * the state of a commandId (waiting for reply) is done when a RMAP write reply is received. + * This is stored in a map for each cookie, to not only track the state, + * but also information about the sent command. Tracking this information + * is needed as the state of a commandId (waiting for reply) is done when a + * write reply is received. */ struct CookieInfo { CookieState_t state; @@ -1102,10 +1134,14 @@ private: /** * Handle the device handler mode. * - * - checks whether commands are valid for the current mode, rejects them accordingly - * - checks whether commanded mode transitions are required and calls handleCommandedModeTransition() - * - does the necessary action for the current mode or calls doChildStateMachine in modes @c MODE_TO_ON and @c MODE_TO_OFF - * - actions that happen in transitions (eg setting a timeout) are handled in setMode() + * - checks whether commands are valid for the current mode, rejects + * them accordingly + * - checks whether commanded mode transitions are required and calls + * handleCommandedModeTransition() + * - does the necessary action for the current mode or calls + * doChildStateMachine in modes @c MODE_TO_ON and @c MODE_TO_OFF + * - actions that happen in transitions (e.g. setting a timeout) are + * handled in setMode() */ void doStateMachine(void); @@ -1115,16 +1151,17 @@ private: /** * Decrement the counter for the timout of replies. * - * This is called at the beginning of each cycle. It checks whether a reply has timed out (that means a reply was expected - * but not received). + * This is called at the beginning of each cycle. It checks whether a + * reply has timed out (that means a reply was expected but not received). */ void decrementDeviceReplyMap(void); /** * Convenience function to handle a reply. * - * Called after scanForReply() has found a packet. Checks if the found id is in the #deviceCommandMap, if so, - * calls interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) for further action. + * Called after scanForReply() has found a packet. Checks if the found ID + * is in the #deviceCommandMap, if so, calls + * #interpretDeviceReply for further action. * * It also resets the timeout counter for the command id. * @@ -1184,7 +1221,7 @@ private: * @param[out] len * @return * - @c RETURN_OK @c data is valid - * - @c RETURN_FAILED IPCStore is NULL + * - @c RETURN_FAILED IPCStore is nullptr * - the return value from the IPCStore if it was not @c RETURN_OK */ ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, @@ -1208,6 +1245,9 @@ private: void parseReply(const uint8_t* receivedData, size_t receivedDataLen); + + void handleTransitionToOnMode(Mode_t commandedMode, + Submode_t commandedSubmode); }; #endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ diff --git a/events/CMakeLists.txt b/events/CMakeLists.txt new file mode 100644 index 00000000..9e63deb8 --- /dev/null +++ b/events/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + Event.cpp + EventManager.cpp + EventMessage.cpp +) + +add_subdirectory(eventmatching) \ No newline at end of file diff --git a/events/eventmatching/CMakeLists.txt b/events/eventmatching/CMakeLists.txt new file mode 100644 index 00000000..81ff9ed8 --- /dev/null +++ b/events/eventmatching/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + EventIdRangeMatcher.cpp + EventMatchTree.cpp + ReporterRangeMatcher.cpp + SeverityRangeMatcher.cpp +) \ No newline at end of file diff --git a/fdir/CMakeLists.txt b/fdir/CMakeLists.txt new file mode 100644 index 00000000..f5ffbba8 --- /dev/null +++ b/fdir/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + EventCorrelation.cpp + FailureIsolationBase.cpp + FaultCounter.cpp +) \ No newline at end of file diff --git a/globalfunctions/CMakeLists.txt b/globalfunctions/CMakeLists.txt new file mode 100644 index 00000000..2b3dcf8e --- /dev/null +++ b/globalfunctions/CMakeLists.txt @@ -0,0 +1,12 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + arrayprinter.cpp + AsciiConverter.cpp + CRC.cpp + DleEncoder.cpp + PeriodicOperationDivider.cpp + timevalOperations.cpp + Type.cpp +) + +add_subdirectory(math) \ No newline at end of file diff --git a/globalfunctions/math/CMakeLists.txt b/globalfunctions/math/CMakeLists.txt new file mode 100644 index 00000000..a9c4ded7 --- /dev/null +++ b/globalfunctions/math/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + QuaternionOperations.cpp +) diff --git a/health/CMakeLists.txt b/health/CMakeLists.txt new file mode 100644 index 00000000..d5f3ccd3 --- /dev/null +++ b/health/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + HealthHelper.cpp + HealthMessage.cpp + HealthTable.cpp +) \ No newline at end of file diff --git a/internalError/CMakeLists.txt b/internalError/CMakeLists.txt new file mode 100644 index 00000000..2b383914 --- /dev/null +++ b/internalError/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + InternalErrorReporter.cpp +) \ No newline at end of file diff --git a/ipc/CMakeLists.txt b/ipc/CMakeLists.txt new file mode 100644 index 00000000..6a3afe33 --- /dev/null +++ b/ipc/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CommandMessage.cpp + CommandMessageCleaner.cpp + MessageQueueMessage.cpp +) \ No newline at end of file diff --git a/memory/CMakeLists.txt b/memory/CMakeLists.txt new file mode 100644 index 00000000..9edb9031 --- /dev/null +++ b/memory/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + MemoryHelper.cpp + MemoryMessage.cpp +) \ No newline at end of file diff --git a/modes/CMakeLists.txt b/modes/CMakeLists.txt new file mode 100644 index 00000000..8e5c719b --- /dev/null +++ b/modes/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ModeHelper.cpp + ModeMessage.cpp +) \ No newline at end of file diff --git a/monitoring/CMakeLists.txt b/monitoring/CMakeLists.txt new file mode 100644 index 00000000..d26e807c --- /dev/null +++ b/monitoring/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + LimitViolationReporter.cpp + MonitoringMessage.cpp +) \ No newline at end of file diff --git a/objectmanager/CMakeLists.txt b/objectmanager/CMakeLists.txt new file mode 100644 index 00000000..72aaec89 --- /dev/null +++ b/objectmanager/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ObjectManager.cpp + SystemObject.cpp +) \ No newline at end of file diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt new file mode 100644 index 00000000..02ff2405 --- /dev/null +++ b/osal/CMakeLists.txt @@ -0,0 +1,34 @@ +# Check the OS_FSFW variable +if(${OS_FSFW} STREQUAL "freertos") + add_subdirectory(FreeRTOS) +elseif(${OS_FSFW} STREQUAL "rtems") + add_subdirectory(rtems) +elseif(${OS_FSFW} STREQUAL "linux") + add_subdirectory(linux) +elseif(${OS_FSFW} STREQUAL "host") + add_subdirectory(host) + if (WIN32) + add_subdirectory(windows) + elseif(UNIX) + target_sources(${LIB_FSFW_NAME} + PUBLIC + linux/TcUnixUdpPollingTask.cpp + linux/TmTcUnixUdpBridge.cpp + ) + endif () + +else() + + message(WARNING "The OS_FSFW variable was not set. Assuming host OS..") + # Not set. Assumuing this is a host build, try to determine host OS + if (WIN32) + add_subdirectory(host) + add_subdirectory(windows) + elseif (UNIX) + add_subdirectory(linux) + else () + # MacOS or other OSes have not been tested yet / are not supported. + message(FATAL_ERROR "The host OS could not be determined! Aborting.") + endif() + +endif() \ No newline at end of file diff --git a/osal/host/CMakeLists.txt b/osal/host/CMakeLists.txt new file mode 100644 index 00000000..d73e6f27 --- /dev/null +++ b/osal/host/CMakeLists.txt @@ -0,0 +1,21 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + Clock.cpp + FixedTimeslotTask.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicTask.cpp + QueueFactory.cpp + QueueMapManager.cpp + SemaphoreFactory.cpp + TaskFactory.cpp +) + +if(UNIX) + add_definitions(-pthread) + target_link_libraries(${LIB_FSFW_NAME} + PRIVATE + rt + ) +endif() \ No newline at end of file diff --git a/osal/linux/CMakeLists.txt b/osal/linux/CMakeLists.txt new file mode 100644 index 00000000..c0096e42 --- /dev/null +++ b/osal/linux/CMakeLists.txt @@ -0,0 +1,25 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + Clock.cpp + BinarySemaphore.cpp + CountingSemaphore.cpp + FixedTimeslotTask.cpp + InternalErrorCodes.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicPosixTask.cpp + PosixThread.cpp + QueueFactory.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + TcUnixUdpPollingTask.cpp + TmTcUnixUdpBridge.cpp + Timer.cpp +) + +target_link_libraries(${LIB_FSFW_NAME} + PRIVATE + rt + pthread +) diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt new file mode 100644 index 00000000..b6e76d6a --- /dev/null +++ b/osal/windows/CMakeLists.txt @@ -0,0 +1,11 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + TcWinUdpPollingTask.cpp + TmTcWinUdpBridge.cpp +) + +target_link_libraries(${LIB_FSFW_NAME} + PRIVATE + wsock32 + ws2_32 +) \ No newline at end of file diff --git a/parameters/CMakeLists.txt b/parameters/CMakeLists.txt new file mode 100644 index 00000000..fb5e4590 --- /dev/null +++ b/parameters/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ParameterHelper.cpp + ParameterMessage.cpp + ParameterWrapper.cpp +) \ No newline at end of file diff --git a/power/CMakeLists.txt b/power/CMakeLists.txt new file mode 100644 index 00000000..1c625db1 --- /dev/null +++ b/power/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + Fuse.cpp + PowerComponent.cpp + PowerSensor.cpp + PowerSwitcher.cpp +) \ No newline at end of file diff --git a/pus/CMakeLists.txt b/pus/CMakeLists.txt new file mode 100644 index 00000000..758c2629 --- /dev/null +++ b/pus/CMakeLists.txt @@ -0,0 +1,11 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CService200ModeCommanding.cpp + CService201HealthCommanding.cpp + Service17Test.cpp + Service1TelecommandVerification.cpp + Service2DeviceAccess.cpp + Service5EventReporting.cpp + Service8FunctionManagement.cpp + Service9TimeManagement.cpp +) \ No newline at end of file diff --git a/rmap/CMakeLists.txt b/rmap/CMakeLists.txt new file mode 100644 index 00000000..78c99e42 --- /dev/null +++ b/rmap/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + RMAP.cpp + RMAPCookie.cpp + RmapDeviceCommunicationIF.cpp +) + diff --git a/serialize/CMakeLists.txt b/serialize/CMakeLists.txt new file mode 100644 index 00000000..fc2387e8 --- /dev/null +++ b/serialize/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + SerialBufferAdapter.cpp +) \ No newline at end of file diff --git a/serviceinterface/CMakeLists.txt b/serviceinterface/CMakeLists.txt new file mode 100644 index 00000000..d84adbeb --- /dev/null +++ b/serviceinterface/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ServiceInterfaceStream.cpp + ServiceInterfaceBuffer.cpp +) \ No newline at end of file diff --git a/storagemanager/CMakeLists.txt b/storagemanager/CMakeLists.txt new file mode 100644 index 00000000..57c92195 --- /dev/null +++ b/storagemanager/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ConstStorageAccessor.cpp + StorageAccessor.cpp +) \ No newline at end of file diff --git a/subsystem/CMakeLists.txt b/subsystem/CMakeLists.txt new file mode 100644 index 00000000..5c98ee70 --- /dev/null +++ b/subsystem/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + Subsystem.cpp + SubsystemBase.cpp +) + +add_subdirectory(modes) \ No newline at end of file diff --git a/subsystem/modes/CMakeLists.txt b/subsystem/modes/CMakeLists.txt new file mode 100644 index 00000000..6ac6a293 --- /dev/null +++ b/subsystem/modes/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + ModeSequenceMessage.cpp + ModeStore.cpp +) diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt new file mode 100644 index 00000000..1964bb4e --- /dev/null +++ b/tasks/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + FixedSequenceSlot.cpp + FixedSlotSequence.cpp +) \ No newline at end of file diff --git a/tcdistribution/CMakeLists.txt b/tcdistribution/CMakeLists.txt new file mode 100644 index 00000000..17dc186c --- /dev/null +++ b/tcdistribution/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CCSDSDistributor.cpp + PUSDistributor.cpp + TcDistributor.cpp + TcPacketCheck.cpp +) diff --git a/thermal/CMakeLists.txt b/thermal/CMakeLists.txt new file mode 100644 index 00000000..67664fbe --- /dev/null +++ b/thermal/CMakeLists.txt @@ -0,0 +1,10 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + AbstractTemperatureSensor.cpp + CoreComponent.cpp + Heater.cpp + RedundantHeater.cpp + ThermalComponent.cpp + ThermalModule.cpp + ThermalMonitor.cpp +) diff --git a/timemanager/CMakeLists.txt b/timemanager/CMakeLists.txt new file mode 100644 index 00000000..3367775f --- /dev/null +++ b/timemanager/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CCSDSTime.cpp + Countdown.cpp + Stopwatch.cpp + TimeMessage.cpp + TimeStamper.cpp +) diff --git a/tmstorage/CMakeLists.txt b/tmstorage/CMakeLists.txt new file mode 100644 index 00000000..7990d85a --- /dev/null +++ b/tmstorage/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + TmStoreMessage.cpp +) diff --git a/tmtcpacket/CMakeLists.txt b/tmtcpacket/CMakeLists.txt new file mode 100644 index 00000000..fe3d2a4d --- /dev/null +++ b/tmtcpacket/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + SpacePacket.cpp + SpacePacketBase.cpp +) + +add_subdirectory(packetmatcher) +add_subdirectory(pus) \ No newline at end of file diff --git a/tmtcpacket/packetmatcher/CMakeLists.txt b/tmtcpacket/packetmatcher/CMakeLists.txt new file mode 100644 index 00000000..e9a8d03b --- /dev/null +++ b/tmtcpacket/packetmatcher/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + PacketMatchTree.cpp +) diff --git a/tmtcpacket/pus/CMakeLists.txt b/tmtcpacket/pus/CMakeLists.txt new file mode 100644 index 00000000..fcfc82d2 --- /dev/null +++ b/tmtcpacket/pus/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + TcPacketBase.cpp + TcPacketStored.cpp + TmPacketBase.cpp + TmPacketMinimal.cpp + TmPacketStored.cpp +) diff --git a/tmtcservices/CMakeLists.txt b/tmtcservices/CMakeLists.txt new file mode 100644 index 00000000..c30af214 --- /dev/null +++ b/tmtcservices/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CommandingServiceBase.cpp + PusServiceBase.cpp + PusVerificationReport.cpp + TmTcBridge.cpp + TmTcMessage.cpp + VerificationReporter.cpp +) \ No newline at end of file