Merge branch 'mueller/reboot-file-handling' into mueller/plpcdu-sus-updates
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
This commit is contained in:
commit
006e9e2229
16
README.md
16
README.md
@ -441,12 +441,24 @@ Beagle Bone Black for download here
|
|||||||
Download it and unzip it somewhere in the Xilinx installation folder.
|
Download it and unzip it somewhere in the Xilinx installation folder.
|
||||||
You can use the following command if `wget` can be used or for CI/CD:
|
You can use the following command if `wget` can be used or for CI/CD:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/agnJGYeRf6fw2ci/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
|
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
|
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
|
||||||
|
|
||||||
|
### Updating system root for CI
|
||||||
|
|
||||||
|
If the system root is updated, it needs to be manually updated on the buggy file server.
|
||||||
|
If access on `buggy.irs.uni-stuttgart.de` is possible with `ssh` and the rootfs in the cloud
|
||||||
|
[was updated](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/rootfs&fileid=831849)
|
||||||
|
as well, you can update the rootfs like this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /var/www/eive/tools
|
||||||
|
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
## Setting up UNIX environment for real-time functionalities
|
## Setting up UNIX environment for real-time functionalities
|
||||||
|
|
||||||
Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities
|
Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities
|
||||||
|
@ -170,15 +170,15 @@ void Q7STestTask::testProtHandler() {
|
|||||||
bool opPerformed = false;
|
bool opPerformed = false;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
// If any chips are unlocked, lock them here
|
// If any chips are unlocked, lock them here
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(xsc::Chip::ALL_CHIP, xsc::Copy::ALL_COPY, true,
|
||||||
CoreController::Chip::ALL_CHIP, CoreController::Copy::ALL_COPY, true, opPerformed, true);
|
opPerformed, true);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlock own copy
|
// unlock own copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, false,
|
||||||
CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, false, opPerformed, true);
|
opPerformed, true);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
||||||
}
|
}
|
||||||
@ -191,8 +191,8 @@ void Q7STestTask::testProtHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lock own copy
|
// lock own copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true,
|
||||||
CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, true, opPerformed, true);
|
opPerformed, true);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
||||||
}
|
}
|
||||||
@ -205,8 +205,8 @@ void Q7STestTask::testProtHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// unlock specific copy
|
// unlock specific copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(xsc::Chip::CHIP_1, xsc::Copy::COPY_1, false,
|
||||||
CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, false, opPerformed, true);
|
opPerformed, true);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
||||||
}
|
}
|
||||||
@ -219,8 +219,8 @@ void Q7STestTask::testProtHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lock specific copy
|
// lock specific copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(xsc::Chip::CHIP_1, xsc::Copy::COPY_1, true,
|
||||||
CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, true, opPerformed, true);
|
opPerformed, true);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
#include "bsp_q7s/memory/scratchApi.h"
|
#include "bsp_q7s/memory/scratchApi.h"
|
||||||
|
|
||||||
CoreController::Chip CoreController::CURRENT_CHIP = Chip::NO_CHIP;
|
xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
|
||||||
CoreController::Copy CoreController::CURRENT_COPY = Copy::NO_COPY;
|
xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
|
||||||
|
|
||||||
CoreController::CoreController(object_id_t objectId)
|
CoreController::CoreController(object_id_t objectId)
|
||||||
: ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) {
|
: ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) {
|
||||||
@ -59,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,
|
||||||
@ -79,6 +80,8 @@ ReturnValue_t CoreController::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
|
|
||||||
|
triggerEvent(REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
||||||
return ExtendedControllerBase::initialize();
|
return ExtendedControllerBase::initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +107,59 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t *data, size_t size) {
|
||||||
|
switch (actionId) {
|
||||||
|
case (LIST_DIRECTORY_INTO_FILE): {
|
||||||
|
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
||||||
|
}
|
||||||
|
case (SWITCH_REBOOT_FILE_HANDLING): {
|
||||||
|
if (size < 1) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
|
||||||
|
// Disable the reboot file mechanism
|
||||||
|
parseRebootFile(path, rebootFile);
|
||||||
|
if (data[0] == 0) {
|
||||||
|
rebootFile.enabled = false;
|
||||||
|
rewriteRebootFile(rebootFile);
|
||||||
|
} else if (data[0] == 1) {
|
||||||
|
rebootFile.enabled = true;
|
||||||
|
rewriteRebootFile(rebootFile);
|
||||||
|
} else {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RESET_ALL_REBOOT_COUNTERS): {
|
||||||
|
resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY);
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RESET_REBOOT_COUNTER_00): {
|
||||||
|
resetRebootCount(xsc::CHIP_0, xsc::COPY_0);
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RESET_REBOOT_COUNTER_01): {
|
||||||
|
resetRebootCount(xsc::CHIP_0, xsc::COPY_1);
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RESET_REBOOT_COUNTER_10): {
|
||||||
|
resetRebootCount(xsc::CHIP_1, xsc::COPY_0);
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RESET_REBOOT_COUNTER_11): {
|
||||||
|
resetRebootCount(xsc::CHIP_1, xsc::COPY_1);
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (REBOOT_OBC): {
|
||||||
|
return actionPerformReboot(data, size);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return HasActionsIF::INVALID_ACTION_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) {
|
uint32_t *msToReachTheMode) {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -502,21 +558,6 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
|
||||||
const uint8_t *data, size_t size) {
|
|
||||||
switch (actionId) {
|
|
||||||
case (LIST_DIRECTORY_INTO_FILE): {
|
|
||||||
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
|
||||||
}
|
|
||||||
case (REBOOT_OBC): {
|
|
||||||
return actionPerformReboot(data, size);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return HasActionsIF::INVALID_ACTION_ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CoreController::sdColdRedundantBlockingInit() {
|
ReturnValue_t CoreController::sdColdRedundantBlockingInit() {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
|
||||||
@ -691,7 +732,7 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
|||||||
|
|
||||||
ReturnValue_t CoreController::initBootCopy() {
|
ReturnValue_t CoreController::initBootCopy() {
|
||||||
if (not std::filesystem::exists(CURR_COPY_FILE)) {
|
if (not std::filesystem::exists(CURR_COPY_FILE)) {
|
||||||
// Thils file is created by the systemd service eive-early-config so this should
|
// This file is created by the systemd service eive-early-config so this should
|
||||||
// not happen normally
|
// not happen normally
|
||||||
std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE);
|
std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE);
|
||||||
int result = std::system(cmd.c_str());
|
int result = std::system(cmd.c_str());
|
||||||
@ -699,22 +740,18 @@ ReturnValue_t CoreController::initBootCopy() {
|
|||||||
utility::handleSystemError(result, "CoreController::initBootCopy");
|
utility::handleSystemError(result, "CoreController::initBootCopy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ifstream file(CURR_COPY_FILE);
|
|
||||||
std::string line;
|
getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY);
|
||||||
std::getline(file, line);
|
|
||||||
std::istringstream iss(line);
|
|
||||||
int value = 0;
|
|
||||||
iss >> value;
|
|
||||||
CURRENT_CHIP = static_cast<Chip>(value);
|
|
||||||
iss >> value;
|
|
||||||
CURRENT_COPY = static_cast<Copy>(value);
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::getCurrentBootCopy(Chip &chip, Copy ©) {
|
void CoreController::getCurrentBootCopy(xsc::Chip &chip, xsc::Copy ©) {
|
||||||
|
xsc_libnor_chip_t xscChip;
|
||||||
|
xsc_libnor_copy_t xscCopy;
|
||||||
|
xsc_boot_get_chip_copy(&xscChip, &xscCopy);
|
||||||
// Not really thread-safe but it does not need to be
|
// Not really thread-safe but it does not need to be
|
||||||
chip = CURRENT_CHIP;
|
chip = static_cast<xsc::Chip>(xscChip);
|
||||||
copy = CURRENT_COPY;
|
copy = static_cast<xsc::Copy>(xscCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initWatchdogFifo() {
|
ReturnValue_t CoreController::initWatchdogFifo() {
|
||||||
@ -761,8 +798,8 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
|
|||||||
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0);
|
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0);
|
||||||
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1);
|
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1);
|
||||||
// If any boot copies are unprotected
|
// If any boot copies are unprotected
|
||||||
ReturnValue_t retval =
|
ReturnValue_t retval = setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true,
|
||||||
setBootCopyProtection(Chip::SELF_CHIP, Copy::SELF_COPY, true, protOpPerformed, false);
|
protOpPerformed, false);
|
||||||
if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
|
if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
|
||||||
sif::info << "Running slot was writeprotected before reboot" << std::endl;
|
sif::info << "Running slot was writeprotected before reboot" << std::endl;
|
||||||
}
|
}
|
||||||
@ -773,7 +810,7 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
|
|||||||
}
|
}
|
||||||
return HasActionsIF::EXECUTION_FINISHED;
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
if (size < 3) {
|
if (size < 3 or (data[1] > 1 or data[2] > 1)) {
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
}
|
}
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
@ -784,21 +821,53 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
|
|||||||
// Check that the target chip and copy is writeprotected first
|
// Check that the target chip and copy is writeprotected first
|
||||||
generateChipStateFile();
|
generateChipStateFile();
|
||||||
// If any boot copies are unprotected, protect them here
|
// If any boot copies are unprotected, protect them here
|
||||||
ReturnValue_t retval = setBootCopyProtection(
|
auto tgtChip = static_cast<xsc::Chip>(data[1]);
|
||||||
static_cast<Chip>(data[1]), static_cast<Copy>(data[2]), true, protOpPerformed, false);
|
auto tgtCopy = static_cast<xsc::Copy>(data[2]);
|
||||||
|
|
||||||
|
ReturnValue_t retval =
|
||||||
|
setBootCopyProtection(static_cast<xsc::Chip>(data[1]), static_cast<xsc::Copy>(data[2]), true,
|
||||||
|
protOpPerformed, false);
|
||||||
if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
|
if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
|
||||||
sif::info << "Target slot was writeprotected before reboot" << std::endl;
|
sif::info << "Target slot was writeprotected before reboot" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The second byte in data is the target chip, the third byte is the target copy
|
switch (tgtChip) {
|
||||||
std::string cmdString =
|
case (xsc::Chip::CHIP_0): {
|
||||||
"xsc_boot_copy " + std::to_string(data[1]) + " " + std::to_string(data[2]);
|
switch (tgtCopy) {
|
||||||
int result = std::system(cmdString.c_str());
|
case (xsc::Copy::COPY_0): {
|
||||||
if (result != 0) {
|
xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL);
|
||||||
utility::handleSystemError(result, "CoreController::executeAction");
|
break;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
}
|
||||||
|
case (xsc::Copy::COPY_1): {
|
||||||
|
xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (xsc::Chip::CHIP_1): {
|
||||||
|
switch (tgtCopy) {
|
||||||
|
case (xsc::Copy::COPY_0): {
|
||||||
|
xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (xsc::Copy::COPY_1): {
|
||||||
|
xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return HasActionsIF::EXECUTION_FINISHED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreController::~CoreController() {}
|
CoreController::~CoreController() {}
|
||||||
@ -852,8 +921,8 @@ ReturnValue_t CoreController::generateChipStateFile() {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy targetCopy, bool protect,
|
ReturnValue_t CoreController::setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy,
|
||||||
bool &protOperationPerformed,
|
bool protect, bool &protOperationPerformed,
|
||||||
bool updateProtFile) {
|
bool updateProtFile) {
|
||||||
bool allChips = false;
|
bool allChips = false;
|
||||||
bool allCopies = false;
|
bool allCopies = false;
|
||||||
@ -862,14 +931,14 @@ ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy target
|
|||||||
protOperationPerformed = false;
|
protOperationPerformed = false;
|
||||||
|
|
||||||
switch (targetChip) {
|
switch (targetChip) {
|
||||||
case (Chip::ALL_CHIP): {
|
case (xsc::Chip::ALL_CHIP): {
|
||||||
allChips = true;
|
allChips = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (Chip::NO_CHIP): {
|
case (xsc::Chip::NO_CHIP): {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Chip::SELF_CHIP): {
|
case (xsc::Chip::SELF_CHIP): {
|
||||||
selfChip = true;
|
selfChip = true;
|
||||||
targetChip = CURRENT_CHIP;
|
targetChip = CURRENT_CHIP;
|
||||||
break;
|
break;
|
||||||
@ -879,14 +948,14 @@ ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy target
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (targetCopy) {
|
switch (targetCopy) {
|
||||||
case (Copy::ALL_COPY): {
|
case (xsc::Copy::ALL_COPY): {
|
||||||
allCopies = true;
|
allCopies = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (Copy::NO_COPY): {
|
case (xsc::Copy::NO_COPY): {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Copy::SELF_COPY): {
|
case (xsc::Copy::SELF_COPY): {
|
||||||
selfCopy = true;
|
selfCopy = true;
|
||||||
targetCopy = CURRENT_COPY;
|
targetCopy = CURRENT_COPY;
|
||||||
break;
|
break;
|
||||||
@ -909,10 +978,10 @@ ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy target
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CoreController::handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
|
int CoreController::handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy,
|
||||||
bool &protOperationPerformed, bool selfChip,
|
bool protect, bool &protOperationPerformed,
|
||||||
bool selfCopy, bool allChips, bool allCopies,
|
bool selfChip, bool selfCopy, bool allChips,
|
||||||
uint8_t arrIdx) {
|
bool allCopies, uint8_t arrIdx) {
|
||||||
bool currentProt = protArray[arrIdx];
|
bool currentProt = protArray[arrIdx];
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
bool performOp = false;
|
bool performOp = false;
|
||||||
@ -925,22 +994,22 @@ int CoreController::handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Chip currentChip;
|
xsc::Chip currentChip;
|
||||||
Copy currentCopy;
|
xsc::Copy currentCopy;
|
||||||
oss << "writeprotect ";
|
oss << "writeprotect ";
|
||||||
if (arrIdx == 0 or arrIdx == 1) {
|
if (arrIdx == 0 or arrIdx == 1) {
|
||||||
oss << "0 ";
|
oss << "0 ";
|
||||||
currentChip = Chip::CHIP_0;
|
currentChip = xsc::Chip::CHIP_0;
|
||||||
} else {
|
} else {
|
||||||
oss << "1 ";
|
oss << "1 ";
|
||||||
currentChip = Chip::CHIP_1;
|
currentChip = xsc::Chip::CHIP_1;
|
||||||
}
|
}
|
||||||
if (arrIdx == 0 or arrIdx == 2) {
|
if (arrIdx == 0 or arrIdx == 2) {
|
||||||
oss << "0 ";
|
oss << "0 ";
|
||||||
currentCopy = Copy::COPY_0;
|
currentCopy = xsc::Copy::COPY_0;
|
||||||
} else {
|
} else {
|
||||||
oss << "1 ";
|
oss << "1 ";
|
||||||
currentCopy = Copy::COPY_1;
|
currentCopy = xsc::Copy::COPY_1;
|
||||||
}
|
}
|
||||||
if (protect) {
|
if (protect) {
|
||||||
oss << "1";
|
oss << "1";
|
||||||
@ -1035,29 +1104,29 @@ ReturnValue_t CoreController::handleProtInfoUpdateLine(std::string nextLine) {
|
|||||||
uint8_t wordIdx = 0;
|
uint8_t wordIdx = 0;
|
||||||
uint8_t arrayIdx = 0;
|
uint8_t arrayIdx = 0;
|
||||||
istringstream iss(nextLine);
|
istringstream iss(nextLine);
|
||||||
Chip currentChip = Chip::CHIP_0;
|
xsc::Chip currentChip = xsc::Chip::CHIP_0;
|
||||||
Copy currentCopy = Copy::COPY_0;
|
xsc::Copy currentCopy = xsc::Copy::COPY_0;
|
||||||
while (iss >> word) {
|
while (iss >> word) {
|
||||||
if (wordIdx == 1) {
|
if (wordIdx == 1) {
|
||||||
currentChip = static_cast<Chip>(stoi(word));
|
currentChip = static_cast<xsc::Chip>(stoi(word));
|
||||||
}
|
}
|
||||||
if (wordIdx == 3) {
|
if (wordIdx == 3) {
|
||||||
currentCopy = static_cast<Copy>(stoi(word));
|
currentCopy = static_cast<xsc::Copy>(stoi(word));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wordIdx == 3) {
|
if (wordIdx == 3) {
|
||||||
if (currentChip == Chip::CHIP_0) {
|
if (currentChip == xsc::Chip::CHIP_0) {
|
||||||
if (currentCopy == Copy::COPY_0) {
|
if (currentCopy == xsc::Copy::COPY_0) {
|
||||||
arrayIdx = 0;
|
arrayIdx = 0;
|
||||||
} else if (currentCopy == Copy::COPY_1) {
|
} else if (currentCopy == xsc::Copy::COPY_1) {
|
||||||
arrayIdx = 1;
|
arrayIdx = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (currentChip == Chip::CHIP_1) {
|
else if (currentChip == xsc::Chip::CHIP_1) {
|
||||||
if (currentCopy == Copy::COPY_0) {
|
if (currentCopy == xsc::Copy::COPY_0) {
|
||||||
arrayIdx = 2;
|
arrayIdx = 2;
|
||||||
} else if (currentCopy == Copy::COPY_1) {
|
} else if (currentCopy == xsc::Copy::COPY_1) {
|
||||||
arrayIdx = 3;
|
arrayIdx = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1103,3 +1172,363 @@ void CoreController::performWatchdogControlOperation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
rebootFile.enabled = true;
|
||||||
|
rebootFile.img00Cnt = 0;
|
||||||
|
rebootFile.img01Cnt = 0;
|
||||||
|
rebootFile.img10Cnt = 0;
|
||||||
|
rebootFile.img11Cnt = 0;
|
||||||
|
rebootFile.lastChip = xsc::Chip::CHIP_0;
|
||||||
|
rebootFile.lastCopy = xsc::Copy::COPY_0;
|
||||||
|
rebootFile.bootFlag = false;
|
||||||
|
rewriteRebootFile(rebootFile);
|
||||||
|
} else {
|
||||||
|
if (not parseRebootFile(path, rebootFile)) {
|
||||||
|
performRebootFileHandling(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
case (xsc::COPY_0): {
|
||||||
|
rebootFile.img00Cnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (xsc::COPY_1): {
|
||||||
|
rebootFile.img01Cnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (xsc::CHIP_1): {
|
||||||
|
switch (CURRENT_COPY) {
|
||||||
|
case (xsc::COPY_0): {
|
||||||
|
rebootFile.img10Cnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (xsc::COPY_1): {
|
||||||
|
rebootFile.img11Cnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CURRENT_CHIP == xsc::CHIP_0 and CURRENT_COPY == xsc::COPY_0) {
|
||||||
|
}
|
||||||
|
if (rebootFile.relevantBootCnt > rebootFile.maxCount) {
|
||||||
|
// Reboot to other image
|
||||||
|
bool doReboot = false;
|
||||||
|
determineAndExecuteReboot(rebootFile, doReboot, rebootFile.lastChip, rebootFile.lastCopy);
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
rewriteRebootFile(rebootFile);
|
||||||
|
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(rebootFile.lastChip),
|
||||||
|
static_cast<xsc_libnor_copy_t>(rebootFile.lastCopy));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rewriteRebootFile(rebootFile);
|
||||||
|
}
|
||||||
|
doPerformRebootFileHandling = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot,
|
||||||
|
xsc::Chip &tgtChip, xsc::Copy &tgtCopy) {
|
||||||
|
tgtChip = xsc::CHIP_0;
|
||||||
|
tgtCopy = xsc::COPY_0;
|
||||||
|
needsReboot = false;
|
||||||
|
if ((CURRENT_COPY == xsc::COPY_0) and (CURRENT_CHIP == xsc::CHIP_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;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_1;
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_0;
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((CURRENT_COPY == xsc::COPY_0) and (CURRENT_CHIP == xsc::CHIP_1) and
|
||||||
|
(rf.img01Cnt >= rf.maxCount)) {
|
||||||
|
needsReboot = true;
|
||||||
|
if (rf.img00Cnt >= rf.maxCount) {
|
||||||
|
if (rf.img10Cnt >= rf.maxCount) {
|
||||||
|
if (rf.img11Cnt >= rf.maxCount) {
|
||||||
|
// Reboot to fallback image
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_1;
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_1;
|
||||||
|
tgtCopy = xsc::COPY_0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Reboot on fallback image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((CURRENT_COPY == xsc::COPY_1) and (CURRENT_CHIP == xsc::CHIP_0) and
|
||||||
|
(rf.img10Cnt >= rf.maxCount)) {
|
||||||
|
needsReboot = true;
|
||||||
|
if (rf.img11Cnt >= rf.maxCount) {
|
||||||
|
if (rf.img00Cnt >= rf.maxCount) {
|
||||||
|
if (rf.img01Cnt >= rf.maxCount) {
|
||||||
|
// Reboot to fallback image
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_0;
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_0;
|
||||||
|
tgtCopy = xsc::COPY_0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_1;
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((CURRENT_COPY == xsc::COPY_1) and (CURRENT_CHIP == xsc::CHIP_1) and
|
||||||
|
(rf.img11Cnt >= rf.maxCount)) {
|
||||||
|
needsReboot = true;
|
||||||
|
if (rf.img10Cnt >= rf.maxCount) {
|
||||||
|
if (rf.img00Cnt >= rf.maxCount) {
|
||||||
|
if (rf.img01Cnt >= rf.maxCount) {
|
||||||
|
// Reboot to fallback image
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_0;
|
||||||
|
tgtCopy = xsc::COPY_1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_0;
|
||||||
|
tgtCopy = xsc::COPY_0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtChip = xsc::CHIP_1;
|
||||||
|
tgtCopy = xsc::COPY_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
|
||||||
|
using namespace std;
|
||||||
|
std::string selfMatch;
|
||||||
|
if (CURRENT_CHIP == xsc::CHIP_0) {
|
||||||
|
if (CURRENT_COPY == xsc::COPY_0) {
|
||||||
|
selfMatch = "00";
|
||||||
|
} else {
|
||||||
|
selfMatch = "01";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (CURRENT_COPY == xsc::COPY_0) {
|
||||||
|
selfMatch = "10";
|
||||||
|
} else {
|
||||||
|
selfMatch = "11";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.enabled;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
iss >> word;
|
||||||
|
if (word.find("maxcnt:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.maxCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
iss >> word;
|
||||||
|
if (word.find("img00:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.img00Cnt;
|
||||||
|
if (word.find(selfMatch) != string::npos) {
|
||||||
|
rf.relevantBootCnt = rf.img00Cnt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
iss >> word;
|
||||||
|
if (word.find("img01:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.img01Cnt;
|
||||||
|
if (word.find(selfMatch) != string::npos) {
|
||||||
|
rf.relevantBootCnt = rf.img01Cnt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
iss >> word;
|
||||||
|
if (word.find("img10:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.img10Cnt;
|
||||||
|
if (word.find(selfMatch) != string::npos) {
|
||||||
|
rf.relevantBootCnt = rf.img10Cnt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
iss >> word;
|
||||||
|
if (word.find("img11:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.img11Cnt;
|
||||||
|
if (word.find(selfMatch) != string::npos) {
|
||||||
|
rf.relevantBootCnt = rf.img11Cnt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
iss >> word;
|
||||||
|
if (word.find("bootflag:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> rf.bootFlag;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
if (word.find("last:") == string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> chipRaw;
|
||||||
|
if (iss.fail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iss >> copyRaw;
|
||||||
|
if (iss.fail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chipRaw > 1 or copyRaw > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rf.lastChip = static_cast<xsc::Chip>(chipRaw);
|
||||||
|
rf.lastCopy = static_cast<xsc::Copy>(copyRaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iss.fail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lineIdx++;
|
||||||
|
}
|
||||||
|
if (lineIdx < 8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) {
|
||||||
|
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
|
||||||
|
// Disable the reboot file mechanism
|
||||||
|
parseRebootFile(path, rebootFile);
|
||||||
|
if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) {
|
||||||
|
rebootFile.img00Cnt = 0;
|
||||||
|
rebootFile.img01Cnt = 0;
|
||||||
|
rebootFile.img10Cnt = 0;
|
||||||
|
rebootFile.img11Cnt = 0;
|
||||||
|
} else {
|
||||||
|
if (tgtChip == xsc::CHIP_0) {
|
||||||
|
if (tgtCopy == xsc::COPY_0) {
|
||||||
|
rebootFile.img00Cnt = 0;
|
||||||
|
} else {
|
||||||
|
rebootFile.img01Cnt = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tgtCopy == xsc::COPY_0) {
|
||||||
|
rebootFile.img10Cnt = 0;
|
||||||
|
} else {
|
||||||
|
rebootFile.img11Cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rewriteRebootFile(rebootFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::rewriteRebootFile(RebootFile file) {
|
||||||
|
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
|
||||||
|
std::ofstream rebootFile(path);
|
||||||
|
if (rebootFile.is_open()) {
|
||||||
|
// Initiate reboot file first. Reboot handling will be on on initialization
|
||||||
|
rebootFile << "on: " << file.enabled << "\nmaxcnt: " << file.maxCount
|
||||||
|
<< "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt
|
||||||
|
<< "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt
|
||||||
|
<< "\nbootflag: " << file.bootFlag << "\nlast: " << file.lastChip << " "
|
||||||
|
<< file.lastCopy << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
||||||
|
|
||||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||||
|
#include <libxiphos.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
@ -10,24 +13,64 @@
|
|||||||
class Timer;
|
class Timer;
|
||||||
class SdCardManager;
|
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 };
|
||||||
|
|
||||||
|
} // namespace xsc
|
||||||
|
|
||||||
|
struct RebootFile {
|
||||||
|
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
||||||
|
|
||||||
|
bool enabled = false;
|
||||||
|
size_t maxCount = DEFAULT_MAX_BOOT_CNT;
|
||||||
|
uint8_t img00Cnt = 0;
|
||||||
|
uint8_t img01Cnt = 0;
|
||||||
|
uint8_t img10Cnt = 0;
|
||||||
|
uint8_t img11Cnt = 0;
|
||||||
|
uint8_t relevantBootCnt = 0;
|
||||||
|
bool bootFlag = false;
|
||||||
|
xsc::Chip lastChip = xsc::Chip::CHIP_0;
|
||||||
|
xsc::Copy lastCopy = xsc::Copy::COPY_0;
|
||||||
|
};
|
||||||
|
|
||||||
class CoreController : public ExtendedControllerBase {
|
class CoreController : public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
enum Chip : uint8_t { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
static xsc::Chip CURRENT_CHIP;
|
||||||
|
static xsc::Copy CURRENT_COPY;
|
||||||
enum Copy : uint8_t { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
|
||||||
|
|
||||||
static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh";
|
static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh";
|
||||||
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/sd_status";
|
static constexpr char VERSION_FILE[] = "/conf/version.txt";
|
||||||
|
static constexpr char REBOOT_FILE[] = "/conf/reboot.txt";
|
||||||
|
|
||||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||||
|
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
|
||||||
|
static constexpr ActionId_t RESET_ALL_REBOOT_COUNTERS = 6;
|
||||||
|
static constexpr ActionId_t RESET_REBOOT_COUNTER_00 = 7;
|
||||||
|
static constexpr ActionId_t RESET_REBOOT_COUNTER_01 = 8;
|
||||||
|
static constexpr ActionId_t RESET_REBOOT_COUNTER_10 = 9;
|
||||||
|
static constexpr ActionId_t RESET_REBOOT_COUNTER_11 = 10;
|
||||||
|
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 11;
|
||||||
|
|
||||||
static constexpr ActionId_t REBOOT_OBC = 32;
|
static constexpr ActionId_t REBOOT_OBC = 32;
|
||||||
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||||
|
|
||||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||||
|
//! [EXPORT] : [COMMENT] Software reboot occured. Can also be a systemd reboot.
|
||||||
|
//! P1: Current Chip, P2: Current Copy
|
||||||
|
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM);
|
||||||
|
//! [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 =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
||||||
|
//! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU..
|
||||||
|
static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
||||||
|
|
||||||
CoreController(object_id_t objectId);
|
CoreController(object_id_t objectId);
|
||||||
virtual ~CoreController();
|
virtual ~CoreController();
|
||||||
@ -48,7 +91,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
*/
|
*/
|
||||||
static ReturnValue_t generateChipStateFile();
|
static ReturnValue_t generateChipStateFile();
|
||||||
static ReturnValue_t incrementAllocationFailureCount();
|
static ReturnValue_t incrementAllocationFailureCount();
|
||||||
static void getCurrentBootCopy(Chip& chip, Copy& copy);
|
static void getCurrentBootCopy(xsc::Chip& chip, xsc::Copy& copy);
|
||||||
|
|
||||||
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
|
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
|
||||||
|
|
||||||
@ -63,15 +106,12 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
* @param updateProtFile Specify whether the protection info file is updated
|
* @param updateProtFile Specify whether the protection info file is updated
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t setBootCopyProtection(Chip targetChip, Copy targetCopy, bool protect,
|
ReturnValue_t setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect,
|
||||||
bool& protOperationPerformed, bool updateProtFile = true);
|
bool& protOperationPerformed, bool updateProtFile = true);
|
||||||
|
|
||||||
bool sdInitFinished() const;
|
bool sdInitFinished() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Chip CURRENT_CHIP;
|
|
||||||
static Copy CURRENT_COPY;
|
|
||||||
|
|
||||||
// Designated value for rechecking FIFO open
|
// Designated value for rechecking FIFO open
|
||||||
static constexpr int RETRY_FIFO_OPEN = -2;
|
static constexpr int RETRY_FIFO_OPEN = -2;
|
||||||
int watchdogFifoFd = 0;
|
int watchdogFifoFd = 0;
|
||||||
@ -122,6 +162,8 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
sd::SdState commandedState = sd::SdState::OFF;
|
sd::SdState commandedState = sd::SdState::OFF;
|
||||||
};
|
};
|
||||||
SdInfo sdInfo;
|
SdInfo sdInfo;
|
||||||
|
RebootFile rebootFile = {};
|
||||||
|
bool doPerformRebootFileHandling = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index 0: Chip 0 Copy 0
|
* Index 0: Chip 0 Copy 0
|
||||||
@ -152,6 +194,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
void determinePreferredSdCard();
|
void determinePreferredSdCard();
|
||||||
void executeNextExternalSdCommand();
|
void executeNextExternalSdCommand();
|
||||||
void checkExternalSdCommandStatus();
|
void checkExternalSdCommandStatus();
|
||||||
|
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);
|
||||||
@ -160,9 +203,14 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
void performWatchdogControlOperation();
|
void performWatchdogControlOperation();
|
||||||
|
|
||||||
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
|
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
|
||||||
int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
|
int handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::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(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
|
||||||
|
xsc::Copy& tgtCopy);
|
||||||
|
void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
||||||
|
bool parseRebootFile(std::string path, RebootFile& file);
|
||||||
|
void rewriteRebootFile(RebootFile file);
|
||||||
};
|
};
|
||||||
|
|
||||||
#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>
|
||||||
@ -23,7 +24,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: public SdCardMountedIF {
|
class SdCardManager: public SystemObject, public SdCardMountedIF {
|
||||||
friend class SdCardAccess;
|
friend class SdCardAccess;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -55,6 +56,7 @@ class SdCardManager: public SdCardMountedIF {
|
|||||||
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";
|
||||||
|
@ -81,8 +81,19 @@ set(CMAKE_PREFIX_PATH
|
|||||||
# "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
|
# "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(C_FLAGS
|
||||||
|
-mcpu=cortex-a9
|
||||||
|
-mfpu=neon-vfpv3
|
||||||
|
-mfloat-abi=hard
|
||||||
|
${COMMON_FLAGS}
|
||||||
|
-lgpiod
|
||||||
|
-lxiphos
|
||||||
|
)
|
||||||
|
|
||||||
|
string (REPLACE ";" " " C_FLAGS "${C_FLAGS}")
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS
|
set(CMAKE_C_FLAGS
|
||||||
"-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod"
|
${C_FLAGS}
|
||||||
CACHE STRING "C flags for Q7S"
|
CACHE STRING "C flags for Q7S"
|
||||||
)
|
)
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
|
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