Merge pull request 'Custom FDIR for tmp devices' (#598) from tmp_dev_custom_fdir into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

Reviewed-on: #598
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
This commit is contained in:
Robin Müller 2023-04-14 18:55:55 +02:00
commit fc8a8ce5a9
23 changed files with 138 additions and 101 deletions

View File

@ -37,9 +37,8 @@ will consitute of a breaking change warranting a new major release:
## Changed ## Changed
- STR `wire` library updated to v10.3. Submodule renamed to `sagittactl`. - STR `wire` library updated to v10.3. Submodule renamed to `sagittactl`.
- Custom FDIR for TMP1075 sensors. The device handlers reject `NEEDS_RECOVERY` health commands
## Changed anyway, so it does not really make sense to use the default FDIR.
- Reject `NEEDS_RECOVERY` health commands for the heater health devices. - Reject `NEEDS_RECOVERY` health commands for the heater health devices.
## Added ## Added

View File

@ -27,8 +27,9 @@
#include <mission/system/acs/ImtqAssembly.h> #include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h> #include <mission/system/acs/StrAssembly.h>
#include <mission/system/acs/StrFdir.h> #include <mission/system/acs/StrFdir.h>
#include <mission/system/com/SyrlinksAssembly.h>
#include <mission/system/objects/CamSwitcher.h> #include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/SyrlinksAssembly.h> #include <mission/system/tcs/TmpDevFdir.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h" #include "bsp_q7s/boardtest/Q7STestTask.h"
@ -62,17 +63,15 @@
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/SyrlinksFdir.h" #include "mission/system/com/SyrlinksFdir.h"
#include "mission/system/com/comModeTree.h" #include "mission/system/com/comModeTree.h"
#include "mission/system/fdir/RtdFdir.h"
#include "mission/system/objects/TcsBoardAssembly.h"
#include "mission/system/power/GomspacePowerFdir.h" #include "mission/system/power/GomspacePowerFdir.h"
#include "mission/system/tcs/RtdFdir.h"
#include "mission/system/tcs/TcsBoardAssembly.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tmtc/tmFilters.h" #include "mission/tmtc/tmFilters.h"
#include "mission/utility/GlobalConfigHandler.h" #include "mission/utility/GlobalConfigHandler.h"
#include "tmtc/pusIds.h" #include "tmtc/pusIds.h"
using gpio::Direction;
using gpio::Levels;
#if OBSW_TEST_LIBGPIOD == 1 #if OBSW_TEST_LIBGPIOD == 1
#include "linux/boardtest/LibgpiodTest.h" #include "linux/boardtest/LibgpiodTest.h"
#endif #endif
@ -123,6 +122,9 @@ using gpio::Levels;
#include "mission/system/acs/AcsBoardAssembly.h" #include "mission/system/acs/AcsBoardAssembly.h"
#include "mission/tmtc/TmFunnelHandler.h" #include "mission/tmtc/TmFunnelHandler.h"
using gpio::Direction;
using gpio::Levels;
ResetArgs RESET_ARGS_GNSS; ResetArgs RESET_ARGS_GNSS;
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN; std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
std::atomic_bool PTME_LOCKED = false; std::atomic_bool PTME_LOCKED = false;
@ -164,6 +166,7 @@ void ObjectFactory::createTmpComponents() {
new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE)); new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE));
auto* tmpDevHandler = auto* tmpDevHandler =
new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]); new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]);
tmpDevHandler->setCustomFdir(new TmpDevFdir(tmpDevIds[idx].first));
tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
// TODO: Remove this after TCS subsystem was added // TODO: Remove this after TCS subsystem was added
// These devices are connected to the 3V3 stack and should be powered permanently. Therefore, // These devices are connected to the 3V3 stack and should be powered permanently. Therefore,

View File

