diff --git a/fsfw b/fsfw index 6e0b9069..2d9216ba 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 6e0b90696da2dfd2ec4749dfdb73950be2283c25 +Subproject commit 2d9216ba19f1931225daa5b6b6f244a48c09f1b9 diff --git a/unittest/rebootLogic/src/CoreController.cpp b/unittest/rebootLogic/src/CoreController.cpp index 3a6b2e52..a813cde7 100644 --- a/unittest/rebootLogic/src/CoreController.cpp +++ b/unittest/rebootLogic/src/CoreController.cpp @@ -31,6 +31,12 @@ void CoreController::performRebootFileHandling(bool recreateFile) { 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); } else { @@ -39,41 +45,17 @@ void CoreController::performRebootFileHandling(bool recreateFile) { } } - switch (CURRENT_CHIP) { - case (xsc::CHIP_0): { - switch (CURRENT_COPY) { - case (xsc::COPY_0): { - rebootFile.img00Cnt++; - break; - } - case (xsc::COPY_1): { - rebootFile.img01Cnt++; - break; - } - default: { - break; - } - } - break; + if (CURRENT_CHIP == xsc::CHIP_0) { + if (CURRENT_COPY == xsc::COPY_0) { + rebootFile.img00Cnt++; + } else { + rebootFile.img01Cnt++; } - case (xsc::CHIP_1): { - switch (CURRENT_COPY) { - case (xsc::COPY_0): { - rebootFile.img10Cnt++; - break; - } - case (xsc::COPY_1): { - rebootFile.img11Cnt++; - break; - } - default: { - break; - } - } - break; - } - default: { - break; + } else { + if (CURRENT_COPY == xsc::COPY_0) { + rebootFile.img10Cnt++; + } else { + rebootFile.img11Cnt++; } } @@ -87,6 +69,27 @@ void CoreController::performRebootFileHandling(bool recreateFile) { rebootFile.bootFlag = false; } + if(rebootFile.mechanismNextChip != xsc::NO_CHIP and rebootFile.mechanismNextCopy != xsc::NO_COPY) { + if(CURRENT_CHIP != rebootFile.mechanismNextChip or CURRENT_COPY != rebootFile.mechanismNextCopy) { + // 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; + } else { + rebootFile.img01Lock = true; + } + } else { + if (rebootFile.mechanismNextCopy == xsc::COPY_0) { + rebootFile.img10Lock = true; + } else { + rebootFile.img11Lock = true; + } + } + } + } + // Only reboot if the reboot functionality is enabled. // The handler will still increment the boot counts if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) { @@ -104,6 +107,8 @@ void CoreController::performRebootFileHandling(bool recreateFile) { #endif rebootFile.lastChip = CURRENT_CHIP; rebootFile.lastCopy = CURRENT_COPY; + rebootFile.mechanismNextChip = tgtChip; + rebootFile.mechanismNextCopy = tgtCopy; rewriteRebootFile(rebootFile); xsc_boot_copy(static_cast(tgtChip), static_cast(tgtCopy)); @@ -122,82 +127,82 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_0) and (rf.img00Cnt >= rf.maxCount)) { needsReboot = true; - if (rf.img01Cnt >= rf.maxCount) { - if (rf.img10Cnt >= rf.maxCount) { - if (rf.img11Cnt >= rf.maxCount) { - // Can't really do much here. Stay on image - std::cout << "All reboot counts too high, but already on fallback image" << std::endl; - return; - } else { - tgtChip = xsc::CHIP_1; - tgtCopy = xsc::COPY_1; - } - } else { - tgtChip = xsc::CHIP_1; - tgtCopy = xsc::COPY_0; - } - } else { + if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) { tgtCopy = xsc::COPY_1; + return; + } + if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) { + tgtChip = xsc::CHIP_1; + return; } + if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) { + tgtChip = xsc::CHIP_1; + tgtCopy = xsc::COPY_1; + return; + } + // Can't really do much here. Stay on image + std::cout << "All reboot counts too high or all fallback images locked, already on fallback image" << std::endl; + needsReboot = false; + return; } if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_1) and (rf.img01Cnt >= rf.maxCount)) { needsReboot = true; - if (rf.img00Cnt >= rf.maxCount) { - if (rf.img10Cnt >= rf.maxCount) { - if (rf.img11Cnt >= rf.maxCount) { - // Reboot to fallback image - } else { - tgtChip = xsc::CHIP_1; - tgtCopy = xsc::COPY_1; - } - } else { - tgtChip = xsc::CHIP_1; - tgtCopy = xsc::COPY_0; - } - } else { + if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) { // Reboot on fallback image + return; } + if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) { + tgtChip = xsc::CHIP_1; + return; + } + if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) { + tgtChip = xsc::CHIP_1; + tgtCopy = xsc::COPY_1; + } + if(rf.img00Lock) { + needsReboot = false; + } + // Reboot to fallback image } if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_0) and (rf.img10Cnt >= rf.maxCount)) { needsReboot = true; - if (rf.img11Cnt >= rf.maxCount) { - if (rf.img00Cnt >= rf.maxCount) { - if (rf.img01Cnt >= rf.maxCount) { - // Reboot to fallback image - } else { - tgtChip = xsc::CHIP_0; - tgtCopy = xsc::COPY_1; - } - } else { - tgtChip = xsc::CHIP_0; - tgtCopy = xsc::COPY_0; - } - } else { + if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) { tgtChip = xsc::CHIP_1; tgtCopy = xsc::COPY_1; + return; } + if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) { + return; + } + if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) { + tgtCopy = xsc::COPY_1; + return; + } + if(rf.img00Lock) { + needsReboot = false; + } + // Reboot to fallback image } if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_1) and (rf.img11Cnt >= rf.maxCount)) { needsReboot = true; - if (rf.img10Cnt >= rf.maxCount) { - if (rf.img00Cnt >= rf.maxCount) { - if (rf.img01Cnt >= rf.maxCount) { - // Reboot to fallback image - } else { - tgtChip = xsc::CHIP_0; - tgtCopy = xsc::COPY_1; - } - } else { - tgtChip = xsc::CHIP_0; - tgtCopy = xsc::COPY_0; - } - } else { + if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) { tgtChip = xsc::CHIP_1; - tgtCopy = xsc::COPY_0; + return; } + if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) { + return; + } + if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) { + tgtCopy = xsc::COPY_1; + return; + } + if(rf.img00Lock) { + needsReboot = false; + } + // Reboot to fallback image } } @@ -286,6 +291,38 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) { break; } case 6: { + iss >> word; + if (word.find("img00lock:") == string::npos) { + return false; + } + iss >> rf.img00Lock; + break; + } + case 7: { + iss >> word; + if (word.find("img01lock:") == string::npos) { + return false; + } + iss >> rf.img01Lock; + break; + } + case 8: { + iss >> word; + if (word.find("img10lock:") == string::npos) { + return false; + } + iss >> rf.img10Lock; + break; + } + case 9: { + iss >> word; + if (word.find("img11lock:") == string::npos) { + return false; + } + iss >> rf.img11Lock; + break; + } + case 10: { iss >> word; if (word.find("bootflag:") == string::npos) { return false; @@ -293,7 +330,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) { iss >> rf.bootFlag; break; } - case 7: { + case 11: { iss >> word; int copyRaw = 0; int chipRaw = 0; @@ -314,6 +351,30 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) { } rf.lastChip = static_cast(chipRaw); rf.lastCopy = static_cast(copyRaw); + break; + } + case 12: { + iss >> word; + int copyRaw = 0; + int chipRaw = 0; + if (word.find("next:") == string::npos) { + return false; + } + iss >> chipRaw; + if (iss.fail()) { + return false; + } + iss >> copyRaw; + if (iss.fail()) { + return false; + } + + if (chipRaw > 2 or copyRaw > 2) { + return false; + } + rf.mechanismNextChip = static_cast(chipRaw); + rf.mechanismNextCopy = static_cast(copyRaw); + break; } } if (iss.fail()) { @@ -362,8 +423,12 @@ void CoreController::rewriteRebootFile(RebootFile file) { rebootFile << "on: " << file.enabled << "\nmaxcnt: " << file.maxCount << "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt << "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt + << "\nimg00lock: " << file.img00Lock << "\nimg01lock: " << file.img01Lock + << "\nimg10lock: " << file.img01Lock << "\nimg11lock: " << file.img11Lock << "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast(file.lastChip) - << " " << static_cast(file.lastCopy) << "\n"; + << " " << static_cast(file.lastCopy) << "\nnext: " + << static_cast(file.mechanismNextChip) << " " + << static_cast(file.mechanismNextCopy) << "\n"; } } diff --git a/unittest/rebootLogic/src/CoreController.h b/unittest/rebootLogic/src/CoreController.h index d7d20433..e5b56595 100644 --- a/unittest/rebootLogic/src/CoreController.h +++ b/unittest/rebootLogic/src/CoreController.h @@ -24,10 +24,16 @@ struct RebootFile { uint32_t img01Cnt = 0; uint32_t img10Cnt = 0; uint32_t img11Cnt = 0; + bool img00Lock = false; + bool img01Lock = false; + bool img10Lock = false; + bool img11Lock = false; uint32_t* relevantBootCnt = &img00Cnt; bool bootFlag = false; xsc::Chip lastChip = xsc::Chip::CHIP_0; xsc::Copy lastCopy = xsc::Copy::COPY_0; + xsc::Chip mechanismNextChip = xsc::Chip::NO_CHIP; + xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY; }; class SdCardManager; diff --git a/unittest/rebootLogic/src/main.cpp b/unittest/rebootLogic/src/main.cpp index 9d6ef218..fbd6cc03 100644 --- a/unittest/rebootLogic/src/main.cpp +++ b/unittest/rebootLogic/src/main.cpp @@ -48,8 +48,8 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { REQUIRE(rf.img10Cnt == 0); REQUIRE(rf.img11Cnt == 0); REQUIRE(rf.bootFlag == 0); - REQUIRE(rf.lastChip == 0); - REQUIRE(rf.lastCopy == 0); + REQUIRE(rf.lastChip == xsc::CHIP_0); + REQUIRE(rf.lastCopy == xsc::COPY_0); uint8_t newRebootCnt = 3; CHECK(ctrl.executeAction(CoreController::SET_MAX_REBOOT_CNT, 0, &newRebootCnt, 1) == HasActionsIF::EXECUTION_FINISHED); ctrl.parseRebootFile(REBOOT_FILE, rf); @@ -163,8 +163,9 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { CHECK(((info.p2 >> 16) & 0xFF) == 3); CHECK(((info.p2 >> 8) & 0xFF) == 3); CHECK((info.p2 & 0xFF) == 3); + // No reboot was triggered ctrl.parseRebootFile(REBOOT_FILE, rf); - REQUIRE(rf.img00Cnt == 4); + REQUIRE(rf.img00Cnt == 3); REQUIRE(rf.img01Cnt == 3); REQUIRE(rf.img10Cnt == 3); REQUIRE(rf.img11Cnt == 3); @@ -175,7 +176,7 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { ctrl.performRebootFileHandling(false); ctrl.parseRebootFile(REBOOT_FILE, rf); REQUIRE(rf.enabled == 1); - REQUIRE(rf.img00Cnt == 5); + REQUIRE(rf.img00Cnt == 4); REQUIRE(rf.img01Cnt == 0); REQUIRE(rf.img10Cnt == 3); REQUIRE(rf.img11Cnt == 3);