From a3f63e970f364259800f3af9702113b82ed2d2be Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 23 Feb 2022 16:19:05 +0100 Subject: [PATCH] continued reboot handler --- bsp_q7s/core/CoreController.cpp | 237 ++++++++++++++++++++++++---- bsp_q7s/core/CoreController.h | 14 +- bsp_q7s/memory/SdCardManager.cpp | 3 +- bsp_q7s/memory/SdCardManager.h | 4 +- common/config/commonObjects.h | 1 + mission/devices/SusHandler.cpp | 3 +- unittest/CMakeLists.txt | 5 - unittest/rebootLogic/.gitignore | 1 + unittest/rebootLogic/CMakeLists.txt | 11 ++ unittest/rebootLogic/main.cpp | 5 + 10 files changed, 239 insertions(+), 45 deletions(-) delete mode 100644 unittest/CMakeLists.txt create mode 100644 unittest/rebootLogic/.gitignore create mode 100644 unittest/rebootLogic/CMakeLists.txt create mode 100644 unittest/rebootLogic/main.cpp diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 21e4b65e..f60f3cc3 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -16,7 +16,6 @@ #include #include -#include #include @@ -60,6 +59,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { void CoreController::performControlOperation() { performWatchdogControlOperation(); sdStateMachine(); + performRebootFileHandling(false); } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, @@ -794,41 +794,41 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si sif::info << "Target slot was writeprotected before reboot" << std::endl; } - switch(tgtChip) { - case(Chip::CHIP_0): { - switch(tgtCopy) { - case(Copy::COPY_0): { - xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL); + switch (tgtChip) { + case (Chip::CHIP_0): { + switch (tgtCopy) { + case (Copy::COPY_0): { + xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL); + break; + } + case (Copy::COPY_1): { + xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD); + break; + } + default: { + break; + } + } break; } - case(Copy::COPY_1): { - xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD); + case (Chip::CHIP_1): { + switch (tgtCopy) { + case (Copy::COPY_0): { + xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL); + break; + } + case (Copy::COPY_1): { + xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD); + break; + } + default: { + break; + } + } break; } - default: { + default: break; - } - } - break; - } - case(Chip::CHIP_1): { - switch(tgtCopy) { - case(Copy::COPY_0): { - xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL); - break; - } - case(Copy::COPY_1): { - xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD); - break; - } - default: { - break; - } - } - break; - } - default: - break; } return HasReturnvaluesIF::RETURN_FAILED; } @@ -1136,9 +1136,178 @@ void CoreController::performWatchdogControlOperation() { } } -void CoreController::performRebootFileHandling() { - if(doPerformRebootFileHandling and sdcMan->isSdCardMounted(sdInfo.pref)) { - auto mntPrefix = std::filesystem::path(sdcMan->getCurrentMountPrefix(sdInfo.pref)); +void CoreController::performRebootFileHandling(bool recreateFile) { + bool sdCardMounted = false; + if (not recreateFile and doPerformRebootFileHandling) { + sdCardMounted = sdcMan->isSdCardMounted(sdInfo.pref); + } + if ((doPerformRebootFileHandling and sdCardMounted) or recreateFile) { + using namespace std; + if (recreateFile) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl; +#endif + } + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + if (not std::filesystem::exists(path) or recreateFile) { + std::ofstream rebootFile(path); + if (rebootFile.is_open()) { + // Initiate reboot file first. Reboot handling will be on on initialization + rebootFile << "on: 1\nmaxcnt: " << static_cast(DEFAULT_MAX_BOOT_CNT) + << "\nimg00: 0\nimg01: 0\nimg10: 0\nimg11: 0\n"; + } + } + xsc_libnor_chip_t chip; + xsc_libnor_copy_t copy; + xsc_boot_get_chip_copy(&chip, ©); + std::string selfMatch; + if (chip == XSC_LIBNOR_CHIP_0) { + if (copy == XSC_LIBNOR_COPY_NOMINAL) { + selfMatch = "00"; + } else { + selfMatch = "01"; + } + } else { + if (copy == XSC_LIBNOR_COPY_NOMINAL) { + selfMatch = "10"; + } else { + selfMatch = "11"; + } + } + uint8_t relevantBootCnt = 0; + bool on = true; + size_t maxCnt = DEFAULT_MAX_BOOT_CNT; + uint8_t bootCnt00 = 0; + uint8_t bootCnt01 = 0; + uint8_t bootCnt10 = 0; + uint8_t bootCnt11 = 0; + ifstream file(path); + string word; + + string line; + uint8_t lineIdx = 0; + while (std::getline(file, line)) { + istringstream iss(line); + switch (lineIdx) { + case 0: { + iss >> word; + if (word.find("on:") == string::npos) { + // invalid file + performRebootFileHandling(true); + return; + } + iss >> on; + break; + } + case 1: { + iss >> word; + if (word.find("maxcnt:") == string::npos) { + performRebootFileHandling(true); + return; + } + iss >> maxCnt; + break; + } + case 2: { + iss >> word; + if (word.find("img00:") == string::npos) { + performRebootFileHandling(true); + return; + } + iss >> bootCnt00; + if (word.find(selfMatch) != string::npos) { + relevantBootCnt = bootCnt00; + } + break; + } + case 3: { + iss >> word; + if (word.find("img01:") == string::npos) { + performRebootFileHandling(true); + return; + } + iss >> bootCnt01; + if (word.find(selfMatch) != string::npos) { + relevantBootCnt = bootCnt01; + } + break; + } + case 4: { + iss >> word; + if (word.find("img10:") == string::npos) { + performRebootFileHandling(true); + return; + } + iss >> bootCnt10; + if (word.find(selfMatch) != string::npos) { + relevantBootCnt = bootCnt10; + } + break; + } + case 5: { + iss >> word; + if (word.find("img11:") == string::npos) { + performRebootFileHandling(true); + return; + } + iss >> bootCnt11; + if (word.find(selfMatch) != string::npos) { + relevantBootCnt = bootCnt11; + } + break; + } + } + lineIdx++; + } + if (relevantBootCnt > maxCnt) { + // Reboot to other image + determineAndExecuteReboot(copy, chip, bootCnt00, bootCnt01, bootCnt10, bootCnt11, maxCnt); + } doPerformRebootFileHandling = false; } } + +void CoreController::determineAndExecuteReboot(xsc_libnor_copy_t copy, xsc_libnor_chip_t chip, + uint8_t cnt00, uint8_t cnt01, uint8_t cnt10, + uint8_t cnt11, uint8_t maxCnt) { + xsc_libnor_chip_t tgtChip = XSC_LIBNOR_CHIP_0; + xsc_libnor_copy_t tgtCopy = XSC_LIBNOR_COPY_NOMINAL; + if((copy == XSC_LIBNOR_COPY_GOLD) and (chip == XSC_LIBNOR_CHIP_1) and (cnt11 >= maxCnt)) { + if(cnt10 >= maxCnt) { + if(cnt00 >= maxCnt) { + if(cnt01 >= maxCnt) { + // Reboot to fallback image + } else { + tgtChip = XSC_LIBNOR_CHIP_0; + tgtCopy = XSC_LIBNOR_COPY_GOLD; + } + } else { + tgtChip = XSC_LIBNOR_CHIP_0; + tgtCopy = XSC_LIBNOR_COPY_NOMINAL; + } + } else { + tgtChip = XSC_LIBNOR_CHIP_1; + tgtCopy = XSC_LIBNOR_COPY_NOMINAL; + } + } + if((copy == XSC_LIBNOR_COPY_NOMINAL) and (chip == XSC_LIBNOR_CHIP_0) and (cnt00 >= maxCnt)) { + if(cnt01 >= maxCnt) { + if(cnt10 >= maxCnt) { + if(cnt11 >= maxCnt) { + // Can't really do much here. Stay on image + sif::warning << "All reboot counts too high, but already on fallback image" << std::endl; + return; + } else { + tgtChip = XSC_LIBNOR_CHIP_1; + tgtCopy = XSC_LIBNOR_COPY_NOMINAL; + } + } else { + tgtChip = XSC_LIBNOR_CHIP_1; + tgtCopy = XSC_LIBNOR_COPY_GOLD; + } + } else { + tgtCopy = XSC_LIBNOR_COPY_GOLD; + } + } + xsc_boot_copy(tgtChip, tgtCopy); +} diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 75ac0433..78d7584b 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -1,12 +1,15 @@ #ifndef BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_ -#include - #include "bsp_q7s/memory/SdCardManager.h" #include "events/subsystemIdRanges.h" + +#include #include "fsfw/controller/ExtendedControllerBase.h" +#include +#include + class Timer; class SdCardManager; @@ -20,6 +23,9 @@ class CoreController : public ExtendedControllerBase { static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt"; static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt"; static constexpr char VERSION_FILE[] = "/conf/version.txt"; + static constexpr char REBOOT_FILE[] = "/conf/reboot.txt"; + + static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10; static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; static constexpr ActionId_t REBOOT_OBC = 32; @@ -153,7 +159,7 @@ class CoreController : public ExtendedControllerBase { void determinePreferredSdCard(); void executeNextExternalSdCommand(); void checkExternalSdCommandStatus(); - void performRebootFileHandling(); + void performRebootFileHandling(bool recreateFile); ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size); @@ -165,6 +171,8 @@ class CoreController : public ExtendedControllerBase { int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect, bool& protOperationPerformed, bool selfChip, bool selfCopy, bool allChips, bool allCopies, uint8_t arrIdx); + void determineAndExecuteReboot(xsc_libnor_copy_t copy, xsc_libnor_chip_t chip, uint8_t cnt00, + uint8_t cnt01, uint8_t cnt10, uint8_t cnt11, uint8_t maxCnt); }; #endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */ diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 3647ff7b..b9b89bb9 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -7,6 +7,7 @@ #include #include +#include "common/config/commonObjects.h" #include "fsfw/ipc/MutexFactory.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "linux/utility/utility.h" @@ -14,7 +15,7 @@ SdCardManager* SdCardManager::factoryInstance = nullptr; -SdCardManager::SdCardManager() : cmdExecutor(256) {} +SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) {} SdCardManager::~SdCardManager() {} diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index ba5c934a..51ea3425 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ +#include #include #include @@ -22,7 +23,7 @@ class MutexIF; * @brief Manages handling of SD cards like switching them on or off or getting the current * state */ -class SdCardManager { +class SdCardManager : public SystemObject { friend class SdCardAccess; public: @@ -54,6 +55,7 @@ class SdCardManager { static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); + static constexpr Event MOUNTED_SD_CARD = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); // C++17 does not support constexpr std::string yet static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index c97bdd41..6cc90be9 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -11,6 +11,7 @@ enum commonObjects: uint32_t { TMTC_BRIDGE = 0x50000300, TMTC_POLLING_TASK = 0x50000400, FILE_SYSTEM_HANDLER = 0x50000500, + SDC_MANAGER = 0x50000550, PTME = 0x50000600, PDEC_HANDLER = 0x50000700, CCSDS_HANDLER = 0x50000800, diff --git a/mission/devices/SusHandler.cpp b/mission/devices/SusHandler.cpp index 9c55409e..602e0a20 100644 --- a/mission/devices/SusHandler.cpp +++ b/mission/devices/SusHandler.cpp @@ -214,7 +214,8 @@ void SusHandler::setToGoToNormalMode(bool enable) { this->goToNormalModeImmediat void SusHandler::printDataset() { if (periodicPrintout) { if (divider.checkAndIncrement()) { - sif::info << "SUS ADC " << static_cast(susIdx) << " hex [" << std::setfill('0') << std::hex; + sif::info << "SUS ADC " << static_cast(susIdx) << " hex [" << std::setfill('0') + << std::hex; for (uint8_t idx = 0; idx < 6; idx++) { sif::info << std::setw(3) << dataset.channels[idx]; if (idx < 6 - 1) { diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt deleted file mode 100644 index 0c799d45..00000000 --- a/unittest/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_subdirectory(testcfg) - -target_sources(${TARGET_NAME} PRIVATE - main.cpp -) \ No newline at end of file diff --git a/unittest/rebootLogic/.gitignore b/unittest/rebootLogic/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/unittest/rebootLogic/.gitignore @@ -0,0 +1 @@ +/build diff --git a/unittest/rebootLogic/CMakeLists.txt b/unittest/rebootLogic/CMakeLists.txt new file mode 100644 index 00000000..74fdb423 --- /dev/null +++ b/unittest/rebootLogic/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.0.0) +project(reboot-logic VERSION 0.1.0) + +include(CTest) +enable_testing() + +add_executable(reboot-logic main.cpp) + +set(CPACK_PROJECT_NAME ${PROJECT_NAME}) +set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) +include(CPack) diff --git a/unittest/rebootLogic/main.cpp b/unittest/rebootLogic/main.cpp new file mode 100644 index 00000000..c4a394dc --- /dev/null +++ b/unittest/rebootLogic/main.cpp @@ -0,0 +1,5 @@ +#include + +int main(int, char**) { + std::cout << "Hello, world!\n"; +}