@ -30,7 +30,7 @@
#include <mission/system/acs/ImtqAssembly.h> #include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h> #include <mission/system/acs/StrAssembly.h>
#include <mission/system/objects/CamSwitcher.h> #include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/TcsBoardAssembly.h> #include <mission/system/tcs/TcsBoardAssembly.h>
#include "TemperatureSensorInserter.h" #include "TemperatureSensorInserter.h"
#include "dummies/Max31865Dummy.h" #include "dummies/Max31865Dummy.h"
@ -38,8 +38,8 @@
#include "mission/genericFactory.h" #include "mission/genericFactory.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/comModeTree.h" #include "mission/system/com/comModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tcs/defs.h" #include "mission/tcs/defs.h"
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) { void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {

View File

@ -17,8 +17,8 @@
#include <mission/payload/ScexDeviceHandler.h> #include <mission/payload/ScexDeviceHandler.h>
#include <mission/system/acs/SusAssembly.h> #include <mission/system/acs/SusAssembly.h>
#include <mission/system/acs/SusFdir.h> #include <mission/system/acs/SusFdir.h>
#include <mission/system/fdir/RtdFdir.h> #include <mission/system/tcs/RtdFdir.h>
#include <mission/system/objects/TcsBoardAssembly.h> #include <mission/system/tcs/TcsBoardAssembly.h>
#include <mission/tcs/Max31865EiveHandler.h> #include <mission/tcs/Max31865EiveHandler.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"
@ -27,8 +27,8 @@
#include "devices/gpioIds.h" #include "devices/gpioIds.h"
#include "eive/definitions.h" #include "eive/definitions.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tcs/defs.h" #include "mission/tcs/defs.h"
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,

View File

@ -30,7 +30,7 @@
#include <mission/system/acs/AcsBoardAssembly.h> #include <mission/system/acs/AcsBoardAssembly.h>
#include <mission/system/acs/RwAssembly.h> #include <mission/system/acs/RwAssembly.h>
#include <mission/system/acs/SusAssembly.h> #include <mission/system/acs/SusAssembly.h>
#include <mission/system/objects/TcsBoardAssembly.h> #include <mission/system/tcs/TcsBoardAssembly.h>
#include <mission/tcs/HeaterHandler.h> #include <mission/tcs/HeaterHandler.h>
#include <mission/tmtc/CfdpTmFunnel.h> #include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PersistentTmStore.h> #include <mission/tmtc/PersistentTmStore.h>
@ -47,7 +47,7 @@
#include "mission/cfdp/Config.h" #include "mission/cfdp/Config.h"
#include "mission/system/acs/RwAssembly.h" #include "mission/system/acs/RwAssembly.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/tree/tcsModeTree.h" #include "mission/system/tcs/tcsModeTree.h"
#include "mission/tcs/defs.h" #include "mission/tcs/defs.h"
#include "mission/tmtc/tmFilters.h" #include "mission/tmtc/tmFilters.h"
#include "objects/systemObjectList.h" #include "objects/systemObjectList.h"

View File

@ -1,8 +1,8 @@
add_subdirectory(objects) add_subdirectory(objects)
add_subdirectory(tree) add_subdirectory(tree)
add_subdirectory(acs) add_subdirectory(acs)
add_subdirectory(tcs)
add_subdirectory(com) add_subdirectory(com)
add_subdirectory(fdir)
add_subdirectory(power) add_subdirectory(power)
target_sources( target_sources(

View File

@ -1 +0,0 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE RtdFdir.cpp)

View File

@ -1,4 +1,3 @@
target_sources( target_sources(
${LIB_EIVE_MISSION} ${LIB_EIVE_MISSION} PRIVATE CamSwitcher.cpp PayloadSubsystem.cpp
PRIVATE CamSwitcher.cpp TcsSubsystem.cpp PayloadSubsystem.cpp Stack5VHandler.cpp PowerStateMachineBase.cpp)
Stack5VHandler.cpp PowerStateMachineBase.cpp TcsBoardAssembly.cpp)

View File

@ -1,57 +0,0 @@
#include "SyrlinksAssembly.h"
#include <eive/objects.h>
using namespace returnvalue;
SyrlinksAssembly::SyrlinksAssembly(object_id_t objectId) : AssemblyBase(objectId) {
ModeListEntry entry;
entry.setObject(objects::SYRLINKS_HANDLER);
entry.setMode(MODE_OFF);
entry.setSubmode(SUBMODE_NONE);
commandTable.insert(entry);
}
ReturnValue_t SyrlinksAssembly::commandChildren(Mode_t mode, Submode_t submode) {
commandTable[0].setMode(mode);
commandTable[0].setSubmode(submode);
HybridIterator<ModeListEntry> iter(commandTable.begin(), commandTable.end());
if (recoveryState == RECOVERY_IDLE) {
ReturnValue_t result = checkAndHandleHealthState(mode, submode);
if (result == NEED_TO_CHANGE_HEALTH) {
return OK;
}
}
executeTable(iter);
return returnvalue::OK;
}
ReturnValue_t SyrlinksAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) {
if (childrenMap[objects::SYRLINKS_HANDLER].mode != wantedMode) {
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
}
return returnvalue::OK;
}
ReturnValue_t SyrlinksAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) {
return returnvalue::OK;
}
return returnvalue::FAILED;
}
ReturnValue_t SyrlinksAssembly::checkAndHandleHealthState(Mode_t deviceMode,
Submode_t deviceSubmode) {
HealthState health = healthHelper.healthTable->getHealth(objects::SYRLINKS_HANDLER);
if (health == FAULTY or health == PERMANENT_FAULTY) {
overwriteDeviceHealth(objects::SYRLINKS_HANDLER, health);
return NEED_TO_CHANGE_HEALTH;
} else if (health == EXTERNAL_CONTROL) {
modeHelper.setForced(true);
}
return OK;
}
void SyrlinksAssembly::handleChildrenLostMode(ReturnValue_t result) {
startTransition(mode, submode);
}

