continued reboot handler

This commit is contained in:
Robin Müller 2022-02-23 16:19:05 +01:00
parent dbba10185c
commit a3f63e970f
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
10 changed files with 239 additions and 45 deletions

View File

@ -16,7 +16,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <libxiphos.h>
#include <filesystem> #include <filesystem>
@ -60,6 +59,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
void CoreController::performControlOperation() { void CoreController::performControlOperation() {
performWatchdogControlOperation(); performWatchdogControlOperation();
sdStateMachine(); sdStateMachine();
performRebootFileHandling(false);
} }
ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, 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; sif::info << "Target slot was writeprotected before reboot" << std::endl;
} }
switch(tgtChip) { switch (tgtChip) {
case(Chip::CHIP_0): { case (Chip::CHIP_0): {
switch(tgtCopy) { switch (tgtCopy) {
case(Copy::COPY_0): { case (Copy::COPY_0): {
xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL); 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; break;
} }
case(Copy::COPY_1): { case (Chip::CHIP_1): {
xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD); 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; break;
} }
default: { default:
break; 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; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -1136,9 +1136,178 @@ void CoreController::performWatchdogControlOperation() {
} }
} }
void CoreController::performRebootFileHandling() { void CoreController::performRebootFileHandling(bool recreateFile) {
if(doPerformRebootFileHandling and sdcMan->isSdCardMounted(sdInfo.pref)) { bool sdCardMounted = false;
auto mntPrefix = std::filesystem::path(sdcMan->getCurrentMountPrefix(sdInfo.pref)); 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<int>(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, &copy);
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; 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);
}

View File

@ -1,12 +1,15 @@
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_ #ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
#define BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/SdCardManager.h"
#include "events/subsystemIdRanges.h" #include "events/subsystemIdRanges.h"
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include "fsfw/controller/ExtendedControllerBase.h" #include "fsfw/controller/ExtendedControllerBase.h"
#include <cstddef>
#include <libxiphos.h>
class Timer; class Timer;
class SdCardManager; class SdCardManager;
@ -20,6 +23,9 @@ class CoreController : public ExtendedControllerBase {
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt"; static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt"; static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
static constexpr char VERSION_FILE[] = "/conf/version.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 LIST_DIRECTORY_INTO_FILE = 0;
static constexpr ActionId_t REBOOT_OBC = 32; static constexpr ActionId_t REBOOT_OBC = 32;
@ -153,7 +159,7 @@ class CoreController : public ExtendedControllerBase {
void determinePreferredSdCard(); void determinePreferredSdCard();
void executeNextExternalSdCommand(); void executeNextExternalSdCommand();
void checkExternalSdCommandStatus(); void checkExternalSdCommandStatus();
void performRebootFileHandling(); void performRebootFileHandling(bool recreateFile);
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size); const uint8_t* data, size_t size);
@ -165,6 +171,8 @@ class CoreController : public ExtendedControllerBase {
int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect, int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
bool& protOperationPerformed, bool selfChip, bool selfCopy, bool& protOperationPerformed, bool selfChip, bool selfCopy,
bool allChips, bool allCopies, uint8_t arrIdx); 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_ */ #endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */

View File

@ -7,6 +7,7 @@
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include "common/config/commonObjects.h"
#include "fsfw/ipc/MutexFactory.h" #include "fsfw/ipc/MutexFactory.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include "linux/utility/utility.h" #include "linux/utility/utility.h"
@ -14,7 +15,7 @@
SdCardManager* SdCardManager::factoryInstance = nullptr; SdCardManager* SdCardManager::factoryInstance = nullptr;
SdCardManager::SdCardManager() : cmdExecutor(256) {} SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) {}
SdCardManager::~SdCardManager() {} SdCardManager::~SdCardManager() {}

View File

@ -1,6 +1,7 @@
#ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_
#define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <poll.h> #include <poll.h>
#include <array> #include <array>
@ -22,7 +23,7 @@ class MutexIF;
* @brief Manages handling of SD cards like switching them on or off or getting the current * @brief Manages handling of SD cards like switching them on or off or getting the current
* state * state
*/ */
class SdCardManager { class SdCardManager : public SystemObject {
friend class SdCardAccess; friend class SdCardAccess;
public: public:
@ -54,6 +55,7 @@ class SdCardManager {
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; 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 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 // C++17 does not support constexpr std::string yet
static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1";

View File

@ -11,6 +11,7 @@ enum commonObjects: uint32_t {
TMTC_BRIDGE = 0x50000300, TMTC_BRIDGE = 0x50000300,
TMTC_POLLING_TASK = 0x50000400, TMTC_POLLING_TASK = 0x50000400,
FILE_SYSTEM_HANDLER = 0x50000500, FILE_SYSTEM_HANDLER = 0x50000500,
SDC_MANAGER = 0x50000550,
PTME = 0x50000600, PTME = 0x50000600,
PDEC_HANDLER = 0x50000700, PDEC_HANDLER = 0x50000700,
CCSDS_HANDLER = 0x50000800, CCSDS_HANDLER = 0x50000800,

View File

@ -214,7 +214,8 @@ void SusHandler::setToGoToNormalMode(bool enable) { this->goToNormalModeImmediat
void SusHandler::printDataset() { void SusHandler::printDataset() {
if (periodicPrintout) { if (periodicPrintout) {
if (divider.checkAndIncrement()) { if (divider.checkAndIncrement()) {
sif::info << "SUS ADC " << static_cast<int>(susIdx) << " hex [" << std::setfill('0') << std::hex; sif::info << "SUS ADC " << static_cast<int>(susIdx) << " hex [" << std::setfill('0')
<< std::hex;
for (uint8_t idx = 0; idx < 6; idx++) { for (uint8_t idx = 0; idx < 6; idx++) {
sif::info << std::setw(3) << dataset.channels[idx]; sif::info << std::setw(3) << dataset.channels[idx];
if (idx < 6 - 1) { if (idx < 6 - 1) {

View File

@ -1,5 +0,0 @@
add_subdirectory(testcfg)
target_sources(${TARGET_NAME} PRIVATE
main.cpp
)

1
unittest/rebootLogic/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -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)

View File

@ -0,0 +1,5 @@
#include <iostream>
int main(int, char**) {
std::cout << "Hello, world!\n";
}