v1.10.0 #220
@ -16,7 +16,6 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <libxiphos.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
@ -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<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, ©);
|
||||
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);
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
|
||||
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
||||
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
|
||||
#include "bsp_q7s/memory/SdCardManager.h"
|
||||
#include "events/subsystemIdRanges.h"
|
||||
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <libxiphos.h>
|
||||
|
||||
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_ */
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#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() {}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_
|
||||
#define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_
|
||||
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <array>
|
||||
@ -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";
|
||||
|
@ -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,
|
||||
|
@ -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<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++) {
|
||||
sif::info << std::setw(3) << dataset.channels[idx];
|
||||
if (idx < 6 - 1) {
|
||||
|
@ -1,5 +0,0 @@
|
||||
add_subdirectory(testcfg)
|
||||
|
||||
target_sources(${TARGET_NAME} PRIVATE
|
||||
main.cpp
|
||||
)
|
1
unittest/rebootLogic/.gitignore
vendored
Normal file
1
unittest/rebootLogic/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
11
unittest/rebootLogic/CMakeLists.txt
Normal file
11
unittest/rebootLogic/CMakeLists.txt
Normal 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)
|
5
unittest/rebootLogic/main.cpp
Normal file
5
unittest/rebootLogic/main.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include <iostream>
|
||||
|
||||
int main(int, char**) {
|
||||
std::cout << "Hello, world!\n";
|
||||
}
|
Loading…
Reference in New Issue
Block a user