Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -224,62 +224,22 @@ void AuthenticationRouter ::GET_COMMAND_LOSS_DATA_cmdHandler(FwOpcodeType opCode
}

Fw::Time AuthenticationRouter ::update_command_loss_start(bool write_to_file) {
// Lock the mutex to prevent multiple threads from updating the command loss start time simultaneously
Os::ScopeLock lock(this->m_commandLossMutex);

// Update file with current time and cache it
Fw::Time current_time = this->getTime();

// if current time base if monotonic, we don't want to write it to file, but we still want to update the cached
// time and return it this way we never write monotonic time to file, which would be invalid on reboot and if
// the system is using monotonic time, we don't consistently return a previously saved workstation time to a
// cube stuck on monotonic (ie broken RTC). So we don't write monotonic time to file, but cache it for use in
// current session

if (current_time.getTimeBase() == TimeBase::TB_PROC_TIME) {
if (write_to_file) {
// Don't write monotonic time to file, but cache it for use in current session
this->m_commandLossStartTime = current_time;
return current_time;
} else {
// Return cached time (the time when last command arrived)
return this->m_commandLossStartTime;
}
}

Fw::ParamValid is_valid;
auto time_file = this->paramGet_COMM_LOSS_TIME_START_FILE(is_valid);

if (write_to_file) {
Os::File::Status status = Utilities::FileHelper::writeToFile(time_file.toChar(), current_time);
if (status != Os::File::OP_OK) {
this->log_WARNING_HI_CommandLossFileInitFailure();
}
// If writing (command received), reset the timer to current time
// On boot, m_commandLossStartTime starts at ZERO_TIME, so first command will set it
// Also reset if timebase changed (can't compare times with different timebases)
bool changed_time_base = this->m_commandLossStartTime.getTimeBase() != current_time.getTimeBase();
if (write_to_file || this->m_commandLossStartTime == Fw::ZERO_TIME || changed_time_base) {
this->m_commandLossStartTime = current_time;

return current_time;
} else {
// Check if we need to load from file (cache is zero/uninitialized or timebase mismatch with the file)
// Otherwise we want to read from the cache in case the filesystem is broken
// Also invalidate cache if timebase changed (e.g., system switched from monotonic to workstation time)
if (this->m_commandLossStartTime == Fw::ZERO_TIME ||
this->m_commandLossStartTime.getTimeBase() != current_time.getTimeBase()) {
// Read stored time from file, or use current time if file doesn't exist
Fw::Time time = this->getTime();
Os::File::Status status = Utilities::FileHelper::readFromFile(time_file.toChar(), time);

// On read failure, write the current time to the file for future reads
if (status != Os::File::OP_OK) {
status = Utilities::FileHelper::writeToFile(time_file.toChar(), time);
if (status != Os::File::OP_OK) {
this->log_WARNING_HI_CommandLossFileInitFailure();
}
}
// Cache the loaded time
this->m_commandLossStartTime = time;
}
// Return cached time
return this->m_commandLossStartTime;
}

// If reading (checking timer), return the stored start time
return this->m_commandLossStartTime;
}

void AuthenticationRouter ::fileBufferReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
Expand Down
6 changes: 5 additions & 1 deletion FprimeZephyrReference/Components/ModeManager/ModeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ void ModeManager ::loadState() {
if (this->m_mode == SystemMode::SAFE_MODE) {
// Turn off non-critical components to match safe mode state
this->turnOffNonCriticalComponents();
// run radio safe to match default safe params
this->runSafeModeSequence();

// Log that we're restoring safe mode (not entering it fresh)
Fw::LogStringArg reasonStr("State restored from persistent storage");
Expand Down Expand Up @@ -311,9 +313,11 @@ void ModeManager ::loadState() {
// Handle unintended reboot detection AFTER basic state restoration
// This ensures we enter safe mode due to system fault
if (unintendedReboot) {
// On unintended reboot, re-enter safe mode and run the safe mode sequence
// On unintended reboot, enter safe mode and run the safe mode sequence
// (e.g., to reset radio parameters and enforce any transmit delay policy)
this->log_WARNING_HI_UnintendedRebootDetected();
this->enterSafeMode(Components::SafeModeReason::SYSTEM_FAULT);
this->runSafeModeSequence();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I this we have a potential issue here, where calling the SafeModeSequence on an unintended reboot will cause the safe mode sequencer to conflict with the primary command sequencer (which may be running the startup sequence with almost exactly the same timing as the radio_enter_safe.seq

}

// Clear clean shutdown flag for next boot detection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ module Components {
@ Debounce time for voltage transitions (seconds)
param SafeModeDebounceSeconds: U32 default 10

param SAFEMODE_SEQUENCE_FILE: string default "/seq/radio_enter_safe.bin"
param SAFEMODE_SEQUENCE_FILE: string default "/seq/enter_safe.bin"

###############################################################################
# Standard AC Ports: Required for Channels, Events, Commands, and Parameters #
Expand Down
4 changes: 2 additions & 2 deletions FprimeZephyrReference/Components/Watchdog/Watchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void Watchdog ::start_handler(FwIndexType portNum) {

void Watchdog ::stop_handler(FwIndexType portNum) {
// Stop the watchdog
this->prepareForReboot_out(0);

this->m_run = false;

// Report watchdog stopped
Expand All @@ -68,8 +68,8 @@ void Watchdog ::START_WATCHDOG_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {

void Watchdog ::STOP_WATCHDOG_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
// call stop handler
this->prepareForReboot_out(0);
this->stop_handler(0);

// Provide command response
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
Expand Down
9 changes: 9 additions & 0 deletions sequences/enter_safe.seq
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; Enter safe: turn off load switches
R00:00:00 ReferenceDeployment.face4LoadSwitch.TURN_OFF
R00:00:00 ReferenceDeployment.face0LoadSwitch.TURN_OFF
R00:00:01 ReferenceDeployment.face1LoadSwitch.TURN_OFF
R00:00:01 ReferenceDeployment.face2LoadSwitch.TURN_OFF
R00:00:01 ReferenceDeployment.face3LoadSwitch.TURN_OFF
R00:00:01 ReferenceDeployment.face5LoadSwitch.TURN_OFF
R00:00:01 ReferenceDeployment.payloadPowerLoadSwitch.TURN_OFF
R00:00:01 ReferenceDeployment.payloadBatteryLoadSwitch.TURN_OFF
4 changes: 2 additions & 2 deletions sequences/radio_enter_safe.seq
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
R05:00:00 ReferenceDeployment.lora.TRANSMIT, DISABLED
R00:00:00 ReferenceDeployment.lora.TRANSMIT, DISABLED
R00:00:00 ReferenceDeployment.lora.DATA_RATE_PRM_SET, SF_8
R00:00:00 ReferenceDeployment.downlinkDelay.DIVIDER_PRM_SET, 299
R00:00:00 ReferenceDeployment.telemetryDelay.DIVIDER_PRM_SET, 29
R00:00:00 ReferenceDeployment.lora.CODING_RATE_PRM_SET, CR_4_5
R00:00:00 ReferenceDeployment.lora.BANDWIDTH_RX_PRM_SET, BW_125_KHZ
R00:00:00 ReferenceDeployment.lora.BANDWIDTH_TX_PRM_SET, BW_125_KHZ
R00:00:01 ReferenceDeployment.lora.TRANSMIT, ENABLED
R00:45:00 ReferenceDeployment.lora.TRANSMIT, ENABLED
9 changes: 9 additions & 0 deletions sequences/startup.seq
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ R00:00:00 CdhCore.events.SET_ID_FILTER, 268439553, ENABLED ; RateGroupSlip (50)
R00:00:00 CdhCore.events.SET_ID_FILTER, 268443649, ENABLED ; RateGroupSlip (10)

R00:45:00 ReferenceDeployment.antennaDeployer.DEPLOY
R00:00:00 ReferenceDeployment.lora.TRANSMIT, DISABLED
R00:00:00 ReferenceDeployment.lora.DATA_RATE_PRM_SET, SF_8
R00:00:00 ReferenceDeployment.downlinkDelay.DIVIDER_PRM_SET, 299
R00:00:00 ReferenceDeployment.telemetryDelay.DIVIDER_PRM_SET, 29
R00:00:00 ReferenceDeployment.lora.CODING_RATE_PRM_SET, CR_4_5
R00:00:00 ReferenceDeployment.lora.BANDWIDTH_RX_PRM_SET, BW_125_KHZ
R00:00:00 ReferenceDeployment.lora.BANDWIDTH_TX_PRM_SET, BW_125_KHZ


R00:00:00 ReferenceDeployment.lora.TRANSMIT ENABLED

; Exit Safe Mode should turn on faces
Expand Down