Reboot File Handling #154

Merged
meierj merged 27 commits from mueller/reboot-file-handling into develop 2022-03-01 17:24:27 +01:00
11 changed files with 299 additions and 92 deletions
Showing only changes of commit 0d1ff8585c - Show all commits

View File

@ -151,8 +151,8 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
resetRebootCount(xsc::CHIP_1, xsc::COPY_1);
return HasActionsIF::EXECUTION_FINISHED;
}
case(SET_MAX_REBOOT_CNT): {
if(size < 1) {
case (SET_MAX_REBOOT_CNT): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
@ -1189,7 +1189,7 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
if (not std::filesystem::exists(path) or recreateFile) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
std::cout << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
#endif
rebootFile.enabled = true;
rebootFile.img00Cnt = 0;
@ -1206,16 +1206,6 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
}
}
if (rebootFile.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;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
// Clear the boot flag
rebootFile.bootFlag = false;
}
switch (CURRENT_CHIP) {
case (xsc::CHIP_0): {
switch (CURRENT_COPY) {
@ -1253,22 +1243,34 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
break;
}
}
if (CURRENT_CHIP == xsc::CHIP_0 and CURRENT_COPY == xsc::COPY_0) {
if (rebootFile.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;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
// Clear the boot flag
rebootFile.bootFlag = false;
}
if (rebootFile.relevantBootCnt > rebootFile.maxCount) {
if (*rebootFile.relevantBootCnt >= rebootFile.maxCount) {
// Reboot to other image
bool doReboot = false;
determineAndExecuteReboot(rebootFile, doReboot, rebootFile.lastChip, rebootFile.lastCopy);
xsc::Chip tgtChip = xsc::NO_CHIP;
xsc::Copy tgtCopy = xsc::NO_COPY;
determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy);
if (doReboot) {
rebootFile.bootFlag = true;
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
<< "too high. Rebooting to " << rebootFile.lastChip << " " << rebootFile.lastCopy
<< std::endl;
std::cout << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
<< " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl;
#endif
rebootFile.lastChip = CURRENT_CHIP;
rebootFile.lastCopy = CURRENT_COPY;
rewriteRebootFile(rebootFile);
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(rebootFile.lastChip),
static_cast<xsc_libnor_copy_t>(rebootFile.lastCopy));
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(tgtChip),
static_cast<xsc_libnor_copy_t>(tgtCopy));
}
} else {
rewriteRebootFile(rebootFile);
@ -1280,14 +1282,14 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
tgtChip = xsc::CHIP_0;
tgtCopy = xsc::COPY_0;

There might be the unlikely but nevertheless possible case that one of the firmware images is corrupted and all reboot counters except for the counter of the partition containing the corrupted firmware reached the maximum reboot count. I think this could lead in the current configuration to a scenario where the OBSW tries to boot from the partition with the corrupted firmware (because the reboot counter for this image is the only one not set to max reboot counts) but always ends in another image because the Xiphos bootloader prevents booting the corrupted image (according to datasheet performs integrity check by means of a CRC and md5sum).
Just my thoughts on this. Maybe you already considered this scenario.

There might be the unlikely but nevertheless possible case that one of the firmware images is corrupted and all reboot counters except for the counter of the partition containing the corrupted firmware reached the maximum reboot count. I think this could lead in the current configuration to a scenario where the OBSW tries to boot from the partition with the corrupted firmware (because the reboot counter for this image is the only one not set to max reboot counts) but always ends in another image because the Xiphos bootloader prevents booting the corrupted image (according to datasheet performs integrity check by means of a CRC and md5sum). Just my thoughts on this. Maybe you already considered this scenario.
needsReboot = false;
if ((CURRENT_COPY == xsc::COPY_0) and (CURRENT_CHIP == xsc::CHIP_0) and
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
sif::warning << "All reboot counts too high, but already on fallback image" << std::endl;
std::cout << "All reboot counts too high, but already on fallback image" << std::endl;
return;
} else {
tgtChip = xsc::CHIP_1;
@ -1301,7 +1303,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
tgtCopy = xsc::COPY_1;
}
}
if ((CURRENT_COPY == xsc::COPY_0) and (CURRENT_CHIP == xsc::CHIP_1) and
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img01Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img00Cnt >= rf.maxCount) {
@ -1320,7 +1322,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
// Reboot on fallback image
}
}
if ((CURRENT_COPY == xsc::COPY_1) and (CURRENT_CHIP == xsc::CHIP_0) and
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img10Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img11Cnt >= rf.maxCount) {
@ -1340,7 +1342,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
tgtCopy = xsc::COPY_1;
}
}
if ((CURRENT_COPY == xsc::COPY_1) and (CURRENT_CHIP == xsc::CHIP_1) and
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img11Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img10Cnt >= rf.maxCount) {
@ -1409,7 +1411,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img00Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img00Cnt;
rf.relevantBootCnt = &rf.img00Cnt;
}
break;
}
@ -1420,7 +1422,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img01Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img01Cnt;
rf.relevantBootCnt = &rf.img01Cnt;
}
break;
}
@ -1431,7 +1433,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img10Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img10Cnt;
rf.relevantBootCnt = &rf.img10Cnt;
}
break;
}
@ -1442,7 +1444,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img11Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img11Cnt;
rf.relevantBootCnt = &rf.img11Cnt;
}
break;
}
@ -1456,15 +1458,8 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
case 7: {
iss >> word;
if (word.find("bootflag:") == string::npos) {
return false;
}
break;
}
case 8: {
iss >> word;
uint8_t copyRaw = 0;
uint8_t chipRaw = 0;
int copyRaw = 0;
int chipRaw = 0;
if (word.find("last:") == string::npos) {
return false;
}

View File

@ -15,8 +15,8 @@ class SdCardManager;
namespace xsc {
enum Chip : uint8_t { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : uint8_t { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
} // namespace xsc
@ -29,7 +29,7 @@ struct RebootFile {
uint32_t img01Cnt = 0;
uint32_t img10Cnt = 0;
uint32_t img11Cnt = 0;
uint32_t relevantBootCnt = 0;
uint32_t* relevantBootCnt = &img00Cnt;
bool bootFlag = false;
xsc::Chip lastChip = xsc::Chip::CHIP_0;
xsc::Copy lastCopy = xsc::Copy::COPY_0;

View File

@ -1,6 +1,51 @@
{
"editor.tabSize": 2,
"files.associations": {
"iosfwd": "cpp"
"iosfwd": "cpp",
"array": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"fstream": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"numbers": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"variant": "cpp",
"filesystem": "cpp",
"queue": "cpp"
}
}

View File

@ -14,6 +14,7 @@ xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
CoreController::CoreController() {
sdcMan = new SdCardManager();
setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0);
}
void CoreController::performRebootFileHandling(bool recreateFile) {
@ -38,16 +39,6 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
}
}
if (rebootFile.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;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
// Clear the boot flag
rebootFile.bootFlag = false;
}
switch (CURRENT_CHIP) {
case (xsc::CHIP_0): {
switch (CURRENT_COPY) {
@ -85,22 +76,35 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
break;
}
}
if (CURRENT_CHIP == xsc::CHIP_0 and CURRENT_COPY == xsc::COPY_0) {
if (rebootFile.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;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
// Clear the boot flag
rebootFile.bootFlag = false;
}
if (rebootFile.relevantBootCnt > rebootFile.maxCount) {
if (*rebootFile.relevantBootCnt >= rebootFile.maxCount) {
// Reboot to other image
bool doReboot = false;
determineAndExecuteReboot(rebootFile, doReboot, rebootFile.lastChip, rebootFile.lastCopy);
xsc::Chip tgtChip = xsc::NO_CHIP;
xsc::Copy tgtCopy = xsc::NO_COPY;
determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy);
if (doReboot) {
rebootFile.bootFlag = true;
#if OBSW_VERBOSE_LEVEL >= 1
std::cout << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
<< "too high. Rebooting to " << rebootFile.lastChip << " " << rebootFile.lastCopy
<< " too high. Rebooting to " << tgtChip << " " << tgtCopy
<< std::endl;
#endif
rebootFile.lastChip = CURRENT_CHIP;
rebootFile.lastCopy = CURRENT_COPY;
rewriteRebootFile(rebootFile);
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(rebootFile.lastChip),
static_cast<xsc_libnor_copy_t>(rebootFile.lastCopy));
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(tgtChip),
static_cast<xsc_libnor_copy_t>(tgtCopy));
}
} else {
rewriteRebootFile(rebootFile);
@ -113,7 +117,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
tgtChip = xsc::CHIP_0;
tgtCopy = xsc::COPY_0;
needsReboot = false;
if ((CURRENT_COPY == xsc::COPY_0) and (CURRENT_CHIP == xsc::CHIP_0) and
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img00Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img01Cnt >= rf.maxCount) {
@ -134,7 +138,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
tgtCopy = xsc::COPY_1;
}
}
if ((CURRENT_COPY == xsc::COPY_0) and (CURRENT_CHIP == xsc::CHIP_1) and
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img01Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img00Cnt >= rf.maxCount) {
@ -153,7 +157,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
// Reboot on fallback image
}
}
if ((CURRENT_COPY == xsc::COPY_1) and (CURRENT_CHIP == xsc::CHIP_0) and
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img10Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img11Cnt >= rf.maxCount) {
@ -173,7 +177,7 @@ void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot
tgtCopy = xsc::COPY_1;
}
}
if ((CURRENT_COPY == xsc::COPY_1) and (CURRENT_CHIP == xsc::CHIP_1) and
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img11Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img10Cnt >= rf.maxCount) {
@ -242,7 +246,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img00Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img00Cnt;
rf.relevantBootCnt = &rf.img00Cnt;
}
break;
}
@ -253,7 +257,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img01Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img01Cnt;
rf.relevantBootCnt = &rf.img01Cnt;
}
break;
}
@ -264,7 +268,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img10Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img10Cnt;
rf.relevantBootCnt = &rf.img10Cnt;
}
break;
}
@ -275,7 +279,7 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
iss >> rf.img11Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = rf.img11Cnt;
rf.relevantBootCnt = &rf.img11Cnt;
}
break;
}
@ -289,15 +293,8 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
}
case 7: {
iss >> word;
if (word.find("bootflag:") == string::npos) {
return false;
}
break;
}
case 8: {
iss >> word;
uint8_t copyRaw = 0;
uint8_t chipRaw = 0;
int copyRaw = 0;
int chipRaw = 0;
if (word.find("last:") == string::npos) {
return false;
}
@ -363,8 +360,8 @@ void CoreController::rewriteRebootFile(RebootFile file) {
rebootFile << "on: " << file.enabled << "\nmaxcnt: " << file.maxCount
<< "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt
<< "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt
<< "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast<int>(file.lastChip) << " "
<< static_cast<int>(file.lastCopy) << "\n";
<< "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast<int>(file.lastChip)
<< " " << static_cast<int>(file.lastCopy) << "\n";
}
}
@ -424,4 +421,9 @@ switch (actionId) {
return HasActionsIF::INVALID_ACTION_ID;
}
}
}
void CoreController::setCurrentBootCopy(xsc::Chip chip, xsc::Copy copy) {
CURRENT_CHIP = chip;
CURRENT_COPY = copy;
}