View File

@ -1,20 +0,0 @@
#ifndef MISSION_SYSTEM_OBJECTS_SYRLINKSASSEMBLY_H_
#define MISSION_SYSTEM_OBJECTS_SYRLINKSASSEMBLY_H_
#include <fsfw/devicehandlers/AssemblyBase.h>
class SyrlinksAssembly : public AssemblyBase {
public:
SyrlinksAssembly(object_id_t objectId);
private:
FixedArrayList<ModeListEntry, 1> commandTable;
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
void handleChildrenLostMode(ReturnValue_t result) override;
ReturnValue_t checkAndHandleHealthState(Mode_t deviceMode, Submode_t deviceSubmode);
};
#endif /* MISSION_SYSTEM_OBJECTS_SYRLINKSASSEMBLY_H_ */

View File

@ -11,8 +11,8 @@
#include "eive/objects.h" #include "eive/objects.h"
#include "mission/com/defs.h" #include "mission/com/defs.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "treeUtil.h" #include "treeUtil.h"
namespace { namespace {

View File

@ -0,0 +1,3 @@
target_sources(
${LIB_EIVE_MISSION} PRIVATE tcsModeTree.cpp TcsSubsystem.cpp
TcsBoardAssembly.cpp RtdFdir.cpp TmpDevFdir.cpp)

View File

@ -0,0 +1,91 @@
#include "TmpDevFdir.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/power/Fuse.h>
#include <fsfw/thermal/ThermalComponentIF.h>
TmpDevFdir::TmpDevFdir(object_id_t sensorId)
: DeviceHandlerFailureIsolation(sensorId, objects::NO_OBJECT) {}
ReturnValue_t TmpDevFdir::eventReceived(EventMessage* event) {
if (isFdirInActionOrAreWeFaulty(event)) {
return returnvalue::OK;
}
ReturnValue_t result = returnvalue::FAILED;
switch (event->getEvent()) {
case HasModesIF::MODE_TRANSITION_FAILED:
case HasModesIF::OBJECT_IN_INVALID_MODE:
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
// We'll try a recovery as long as defined in MAX_REBOOT.
// Might cause some AssemblyBase cycles, so keep number low.
// Ignored for TMP device, no way to power cycle it without going to OFF/BOOT mode.
// handleRecovery(event->getEvent());
break;
case DeviceHandlerIF::DEVICE_INTERPRETING_REPLY_FAILED:
case DeviceHandlerIF::DEVICE_READING_REPLY_FAILED:
case DeviceHandlerIF::DEVICE_UNREQUESTED_REPLY:
case DeviceHandlerIF::DEVICE_UNKNOWN_REPLY: // Some DH's generate generic reply-ids.
case DeviceHandlerIF::DEVICE_BUILDING_COMMAND_FAILED:
// These faults all mean that there were stupid replies from a device.
// With now way to do a recovery, set the device to faulty immediately.
setFaulty(event->getEvent());
break;
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
// The two above should never be confirmed.
case DeviceHandlerIF::DEVICE_MISSED_REPLY:
result = sendConfirmationRequest(event);
if (result == returnvalue::OK) {
break;
}
// else
setFaulty(event->getEvent());
break;
case StorageManagerIF::GET_DATA_FAILED:
case StorageManagerIF::STORE_DATA_FAILED:
// Rather strange bugs, occur in RAW mode only. Ignore.
break;
case DeviceHandlerIF::INVALID_DEVICE_COMMAND:
// Ignore, is bad configuration. We can't do anything in flight.
break;
case HasHealthIF::HEALTH_INFO:
case HasModesIF::MODE_INFO:
case HasModesIF::CHANGING_MODE:
// Do nothing, but mark as handled.
break;
//****Thermal*****
case ThermalComponentIF::COMPONENT_TEMP_LOW:
case ThermalComponentIF::COMPONENT_TEMP_HIGH:
case ThermalComponentIF::COMPONENT_TEMP_OOL_LOW:
case ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH:
// Well, the device is not really faulty, but it is required to stay off as long as possible.
setFaulty(event->getEvent());
break;
case ThermalComponentIF::TEMP_NOT_IN_OP_RANGE:
// Ignore, is information only.
break;
//*******Default monitoring variables. Are currently not used.*****
// case DeviceHandlerIF::MONITORING_LIMIT_EXCEEDED:
// setFaulty(event->getEvent());
// break;
// case DeviceHandlerIF::MONITORING_AMBIGUOUS:
// break;
default:
// We don't know the event, someone else should handle it.
return returnvalue::FAILED;
}
return returnvalue::OK;
}
void TmpDevFdir::eventConfirmed(EventMessage* event) {
switch (event->getEvent()) {
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
case DeviceHandlerIF::DEVICE_MISSED_REPLY:
setFaulty(event->getEvent());
break;
default:
break;
}
}

View File

@ -0,0 +1,20 @@
#ifndef MISSION_SYSTEM_TCS_TMPDEVFDIR_H_
#define MISSION_SYSTEM_TCS_TMPDEVFDIR_H_
#include <fsfw/devicehandlers/DeviceHandlerFailureIsolation.h>
/**
* Special FDIR because we can not simply power cycle the TMP devices which are powered by the
* 3.3 V stack and there is also no way to logically reset or re-configure the TMP devices in
* any way. In general, instead of doing a recovery, the TMP devices should be set faulty
* immediately for the EIVE project.
*/
class TmpDevFdir : public DeviceHandlerFailureIsolation {
public:
TmpDevFdir(object_id_t sensorId);
private:
ReturnValue_t eventReceived(EventMessage* event) override;
void eventConfirmed(EventMessage* event) override;
};
#endif /* MISSION_SYSTEM_TCS_TMPDEVFDIR_H_ */

View File

@ -1,7 +1,7 @@
#ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_ #ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_
#define MISSION_SYSTEM_TREE_TCSMODETREE_H_ #define MISSION_SYSTEM_TREE_TCSMODETREE_H_
#include <mission/system/objects/TcsSubsystem.h> #include <mission/system/tcs/TcsSubsystem.h>
namespace satsystem { namespace satsystem {
namespace tcs { namespace tcs {

View File

@ -1 +1 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp tcsModeTree.cpp) target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp)