I2C reboot procedure for EIVE system
Some checks failed
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
Robin Müller 2023-04-06 16:50:33 +02:00
parent d8ec121131
commit 3bd434bbc3
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
17 changed files with 267 additions and 154 deletions

View File

@ -5,7 +5,7 @@
#include <fsfw/power/DummyPowerSwitcher.h> #include <fsfw/power/DummyPowerSwitcher.h>
#include <fsfw_hal/common/gpio/GpioCookie.h> #include <fsfw_hal/common/gpio/GpioCookie.h>
#include <mission/power/gsDefs.h> #include <mission/power/gsDefs.h>
#include <mission/system/tree/system.h> #include <mission/system/systemTree.h>
#include <mission/utility/DummySdCardManager.h> #include <mission/utility/DummySdCardManager.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"

View File

@ -16,7 +16,7 @@
#include "fsfw/version.h" #include "fsfw/version.h"
#include "mission/acs/defs.h" #include "mission/acs/defs.h"
#include "mission/com/defs.h" #include "mission/com/defs.h"
#include "mission/system/tree/system.h" #include "mission/system/systemTree.h"
#include "q7sConfig.h" #include "q7sConfig.h"
#include "watchdog/definitions.h" #include "watchdog/definitions.h"

View File

@ -5,4 +5,6 @@ add_subdirectory(com)
add_subdirectory(fdir) add_subdirectory(fdir)
add_subdirectory(power) add_subdirectory(power)
target_sources(${LIB_EIVE_MISSION} PRIVATE DualLanePowerStateMachine.cpp) target_sources(
${LIB_EIVE_MISSION} PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp
EiveSystem.cpp treeUtil.cpp)

View File

@ -0,0 +1,203 @@
#include "EiveSystem.h"
#include <eive/objects.h>
#include <fsfw/events/EventManager.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <mission/acs/defs.h>
#include <mission/com/defs.h>
#include <mission/controller/tcsDefs.h>
#include "mission/power/bpxBattDefs.h"
#include "mission/power/defs.h"
#include "mission/sysDefs.h"
EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables),
actionHelper(this, commandQueue) {
auto mqArgs = MqArgs(SubsystemBase::getObjectId(), static_cast<void*>(this));
eventQueue =
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
}
void EiveSystem::announceMode(bool recursive) {
const char* modeStr = "UNKNOWN";
switch (mode) {
case (satsystem::Mode::BOOT): {
modeStr = "OFF/BOOT";
break;
}
case (satsystem::Mode::SAFE): {
modeStr = "SAFE";
break;
}
case (satsystem::Mode::PTG_IDLE): {
modeStr = "POINTING IDLE";
break;
}
case (acs::AcsMode::PTG_INERTIAL): {
modeStr = "POINTING INERTIAL";
break;
}
case (acs::AcsMode::PTG_TARGET): {
modeStr = "POINTING TARGET";
break;
}
case (acs::AcsMode::PTG_TARGET_GS): {
modeStr = "POINTING TARGET GS";
break;
}
}
sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl;
return Subsystem::announceMode(recursive);
}
void EiveSystem::performChildOperation() {
ReturnValue_t result;
Subsystem::performChildOperation();
handleEventMessages();
if (not isInTransition and performSafeRecovery) {
commandSelfToSafe();
performSafeRecovery = false;
return;
}
if (not isInTransition and performI2cReboot) {
if (i2cRebootState == I2cRebootState::SYSTEM_MODE_BOOT) {
startTransition(satsystem::Mode::BOOT, 0);
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT;
i2cRebootCountdown.resetTimer();
} else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT) {
if (mode == satsystem::Mode::BOOT) {
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_OFF);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
CommandMessage msg;
ActionMessage::setCommand(&msg, BpxBattery::REBOOT, store_address_t());
result = commandQueue->sendMessage(bpxBattQueueId, &msg);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_ON;
}
if (i2cRebootCountdown.hasTimedOut()) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
performI2cReboot = false;
}
} else if (i2cRebootState == I2cRebootState::SWITCH_3V3_STACK_ON) {
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_ON);
if (result != returnvalue::OK) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
performI2cReboot = false;
}
i2cRebootState = I2cRebootState::SYSTEM_MODE_SAFE;
} else if (i2cRebootState == I2cRebootState::SYSTEM_MODE_SAFE) {
if (powerSwitcher->getSwitchState(power::Switches::P60_DOCK_3V3_STACK) ==
PowerSwitchIF::SWITCH_ON) {
// This should always be accepted
commandSelfToSafe();
i2cRebootState = I2cRebootState::NONE;
performI2cReboot = false;
actionHelper.finish(true, actionCommandedBy, EXECUTE_I2C_REBOOT);
}
}
// Timeout handling for the internal procedure.
if (i2cRebootState != I2cRebootState::NONE and i2cRebootCountdown.hasTimedOut()) {
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
PowerSwitchIF::SWITCH_ON);
// This should always be accepted
commandSelfToSafe();
}
}
}
ReturnValue_t EiveSystem::initialize() {
if (powerSwitcher == nullptr) {
return ObjectManager::CHILD_INIT_FAILED;
}
ReturnValue_t result = actionHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
auto* bpxDest = ObjectManager::instance()->get<HasActionsIF>(objects::BPX_BATT_HANDLER);
if (bpxDest == nullptr) {
return ObjectManager::CHILD_INIT_FAILED;
}
bpxBattQueueId = bpxDest->getCommandQueue();
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->registerListener(eventQueue->getId());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "AcsSubsystem::registerListener: Failed to register as "
"listener"
<< std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
return Subsystem::initialize();
}
void EiveSystem::handleEventMessages() {
EventMessage event;
for (ReturnValue_t status = eventQueue->receiveMessage(&event); status == returnvalue::OK;
status = eventQueue->receiveMessage(&event)) {
switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE:
switch (event.getEvent()) {
case tcsCtrl::OBC_OVERHEATING:
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
if (isInTransition) {
performSafeRecovery = true;
return;
}
commandSelfToSafe();
break;
}
}
break;
default:
sif::debug << "EiveSystem: Did not subscribe to event " << event.getEvent() << std::endl;
break;
}
}
}
MessageQueueId_t EiveSystem::getCommandQueue() const { return Subsystem::getCommandQueue(); }
ReturnValue_t EiveSystem::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
switch (actionId) {
case (EXECUTE_I2C_REBOOT): {
performI2cReboot = true;
i2cRebootState = I2cRebootState::SYSTEM_MODE_BOOT;
this->actionCommandedBy = commandedBy;
return returnvalue::OK;
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
}
return returnvalue::OK;
}
void EiveSystem::setPowerSwitcher(PowerSwitchIF* pwrSwitcher) {}
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }

View File

@ -0,0 +1,46 @@
#ifndef MISSION_SYSTEM_EIVESYSTEM_H_
#define MISSION_SYSTEM_EIVESYSTEM_H_
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfw/subsystem/Subsystem.h>
class EiveSystem : public Subsystem, public HasActionsIF {
public:
static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10;
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
void setPowerSwitcher(PowerSwitchIF* pwrSwitcher);
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
private:
enum class I2cRebootState {
NONE,
SYSTEM_MODE_BOOT,
SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT,
SWITCH_3V3_STACK_ON,
SYSTEM_MODE_SAFE
} i2cRebootState = I2cRebootState::NONE;
MessageQueueIF* eventQueue = nullptr;
bool performSafeRecovery = false;
bool performI2cReboot = false;
ActionHelper actionHelper;
PowerSwitchIF* powerSwitcher = nullptr;
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE;
Countdown i2cRebootCountdown = Countdown(10000);
ReturnValue_t initialize() override;
void performChildOperation() override;
void announceMode(bool recursive) override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
void handleEventMessages();
void commandSelfToSafe();
};
#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */

View File

@ -11,7 +11,7 @@
#include "eive/objects.h" #include "eive/objects.h"
#include "mission/acs/defs.h" #include "mission/acs/defs.h"
#include "mission/power/defs.h" #include "mission/power/defs.h"
#include "mission/system/tree/util.h" #include "mission/system/treeUtil.h"
AcsSubsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24); AcsSubsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24);

View File

@ -6,7 +6,7 @@
#include "eive/objects.h" #include "eive/objects.h"
#include "mission/com/defs.h" #include "mission/com/defs.h"
#include "mission/system/tree/util.h" #include "mission/system/treeUtil.h"
const auto check = subsystem::checkInsert; const auto check = subsystem::checkInsert;

View File

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

View File