View File

@ -9,8 +9,8 @@
namespace xsc {
enum Chip : uint8_t { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : uint8_t { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
} // namespace xsc
@ -24,7 +24,7 @@ struct RebootFile {
uint32_t img01Cnt = 0;
uint32_t img10Cnt = 0;
uint32_t img11Cnt = 0;
uint32_t relevantBootCnt = 0;
uint32_t* relevantBootCnt = &img00Cnt;
bool bootFlag = false;
xsc::Chip lastChip = xsc::Chip::CHIP_0;
xsc::Copy lastCopy = xsc::Copy::COPY_0;
@ -35,7 +35,10 @@ class SdCardManager;
class CoreController {
public:
static constexpr char REBOOT_FILE[] = "/conf/reboot.txt";
static constexpr uint32_t REBOOT_MECHANISM_TRIGGERED = 1;
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
//! P2: Each byte is the respective reboot count for the slots
static constexpr Event REBOOT_MECHANISM_TRIGGERED = 1;
static xsc::Chip CURRENT_CHIP;
static xsc::Copy CURRENT_COPY;
@ -49,6 +52,7 @@ public:
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);

View File

@ -1,5 +1,6 @@
#include <cstdint>
using Event = uint32_t;
using ActionId_t = uint32_t;
using MessageQueueId_t = uint32_t;
using ReturnValue_t = uint16_t;

View File

@ -1,3 +1,20 @@
#include "event.h"
#include <queue>
void triggerEvent(uint32_t event, uint32_t p1, uint32_t p2) {}
std::queue<EventInfo> EVENT_QUEUE = {};
void triggerEvent(Event event, uint32_t p1, uint32_t p2) {
EventInfo info = {};
info.event = event;
info.p1 = p1;
info.p2 = p2;
EVENT_QUEUE.push(info);
}
void eventWasCalled(EventInfo& eventInfo, uint32_t& numEvents) {
numEvents = EVENT_QUEUE.size();
if(not EVENT_QUEUE.empty()) {
eventInfo = std::move(EVENT_QUEUE.back());
EVENT_QUEUE.pop();
}
}

View File

@ -1,5 +1,40 @@
#pragma once
#include "definitions.h"
#include <cstdint>
#include <iostream>
void triggerEvent(uint32_t event, uint32_t p1, uint32_t p2);
struct EventInfo {
// That was just for testing, follow rule of 0
/*
EventInfo () {}
EventInfo (const EventInfo& other): event(other.event), p1(other.p1), p2(other.p2) {
std::cout << "Event info copy ctor called" << std::endl;
}
EventInfo &operator= (const EventInfo& other) {
std::cout << "Event info assignment ctor called" << std::endl;
this->event = other.event;
this->p1 = other.p1;
this->p2 = other.p2;
return *this;
}
EventInfo &operator= (EventInfo&& other) {
std::cout << "Event info move ctor called" << std::endl;
this->event = other.event;
this->p1 = other.p1;
this->p2 = other.p2;
return *this;
}
*/
uint32_t event = 0;
uint32_t p1 = 0;
uint32_t p2 = 0;
};
void triggerEvent(Event event, uint32_t p1, uint32_t p2);
void eventWasCalled(EventInfo& eventInfo, uint32_t& numEvents);

View File

@ -1,5 +1,23 @@
#include "libxiphos.h"
#include "CoreController.h"
bool rebootWasCalled = false;
xsc_libnor_chip_t lastChip;
xsc_libnor_copy_t lastCopy;
bool getRebootWasCalled(xsc_libnor_chip_t& tgtChip, xsc_libnor_copy_t& tgtCopy) {
tgtChip = lastChip;
tgtCopy = lastCopy;
bool tmp = rebootWasCalled;
if(rebootWasCalled) {
rebootWasCalled = false;
}
return tmp;
}
void xsc_boot_copy(xsc_libnor_chip_t boot_chip, xsc_libnor_copy_t boot_copy) {
rebootWasCalled = true;
lastChip = boot_chip;
lastCopy = boot_copy;
CoreController::setCurrentBootCopy(static_cast<xsc::Chip>(boot_chip), static_cast<xsc::Copy>(boot_copy));
}

View File

@ -14,4 +14,12 @@ typedef enum {
XSC_LIBNOR_CHIP_TOTAL_NUMBER
} xsc_libnor_chip_t;
/**
* @brief Used to verify whether reboot function was called
*
* @param tgtChip
* @param tgtCopy
*/
bool getRebootWasCalled(xsc_libnor_chip_t& tgtChip, xsc_libnor_copy_t& tgtCopy);
void xsc_boot_copy(xsc_libnor_chip_t boot_chip, xsc_libnor_copy_t boot_copy);

View File

@ -1,28 +1,110 @@
#include "CoreController.h"
#include "libxiphos.h"
#include "HasActionsIF.h"
#include "event.h"
#include <catch2/catch_test_macros.hpp>
#include <iostream>
#include <fstream>
#include <filesystem>
static constexpr bool CAT_FILE_TO_CONSOLE = true;
static constexpr bool CAT_FILE_TO_CONSOLE = false;
const std::string CONF_PATH = "/tmp/conf";
const std::string REBOOT_FILE = CONF_PATH + "/reboot.txt";
void catFileToConsole();
TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) {
if(not std::filesystem::exists(CONF_PATH)) {
std::filesystem::create_directory(CONF_PATH);
}
CoreController ctrl;
if(not std::filesystem::exists(CONF_PATH)) {
std::filesystem::create_directory(CONF_PATH);
}
CoreController ctrl;
RebootFile rf;
SECTION ("Primary") {
xsc_libnor_chip_t chip;
xsc_libnor_copy_t copy;
RebootFile rf = {};
ctrl.rewriteRebootFile(rf);
REQUIRE(rf.enabled == 0);
REQUIRE(rf.maxCount == RebootFile::DEFAULT_MAX_BOOT_CNT);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.bootFlag == 0);
REQUIRE(rf.lastChip == 0);
REQUIRE(rf.lastCopy == 0);
// This recreates the file but should also increment the boot counter of the current image
REQUIRE(ctrl.CURRENT_CHIP == xsc::CHIP_0);
REQUIRE(ctrl.CURRENT_COPY == xsc::COPY_0);
ctrl.performRebootFileHandling(true);
catFileToConsole();
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.maxCount == RebootFile::DEFAULT_MAX_BOOT_CNT);
REQUIRE(rf.img00Cnt == 1);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.bootFlag == 0);
REQUIRE(rf.lastChip == 0);
REQUIRE(rf.lastCopy == 0);
uint8_t newRebootCnt = 3;
CHECK(ctrl.executeAction(CoreController::SET_MAX_REBOOT_CNT, 0, &newRebootCnt, 1) == HasActionsIF::EXECUTION_FINISHED);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
std::filesystem::remove_all(CONF_PATH);
REQUIRE(rf.maxCount == 3);
REQUIRE(not getRebootWasCalled(chip, copy));
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.bootFlag == true);
REQUIRE(rf.lastChip == xsc::CHIP_0);
REQUIRE(rf.lastCopy == xsc::COPY_0);
REQUIRE(getRebootWasCalled(chip, copy));
REQUIRE(chip == XSC_LIBNOR_CHIP_0);
REQUIRE(copy == XSC_LIBNOR_COPY_GOLD);
EventInfo info = {};
uint32_t numEvents = 0;
ctrl.performRebootFileHandling(false);
eventWasCalled(info, numEvents);
CHECK(numEvents == 1);
CHECK(info.event == CoreController::REBOOT_MECHANISM_TRIGGERED);
CHECK(static_cast<xsc::Chip>((info.p1 >> 16) & 0xFFFF) == xsc::CHIP_0);
CHECK(static_cast<xsc::Copy>(info.p1 & 0xFFFF) == xsc::COPY_0);
CHECK(((info.p2 >> 24) & 0xFF) == 3);
CHECK(((info.p2 >> 16) & 0xFF) == 1);
CHECK(((info.p2 >> 8) & 0xFF) == 0);
CHECK((info.p2 & 0xFF) == 0);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 1);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
// Flag was cleared when event was thrown
REQUIRE(rf.bootFlag == false);
REQUIRE(rf.lastChip == xsc::CHIP_0);
REQUIRE(rf.lastCopy == xsc::COPY_0);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 3);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
}
if(std::filesystem::exists(CONF_PATH)) {
std::uintmax_t n = std::filesystem::remove_all(CONF_PATH);
CHECK(n == 2);
}
}
void catFileToConsole() {