v1.10.0 #220
@ -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,
|
||||||
@ -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, ©);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@ -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_ */
|
||||||
|
@ -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() {}
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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