From a15e0bbaa5ba53f42af4bebaa4db2a58c0933d51 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 13:26:02 +0200 Subject: [PATCH 01/11] sd card is now mounted as well --- bsp_q7s/core/CoreController.cpp | 7 +++++-- bsp_q7s/memory/SdCardManager.cpp | 13 +++++++++++-- bsp_q7s/memory/SdCardManager.h | 19 ++++++++++++------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index ced75056..421a96d9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -41,7 +41,10 @@ ReturnValue_t CoreController::initialize() { sif::info << "Switching on SD card " << printoutString << ".." << std::endl; result = SdCardManager::instance()->switchOnSdCard(preferredSdCard, true); - if(result == SdCardManager::ALREADY_ON) { + if(result == SdCardManager::ALREADY_MOUNTED) { + sif::info << "SD card " << printoutString << " is already on and mounted" << std::endl; + } + else if(result == SdCardManager::ALREADY_ON) { sif::info << "SD card " << printoutString << " is already on" << std::endl; } else if(result != HasReturnvaluesIF::RETURN_OK) { @@ -49,7 +52,7 @@ ReturnValue_t CoreController::initialize() { << std::endl; } else { - sif::info << "SD card " << printoutString << " was switched on" << std::endl; + sif::info << "SD card " << printoutString << " was switched on and mounted" << std::endl; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 9c47f0de..232000a3 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -39,9 +39,18 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar return result; } if(sdCard == sd::SdCard::SLOT_0) { - if(active.first == sd::SdStatus::ON or active.first == sd::SdStatus::MOUNTED) { - return ALREADY_ON; + if(active.first == sd::SdStatus::MOUNTED) { + return ALREADY_MOUNTED; } + else if(active.first == sd::SdStatus::ON) { + if(not doMountSdCard) { + return ALREADY_ON; + } + else { + return mountSdCard(sdCard); + } + } + } else if(sdCard == sd::SdCard::SLOT_1) { if(active.second == sd::SdStatus::ON or active.second == sd::SdStatus::MOUNTED) { diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 810536fe..b3a33d42 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -21,17 +21,22 @@ class SdCardManager { public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; - static constexpr ReturnValue_t ALREADY_ON = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); - static constexpr ReturnValue_t ALREADY_OFF = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); - static constexpr ReturnValue_t STATUS_FILE_NEXISTS = + static constexpr ReturnValue_t ALREADY_ON = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); + static constexpr ReturnValue_t ALREADY_MOUNTED = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); + static constexpr ReturnValue_t ALREADY_OFF = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); + static constexpr ReturnValue_t STATUS_FILE_NEXISTS = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10); static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); - static constexpr ReturnValue_t MOUNT_ERROR = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 4); + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 11); + static constexpr ReturnValue_t MOUNT_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 12); static constexpr ReturnValue_t UNMOUNT_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 5); + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13); static constexpr ReturnValue_t SYSTEM_CALL_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 6); + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14); // C++17 does not support constexpr std::string yet static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; From bd505f35e21cdcde1dad61d6dd462263544302d2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 14:32:20 +0200 Subject: [PATCH 02/11] cold redundant and hot redundant configuration --- bsp_q7s/boardconfig/q7sConfig.h.in | 11 +++ bsp_q7s/core/CoreController.cpp | 127 +++++++++++++++++++++++------ bsp_q7s/core/CoreController.h | 2 + bsp_q7s/memory/SdCardManager.cpp | 42 ++++++---- bsp_q7s/memory/SdCardManager.h | 8 +- bsp_q7s/memory/definitions.h | 2 +- bsp_q7s/memory/scratchApi.h | 2 + 7 files changed, 149 insertions(+), 45 deletions(-) diff --git a/bsp_q7s/boardconfig/q7sConfig.h.in b/bsp_q7s/boardconfig/q7sConfig.h.in index 9bed2a4a..92c47994 100644 --- a/bsp_q7s/boardconfig/q7sConfig.h.in +++ b/bsp_q7s/boardconfig/q7sConfig.h.in @@ -4,6 +4,17 @@ #include #cmakedefine01 Q7S_SIMPLE_MODE + +#define Q7S_SD_NONE 0 +#define Q7S_SD_COLD_REDUNDANT 1 +#define Q7S_SD_HOT_REDUNDANT 2 +// The OBSW will perform different actions to set up the SD cards depending on the flag set here +// Set to Q7S_SD_NONE: Don't do anything +// Set to Q7S_COLD_REDUNDANT: On startup, get the prefered SD card, turn it on and mount it, and +// turn off the second SD card if it is on +// Set to Q7S_HOT_REDUNDANT: On startup, turn on both SD cards and mount them +#define Q7S_SD_CARD_CONFIG 1 + #define Q7S_ADD_RTD_DEVICES 0 /* Only one of those 2 should be enabled! */ diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 421a96d9..f7f907d0 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1,8 +1,10 @@ #include "CoreController.h" +#include "q7sConfig.h" + #include "../memory/SdCardManager.h" CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { +ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { } ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { @@ -22,15 +24,19 @@ LocalPoolDataSetBase* CoreController::getDataSetHandle(sid_t sid) { } ReturnValue_t CoreController::initialize() { - // Find a way to store this non-volatile outside of SD cards (ProASIC?) - sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; - std::string printoutString; - if(preferredSdCard == sd::SdCard::SLOT_0) { - printoutString = "0"; - } - else { - printoutString = "1"; - } + return sdCardInit(); +} + +ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t *msToReachTheMode) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CoreController::sdCardInit() { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +#else // Creator or update status file ReturnValue_t result = SdCardManager::instance()->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -38,26 +44,99 @@ ReturnValue_t CoreController::initialize() { << std::endl; } - sif::info << "Switching on SD card " << printoutString << ".." << std::endl; + SdCardManager* sdcMan = SdCardManager::instance(); + auto sdStatus = std::pair(sd::SdStatus::OFF, sd::SdStatus::OFF); + result = sdcMan->getSdCardActiveStatus(sdStatus); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Getting SD card activity status failed" << std::endl; + } - result = SdCardManager::instance()->switchOnSdCard(preferredSdCard, true); - if(result == SdCardManager::ALREADY_MOUNTED) { - sif::info << "SD card " << printoutString << " is already on and mounted" << std::endl; - } - else if(result == SdCardManager::ALREADY_ON) { - sif::info << "SD card " << printoutString << " is already on" << std::endl; - } - else if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Turning SD card on failed" +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + sif::info << "Cold redundant SD card configuration" << std::endl; + sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; + result = sdcMan->getPreferredSdCard(preferredSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Could not get prefered SD card information from the scratch buffer" << std::endl; } + sd::SdCard otherSdc = sd::SdCard::SLOT_0; + std::string printoutString; + std::string otherString; + if(preferredSdCard == sd::SdCard::SLOT_0) { + printoutString = "0"; + otherSdc = sd::SdCard::SLOT_1; + otherString = "1"; + } else { - sif::info << "SD card " << printoutString << " was switched on and mounted" << std::endl; + printoutString = "1"; + otherSdc = sd::SdCard::SLOT_0; + otherString = "0"; + } + + sd::SdStatus targetStatus = sd::SdStatus::OFF; + if(preferredSdCard == sd::SdCard::SLOT_0) { + targetStatus = sdStatus.first; + } + else if(preferredSdCard == sd::SdCard::SLOT_1) { + targetStatus = sdStatus.second; + } + + if(targetStatus == sd::SdStatus::MOUNTED) { + sif::info << "SD card " << printoutString << " is already switched on and mounted" << + std::endl; + result = HasReturnvaluesIF::RETURN_OK; + } + else if(targetStatus == sd::SdStatus::ON) { + sif::info << "Mounting SD card " << printoutString << std::endl; + result = sdcMan->mountSdCard(preferredSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Mounting SD card failed" << std::endl; + } + } + else if(targetStatus == sd::SdStatus::OFF) { + sif::info << "Switching on and mounting SD card " << printoutString << std::endl; + result = sdcMan->switchOnSdCard(preferredSdCard, true); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Switching on and mounting SD card failed" << std::endl; + } + } + + if(result != HasReturnvaluesIF::RETURN_OK) { + // This should not happen.. Switch on other SD card for now + sdcMan->switchOnSdCard(otherSdc, true); + return HasReturnvaluesIF::RETURN_FAILED; + } + + sif::info << "Switching off SD card " << otherString << std::endl; + // Switch off other SD card in cold-redundant mode + result = sdcMan->switchOffSdCard(otherSdc, true); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Switching off SD card " << otherString << " failed" << std::endl; } return HasReturnvaluesIF::RETURN_OK; -} +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + sif::info << "Hot redundant SD card configuration" << std::endl; -ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) { + // Use a lambda to avoid duplicate code + auto setUpSdCard = [sdcMan](sd::SdCard sdCard, sd::SdStatus status, std::string sdString) { + if(status == sd::SdStatus::OFF) { + sif::info << "Switching on and mounting SD card " << sdString << std::endl; + sdcMan->switchOnSdCard(sdCard, true); + } + else if(status == sd::SdStatus::ON) { + sif::info << "Mounting SD card " << sdString << std::endl; + sdcMan->mountSdCard(sdCard); + } + else { + sif::info << "SD card " << sdString << " already on and mounted" << std::endl; + } + }; + + setUpSdCard(sd::SdCard::SLOT_0, sdStatus.first, "0"); + setUpSdCard(sd::SdCard::SLOT_1, sdStatus.second, "1"); return HasReturnvaluesIF::RETURN_OK; +#endif + +#endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ + } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 674ed073..940a9097 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -17,6 +17,8 @@ private: LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); + + ReturnValue_t sdCardInit(); }; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 232000a3..1e9968b5 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -1,4 +1,6 @@ #include "SdCardManager.h" +#include "scratchApi.h" + #include "linux/utility/utility.h" #include "fsfw/ipc/MutexFactory.h" @@ -28,7 +30,7 @@ SdCardManager* SdCardManager::instance() { ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard) { std::pair active; - ReturnValue_t result = sdCardActive(active); + ReturnValue_t result = getSdCardActiveStatus(active); // Not allowed, this function turns on one SD card if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" @@ -67,7 +69,7 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard) { std::pair active; - ReturnValue_t result = sdCardActive(active); + ReturnValue_t result = getSdCardActiveStatus(active); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -99,8 +101,9 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd } ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { - std::string sdstring = ""; - std::string statestring = ""; + using namespace std; + string sdstring = ""; + string statestring = ""; if(sdCard == sd::SdCard::SLOT_0) { sdstring = "0"; } @@ -113,9 +116,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { else { statestring = "off"; } - std::ostringstream command; + ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - int result = std::system(command.str().c_str()); + int result = system(command.str().c_str()); if(result == 0) { return HasReturnvaluesIF::RETURN_OK; } @@ -124,7 +127,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { return SYSTEM_CALL_ERROR; } -ReturnValue_t SdCardManager::sdCardActive(std::pair& active) { +ReturnValue_t SdCardManager::getSdCardActiveStatus(std::pair& active) { using namespace std; if(not filesystem::exists(SD_STATE_FILE)) { return STATUS_FILE_NEXISTS; @@ -152,8 +155,8 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - std::string mountDev; - std::string mountPoint; + string mountDev; + string mountPoint; if(sdCard == sd::SdCard::SLOT_0) { mountDev = SD_0_DEV_NAME; mountPoint = SD_0_MOUNT_POINT; @@ -162,7 +165,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { mountDev = SD_0_DEV_NAME; mountPoint = SD_1_MOUNT_POINT; } - if(not std::filesystem::exists(mountDev)) { + if(not filesystem::exists(mountDev)) { sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to" " turn on the SD card" << std::endl; return MOUNT_ERROR; @@ -197,6 +200,7 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; + sif::debug << sdUnmountCommand << std::endl; int result = system(sdUnmountCommand.c_str()); if (result != 0) { utility::handleSystemError(result, "SdCardManager::unmountSdCard"); @@ -260,13 +264,21 @@ void SdCardManager::processSdStatusLine(std::pair &a idx++; } -sd::SdCard SdCardManager::getPreferredSdCard() const { - //int result = std::system("xsc_scratch read PREFSD > /tmp/pref_sd.txt"); - return preferredSdCard; +ReturnValue_t SdCardManager::getPreferredSdCard(sd::SdCard& sdCard) const { + uint8_t prefSdCard = 0; + ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + sdCard = static_cast(prefSdCard); + return HasReturnvaluesIF::RETURN_OK; } -void SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { - preferredSdCard = sdCard; +ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { + if(sdCard == sd::SdCard::BOTH) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast(sdCard)); } ReturnValue_t SdCardManager::updateSdCardStateFile() { diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index b3a33d42..35ba1654 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -54,9 +54,9 @@ public: */ static SdCardManager* instance(); - void setPreferredSdCard(sd::SdCard sdCard); + ReturnValue_t setPreferredSdCard(sd::SdCard sdCard); - sd::SdCard getPreferredSdCard() const; + ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const; /** * Switch on the specified SD card. @@ -97,7 +97,7 @@ public: * should call #updateSdCardStateFile again in that case * - STATUS_FILE_NEXISTS if the status file does not exist */ - ReturnValue_t sdCardActive(std::pair& active); + ReturnValue_t getSdCardActiveStatus(std::pair& active); /** * Mount the specified SD card. This is necessary to use it. @@ -113,8 +113,6 @@ public: */ ReturnValue_t unmountSdCard(sd::SdCard sdCard); - sd::SdCard getPreferedSdCard() const; - private: SdCardManager(); diff --git a/bsp_q7s/memory/definitions.h b/bsp_q7s/memory/definitions.h index a2d29d9b..546a6585 100644 --- a/bsp_q7s/memory/definitions.h +++ b/bsp_q7s/memory/definitions.h @@ -12,7 +12,7 @@ enum SdStatus: uint8_t { MOUNTED = 2 }; -enum SdCard { +enum SdCard: uint8_t { SLOT_0, SLOT_1, BOTH diff --git a/bsp_q7s/memory/scratchApi.h b/bsp_q7s/memory/scratchApi.h index 09bf6bab..eceda11a 100644 --- a/bsp_q7s/memory/scratchApi.h +++ b/bsp_q7s/memory/scratchApi.h @@ -16,6 +16,8 @@ */ namespace scratch { +static constexpr char PREFERED_SDC_KEY[] = "PREFSD"; + namespace { static uint8_t counter = 0; } From 5fc8b650f9bc8bec29b471fd4ce508ae83f80d6c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 15:19:06 +0200 Subject: [PATCH 03/11] more bugfixes --- bsp_q7s/boardconfig/q7sConfig.h.in | 2 +- bsp_q7s/core/CoreController.cpp | 16 ++++++--- bsp_q7s/memory/SdCardManager.cpp | 57 +++++++++++++++++++----------- bsp_q7s/memory/SdCardManager.h | 16 ++++++--- 4 files changed, 60 insertions(+), 31 deletions(-) diff --git a/bsp_q7s/boardconfig/q7sConfig.h.in b/bsp_q7s/boardconfig/q7sConfig.h.in index 92c47994..11dec25c 100644 --- a/bsp_q7s/boardconfig/q7sConfig.h.in +++ b/bsp_q7s/boardconfig/q7sConfig.h.in @@ -13,7 +13,7 @@ // Set to Q7S_COLD_REDUNDANT: On startup, get the prefered SD card, turn it on and mount it, and // turn off the second SD card if it is on // Set to Q7S_HOT_REDUNDANT: On startup, turn on both SD cards and mount them -#define Q7S_SD_CARD_CONFIG 1 +#define Q7S_SD_CARD_CONFIG Q7S_SD_COLD_REDUNDANT #define Q7S_ADD_RTD_DEVICES 0 diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index f7f907d0..2dcd204c 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -37,14 +37,16 @@ ReturnValue_t CoreController::sdCardInit() { sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; #else - // Creator or update status file - ReturnValue_t result = SdCardManager::instance()->updateSdCardStateFile(); + SdCardManager* sdcMan = SdCardManager::instance(); + + // Create update status file + ReturnValue_t result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } - SdCardManager* sdcMan = SdCardManager::instance(); + auto sdStatus = std::pair(sd::SdStatus::OFF, sd::SdStatus::OFF); result = sdcMan->getSdCardActiveStatus(sdStatus); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -113,15 +115,17 @@ ReturnValue_t CoreController::sdCardInit() { if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Switching off SD card " << otherString << " failed" << std::endl; } + // Update status file + sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT sif::info << "Hot redundant SD card configuration" << std::endl; // Use a lambda to avoid duplicate code - auto setUpSdCard = [sdcMan](sd::SdCard sdCard, sd::SdStatus status, std::string sdString) { + auto setUpSdCard = [&](sd::SdCard sdCard, sd::SdStatus status, std::string sdString) { if(status == sd::SdStatus::OFF) { sif::info << "Switching on and mounting SD card " << sdString << std::endl; - sdcMan->switchOnSdCard(sdCard, true); + sdcMan->switchOnSdCard(sdCard, true, &sdStatus); } else if(status == sd::SdStatus::ON) { sif::info << "Mounting SD card " << sdString << std::endl; @@ -134,6 +138,8 @@ ReturnValue_t CoreController::sdCardInit() { setUpSdCard(sd::SdCard::SLOT_0, sdStatus.first, "0"); setUpSdCard(sd::SdCard::SLOT_1, sdStatus.second, "1"); + // Update status file + sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; #endif diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 1e9968b5..537d3e77 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -28,23 +28,34 @@ SdCardManager* SdCardManager::instance() { return SdCardManager::factoryInstance; } -ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard) { - std::pair active; - ReturnValue_t result = getSdCardActiveStatus(active); +ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard, + SdStatusPair* statusPair) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if(statusPair == nullptr) { + statusPair = std::make_unique().get(); + result = getSdCardActiveStatus(*statusPair); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + // Not allowed, this function turns on one SD card if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + + sd::SdStatus targetStatus; if(sdCard == sd::SdCard::SLOT_0) { - if(active.first == sd::SdStatus::MOUNTED) { - return ALREADY_MOUNTED; - } - else if(active.first == sd::SdStatus::ON) { + targetStatus = statusPair->first; + } + else if(sdCard == sd::SdCard::SLOT_1) { + targetStatus = statusPair->second; + } + + auto switchCall = [&]() { + if(targetStatus == sd::SdStatus::ON) { if(not doMountSdCard) { return ALREADY_ON; } @@ -52,14 +63,19 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar return mountSdCard(sdCard); } } - - } - else if(sdCard == sd::SdCard::SLOT_1) { - if(active.second == sd::SdStatus::ON or active.second == sd::SdStatus::MOUNTED) { - return ALREADY_ON; + else if(targetStatus == sd::SdStatus::MOUNTED) { + return ALREADY_MOUNTED; } - } - result = setSdCardState(sdCard, true); + else if(targetStatus == sd::SdStatus::OFF) { + return setSdCardState(sdCard, true); + } + else { + return HasReturnvaluesIF::RETURN_FAILED; + } + }; + + result = switchCall(); + if(result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) { return result; } @@ -67,7 +83,8 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar return mountSdCard(sdCard); } -ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard) { +ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, + SdStatusPair* statusPair) { std::pair active; ReturnValue_t result = getSdCardActiveStatus(active); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -127,7 +144,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { return SYSTEM_CALL_ERROR; } -ReturnValue_t SdCardManager::getSdCardActiveStatus(std::pair& active) { +ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { using namespace std; if(not filesystem::exists(SD_STATE_FILE)) { return STATUS_FILE_NEXISTS; @@ -162,7 +179,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { mountPoint = SD_0_MOUNT_POINT; } else if(sdCard == sd::SdCard::SLOT_1) { - mountDev = SD_0_DEV_NAME; + mountDev = SD_1_DEV_NAME; mountPoint = SD_1_MOUNT_POINT; } if(not filesystem::exists(mountDev)) { diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 35ba1654..9a4dcbc5 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -19,6 +19,8 @@ class MutexIF; class SdCardManager { friend class SdCardAccess; public: + using SdStatusPair = std::pair; + static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; static constexpr ReturnValue_t ALREADY_ON = @@ -63,20 +65,24 @@ public: * @param sdCard * @param doMountSdCard Mount the SD card after switching it on, which is necessary * to use it + * @param statusPair If the status pair is already available, it can be passed here * @return - RETURN_OK on success, ALREADY_ON if it is already on, * SYSTEM_CALL_ERROR on system error */ - ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true); + ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true, + SdStatusPair* statusPair = nullptr); /** * Switch off the specified SD card. * @param sdCard * @param doUnmountSdCard Unmount the SD card before switching the card off, which makes * the operation safer + * @param statusPair If the status pair is already available, it can be passed here * @return - RETURN_OK on success, ALREADY_ON if it is already on, * SYSTEM_CALL_ERROR on system error */ - ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true); + ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true, + SdStatusPair* statusPair = nullptr); /** * Update the state file or creates one if it does not exist. You need to call this @@ -97,7 +103,7 @@ public: * should call #updateSdCardStateFile again in that case * - STATUS_FILE_NEXISTS if the status file does not exist */ - ReturnValue_t getSdCardActiveStatus(std::pair& active); + ReturnValue_t getSdCardActiveStatus(SdStatusPair& active); /** * Mount the specified SD card. This is necessary to use it. @@ -120,8 +126,8 @@ private: sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; - void processSdStatusLine(std::pair& active, - std::string& line, uint8_t& idx, sd::SdCard& currentSd); + void processSdStatusLine(SdStatusPair& active, std::string& line, uint8_t& idx, + sd::SdCard& currentSd); static SdCardManager* factoryInstance; }; From 5454392a91792dbc2362ee5067a2513b33cefd4d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 15:52:13 +0200 Subject: [PATCH 04/11] some refactoring --- bsp_q7s/core/CoreController.cpp | 112 +++++++++++++++---------------- bsp_q7s/memory/SdCardManager.cpp | 1 - 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 2dcd204c..93df63a7 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -46,96 +46,96 @@ ReturnValue_t CoreController::sdCardInit() { << std::endl; } - auto sdStatus = std::pair(sd::SdStatus::OFF, sd::SdStatus::OFF); result = sdcMan->getSdCardActiveStatus(sdStatus); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } + // Use a lambda to avoid duplicate code + auto setUpSdCard = [&](sd::SdCard sdCard, sd::SdStatus status, std::string sdString) { + std::string mountString; + if(sdCard == sd::SdCard::SLOT_0) { + mountString = SdCardManager::SD_0_MOUNT_POINT; + } + else { + mountString = SdCardManager::SD_1_MOUNT_POINT; + } + + if(status == sd::SdStatus::OFF) { + sif::info << "Switching on and mounting SD card " << sdString << " at " << + mountString << std::endl; + return sdcMan->switchOnSdCard(sdCard, true, &sdStatus); + } + else if(status == sd::SdStatus::ON) { + sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + return sdcMan->mountSdCard(sdCard); + } + else { + sif::info << "SD card " << sdString << " already on and mounted at " << + mountString << std::endl; + return SdCardManager::ALREADY_MOUNTED; + } + }; + #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - sif::info << "Cold redundant SD card configuration" << std::endl; sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; result = sdcMan->getPreferredSdCard(preferredSdCard); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Could not get prefered SD card information from the scratch buffer" << std::endl; } - sd::SdCard otherSdc = sd::SdCard::SLOT_0; - std::string printoutString; + std::string preferredString; + sd::SdStatus preferredStatus = sd::SdStatus::OFF; + + sd::SdStatus otherStatus = sd::SdStatus::OFF; std::string otherString; + sd::SdCard otherSdc = sd::SdCard::SLOT_0; + + sif::info << "Cold redundant SD card configuration, preferred SD card " << + preferredString << std::endl; + if(preferredSdCard == sd::SdCard::SLOT_0) { - printoutString = "0"; + preferredStatus = sdStatus.first; + preferredString = "0"; otherSdc = sd::SdCard::SLOT_1; + otherStatus = sdStatus.second; otherString = "1"; } else { - printoutString = "1"; + preferredString = "1"; + preferredStatus = sdStatus.second; + otherStatus = sdStatus.first; otherSdc = sd::SdCard::SLOT_0; otherString = "0"; } - sd::SdStatus targetStatus = sd::SdStatus::OFF; - if(preferredSdCard == sd::SdCard::SLOT_0) { - targetStatus = sdStatus.first; - } - else if(preferredSdCard == sd::SdCard::SLOT_1) { - targetStatus = sdStatus.second; + result = setUpSdCard(preferredSdCard, preferredStatus, preferredString); + if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Setting up preferred card " << otherString << + " in cold redundant mode failed" << std::endl; + // Try other SD card and mark set up operation as failed + setUpSdCard(otherSdc, otherStatus, otherString); + result = HasReturnvaluesIF::RETURN_FAILED; } - if(targetStatus == sd::SdStatus::MOUNTED) { - sif::info << "SD card " << printoutString << " is already switched on and mounted" << - std::endl; - result = HasReturnvaluesIF::RETURN_OK; - } - else if(targetStatus == sd::SdStatus::ON) { - sif::info << "Mounting SD card " << printoutString << std::endl; - result = sdcMan->mountSdCard(preferredSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Mounting SD card failed" << std::endl; - } - } - else if(targetStatus == sd::SdStatus::OFF) { - sif::info << "Switching on and mounting SD card " << printoutString << std::endl; - result = sdcMan->switchOnSdCard(preferredSdCard, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Switching on and mounting SD card failed" << std::endl; + if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdStatus::OFF) { + sif::info << "Switching off secondary SD card " << otherString << std::endl; + // Switch off other SD card in cold redundant mode if setting up preferred one walked + // without issues + result = sdcMan->switchOffSdCard(otherSdc, otherStatus, &sdStatus); + if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_OFF) { + sif::warning << "Switching off secondary SD card " << otherString << + " in cold redundant mode failed" << std::endl; } } - if(result != HasReturnvaluesIF::RETURN_OK) { - // This should not happen.. Switch on other SD card for now - sdcMan->switchOnSdCard(otherSdc, true); - return HasReturnvaluesIF::RETURN_FAILED; - } - - sif::info << "Switching off SD card " << otherString << std::endl; - // Switch off other SD card in cold-redundant mode - result = sdcMan->switchOffSdCard(otherSdc, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Switching off SD card " << otherString << " failed" << std::endl; - } // Update status file sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT sif::info << "Hot redundant SD card configuration" << std::endl; - // Use a lambda to avoid duplicate code - auto setUpSdCard = [&](sd::SdCard sdCard, sd::SdStatus status, std::string sdString) { - if(status == sd::SdStatus::OFF) { - sif::info << "Switching on and mounting SD card " << sdString << std::endl; - sdcMan->switchOnSdCard(sdCard, true, &sdStatus); - } - else if(status == sd::SdStatus::ON) { - sif::info << "Mounting SD card " << sdString << std::endl; - sdcMan->mountSdCard(sdCard); - } - else { - sif::info << "SD card " << sdString << " already on and mounted" << std::endl; - } - }; - setUpSdCard(sd::SdCard::SLOT_0, sdStatus.first, "0"); setUpSdCard(sd::SdCard::SLOT_1, sdStatus.second, "1"); // Update status file diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 537d3e77..b37f1195 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -217,7 +217,6 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; - sif::debug << sdUnmountCommand << std::endl; int result = system(sdUnmountCommand.c_str()); if (result != 0) { utility::handleSystemError(result, "SdCardManager::unmountSdCard"); From 32ef21ea2241f9d98e1930fda15d91457479503b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 15:58:43 +0200 Subject: [PATCH 05/11] some more fixes --- bsp_q7s/core/CoreController.cpp | 10 +++++----- bsp_q7s/memory/SdCardAccess.cpp | 2 +- bsp_q7s/memory/SdCardAccess.h | 2 +- bsp_q7s/memory/SdCardManager.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 93df63a7..c4863260 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,7 +4,7 @@ #include "../memory/SdCardManager.h" CoreController::CoreController(object_id_t objectId): -ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { } ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { @@ -82,7 +82,7 @@ ReturnValue_t CoreController::sdCardInit() { sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; result = sdcMan->getPreferredSdCard(preferredSdCard); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Could not get prefered SD card information from the scratch buffer" + sif::warning << "Could not get preferred SD card information from the scratch buffer" << std::endl; } std::string preferredString; @@ -92,9 +92,6 @@ ReturnValue_t CoreController::sdCardInit() { std::string otherString; sd::SdCard otherSdc = sd::SdCard::SLOT_0; - sif::info << "Cold redundant SD card configuration, preferred SD card " << - preferredString << std::endl; - if(preferredSdCard == sd::SdCard::SLOT_0) { preferredStatus = sdStatus.first; preferredString = "0"; @@ -110,6 +107,9 @@ ReturnValue_t CoreController::sdCardInit() { otherString = "0"; } + sif::info << "Cold redundant SD card configuration, preferred SD card " << + preferredString << std::endl; + result = setUpSdCard(preferredSdCard, preferredStatus, preferredString); if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Setting up preferred card " << otherString << diff --git a/bsp_q7s/memory/SdCardAccess.cpp b/bsp_q7s/memory/SdCardAccess.cpp index 92837787..55efde98 100644 --- a/bsp_q7s/memory/SdCardAccess.cpp +++ b/bsp_q7s/memory/SdCardAccess.cpp @@ -2,6 +2,6 @@ #include "fsfw/ipc/MutexGuard.h" -SdCardAccess::SdCardAccess(sd::SdCard sdCard) { +SdCardAccess::SdCardAccess() { } diff --git a/bsp_q7s/memory/SdCardAccess.h b/bsp_q7s/memory/SdCardAccess.h index 8128b122..38dc3336 100644 --- a/bsp_q7s/memory/SdCardAccess.h +++ b/bsp_q7s/memory/SdCardAccess.h @@ -5,7 +5,7 @@ class SdCardAccess { public: - SdCardAccess(sd::SdCard sdCard); + SdCardAccess(); private: }; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index b37f1195..36d8f67b 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -90,7 +90,7 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd if(result != HasReturnvaluesIF::RETURN_OK) { return result; } - // Not allowed, this function turns on off SD card + // Not allowed, this function turns off one SD card if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" << std::endl; From 3a6b8cc66be53a65d3d439338898619d4051d347 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 16:32:14 +0200 Subject: [PATCH 06/11] FS queue size configurable --- bsp_q7s/memory/CMakeLists.txt | 1 - bsp_q7s/memory/FileSystemHandler.cpp | 2 +- bsp_q7s/memory/FileSystemHandler.h | 6 ++++++ bsp_q7s/memory/SdCardAccess.cpp | 7 ------- bsp_q7s/memory/SdCardAccess.h | 13 ------------- bsp_q7s/memory/SdCardManager.h | 15 +++++++++++++-- linux/fsfwconfig/OBSWConfig.h.in | 2 ++ 7 files changed, 22 insertions(+), 24 deletions(-) delete mode 100644 bsp_q7s/memory/SdCardAccess.cpp delete mode 100644 bsp_q7s/memory/SdCardAccess.h diff --git a/bsp_q7s/memory/CMakeLists.txt b/bsp_q7s/memory/CMakeLists.txt index ada948fb..6c7d0a94 100644 --- a/bsp_q7s/memory/CMakeLists.txt +++ b/bsp_q7s/memory/CMakeLists.txt @@ -1,6 +1,5 @@ target_sources(${TARGET_NAME} PRIVATE FileSystemHandler.cpp - SdCardAccess.cpp SdCardManager.cpp scratchApi.cpp ) \ No newline at end of file diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 5f7e0435..473a5167 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -6,7 +6,7 @@ FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler): SystemObject(fileSystemHandler) { - mq = QueueFactory::instance()->createMessageQueue(50); + mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE); } FileSystemHandler::~FileSystemHandler() { diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 04cea3dc..803e52b7 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -1,11 +1,15 @@ #ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ #define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ +#include "OBSWConfig.h" + #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/memory/HasFileSystemIF.h" +#include + class FileSystemHandler: public SystemObject, public ExecutableObjectIF, public HasFileSystemIF { @@ -23,6 +27,8 @@ public: private: MessageQueueIF* mq = nullptr; + std::string currentMountPrefix; + static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data, size_t size, diff --git a/bsp_q7s/memory/SdCardAccess.cpp b/bsp_q7s/memory/SdCardAccess.cpp deleted file mode 100644 index 55efde98..00000000 --- a/bsp_q7s/memory/SdCardAccess.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "SdCardAccess.h" - -#include "fsfw/ipc/MutexGuard.h" - -SdCardAccess::SdCardAccess() { - -} diff --git a/bsp_q7s/memory/SdCardAccess.h b/bsp_q7s/memory/SdCardAccess.h deleted file mode 100644 index 38dc3336..00000000 --- a/bsp_q7s/memory/SdCardAccess.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef BSP_Q7S_MEMORY_SDCARDACCESS_H_ -#define BSP_Q7S_MEMORY_SDCARDACCESS_H_ - -#include "definitions.h" - -class SdCardAccess { -public: - SdCardAccess(); -private: -}; - - -#endif /* BSP_Q7S_MEMORY_SDCARDACCESS_H_ */ diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 9a4dcbc5..d47b5322 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -56,8 +56,21 @@ public: */ static SdCardManager* instance(); + /** + * Set the preferred SD card which will determine which SD card will be used as the primary + * SD card in hot redundant and cold redundant mode. This function will not switch the + * SD cards which are currently on and mounted, this needs to be implemented by + * an upper layer by using #switchOffSdCard , #switchOnSdCard and #updateSdCardStateFile + * @param sdCard + * @return + */ ReturnValue_t setPreferredSdCard(sd::SdCard sdCard); + /** + * Get the currently configured preferred SD card + * @param sdCard + * @return + */ ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const; /** @@ -124,8 +137,6 @@ private: ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); - sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; - void processSdStatusLine(SdStatusPair& active, std::string& line, uint8_t& idx, sd::SdCard& currentSd); diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index a5a439ab..ef6b419d 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -14,6 +14,8 @@ #include "commonConfig.h" #include "OBSWVersion.h" +#define OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE 50 + /* These defines should be disabled for mission code but are useful for debugging. */ #define OBSW_VERBOSE_LEVEL 1 From eb7b0770a00d1770e147318a9d94b0e4eaf1353f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:23:32 +0200 Subject: [PATCH 07/11] starting file system handler --- bsp_q7s/memory/FileSystemHandler.cpp | 126 +++++++++++++++++++++------ bsp_q7s/memory/FileSystemHandler.h | 12 ++- bsp_q7s/memory/SdCardManager.cpp | 23 +++++ bsp_q7s/memory/SdCardManager.h | 13 +++ fsfw | 2 +- 5 files changed, 149 insertions(+), 27 deletions(-) diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 473a5167..ba64a991 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -15,33 +15,85 @@ FileSystemHandler::~FileSystemHandler() { ReturnValue_t FileSystemHandler::performOperation(uint8_t unsignedChar) { while(true) { - CommandMessage filemsg; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - while(true) { - result = mq->receiveMessage(&filemsg); - if(result == MessageQueueIF::EMPTY) { - break; - } - else if(result != HasReturnvaluesIF::RETURN_FAILED) { - sif::warning << "FileSystemHandler::performOperation: Message reception failed!" - << std::endl; - break; - } - Command_t command = filemsg.getCommand(); - switch(command) { - case(GenericFileSystemMessage::CMD_CREATE_DIRECTORY): { - break; - } - case(GenericFileSystemMessage::CMD_CREATE_FILE): { - break; - } - } + try { + fileSystemHandlerLoop(); } + catch(std::bad_alloc& e) { + // Restart OBSW, hints at a memory leak + sif::error << "Allocation error in FileSystemHandler::performOperation" + << e.what() << std::endl; + // TODO: If we trigger an event, it might not get sent because were restarting + // Set up an error file or a special flag in the scratch buffer. + // TODO: CoreController: Implement function to restart OBC + } + } +} - // This task will have a low priority and will run permanently in the background - // so we will just run in a permanent loop here and check file system - // messages permanently - TaskFactory::instance()->delayTask(1000); + +void FileSystemHandler::fileSystemHandlerLoop() { + CommandMessage filemsg; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + while(true) { + if(opCounter % 5 == 0) { + fileSystemCheckup(); + } + result = mq->receiveMessage(&filemsg); + if(result == MessageQueueIF::EMPTY) { + break; + } + else if(result != HasReturnvaluesIF::RETURN_FAILED) { + sif::warning << "FileSystemHandler::performOperation: Message reception failed!" + << std::endl; + break; + } + Command_t command = filemsg.getCommand(); + switch(command) { + case(GenericFileSystemMessage::CMD_CREATE_DIRECTORY): { + break; + } + case(GenericFileSystemMessage::CMD_CREATE_FILE): { + break; + } + } + opCounter++; + } + + // This task will have a low priority and will run permanently in the background + // so we will just run in a permanent loop here and check file system + // messages permanently + TaskFactory::instance()->delayTask(1000); +} + +void FileSystemHandler::fileSystemCheckup() { + SdCardManager::SdStatusPair statusPair; + sdcMan->getSdCardActiveStatus(statusPair); + sd::SdCard preferredSdCard; + sdcMan->getPreferredSdCard(preferredSdCard); + if((preferredSdCard == sd::SdCard::SLOT_0) and + (statusPair.first == sd::SdStatus::MOUNTED)) { + currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + } + if((preferredSdCard == sd::SdCard::SLOT_1) and + (statusPair.second == sd::SdStatus::MOUNTED)) { + currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; + } + else { + std::string sdString; + if(preferredSdCard == sd::SdCard::SLOT_0) { + sdString = "0"; + } + else { + sdString = "1"; + } + sif::warning << "FileSystemHandler::performOperation: Inconsistent" << + " state detected. Preferred SD card is " << sdString << + " but does not appear to be mounted. Attempting fix.." << std::endl; + // This function will appear to fix the inconsistent state + ReturnValue_t result = sdcMan->sanitizeState(&preferredSdCard, &statusPair); + if(result != HasReturnvaluesIF::RETURN_OK) { + // Oh no. Trigger medium severity event + sif::error << "Fix failed" << std::endl; + } } } @@ -49,6 +101,22 @@ MessageQueueId_t FileSystemHandler::getCommandQueue() const { return mq->getId(); } +ReturnValue_t FileSystemHandler::initialize() { + sdcMan = SdCardManager::instance(); + sd::SdCard preferredSdCard; + ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if(preferredSdCard == sd::SdCard::SLOT_0) { + currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + } + else if(preferredSdCard == sd::SdCard::SLOT_1) { + currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; + } + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t FileSystemHandler::appendToFile(const char *repositoryPath, const char *filename, const uint8_t *data, size_t size, uint16_t packetNumber, void *args) { return HasReturnvaluesIF::RETURN_OK; @@ -63,3 +131,11 @@ ReturnValue_t FileSystemHandler::deleteFile(const char *repositoryPath, const ch void *args) { return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t FileSystemHandler::createDirectory(const char *repositoryPath, void *args) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t FileSystemHandler::removeDirectory(const char *repositoryPath, void *args) { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 803e52b7..9d3285b1 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ #define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ +#include #include "OBSWConfig.h" #include "fsfw/ipc/MessageQueueIF.h" @@ -19,6 +20,8 @@ public: ReturnValue_t performOperation(uint8_t) override; + ReturnValue_t initialize() override; + /** * Function to get the MessageQueueId_t of the implementing object * @return MessageQueueId_t of the object @@ -27,8 +30,13 @@ public: private: MessageQueueIF* mq = nullptr; - std::string currentMountPrefix; + std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; + SdCardManager* sdcMan = nullptr; + uint8_t opCounter = 0; + + void fileSystemHandlerLoop(); + void fileSystemCheckup(); ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data, size_t size, @@ -38,6 +46,8 @@ private: size_t size = 0, void* args = nullptr) override; ReturnValue_t deleteFile(const char* repositoryPath, const char* filename, void* args = nullptr) override; + ReturnValue_t createDirectory(const char* repositoryPath, void* args = nullptr) override; + ReturnValue_t removeDirectory(const char* repositoryPath, void* args = nullptr) override; }; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 36d8f67b..5a50665b 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -7,6 +7,7 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include +#include #include SdCardManager* SdCardManager::factoryInstance = nullptr; @@ -225,6 +226,28 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t SdCardManager::sanitizeState(sd::SdCard* prefSdCard, SdStatusPair* statusPair) { + if(prefSdCard == nullptr) { + prefSdCard = std::make_unique(sd::SdCard::SLOT_0).get(); + getPreferredSdCard(*prefSdCard); + } + if(statusPair == nullptr) { + statusPair = std::make_unique().get(); + getSdCardActiveStatus(*statusPair); + } + + auto sanitizerFunc = [&](sd::SdCard prefSdCard) { + if(statusPair->first == sd::SdStatus::ON) { + return mountSdCard(prefSdCard); + } + else { + return switchOnSdCard(prefSdCard, true, statusPair); + } + }; + + return sanitizerFunc(*prefSdCard); +} + void SdCardManager::processSdStatusLine(std::pair &active, std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std; diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index d47b5322..966e6e2a 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -132,6 +132,19 @@ public: */ ReturnValue_t unmountSdCard(sd::SdCard sdCard); + /** + * In case that there is a discrepancy between the preferred SD card and the currently + * mounted one, this function will sanitize the state by attempting to mount the + * currently preferred SD card. If the caller already has state information, it can be + * passed into the function. + * @param prefSdCard Preferred SD card captured with #getPreferredSdCard + * @param statusPair Current SD card status capture with #getSdCardActiveStatus + * @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed + * @return + */ + ReturnValue_t sanitizeState(sd::SdCard* prefSdCard = nullptr, + SdStatusPair* statusPair = nullptr); + private: SdCardManager(); diff --git a/fsfw b/fsfw index eef2fd3b..323577cd 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit eef2fd3b7ac764f06ed5d9a3c97c894d92a515fa +Subproject commit 323577cdc69ee2d863e6e61cebd71a8aa75c6d2b From 15ab1dd89dd06e6af273a78f870bf806864f3f82 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:39:36 +0200 Subject: [PATCH 08/11] continued functions to create/delete dir --- bsp_q7s/memory/FileSystemHandler.cpp | 37 ++++++++++++++++++++++++++-- bsp_q7s/memory/FileSystemHandler.h | 3 ++- fsfw | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index ba64a991..12c3a20b 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -4,6 +4,8 @@ #include "fsfw/memory/GenericFileSystemMessage.h" #include "fsfw/ipc/QueueFactory.h" +#include + FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler): SystemObject(fileSystemHandler) { mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE); @@ -133,9 +135,40 @@ ReturnValue_t FileSystemHandler::deleteFile(const char *repositoryPath, const ch } ReturnValue_t FileSystemHandler::createDirectory(const char *repositoryPath, void *args) { - return HasReturnvaluesIF::RETURN_OK; + std::string fullPath = currentMountPrefix + std::string(repositoryPath); + if(std::filesystem::exists(fullPath)) { + return DIRECTORY_ALREADY_EXISTS; + } + if(std::filesystem::create_directory(fullPath)) { + return HasReturnvaluesIF::RETURN_OK; + } + sif::warning << "Creating directory " << fullPath << " failed" << std::endl; + return GENERIC_FILE_ERROR; } -ReturnValue_t FileSystemHandler::removeDirectory(const char *repositoryPath, void *args) { +ReturnValue_t FileSystemHandler::removeDirectory(const char *repositoryPath, + bool deleteRecurively, void *args) { + std::string fullPath = currentMountPrefix + std::string(repositoryPath); + if(not std::filesystem::exists(fullPath)) { + return DIRECTORY_DOES_NOT_EXIST; + } + std::error_code err; + if(not deleteRecurively) { + if(std::filesystem::remove(fullPath, err)) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + // Check error code. Most probably denied permissions because folder is not empty + } + } + else { + if(std::filesystem::remove_all(fullPath, err)) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + // Check error code + } + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 9d3285b1..4f82566d 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -47,7 +47,8 @@ private: ReturnValue_t deleteFile(const char* repositoryPath, const char* filename, void* args = nullptr) override; ReturnValue_t createDirectory(const char* repositoryPath, void* args = nullptr) override; - ReturnValue_t removeDirectory(const char* repositoryPath, void* args = nullptr) override; + ReturnValue_t removeDirectory(const char* repositoryPath, bool deleteRecurively = false, + void* args = nullptr) override; }; diff --git a/fsfw b/fsfw index 323577cd..da8a4470 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 323577cdc69ee2d863e6e61cebd71a8aa75c6d2b +Subproject commit da8a4470734808bed4d872e47c192af694382c41 From aa461d69f15cd48791e95128d5070b8c82724479 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:41:13 +0200 Subject: [PATCH 09/11] added builder functions for full paths --- bsp_q7s/memory/FileSystemHandler.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 12c3a20b..02788b81 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -121,16 +121,25 @@ ReturnValue_t FileSystemHandler::initialize() { ReturnValue_t FileSystemHandler::appendToFile(const char *repositoryPath, const char *filename, const uint8_t *data, size_t size, uint16_t packetNumber, void *args) { + // A double slash between repo and filename should not be an issue, so add it in any case + std::string fullPath = currentMountPrefix + std::string(repositoryPath) + "/" + + std::string(filename); return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t FileSystemHandler::createFile(const char *repositoryPath, const char *filename, const uint8_t *data, size_t size, void *args) { + // A double slash between repo and filename should not be an issue, so add it in any case + std::string fullPath = currentMountPrefix + std::string(repositoryPath) + "/" + + std::string(filename); return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t FileSystemHandler::deleteFile(const char *repositoryPath, const char *filename, void *args) { + // A double slash between repo and filename should not be an issue, so add it in any case + std::string fullPath = currentMountPrefix + std::string(repositoryPath) + "/" + + std::string(filename); return HasReturnvaluesIF::RETURN_OK; } From 4eb740fd075110b2bf92e897cbaa277e90bbe125 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:50:01 +0200 Subject: [PATCH 10/11] minor changes --- bsp_q7s/memory/FileSystemHandler.cpp | 3 ++- bsp_q7s/memory/FileSystemHandler.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 02788b81..1519b92b 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -93,7 +93,8 @@ void FileSystemHandler::fileSystemCheckup() { // This function will appear to fix the inconsistent state ReturnValue_t result = sdcMan->sanitizeState(&preferredSdCard, &statusPair); if(result != HasReturnvaluesIF::RETURN_OK) { - // Oh no. Trigger medium severity event + // Oh no. + // TODO: Trigger medium severity event sif::error << "Fix failed" << std::endl; } } diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 4f82566d..886fa574 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ #define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ -#include +#include "SdCardManager.h" #include "OBSWConfig.h" #include "fsfw/ipc/MessageQueueIF.h" From eb72b7e6e819c698e5cb1bf0c8411dd94123a1d9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Jul 2021 17:55:07 +0200 Subject: [PATCH 11/11] fsfw and fsfw_hal update --- fsfw | 2 +- fsfw_hal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index da8a4470..516e3c0f 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit da8a4470734808bed4d872e47c192af694382c41 +Subproject commit 516e3c0f9f5944081d724773a6743e2319f95979 diff --git a/fsfw_hal b/fsfw_hal index 8ff09c95..1eda4874 160000 --- a/fsfw_hal +++ b/fsfw_hal @@ -1 +1 @@ -Subproject commit 8ff09c95a69f1f43fec6104d6cce1e788b2b870d +Subproject commit 1eda4874cda2a31443c435fc671fd5cae8236660