From 435feb39809230615bb744f91cea0b922ca11171 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 10:43:41 +0200 Subject: [PATCH 01/15] section for rootfs differences --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 05881a16..e9d4a9ef 100644 --- a/README.md +++ b/README.md @@ -703,6 +703,16 @@ Rebooting currently running image: xsc_boot_copy -r ``` +## Preparation of a fresh rootfs + +This section summarizes important changes between a fresh rootfs and the current +EIVE implementation + +- Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir` +- Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir` +- Folder `scripts` in `/home/root` folder. +- `scripts` folder currently contains `update_main_components.sh` script + # Running the EIVE OBSW on a Raspberry Pi Special section for running the EIVE OBSW on the Raspberry Pi. -- 2.43.0 From c399a8f5fb080b43586cb354cc3f9042138a8cd5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 10:48:12 +0200 Subject: [PATCH 02/15] continued prep section --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ba494d96..356ccf75 100644 --- a/README.md +++ b/README.md @@ -709,16 +709,26 @@ Rebooting currently running image: xsc_boot_copy -r ``` -## Preparation of a fresh rootfs +## Preparation of a fresh rootfs and SD card This section summarizes important changes between a fresh rootfs and the current EIVE implementation +### rootfs + - Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir` - Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir` - Folder `scripts` in `/home/root` folder. - `scripts` folder currently contains `update_main_components.sh` script +### SD Cards + +- Folder `bin` for binaries, for example the OBSW +- Folder `misc` for miscellaneous files +- Folder `tc` for telecommands +- Folder `tm` for telemetry +- Folder `xdi` for XDI components (e.g. for firmware or device tree updates) + # Running the EIVE OBSW on a Raspberry Pi Special section for running the EIVE OBSW on the Raspberry Pi. -- 2.43.0 From 9cc236b275025621c50bcb905e3aeb1cadb875aa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 11:37:10 +0200 Subject: [PATCH 03/15] mounting SD cards now as well --- bsp_q7s/memory/SdCardManager.cpp | 181 ++++++++++++++++++++++++++----- bsp_q7s/memory/SdCardManager.h | 28 ++++- bsp_q7s/memory/definitions.h | 9 ++ 3 files changed, 184 insertions(+), 34 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index af963180..8c67ea2c 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -1,4 +1,6 @@ #include "SdCardManager.h" +#include "linux/utility/utility.h" + #include "fsfw/ipc/MutexFactory.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -24,29 +26,66 @@ SdCardManager* SdCardManager::instance() { return SdCardManager::factoryInstance; } -ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard) { - std::pair active; +ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard) { + std::pair active; ReturnValue_t result = sdCardActive(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" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } if(result != HasReturnvaluesIF::RETURN_OK) { return result; } - if((sdCard == sd::SdCard::SLOT_0 and active.first) or - (sdCard == sd::SdCard::SLOT_1 and active.second)) { - return ALREADY_ON; + if(sdCard == sd::SdCard::SLOT_0) { + if(active.first == sd::SdStatus::ON or active.first == sd::SdStatus::MOUNTED) { + return ALREADY_ON; + } } - return setSdCardState(sdCard, true); + else if(sdCard == sd::SdCard::SLOT_1) { + if(active.second == sd::SdStatus::ON or active.second == sd::SdStatus::MOUNTED) { + return ALREADY_ON; + } + } + result = setSdCardState(sdCard, true); + if(result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) { + return result; + } + + return mountSdCard(sdCard); } -ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard) { - std::pair active; +ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard) { + std::pair active; ReturnValue_t result = sdCardActive(active); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } - if((sdCard == sd::SdCard::SLOT_0 and not active.first) or - (sdCard == sd::SdCard::SLOT_1 and not active.second)) { - return ALREADY_OFF; + // Not allowed, this function turns on off 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(sdCard == sd::SdCard::SLOT_0) { + if(active.first == sd::SdStatus::OFF) { + return ALREADY_OFF; + } + } + else if(sdCard == sd::SdCard::SLOT_1) { + if(active.second == sd::SdStatus::OFF) { + return ALREADY_OFF; + } + } + + if(doUnmountSdCard) { + result = unmountSdCard(sdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return setSdCardState(sdCard, false); } @@ -76,7 +115,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { return SYSTEM_CALL_ERROR; } -ReturnValue_t SdCardManager::sdCardActive(std::pair& active) { +ReturnValue_t SdCardManager::sdCardActive(std::pair& active) { using namespace std; if(not filesystem::exists("/tmp/sd_status.txt")) { return STATUS_FILE_NEXISTS; @@ -89,45 +128,127 @@ ReturnValue_t SdCardManager::sdCardActive(std::pair& active) { } string line; uint8_t idx = 0; - + sd::SdCard currentSd = sd::SdCard::SLOT_0; + // Process status file line by line while (std::getline(sdStatus, line)) { - istringstream iss(line); - string word; - sd::SdCard currentSd = sd::SdCard::SLOT_0; - while(iss >> word) { + processSdStatusLine(active, line, idx, currentSd); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { + using namespace std; + if(sdCard == sd::SdCard::BOTH) { + sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + std::string mountDev; + std::string mountPoint; + if(sdCard == sd::SdCard::SLOT_0) { + mountDev = SD_0_DEV_NAME; + mountPoint = SD_0_MOUNT_POINT; + } + else if(sdCard == sd::SdCard::SLOT_1) { + mountDev = SD_0_DEV_NAME; + mountPoint = SD_1_MOUNT_POINT; + } + if(not std::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; + } + + string sdMountCommand = "mount " + mountDev + " " + mountPoint; + int result = system(sdMountCommand.c_str()); + if (result != 0) { + utility::handleSystemError(result, "SdCardManager::mountSdCard"); + return SYSTEM_CALL_ERROR; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { + using namespace std; + if(sdCard == sd::SdCard::BOTH) { + sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + string mountPoint; + if(sdCard == sd::SdCard::SLOT_0) { + mountPoint = SD_0_MOUNT_POINT; + } + else if(sdCard == sd::SdCard::SLOT_1) { + mountPoint = SD_1_MOUNT_POINT; + } + if(filesystem::is_empty(mountPoint)) { + // The mount point will always exist, but if it is empty, that is strong hint that + // the SD card was not mounted properly. Still proceed with operation. + sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; + } + string sdUnmountCommand = "umount " + mountPoint; + int result = system(sdUnmountCommand.c_str()); + if (result != 0) { + utility::handleSystemError(result, "SdCardManager::unmountSdCard"); + return SYSTEM_CALL_ERROR; + } + return HasReturnvaluesIF::RETURN_OK; +} + +void SdCardManager::processSdStatusLine(std::pair &active, + std::string& line, uint8_t& idx, sd::SdCard& currentSd) { + using namespace std; + istringstream iss(line); + string word; + bool slotLine = false; + bool mountLine = false; + while(iss >> word) { + if (word == "Slot") { + slotLine = true; + } + if(word == "Mounted") { + mountLine = true; + } + + if(slotLine) { if (word == "1:") { currentSd = sd::SdCard::SLOT_1; } if(word == "on") { if(currentSd == sd::SdCard::SLOT_0) { - active.first = true; + active.first = sd::SdStatus::ON; } else { - active.second = true; + active.second = sd::SdStatus::ON; } } else if (word == "off") { if(currentSd == sd::SdCard::SLOT_0) { - active.first = false; + active.first = sd::SdStatus::OFF; } else { - active.second = false; + active.second = sd::SdStatus::OFF; } } - else { - continue; - } + } - if(idx > 3) { - sif::warning << "SdCardManager::sdCardActive: Status file has more " - "than 4 lines!" << std::endl; - return STATUS_FILE_FORMAT_INVALID; + if(mountLine) { + if(currentSd == sd::SdCard::SLOT_0) { + active.first = sd::SdStatus::MOUNTED; + } + else { + active.second = sd::SdStatus::MOUNTED; } } - idx++; + + if(idx > 5) { + sif::warning << "SdCardManager::sdCardActive: /tmp/sd_status.txt has more than 6 " + "lines and might be invalid!" << std::endl; + } } - return HasReturnvaluesIF::RETURN_OK; + idx++; } sd::SdCard SdCardManager::getPreferredSdCard() const { diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 0c9c664d..9052d9b0 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -8,6 +8,7 @@ #include #include +#include class MutexIF; @@ -26,8 +27,17 @@ public: HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); + static constexpr ReturnValue_t MOUNT_ERROR = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 4); + static constexpr ReturnValue_t UNMOUNT_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 5); static constexpr ReturnValue_t SYSTEM_CALL_ERROR = - HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 4); + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 6); + + // C++17 does not support constexpr std::string yet + static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; + static constexpr char SD_1_DEV_NAME[] = "/dev/mmcblk1p1"; + static constexpr char SD_0_MOUNT_POINT[] = "/mnt/sd0"; + static constexpr char SD_1_MOUNT_POINT[] = "/mnt/sd1"; virtual ~SdCardManager(); @@ -45,18 +55,22 @@ public: /** * Switch on the specified SD card * @param sdCard + * @param doMountSdCard Mount the SD card after switching it on, which is necessary + * to use it * @return - RETURN_OK on success, ALREADY_ON if it is already on, * SYSTEM_CALL_ERROR on system error */ - ReturnValue_t switchOnSdCard(sd::SdCard sdCard); + ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true); /** * Switch off the specified SD card * @param sdCard + * @param doUnmountSdCard Unmount the SD card before switching the card off, which makes + * the operation safer * @return - RETURN_OK on success, ALREADY_ON if it is already on, * SYSTEM_CALL_ERROR on system error */ - ReturnValue_t switchOffSdCard(sd::SdCard sdCard); + ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true); /** * Updated the state file or creates one if it does not exist. You need to call this @@ -77,7 +91,10 @@ 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 sdCardActive(std::pair& active); + + ReturnValue_t mountSdCard(sd::SdCard sdCard); + ReturnValue_t unmountSdCard(sd::SdCard sdCard); sd::SdCard getPreferedSdCard() const; @@ -88,6 +105,9 @@ private: sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; + void processSdStatusLine(std::pair& active, + std::string& line, uint8_t& idx, sd::SdCard& currentSd); + static SdCardManager* factoryInstance; }; diff --git a/bsp_q7s/memory/definitions.h b/bsp_q7s/memory/definitions.h index 9a998dcc..a2d29d9b 100644 --- a/bsp_q7s/memory/definitions.h +++ b/bsp_q7s/memory/definitions.h @@ -1,8 +1,17 @@ #ifndef BSP_Q7S_MEMORY_DEFINITIONS_H_ #define BSP_Q7S_MEMORY_DEFINITIONS_H_ +#include + namespace sd { +enum SdStatus: uint8_t { + OFF = 0, + ON = 1, + // A mounted SD card is on as well + MOUNTED = 2 +}; + enum SdCard { SLOT_0, SLOT_1, -- 2.43.0 From c03233ad267ebbde7160f538ac9131dae333415c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 11:47:23 +0200 Subject: [PATCH 04/15] added docs and improvements --- bsp_q7s/memory/SdCardManager.cpp | 8 +++++--- bsp_q7s/memory/SdCardManager.h | 20 ++++++++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 8c67ea2c..3a7afc42 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -117,12 +117,12 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { ReturnValue_t SdCardManager::sdCardActive(std::pair& active) { using namespace std; - if(not filesystem::exists("/tmp/sd_status.txt")) { + if(not filesystem::exists(SD_STATE_FILE)) { return STATUS_FILE_NEXISTS; } // Now the file should exist in any case. Still check whether it exists. - fstream sdStatus("/tmp/sd_status.txt"); + fstream sdStatus(SD_STATE_FILE); if (not sdStatus.good()) { return STATUS_FILE_NEXISTS; } @@ -261,7 +261,9 @@ void SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { } ReturnValue_t SdCardManager::updateSdCardStateFile() { - int result = std::system("q7hw sd info all > /tmp/sd_status.txt"); + // Use q7hw utility and pipe the command output into the state file + std::string updateCmd = "q7hw sd info all > " + SD_STATE_FILE; + int result = std::system(updateCmd.c_str()); if(result == 0) { return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 9052d9b0..810536fe 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -38,6 +38,7 @@ public: static constexpr char SD_1_DEV_NAME[] = "/dev/mmcblk1p1"; static constexpr char SD_0_MOUNT_POINT[] = "/mnt/sd0"; static constexpr char SD_1_MOUNT_POINT[] = "/mnt/sd1"; + static constexpr char SD_STATE_FILE[] = "/tmp/sd_status.txt"; virtual ~SdCardManager(); @@ -53,7 +54,7 @@ public: sd::SdCard getPreferredSdCard() const; /** - * Switch on the specified SD card + * Switch on the specified SD card. * @param sdCard * @param doMountSdCard Mount the SD card after switching it on, which is necessary * to use it @@ -63,7 +64,7 @@ public: ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true); /** - * Switch off the specified SD card + * Switch off the specified SD card. * @param sdCard * @param doUnmountSdCard Unmount the SD card before switching the card off, which makes * the operation safer @@ -73,8 +74,8 @@ public: ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true); /** - * Updated the state file or creates one if it does not exist. You need to call this - * function before calling #sdCardActiv + * Update the state file or creates one if it does not exist. You need to call this + * function before calling #sdCardActive * @return - RETURN_OK if the state file was updated successfully * - SYSTEM_CALL_ERROR if the call to create the status file failed */ @@ -93,7 +94,18 @@ public: */ ReturnValue_t sdCardActive(std::pair& active); + /** + * Mount the specified SD card. This is necessary to use it. + * @param sdCard + * @return + */ ReturnValue_t mountSdCard(sd::SdCard sdCard); + /** + * Unmount the specified SD card. This is recommended before switching it off. The SD card + * can't be used after it has been unmounted. + * @param sdCard + * @return + */ ReturnValue_t unmountSdCard(sd::SdCard sdCard); sd::SdCard getPreferedSdCard() const; -- 2.43.0 From ed772665d5578f0eba5958f857ed08498d85ab4a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 11:49:19 +0200 Subject: [PATCH 05/15] fix so it compiles --- bsp_q7s/core/CoreController.cpp | 2 +- bsp_q7s/memory/SdCardManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 98ddb347..ced75056 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -40,7 +40,7 @@ ReturnValue_t CoreController::initialize() { sif::info << "Switching on SD card " << printoutString << ".." << std::endl; - result = SdCardManager::instance()->switchOnSdCard(preferredSdCard); + result = SdCardManager::instance()->switchOnSdCard(preferredSdCard, true); if(result == SdCardManager::ALREADY_ON) { sif::info << "SD card " << printoutString << " is already on" << std::endl; } diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 3a7afc42..9c47f0de 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -262,7 +262,7 @@ void SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { ReturnValue_t SdCardManager::updateSdCardStateFile() { // Use q7hw utility and pipe the command output into the state file - std::string updateCmd = "q7hw sd info all > " + SD_STATE_FILE; + std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); int result = std::system(updateCmd.c_str()); if(result == 0) { return HasReturnvaluesIF::RETURN_OK; -- 2.43.0 From a15e0bbaa5ba53f42af4bebaa4db2a58c0933d51 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 13:26:02 +0200 Subject: [PATCH 06/15] 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"; -- 2.43.0 From bd505f35e21cdcde1dad61d6dd462263544302d2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 14:32:20 +0200 Subject: [PATCH 07/15] 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; } -- 2.43.0 From 5fc8b650f9bc8bec29b471fd4ce508ae83f80d6c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 15:19:06 +0200 Subject: [PATCH 08/15] 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; }; -- 2.43.0 From 5454392a91792dbc2362ee5067a2513b33cefd4d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 15:52:13 +0200 Subject: [PATCH 09/15] 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"); -- 2.43.0 From 32ef21ea2241f9d98e1930fda15d91457479503b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 15:58:43 +0200 Subject: [PATCH 10/15] 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; -- 2.43.0 From 3a6b8cc66be53a65d3d439338898619d4051d347 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 16:32:14 +0200 Subject: [PATCH 11/15] 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 -- 2.43.0 From eb7b0770a00d1770e147318a9d94b0e4eaf1353f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:23:32 +0200 Subject: [PATCH 12/15] 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 -- 2.43.0 From 15ab1dd89dd06e6af273a78f870bf806864f3f82 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:39:36 +0200 Subject: [PATCH 13/15] 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 -- 2.43.0 From aa461d69f15cd48791e95128d5070b8c82724479 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:41:13 +0200 Subject: [PATCH 14/15] 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; } -- 2.43.0 From 4eb740fd075110b2bf92e897cbaa277e90bbe125 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:50:01 +0200 Subject: [PATCH 15/15] 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" -- 2.43.0