New total reboot counter handling #708
@ -322,13 +322,13 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_WATCHDOG_FILE;
|
||||
parseRebootFile(path, rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
if (data[0] == 0) {
|
||||
rebootFile.enabled = false;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.enabled = false;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
} else if (data[0] == 1) {
|
||||
rebootFile.enabled = true;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.enabled = true;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
} else {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
@ -336,8 +336,8 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
}
|
||||
case (READ_REBOOT_MECHANISM_INFO): {
|
||||
std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_WATCHDOG_FILE;
|
||||
parseRebootFile(path, rebootFile);
|
||||
RebootMechanismPacket packet(rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
RebootWatchdogPacket packet(rebootWatchdogFile);
|
||||
ReturnValue_t result = actionHelper.reportData(commandedBy, actionId, &packet);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
@ -448,9 +448,9 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
}
|
||||
std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_WATCHDOG_FILE;
|
||||
// Disable the reboot file mechanism
|
||||
parseRebootFile(path, rebootFile);
|
||||
rebootFile.maxCount = data[0];
|
||||
rewriteRebootFile(rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
rebootWatchdogFile.maxCount = data[0];
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case (XSC_REBOOT_OBC): {
|
||||
@ -1555,7 +1555,7 @@ void CoreController::performMountedSdCardOperations() {
|
||||
if (not timeFileInitDone) {
|
||||
initClockFromTimeFile();
|
||||
}
|
||||
performRebootFileHandling(false);
|
||||
performRebootWatchdogHandling(false);
|
||||
}
|
||||
backupTimeFileHandler();
|
||||
};
|
||||
@ -1627,7 +1627,7 @@ ReturnValue_t CoreController::performSdCardCheck() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void CoreController::performRebootFileHandling(bool recreateFile) {
|
||||
void CoreController::performRebootWatchdogHandling(bool recreateFile) {
|
||||
using namespace std;
|
||||
std::string path = currMntPrefix + REBOOT_WATCHDOG_FILE;
|
||||
std::error_code e;
|
||||
@ -1635,109 +1635,110 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
|
||||
#endif
|
||||
rebootFile.enabled = false;
|
||||
rebootFile.img00Cnt = 0;
|
||||
rebootFile.img01Cnt = 0;
|
||||
rebootFile.img10Cnt = 0;
|
||||
rebootFile.img11Cnt = 0;
|
||||
rebootFile.lastChip = xsc::Chip::CHIP_0;
|
||||
rebootFile.lastCopy = xsc::Copy::COPY_0;
|
||||
rebootFile.img00Lock = false;
|
||||
rebootFile.img01Lock = false;
|
||||
rebootFile.img10Lock = false;
|
||||
rebootFile.img11Lock = false;
|
||||
rebootFile.mechanismNextChip = xsc::Chip::NO_CHIP;
|
||||
rebootFile.mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||
rebootFile.bootFlag = false;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.enabled = false;
|
||||
rebootWatchdogFile.img00Cnt = 0;
|
||||
rebootWatchdogFile.img01Cnt = 0;
|
||||
rebootWatchdogFile.img10Cnt = 0;
|
||||
rebootWatchdogFile.img11Cnt = 0;
|
||||
rebootWatchdogFile.lastChip = xsc::Chip::CHIP_0;
|
||||
rebootWatchdogFile.lastCopy = xsc::Copy::COPY_0;
|
||||
rebootWatchdogFile.img00Lock = false;
|
||||
rebootWatchdogFile.img01Lock = false;
|
||||
rebootWatchdogFile.img10Lock = false;
|
||||
rebootWatchdogFile.img11Lock = false;
|
||||
rebootWatchdogFile.mechanismNextChip = xsc::Chip::NO_CHIP;
|
||||
rebootWatchdogFile.mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||
rebootWatchdogFile.bootFlag = false;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
} else {
|
||||
if (not parseRebootFile(path, rebootFile)) {
|
||||
performRebootFileHandling(true);
|
||||
if (not parseRebootWatchdogFile(path, rebootWatchdogFile)) {
|
||||
performRebootWatchdogHandling(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (CURRENT_CHIP == xsc::CHIP_0) {
|
||||
if (CURRENT_COPY == xsc::COPY_0) {
|
||||
rebootFile.img00Cnt++;
|
||||
rebootWatchdogFile.img00Cnt++;
|
||||
} else {
|
||||
rebootFile.img01Cnt++;
|
||||
rebootWatchdogFile.img01Cnt++;
|
||||
}
|
||||
} else {
|
||||
if (CURRENT_COPY == xsc::COPY_0) {
|
||||
rebootFile.img10Cnt++;
|
||||
rebootWatchdogFile.img10Cnt++;
|
||||
} else {
|
||||
rebootFile.img11Cnt++;
|
||||
rebootWatchdogFile.img11Cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebootFile.bootFlag) {
|
||||
if (rebootWatchdogFile.bootFlag) {
|
||||
// Trigger event to inform ground that a reboot was triggered
|
||||
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
|
||||
uint32_t p1 = rebootWatchdogFile.lastChip << 16 | rebootWatchdogFile.lastCopy;
|
||||
triggerEvent(core::REBOOT_MECHANISM_TRIGGERED, p1, 0);
|
||||
// Clear the boot flag
|
||||
rebootFile.bootFlag = false;
|
||||
rebootWatchdogFile.bootFlag = false;
|
||||
}
|
||||
|
||||
announceBootCounts();
|
||||
|
||||
if (rebootFile.mechanismNextChip != xsc::NO_CHIP and
|
||||
rebootFile.mechanismNextCopy != xsc::NO_COPY) {
|
||||
if (CURRENT_CHIP != rebootFile.mechanismNextChip or
|
||||
CURRENT_COPY != rebootFile.mechanismNextCopy) {
|
||||
std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " +
|
||||
std::to_string(rebootFile.mechanismNextCopy);
|
||||
if (rebootWatchdogFile.mechanismNextChip != xsc::NO_CHIP and
|
||||
rebootWatchdogFile.mechanismNextCopy != xsc::NO_COPY) {
|
||||
if (CURRENT_CHIP != rebootWatchdogFile.mechanismNextChip or
|
||||
CURRENT_COPY != rebootWatchdogFile.mechanismNextCopy) {
|
||||
std::string infoString = std::to_string(rebootWatchdogFile.mechanismNextChip) + " " +
|
||||
std::to_string(rebootWatchdogFile.mechanismNextCopy);
|
||||
sif::warning << "CoreController::performRebootFileHandling: Expected to be on image "
|
||||
<< infoString << " but currently on other image. Locking " << infoString
|
||||
<< std::endl;
|
||||
// Firmware or other component might be corrupt and we are on another image then the target
|
||||
// image specified by the mechanism. We can't really trust the target image anymore.
|
||||
// Lock it for now
|
||||
if (rebootFile.mechanismNextChip == xsc::CHIP_0) {
|
||||
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootFile.img00Lock = true;
|
||||
if (rebootWatchdogFile.mechanismNextChip == xsc::CHIP_0) {
|
||||
if (rebootWatchdogFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootWatchdogFile.img00Lock = true;
|
||||
} else {
|
||||
rebootFile.img01Lock = true;
|
||||
rebootWatchdogFile.img01Lock = true;
|
||||
}
|
||||
} else {
|
||||
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootFile.img10Lock = true;
|
||||
if (rebootWatchdogFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootWatchdogFile.img10Lock = true;
|
||||
} else {
|
||||
rebootFile.img11Lock = true;
|
||||
rebootWatchdogFile.img11Lock = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rebootFile.lastChip = CURRENT_CHIP;
|
||||
rebootFile.lastCopy = CURRENT_COPY;
|
||||
rebootWatchdogFile.lastChip = CURRENT_CHIP;
|
||||
rebootWatchdogFile.lastCopy = CURRENT_COPY;
|
||||
// Only reboot if the reboot functionality is enabled.
|
||||
// The handler will still increment the boot counts
|
||||
if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) {
|
||||
if (rebootWatchdogFile.enabled and
|
||||
(*rebootWatchdogFile.relevantBootCnt >= rebootWatchdogFile.maxCount)) {
|
||||
// Reboot to other image
|
||||
bool doReboot = false;
|
||||
xsc::Chip tgtChip = xsc::NO_CHIP;
|
||||
xsc::Copy tgtCopy = xsc::NO_COPY;
|
||||
determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy);
|
||||
determineAndExecuteReboot(rebootWatchdogFile, doReboot, tgtChip, tgtCopy);
|
||||
if (doReboot) {
|
||||
rebootFile.bootFlag = true;
|
||||
rebootWatchdogFile.bootFlag = true;
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
|
||||
<< " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl;
|
||||
#endif
|
||||
rebootFile.mechanismNextChip = tgtChip;
|
||||
rebootFile.mechanismNextCopy = tgtCopy;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.mechanismNextChip = tgtChip;
|
||||
rebootWatchdogFile.mechanismNextCopy = tgtCopy;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(tgtChip),
|
||||
static_cast<xsc_libnor_copy_t>(tgtCopy));
|
||||
}
|
||||
} else {
|
||||
rebootFile.mechanismNextChip = xsc::NO_CHIP;
|
||||
rebootFile.mechanismNextCopy = xsc::NO_COPY;
|
||||
rebootWatchdogFile.mechanismNextChip = xsc::NO_CHIP;
|
||||
rebootWatchdogFile.mechanismNextCopy = xsc::NO_COPY;
|
||||
}
|
||||
rewriteRebootFile(rebootFile);
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
}
|
||||
|
||||
void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot,
|
||||
void CoreController::determineAndExecuteReboot(RebootWatchdogFile &rf, bool &needsReboot,
|
||||
xsc::Chip &tgtChip, xsc::Copy &tgtCopy) {
|
||||
tgtChip = xsc::CHIP_0;
|
||||
tgtCopy = xsc::COPY_0;
|
||||
@ -1826,7 +1827,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
|
||||
}
|
||||
}
|
||||
|
||||
bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
|
||||
bool CoreController::parseRebootWatchdogFile(std::string path, RebootWatchdogFile &rf) {
|
||||
using namespace std;
|
||||
std::string selfMatch;
|
||||
if (CURRENT_CHIP == xsc::CHIP_0) {
|
||||
@ -2010,31 +2011,31 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
|
||||
|
||||
void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) {
|
||||
std::string path = currMntPrefix + REBOOT_WATCHDOG_FILE;
|
||||
parseRebootFile(path, rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) {
|
||||
rebootFile.img00Cnt = 0;
|
||||
rebootFile.img01Cnt = 0;
|
||||
rebootFile.img10Cnt = 0;
|
||||
rebootFile.img11Cnt = 0;
|
||||
rebootWatchdogFile.img00Cnt = 0;
|
||||
rebootWatchdogFile.img01Cnt = 0;
|
||||
rebootWatchdogFile.img10Cnt = 0;
|
||||
rebootWatchdogFile.img11Cnt = 0;
|
||||
} else {
|
||||
if (tgtChip == xsc::CHIP_0) {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img00Cnt = 0;
|
||||
rebootWatchdogFile.img00Cnt = 0;
|
||||
} else {
|
||||
rebootFile.img01Cnt = 0;
|
||||
rebootWatchdogFile.img01Cnt = 0;
|
||||
}
|
||||
} else {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img10Cnt = 0;
|
||||
rebootWatchdogFile.img10Cnt = 0;
|
||||
} else {
|
||||
rebootFile.img11Cnt = 0;
|
||||
rebootWatchdogFile.img11Cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
rewriteRebootFile(rebootFile);
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
}
|
||||
|
||||
void CoreController::rewriteRebootFile(RebootFile file) {
|
||||
void CoreController::rewriteRebootWatchdogFile(RebootWatchdogFile file) {
|
||||
std::string path = currMntPrefix + REBOOT_WATCHDOG_FILE;
|
||||
std::ofstream rebootFile(path);
|
||||
if (rebootFile.is_open()) {
|
||||
@ -2054,21 +2055,21 @@ void CoreController::rewriteRebootFile(RebootFile file) {
|
||||
void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) {
|
||||
std::string path = currMntPrefix + REBOOT_WATCHDOG_FILE;
|
||||
// Disable the reboot file mechanism
|
||||
parseRebootFile(path, rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
if (tgtChip == xsc::CHIP_0) {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img00Lock = lock;
|
||||
rebootWatchdogFile.img00Lock = lock;
|
||||
} else {
|
||||
rebootFile.img01Lock = lock;
|
||||
rebootWatchdogFile.img01Lock = lock;
|
||||
}
|
||||
} else {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img10Lock = lock;
|
||||
rebootWatchdogFile.img10Lock = lock;
|
||||
} else {
|
||||
rebootFile.img11Lock = lock;
|
||||
rebootWatchdogFile.img11Lock = lock;
|
||||
}
|
||||
}
|
||||
rewriteRebootFile(rebootFile);
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
}
|
||||
|
||||
ReturnValue_t CoreController::backupTimeFileHandler() {
|
||||
@ -2355,10 +2356,12 @@ bool CoreController::startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mo
|
||||
}
|
||||
|
||||
void CoreController::announceBootCounts() {
|
||||
uint64_t totalBootCount =
|
||||
rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt;
|
||||
uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt;
|
||||
uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt;
|
||||
uint64_t totalBootCount = rebootWatchdogFile.img00Cnt + rebootWatchdogFile.img01Cnt +
|
||||
rebootWatchdogFile.img10Cnt + rebootWatchdogFile.img11Cnt;
|
||||
uint32_t individualBootCountsP1 =
|
||||
(rebootWatchdogFile.img00Cnt << 16) | rebootWatchdogFile.img01Cnt;
|
||||
uint32_t individualBootCountsP2 =
|
||||
(rebootWatchdogFile.img10Cnt << 16) | rebootWatchdogFile.img11Cnt;
|
||||
triggerEvent(core::INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
|
||||
triggerEvent(core::REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff,
|
||||
totalBootCount & 0xffffffff);
|
||||
|
@ -24,7 +24,7 @@
|
||||
class Timer;
|
||||
class SdCardManager;
|
||||
|
||||
struct RebootFile {
|
||||
struct RebootWatchdogFile {
|
||||
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
||||
|
||||
bool enabled = true;
|
||||
@ -45,9 +45,9 @@ struct RebootFile {
|
||||
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||
};
|
||||
|
||||
class RebootMechanismPacket : public SerialLinkedListAdapter<SerializeIF> {
|
||||
class RebootWatchdogPacket : public SerialLinkedListAdapter<SerializeIF> {
|
||||
public:
|
||||
RebootMechanismPacket(RebootFile& rf) {
|
||||
RebootWatchdogPacket(RebootWatchdogFile& rf) {
|
||||
enabled = rf.enabled;
|
||||
maxCount = rf.maxCount;
|
||||
img00Count = rf.img00Cnt;
|
||||
@ -100,6 +100,38 @@ class RebootMechanismPacket : public SerialLinkedListAdapter<SerializeIF> {
|
||||
SerializeElement<uint8_t> nextCopy = 0;
|
||||
};
|
||||
|
||||
struct RebootCountersFile {
|
||||
// 16 bit values so all boot counters fit into one event.
|
||||
uint16_t img00Cnt = 0;
|
||||
uint16_t img01Cnt = 0;
|
||||
uint16_t img10Cnt = 0;
|
||||
uint16_t img11Cnt = 0;
|
||||
};
|
||||
|
||||
class RebootCountersPacket : public SerialLinkedListAdapter<SerializeIF> {
|
||||
RebootCountersPacket(RebootCountersFile& rf) {
|
||||
img00Count = rf.img00Cnt;
|
||||
img01Count = rf.img01Cnt;
|
||||
img10Count = rf.img10Cnt;
|
||||
img11Count = rf.img11Cnt;
|
||||
setLinks();
|
||||
}
|
||||
|
||||
private:
|
||||
void setLinks() {
|
||||
setStart(&img00Count);
|
||||
img00Count.setNext(&img01Count);
|
||||
img01Count.setNext(&img10Count);
|
||||
img10Count.setNext(&img11Count);
|
||||
setLast(&img11Count);
|
||||
}
|
||||
|
||||
SerializeElement<uint16_t> img00Count = 0;
|
||||
SerializeElement<uint16_t> img01Count = 0;
|
||||
SerializeElement<uint16_t> img10Count = 0;
|
||||
SerializeElement<uint16_t> img11Count = 0;
|
||||
};
|
||||
|
||||
class CoreController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||
public:
|
||||
enum ParamId : uint8_t { PREF_SD = 0, NUM_IDS };
|
||||
@ -250,7 +282,8 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
||||
std::array<uint8_t, 1024> dirListingBuf{};
|
||||
DirListingDumpContext dumpContext{};
|
||||
|
||||
RebootFile rebootFile = {};
|
||||
RebootWatchdogFile rebootWatchdogFile = {};
|
||||
RebootCountersFile rebootCountersFile = {};
|
||||
|
||||
CommandExecutor cmdExecutor;
|
||||
SimpleRingBuffer cmdReplyBuf;
|
||||
@ -320,7 +353,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
||||
void currentStateSetter(sd::SdCard sdCard, sd::SdState newState);
|
||||
void executeNextExternalSdCommand();
|
||||
void checkExternalSdCommandStatus();
|
||||
void performRebootFileHandling(bool recreateFile);
|
||||
void performRebootWatchdogHandling(bool recreateFile);
|
||||
|
||||
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
@ -339,12 +372,12 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
||||
int handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect,
|
||||
bool& protOperationPerformed, bool selfChip, bool selfCopy,
|
||||
bool allChips, bool allCopies, uint8_t arrIdx);
|
||||
void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
|
||||
void determineAndExecuteReboot(RebootWatchdogFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
|
||||
xsc::Copy& tgtCopy);
|
||||
void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
||||
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
||||
bool parseRebootFile(std::string path, RebootFile& file);
|
||||
void rewriteRebootFile(RebootFile file);
|
||||
bool parseRebootWatchdogFile(std::string path, RebootWatchdogFile& file);
|
||||
void rewriteRebootWatchdogFile(RebootWatchdogFile file);
|
||||
void announceBootCounts();
|
||||
void announceVersionInfo();
|
||||
void announceCurrentImageInfo();
|
||||
|
@ -19,116 +19,117 @@ CoreController::CoreController() {
|
||||
setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0);
|
||||
}
|
||||
|
||||
void CoreController::performRebootFileHandling(bool recreateFile) {
|
||||
void CoreController::performRebootWatchdogHandling(bool recreateFile) {
|
||||
using namespace std;
|
||||
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.active) + REBOOT_WATCHDOG_FILE;
|
||||
if (not std::filesystem::exists(path) or recreateFile) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
|
||||
#endif
|
||||
rebootFile.enabled = true;
|
||||
rebootFile.img00Cnt = 0;
|
||||
rebootFile.img01Cnt = 0;
|
||||
rebootFile.img10Cnt = 0;
|
||||
rebootFile.img11Cnt = 0;
|
||||
rebootFile.lastChip = xsc::Chip::CHIP_0;
|
||||
rebootFile.lastCopy = xsc::Copy::COPY_0;
|
||||
rebootFile.img00Lock = false;
|
||||
rebootFile.img01Lock = false;
|
||||
rebootFile.img10Lock = false;
|
||||
rebootFile.img11Lock = false;
|
||||
rebootFile.mechanismNextChip = xsc::Chip::NO_CHIP;
|
||||
rebootFile.mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||
rebootFile.bootFlag = false;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.enabled = true;
|
||||
rebootWatchdogFile.img00Cnt = 0;
|
||||
rebootWatchdogFile.img01Cnt = 0;
|
||||
rebootWatchdogFile.img10Cnt = 0;
|
||||
rebootWatchdogFile.img11Cnt = 0;
|
||||
rebootWatchdogFile.lastChip = xsc::Chip::CHIP_0;
|
||||
rebootWatchdogFile.lastCopy = xsc::Copy::COPY_0;
|
||||
rebootWatchdogFile.img00Lock = false;
|
||||
rebootWatchdogFile.img01Lock = false;
|
||||
rebootWatchdogFile.img10Lock = false;
|
||||
rebootWatchdogFile.img11Lock = false;
|
||||
rebootWatchdogFile.mechanismNextChip = xsc::Chip::NO_CHIP;
|
||||
rebootWatchdogFile.mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||
rebootWatchdogFile.bootFlag = false;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
} else {
|
||||
if (not parseRebootFile(path, rebootFile)) {
|
||||
performRebootFileHandling(true);
|
||||
if (not parseRebootWatchdogFile(path, rebootWatchdogFile)) {
|
||||
performRebootWatchdogHandling(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (CURRENT_CHIP == xsc::CHIP_0) {
|
||||
if (CURRENT_COPY == xsc::COPY_0) {
|
||||
rebootFile.img00Cnt++;
|
||||
rebootWatchdogFile.img00Cnt++;
|
||||
} else {
|
||||
rebootFile.img01Cnt++;
|
||||
rebootWatchdogFile.img01Cnt++;
|
||||
}
|
||||
} else {
|
||||
if (CURRENT_COPY == xsc::COPY_0) {
|
||||
rebootFile.img10Cnt++;
|
||||
rebootWatchdogFile.img10Cnt++;
|
||||
} else {
|
||||
rebootFile.img11Cnt++;
|
||||
rebootWatchdogFile.img11Cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebootFile.bootFlag) {
|
||||
if (rebootWatchdogFile.bootFlag) {
|
||||
// Trigger event to inform ground that a reboot was triggered
|
||||
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
|
||||
uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 |
|
||||
rebootFile.img11Cnt;
|
||||
uint32_t p1 = rebootWatchdogFile.lastChip << 16 | rebootWatchdogFile.lastCopy;
|
||||
uint32_t p2 = rebootWatchdogFile.img00Cnt << 24 | rebootWatchdogFile.img01Cnt << 16 |
|
||||
rebootWatchdogFile.img10Cnt << 8 | rebootWatchdogFile.img11Cnt;
|
||||
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
|
||||
// Clear the boot flag
|
||||
rebootFile.bootFlag = false;
|
||||
rebootWatchdogFile.bootFlag = false;
|
||||
}
|
||||
|
||||
if (rebootFile.mechanismNextChip != xsc::NO_CHIP and
|
||||
rebootFile.mechanismNextCopy != xsc::NO_COPY) {
|
||||
if (CURRENT_CHIP != rebootFile.mechanismNextChip or
|
||||
CURRENT_COPY != rebootFile.mechanismNextCopy) {
|
||||
std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " +
|
||||
std::to_string(rebootFile.mechanismNextCopy);
|
||||
if (rebootWatchdogFile.mechanismNextChip != xsc::NO_CHIP and
|
||||
rebootWatchdogFile.mechanismNextCopy != xsc::NO_COPY) {
|
||||
if (CURRENT_CHIP != rebootWatchdogFile.mechanismNextChip or
|
||||
CURRENT_COPY != rebootWatchdogFile.mechanismNextCopy) {
|
||||
std::string infoString = std::to_string(rebootWatchdogFile.mechanismNextChip) + " " +
|
||||
std::to_string(rebootWatchdogFile.mechanismNextCopy);
|
||||
sif::warning << "CoreController::performRebootFileHandling: Expected to be on image "
|
||||
<< infoString << " but currently on other image. Locking " << infoString
|
||||
<< std::endl;
|
||||
// Firmware or other component might be corrupt and we are on another image then the target
|
||||
// image specified by the mechanism. We can't really trust the target image anymore.
|
||||
// Lock it for now
|
||||
if (rebootFile.mechanismNextChip == xsc::CHIP_0) {
|
||||
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootFile.img00Lock = true;
|
||||
if (rebootWatchdogFile.mechanismNextChip == xsc::CHIP_0) {
|
||||
if (rebootWatchdogFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootWatchdogFile.img00Lock = true;
|
||||
} else {
|
||||
rebootFile.img01Lock = true;
|
||||
rebootWatchdogFile.img01Lock = true;
|
||||
}
|
||||
} else {
|
||||
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootFile.img10Lock = true;
|
||||
if (rebootWatchdogFile.mechanismNextCopy == xsc::COPY_0) {
|
||||
rebootWatchdogFile.img10Lock = true;
|
||||
} else {
|
||||
rebootFile.img11Lock = true;
|
||||
rebootWatchdogFile.img11Lock = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rebootFile.lastChip = CURRENT_CHIP;
|
||||
rebootFile.lastCopy = CURRENT_COPY;
|
||||
rebootWatchdogFile.lastChip = CURRENT_CHIP;
|
||||
rebootWatchdogFile.lastCopy = CURRENT_COPY;
|
||||
// Only reboot if the reboot functionality is enabled.
|
||||
// The handler will still increment the boot counts
|
||||
if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) {
|
||||
if (rebootWatchdogFile.enabled and
|
||||
(*rebootWatchdogFile.relevantBootCnt >= rebootWatchdogFile.maxCount)) {
|
||||
// Reboot to other image
|
||||
bool doReboot = false;
|
||||
xsc::Chip tgtChip = xsc::NO_CHIP;
|
||||
xsc::Copy tgtCopy = xsc::NO_COPY;
|
||||
determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy);
|
||||
determineAndExecuteReboot(rebootWatchdogFile, doReboot, tgtChip, tgtCopy);
|
||||
if (doReboot) {
|
||||
rebootFile.bootFlag = true;
|
||||
rebootWatchdogFile.bootFlag = true;
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
|
||||
<< " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl;
|
||||
#endif
|
||||
rebootFile.mechanismNextChip = tgtChip;
|
||||
rebootFile.mechanismNextCopy = tgtCopy;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.mechanismNextChip = tgtChip;
|
||||
rebootWatchdogFile.mechanismNextCopy = tgtCopy;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(tgtChip),
|
||||
static_cast<xsc_libnor_copy_t>(tgtCopy));
|
||||
}
|
||||
} else {
|
||||
rebootFile.mechanismNextChip = xsc::NO_CHIP;
|
||||
rebootFile.mechanismNextCopy = xsc::NO_COPY;
|
||||
rebootWatchdogFile.mechanismNextChip = xsc::NO_CHIP;
|
||||
rebootWatchdogFile.mechanismNextCopy = xsc::NO_COPY;
|
||||
}
|
||||
rewriteRebootFile(rebootFile);
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
}
|
||||
|
||||
void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot,
|
||||
void CoreController::determineAndExecuteReboot(RebootWatchdogFile &rf, bool &needsReboot,
|
||||
xsc::Chip &tgtChip, xsc::Copy &tgtCopy) {
|
||||
tgtChip = xsc::CHIP_0;
|
||||
tgtCopy = xsc::COPY_0;
|
||||
@ -217,7 +218,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
|
||||
}
|
||||
}
|
||||
|
||||
bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
|
||||
bool CoreController::parseRebootWatchdogFile(std::string path, RebootWatchdogFile &rf) {
|
||||
using namespace std;
|
||||
std::string selfMatch;
|
||||
if (CURRENT_CHIP == xsc::CHIP_0) {
|
||||
@ -402,31 +403,31 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
|
||||
void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) {
|
||||
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.active) + REBOOT_WATCHDOG_FILE;
|
||||
// Disable the reboot file mechanism
|
||||
parseRebootFile(path, rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) {
|
||||
rebootFile.img00Cnt = 0;
|
||||
rebootFile.img01Cnt = 0;
|
||||
rebootFile.img10Cnt = 0;
|
||||
rebootFile.img11Cnt = 0;
|
||||
rebootWatchdogFile.img00Cnt = 0;
|
||||
rebootWatchdogFile.img01Cnt = 0;
|
||||
rebootWatchdogFile.img10Cnt = 0;
|
||||
rebootWatchdogFile.img11Cnt = 0;
|
||||
} else {
|
||||
if (tgtChip == xsc::CHIP_0) {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img00Cnt = 0;
|
||||
rebootWatchdogFile.img00Cnt = 0;
|
||||
} else {
|
||||
rebootFile.img01Cnt = 0;
|
||||
rebootWatchdogFile.img01Cnt = 0;
|
||||
}
|
||||
} else {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img10Cnt = 0;
|
||||
rebootWatchdogFile.img10Cnt = 0;
|
||||
} else {
|
||||
rebootFile.img11Cnt = 0;
|
||||
rebootWatchdogFile.img11Cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
rewriteRebootFile(rebootFile);
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
}
|
||||
|
||||
void CoreController::rewriteRebootFile(RebootFile file) {
|
||||
void CoreController::rewriteRebootWatchdogFile(RebootWatchdogFile file) {
|
||||
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.active) + REBOOT_WATCHDOG_FILE;
|
||||
std::ofstream rebootFile(path);
|
||||
if (rebootFile.is_open()) {
|
||||
@ -452,13 +453,13 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
}
|
||||
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.active) + REBOOT_WATCHDOG_FILE;
|
||||
// Disable the reboot file mechanism
|
||||
parseRebootFile(path, rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
if (data[0] == 0) {
|
||||
rebootFile.enabled = false;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.enabled = false;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
} else if (data[0] == 1) {
|
||||
rebootFile.enabled = true;
|
||||
rewriteRebootFile(rebootFile);
|
||||
rebootWatchdogFile.enabled = true;
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
} else {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
@ -492,9 +493,9 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
}
|
||||
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.active) + REBOOT_WATCHDOG_FILE;
|
||||
// Disable the reboot file mechanism
|
||||
parseRebootFile(path, rebootFile);
|
||||
rebootFile.maxCount = data[0];
|
||||
rewriteRebootFile(rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
rebootWatchdogFile.maxCount = data[0];
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
default: {
|
||||
@ -506,21 +507,21 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) {
|
||||
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.active) + REBOOT_WATCHDOG_FILE;
|
||||
// Disable the reboot file mechanism
|
||||
parseRebootFile(path, rebootFile);
|
||||
parseRebootWatchdogFile(path, rebootWatchdogFile);
|
||||
if (tgtChip == xsc::CHIP_0) {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img00Lock = lock;
|
||||
rebootWatchdogFile.img00Lock = lock;
|
||||
} else {
|
||||
rebootFile.img01Lock = lock;
|
||||
rebootWatchdogFile.img01Lock = lock;
|
||||
}
|
||||
} else {
|
||||
if (tgtCopy == xsc::COPY_0) {
|
||||
rebootFile.img10Lock = lock;
|
||||
rebootWatchdogFile.img10Lock = lock;
|
||||
} else {
|
||||
rebootFile.img11Lock = lock;
|
||||
rebootWatchdogFile.img11Lock = lock;
|
||||
}
|
||||
}
|
||||
rewriteRebootFile(rebootFile);
|
||||
rewriteRebootWatchdogFile(rebootWatchdogFile);
|
||||
}
|
||||
|
||||
void CoreController::setCurrentBootCopy(xsc::Chip chip, xsc::Copy copy) {
|
||||
|
@ -14,7 +14,7 @@ enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
||||
|
||||
} // namespace xsc
|
||||
|
||||
struct RebootFile {
|
||||
struct RebootWatchdogFile {
|
||||
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
||||
|
||||
bool enabled = true;
|
||||
@ -57,13 +57,13 @@ class CoreController {
|
||||
static void setCurrentBootCopy(xsc::Chip chip, xsc::Copy copy);
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
void performRebootFileHandling(bool recreateFile);
|
||||
void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
|
||||
void performRebootWatchdogHandling(bool recreateFile);
|
||||
void determineAndExecuteReboot(RebootWatchdogFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
|
||||
xsc::Copy& tgtCopy);
|
||||
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
||||
void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
||||
bool parseRebootFile(std::string path, RebootFile& file);
|
||||
void rewriteRebootFile(RebootFile file);
|
||||
bool parseRebootWatchdogFile(std::string path, RebootWatchdogFile& file);
|
||||
void rewriteRebootWatchdogFile(RebootWatchdogFile file);
|
||||
|
||||
private:
|
||||
struct SdFsmParams {
|
||||
@ -74,6 +74,6 @@ class CoreController {
|
||||
} sdInfo;
|
||||
|
||||
SdCardManager* sdcMan = nullptr;
|
||||
RebootFile rebootFile = {};
|
||||
RebootWatchdogFile rebootWatchdogFile = {};
|
||||
bool doPerformRebootFileHandling = true;
|
||||
};
|
Loading…
Reference in New Issue
Block a user