@ -1,111 +0,0 @@
#include "EiveSystem.h"
#include <eive/objects.h>
#include <fsfw/events/EventManager.h>
#include <fsfw/ipc/QueueFactory.h>
#include <mission/acs/defs.h>
#include <mission/com/defs.h>
#include <mission/controller/tcsDefs.h>
#include "mission/sysDefs.h"
EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {
auto mqArgs = MqArgs(SubsystemBase::getObjectId(), static_cast<void*>(this));
eventQueue =
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
}
void EiveSystem::announceMode(bool recursive) {
const char* modeStr = "UNKNOWN";
switch (mode) {
case (satsystem::Mode::BOOT): {
modeStr = "OFF/BOOT";
break;
}
case (satsystem::Mode::SAFE): {
modeStr = "SAFE";
break;
}
case (satsystem::Mode::PTG_IDLE): {
modeStr = "POINTING IDLE";
break;
}
case (acs::AcsMode::PTG_INERTIAL): {
modeStr = "POINTING INERTIAL";
break;
}
case (acs::AcsMode::PTG_TARGET): {
modeStr = "POINTING TARGET";
break;
}
case (acs::AcsMode::PTG_TARGET_GS): {
modeStr = "POINTING TARGET GS";
break;
}
}
sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl;
return Subsystem::announceMode(recursive);
}
void EiveSystem::performChildOperation() {
Subsystem::performChildOperation();
handleEventMessages();
if (not isInTransition and performSafeRecovery) {
commandSelfToSafe();
performSafeRecovery = false;
}
}
ReturnValue_t EiveSystem::initialize() {
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
ReturnValue_t result = manager->registerListener(eventQueue->getId());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "AcsSubsystem::registerListener: Failed to register as "
"listener"
<< std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
return Subsystem::initialize();
}
void EiveSystem::handleEventMessages() {
EventMessage event;
for (ReturnValue_t status = eventQueue->receiveMessage(&event); status == returnvalue::OK;
status = eventQueue->receiveMessage(&event)) {
switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE:
switch (event.getEvent()) {
case tcsCtrl::OBC_OVERHEATING:
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
if (isInTransition) {
performSafeRecovery = true;
return;
}
commandSelfToSafe();
break;
}
}
break;
default:
sif::debug << "EiveSystem: Did not subscribe to event " << event.getEvent() << std::endl;
break;
}
}
}
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }

View File

@ -1,21 +0,0 @@
#ifndef MISSION_SYSTEM_EIVESYSTEM_H_
#define MISSION_SYSTEM_EIVESYSTEM_H_
#include <fsfw/subsystem/Subsystem.h>
class EiveSystem : public Subsystem {
public:
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
private:
MessageQueueIF* eventQueue = nullptr;
bool performSafeRecovery = false;
ReturnValue_t initialize() override;
void performChildOperation() override;
void announceMode(bool recursive) override;
void handleEventMessages();
void commandSelfToSafe();
};
#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */

View File

@ -1,4 +1,4 @@
#include "system.h" #include "systemTree.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h> #include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/subsystem/Subsystem.h> #include <fsfw/subsystem/Subsystem.h>
@ -9,9 +9,9 @@
#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 "payloadModeTree.h" #include "mission/system/tree/payloadModeTree.h"
#include "tcsModeTree.h" #include "mission/system/tree/tcsModeTree.h"
#include "util.h" #include "treeUtil.h"
namespace { namespace {
// Alias for checker function // Alias for checker function

View File

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

View File

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

View File

@ -10,7 +10,7 @@
#include "eive/objects.h" #include "eive/objects.h"
#include "mission/power/defs.h" #include "mission/power/defs.h"
#include "mission/system/objects/PayloadSubsystem.h" #include "mission/system/objects/PayloadSubsystem.h"
#include "util.h" #include "mission/system/treeUtil.h"
namespace { namespace {
void initOffSequence(Subsystem& ss, ModeListEntry& eh); void initOffSequence(Subsystem& ss, ModeListEntry& eh);

View File

@ -3,7 +3,7 @@
#include "eive/objects.h" #include "eive/objects.h"
#include "fsfw/devicehandlers/DeviceHandlerIF.h" #include "fsfw/devicehandlers/DeviceHandlerIF.h"
#include "fsfw/subsystem/Subsystem.h" #include "fsfw/subsystem/Subsystem.h"
#include "mission/system/tree/util.h" #include "mission/system/treeUtil.h"
TcsSubsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24); TcsSubsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24);

View File

@ -1,4 +1,4 @@
#include "util.h" #include "treeUtil.h"
#include "fsfw/container/FixedMap.h" #include "fsfw/container/FixedMap.h"
#include "fsfw/serviceinterface.h" #include "fsfw/serviceinterface.h"