custom FDIR for tmp devices
This commit is contained in:
@ -1,4 +1,3 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE CamSwitcher.cpp TcsSubsystem.cpp PayloadSubsystem.cpp
|
||||
Stack5VHandler.cpp PowerStateMachineBase.cpp TcsBoardAssembly.cpp)
|
||||
${LIB_EIVE_MISSION} PRIVATE CamSwitcher.cpp PayloadSubsystem.cpp
|
||||
Stack5VHandler.cpp PowerStateMachineBase.cpp)
|
||||
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -1,179 +0,0 @@
|
||||
#include "TcsBoardAssembly.h"
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
|
||||
TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||
power::Switch_t theSwitch, TcsBoardHelper helper,
|
||||
std::atomic_bool& tcsShortlyUnavailable)
|
||||
: SharedPowerAssemblyBase(objectId, pwrSwitcher, theSwitch, 16),
|
||||
helper(helper),
|
||||
tcsShortlyUnavailable(tcsShortlyUnavailable) {
|
||||
ModeListEntry entry;
|
||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||
entry.setObject(helper.rtdInfos[idx].first);
|
||||
entry.setMode(MODE_OFF);
|
||||
entry.setSubmode(SUBMODE_NONE);
|
||||
modeTable.insert(entry);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
// Initialize the mode table to ensure all devices are in a defined state
|
||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||
modeTable[idx].setMode(MODE_OFF);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
if (recoveryState == RecoveryState::RECOVERY_IDLE) {
|
||||
result = checkAndHandleHealthStates(mode, submode);
|
||||
if (result == NEED_TO_CHANGE_HEALTH) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
if (recoveryState != RecoveryState::RECOVERY_STARTED) {
|
||||
if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) {
|
||||
result = handleNormalOrOnModeCmd(mode, submode);
|
||||
}
|
||||
} else {
|
||||
tcsShortlyUnavailable = true;
|
||||
}
|
||||
HybridIterator<ModeListEntry> tableIter(modeTable.begin(), modeTable.end());
|
||||
executeTable(tableIter);
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) {
|
||||
int devsInWrongMode = 0;
|
||||
try {
|
||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||
if (childrenMap.at(helper.rtdInfos[idx].first).mode != wantedMode) {
|
||||
devsInWrongMode++;
|
||||
}
|
||||
}
|
||||
} catch (const std::out_of_range& e) {
|
||||
sif::error << "TcsBoardAssembly: Invalid children map: " << e.what() << std::endl;
|
||||
}
|
||||
if (devsInWrongMode == NUMBER_RTDS) {
|
||||
if (warningSwitch) {
|
||||
sif::warning << "TcsBoardAssembly::checkChildrenStateOn: All devices in wrong mode"
|
||||
<< std::endl;
|
||||
warningSwitch = false;
|
||||
}
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
}
|
||||
// TODO: Can't really do something other than power cycling if devices in wrong mode.
|
||||
// Might attempt one power-cycle. In any case, trigger an event
|
||||
if (devsInWrongMode > 0) {
|
||||
if (warningSwitch) {
|
||||
sif::warning << "TcsBoardAssembly::checkChildrenStateOn: " << devsInWrongMode << " devices in"
|
||||
<< " wrong mode" << std::endl;
|
||||
warningSwitch = false;
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
if (mode == MODE_ON or mode == MODE_OFF or mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return HasModesIF::INVALID_MODE;
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
bool needsSecondStep = false;
|
||||
Mode_t devMode = 0;
|
||||
object_id_t objId = 0;
|
||||
try {
|
||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||
devMode = childrenMap.at(helper.rtdInfos[idx].first).mode;
|
||||
objId = helper.rtdInfos[idx].first;
|
||||
if (mode == devMode) {
|
||||
modeTable[idx].setMode(mode);
|
||||
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (isUseable(objId, devMode)) {
|
||||
if (devMode == MODE_ON) {
|
||||
modeTable[idx].setMode(mode);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
modeTable[idx].setMode(MODE_ON);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
if (internalState != STATE_SECOND_STEP) {
|
||||
needsSecondStep = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode == MODE_ON) {
|
||||
if (isUseable(objId, devMode)) {
|
||||
modeTable[idx].setMode(MODE_ON);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const std::out_of_range& e) {
|
||||
sif::error << "TcsBoardAssembly: Invalid children map: " << e.what() << std::endl;
|
||||
}
|
||||
if (needsSecondStep) {
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) {
|
||||
if (healthHelper.healthTable->isFaulty(object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if device is already in target mode
|
||||
if (childrenMap[object].mode == mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (healthHelper.healthTable->isCommandable(object)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) {
|
||||
triggerEvent(CHILDREN_LOST_MODE, result);
|
||||
startTransition(mode, submode);
|
||||
}
|
||||
|
||||
ReturnValue_t TcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
||||
Submode_t deviceSubmode) {
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
for (const auto& dev : helper.rtdInfos) {
|
||||
HealthState health = healthHelper.healthTable->getHealth(dev.first);
|
||||
if (health == HealthState::HEALTHY) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& dev : helper.rtdInfos) {
|
||||
HealthState health = healthHelper.healthTable->getHealth(dev.first);
|
||||
if (health == FAULTY or health == PERMANENT_FAULTY) {
|
||||
status = NEED_TO_CHANGE_HEALTH;
|
||||
} else if (health == EXTERNAL_CONTROL) {
|
||||
modeHelper.setForced(true);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool TcsBoardAssembly::checkAndHandleRecovery() {
|
||||
bool recoveryPending = SharedPowerAssemblyBase::checkAndHandleRecovery();
|
||||
tcsShortlyUnavailable = recoveryPending;
|
||||
return recoveryPending;
|
||||
}
|
||||
|
||||
void TcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
if (targetMode == MODE_OFF) {
|
||||
AssemblyBase::handleModeTransitionFailed(result);
|
||||
} else {
|
||||
// To avoid transitioning back to off
|
||||
triggerEvent(MODE_TRANSITION_FAILED, result);
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
#ifndef MISSION_SYSTEM_TCSSUBSYSTEM_H_
|
||||
#define MISSION_SYSTEM_TCSSUBSYSTEM_H_
|
||||
|
||||
#include <fsfw/container/FixedArrayList.h>
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
#include <fsfw/power/PowerSwitcher.h>
|
||||
#include <mission/power/defs.h>
|
||||
#include <mission/system/SharedPowerAssemblyBase.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "events/subsystemIdRanges.h"
|
||||
#include "returnvalues/classIds.h"
|
||||
|
||||
struct TcsBoardHelper {
|
||||
TcsBoardHelper(std::array<std::pair<object_id_t, std::string>, 16> rtdInfos)
|
||||
: rtdInfos(std::move(rtdInfos)) {}
|
||||
|
||||
std::array<std::pair<object_id_t, std::string>, 16> rtdInfos = {};
|
||||
};
|
||||
|
||||
class TcsBoardAssembly : public SharedPowerAssemblyBase {
|
||||
public:
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_BOARD_ASS;
|
||||
static constexpr Event CHILDREN_LOST_MODE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
|
||||
TcsBoardAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t switcher,
|
||||
TcsBoardHelper helper, std::atomic_bool& tcsShortlyUnavailable);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t NUMBER_RTDS = 16;
|
||||
bool warningSwitch = true;
|
||||
TcsBoardHelper helper;
|
||||
FixedArrayList<ModeListEntry, NUMBER_RTDS> modeTable;
|
||||
std::atomic_bool& tcsShortlyUnavailable;
|
||||
|
||||
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
||||
/**
|
||||
* Check whether it makes sense to send mode commands to the device
|
||||
* @param object
|
||||
* @param mode
|
||||
* @return
|
||||
*/
|
||||
bool isUseable(object_id_t object, Mode_t mode);
|
||||
|
||||
// AssemblyBase implementation
|
||||
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;
|
||||
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
|
||||
bool checkAndHandleRecovery() override;
|
||||
|
||||
// These two overrides prevent a transition of the whole assembly back to off just because
|
||||
// some devices are not working
|
||||
void handleChildrenLostMode(ReturnValue_t result) override;
|
||||
void handleModeTransitionFailed(ReturnValue_t result) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_TCSSUBSYSTEM_H_ */
|
@ -1,27 +0,0 @@
|
||||
#include "TcsSubsystem.h"
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||
|
||||
TcsSubsystem::TcsSubsystem(object_id_t objectId, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables)
|
||||
: Subsystem(objectId, maxNumberOfSequences, maxNumberOfTables) {}
|
||||
|
||||
void TcsSubsystem::announceMode(bool recursive) {
|
||||
const char* modeStr = "UNKNOWN";
|
||||
switch (mode) {
|
||||
case (HasModesIF::MODE_OFF): {
|
||||
modeStr = "OFF";
|
||||
break;
|
||||
}
|
||||
case (HasModesIF::MODE_ON): {
|
||||
modeStr = "ON";
|
||||
break;
|
||||
}
|
||||
case (DeviceHandlerIF::MODE_NORMAL): {
|
||||
modeStr = "NORMAL";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sif::info << "TCS subsystem is now in " << modeStr << " mode" << std::endl;
|
||||
return Subsystem::announceMode(recursive);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef MISSION_SYSTEM_OBJECTS_TCSSUBSYSTEM_H_
|
||||
#define MISSION_SYSTEM_OBJECTS_TCSSUBSYSTEM_H_
|
||||
#include <fsfw/subsystem/Subsystem.h>
|
||||
|
||||
class TcsSubsystem : public Subsystem {
|
||||
public:
|
||||
TcsSubsystem(object_id_t objectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
|
||||
|
||||
private:
|
||||
void announceMode(bool recursive) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_OBJECTS_TCSSUBSYSTEM_H_ */
|
Reference in New Issue
Block a user