From 1cfb9250fa32e878b4f4419a745c00fb8d866486 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 10:14:17 +0200 Subject: [PATCH 01/21] SDC manager non-blocking mode --- bsp_q7s/core/CoreController.cpp | 20 +++-- bsp_q7s/memory/SdCardManager.cpp | 136 ++++++++++++++++++++++++++----- bsp_q7s/memory/SdCardManager.h | 50 +++++++++++- fsfw | 2 +- tmtc | 2 +- 5 files changed, 180 insertions(+), 30 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b1ca47d9..e49f0007 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,6 +4,7 @@ #include "watchdogConf.h" #include "fsfw/FSFWVersion.h" +#include "fsfw/timemanager/Stopwatch.h" #include "fsfw/serviceinterface/ServiceInterface.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" @@ -32,15 +33,11 @@ CoreController::CoreController(object_id_t objectId): sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << std::endl; } - result = initSdCard(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; - } + result = initBootCopy(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; } - } catch(const std::filesystem::filesystem_error& e) { sif::error << "CoreController::CoreController: Failed with exception " << @@ -91,6 +88,7 @@ ReturnValue_t CoreController::initSdCard() { if(sdcMan == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } + // Create update status file ReturnValue_t result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -168,7 +166,17 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } ReturnValue_t CoreController::initializeAfterTaskCreation() { - ReturnValue_t result = initVersionFile(); + + // TODO: Do this here because this can take a longer time. Later, use non-blocking mode + // to start doing stuff in ctor and initialize function. + // This operation can take 1-2 seconds on reboot, and around 50-100ms if the SD + // card is already on. + ReturnValue_t result = initSdCard(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + } + + result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; } diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 3dfa0b10..4e9ce6c8 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -6,13 +6,17 @@ #include "fsfw/ipc/MutexFactory.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include + #include #include #include +#include SdCardManager* SdCardManager::factoryInstance = nullptr; SdCardManager::SdCardManager() { + waiter.events = POLLIN; } SdCardManager::~SdCardManager() { @@ -128,6 +132,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { using namespace std; string sdstring = ""; string statestring = ""; + if(currentOp != Operations::IDLE) { + return OP_ONGOING; + } if(sdCard == sd::SdCard::SLOT_0) { sdstring = "0"; } @@ -135,20 +142,16 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { sdstring = "1"; } if(on) { + currentOp = Operations::SWITCHING_ON; statestring = "on"; } else { + currentOp = Operations::SWITCHING_OFF; statestring = "off"; } ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - int result = system(command.str().c_str()); - if(result == 0) { - return HasReturnvaluesIF::RETURN_OK; - } - sif::warning << "SdCardManager::setSdCardState: system call failed with code " << - result << std::endl; - return SYSTEM_CALL_ERROR; + return handleCommand(command.str(), "SdCardManager::setSdCardState"); } ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { @@ -174,6 +177,9 @@ ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { using namespace std; + if(currentOp != Operations::IDLE) { + return OP_ONGOING; + } if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" << std::endl; @@ -196,12 +202,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { } 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; + return handleCommand(sdMountCommand, "SdCardManager::mountSdCard"); } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { @@ -229,12 +230,7 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { 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; + return handleCommand(sdUnmountCommand, "SdCardManager::unmountSdCard"); } ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard prefSdCard) { @@ -354,3 +350,105 @@ std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { return SD_1_MOUNT_POINT; } } + +SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { + currentOp = this->currentOp; + switch(currentOpStatus) { + case(OpStatus::IDLE): + case(OpStatus::FAIL): + case(OpStatus::TIMEOUT): + case(OpStatus::SUCCESS):{ + break; + } + case(OpStatus::ONGOING): { + int result = poll(&waiter, 1, 0); + switch(result) { + case(0): { + // No data available + break; + } + case(1): { + if (waiter.revents & POLLIN) { + ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); + if(readBytes == 0) { + // Should not happen.. + sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; + } + else if(readBytes > 0) { + sif::info << currentCmd << " | " << readBuf.data() << std::endl; + } + else { + sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << + ": " << strerror(errno) << std::endl; + return OpStatus::FAIL; + } + } + else if (waiter.revents & POLLERR) { + sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; + } + else if(waiter.revents & POLLHUP) { + int result = pclose(opFile); + if(result != 0) { + sif::error << "SdCardManager::setSdCardState: pclose failed with code " << + result << ": " << strerror(result) << std::endl; + } + opFile = nullptr; + opFileNum = 0; + currentOp = Operations::IDLE; + return OpStatus::SUCCESS; + } + break; + } + default: { + sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << + "for poll call" << std::endl; + break; + } + } + } + } + return currentOpStatus; +} + +void SdCardManager::resetState() { + currentOp = Operations::IDLE; + currentOpStatus = OpStatus::IDLE; + currentOpSdCard = sd::SdCard::NONE; +} + +void SdCardManager::setBlocking(bool blocking) { + this->blocking = blocking; + if(not blocking) { + currentOp = Operations::IDLE; + currentOpStatus = OpStatus::IDLE; + } +} + +ReturnValue_t SdCardManager::handleCommand(std::string cmd, std::string funcName) { + currentCmd = cmd; + opFile = popen(currentCmd.c_str(), "r"); + if(opFile == nullptr) { + return POPEN_CALL_ERROR; + } + if(blocking) { + return handleBlockingOperation(funcName); + } + else { + opFileNum = fileno(opFile); + waiter.fd = opFileNum; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SdCardManager::handleBlockingOperation(std::string funcName) { + while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { + sif::info << currentCmd << " | " << readBuf.data() << std::endl; + } + int result = pclose(opFile); + if(result != 0) { + sif::error << "SdCardManager::setSdCardState: pclose failed with code " << + result << ": " << strerror(result) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 7af57a67..c1832e25 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -8,10 +8,13 @@ #include "fsfw/events/Event.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include + #include #include #include #include +#include class MutexIF; @@ -22,16 +25,33 @@ class MutexIF; class SdCardManager { friend class SdCardAccess; public: + enum class Operations { + SWITCHING_ON, + SWITCHING_OFF, + MOUNTING, + IDLE + }; + + enum class OpStatus { + IDLE, + SUCCESS, + TIMEOUT, + ONGOING, + FAIL + }; + using SdStatusPair = std::pair; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; - static constexpr ReturnValue_t ALREADY_ON = + static constexpr ReturnValue_t OP_ONGOING = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); - static constexpr ReturnValue_t ALREADY_MOUNTED = + static constexpr ReturnValue_t ALREADY_ON = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); - static constexpr ReturnValue_t ALREADY_OFF = + static constexpr ReturnValue_t ALREADY_MOUNTED = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); + static constexpr ReturnValue_t ALREADY_OFF = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); static constexpr ReturnValue_t STATUS_FILE_NEXISTS = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10); static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID = @@ -42,6 +62,8 @@ public: HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13); static constexpr ReturnValue_t SYSTEM_CALL_ERROR = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14); + static constexpr ReturnValue_t POPEN_CALL_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 15); static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; @@ -159,7 +181,26 @@ public: * @return */ std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE); + + OpStatus checkCurrentOp(Operations& currentOp); + + /** + * If there are issues with the state machine, it can be reset with this function + */ + void resetState(); + + void setBlocking(bool blocking); private: + Operations currentOp = Operations::IDLE; + OpStatus currentOpStatus = OpStatus::IDLE; + sd::SdCard currentOpSdCard = sd::SdCard::NONE; + FILE* opFile = nullptr; + bool blocking = true; + struct pollfd waiter {}; + std::array readBuf {}; + std::string currentCmd; + int opFileNum = 0; + SdCardManager(); ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); @@ -169,6 +210,9 @@ private: std::string currentPrefix; + ReturnValue_t handleCommand(std::string cmd, std::string funcName); + ReturnValue_t handleBlockingOperation(std::string funcName); + static SdCardManager* factoryInstance; }; diff --git a/fsfw b/fsfw index bb88490c..1a4a85ce 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit bb88490cc6cda5474d1d4913452eeb758da8cc25 +Subproject commit 1a4a85ceb2ad665e3cd3c2042925ae2f2aae70c1 diff --git a/tmtc b/tmtc index a226bf65..3e8626bf 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a226bf659eeadd3ad300b249d2659043317e2245 +Subproject commit 3e8626bfafa561510323bf8fe3963bc2860950ed From 8104ac0df8a9cb65bfdaab70d251898f27d7bb1e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 15:43:19 +0200 Subject: [PATCH 02/21] using new command executor --- bsp_q7s/memory/SdCardManager.cpp | 219 +++++++++++++++++-------------- bsp_q7s/memory/SdCardManager.h | 6 +- fsfw | 2 +- 3 files changed, 121 insertions(+), 106 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 4e9ce6c8..83d41c36 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -15,8 +15,7 @@ SdCardManager* SdCardManager::factoryInstance = nullptr; -SdCardManager::SdCardManager() { - waiter.events = POLLIN; +SdCardManager::SdCardManager(): cmdExecutor(256) { } SdCardManager::~SdCardManager() { @@ -151,7 +150,12 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { } ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - return handleCommand(command.str(), "SdCardManager::setSdCardState"); + cmdExecutor.load(command.str(), blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState"); + } + return result; } ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { @@ -202,7 +206,12 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { } string sdMountCommand = "mount " + mountDev + " " + mountPoint; - return handleCommand(sdMountCommand, "SdCardManager::mountSdCard"); + cmdExecutor.load(sdMountCommand, blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); + } + return result; } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { @@ -230,7 +239,12 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; - return handleCommand(sdUnmountCommand, "SdCardManager::unmountSdCard"); + cmdExecutor.load(sdUnmountCommand, blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard"); + } + return result; } ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard prefSdCard) { @@ -327,13 +341,12 @@ ReturnValue_t 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 > " + std::string(SD_STATE_FILE); - int result = std::system(updateCmd.c_str()); - if(result == 0) { - return HasReturnvaluesIF::RETURN_OK; + cmdExecutor.load(updateCmd, blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); } - sif::warning << "SdCardManager::updateSdCardStateFile: system call failed with code " << - result << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + return result; } std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { @@ -352,103 +365,107 @@ std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { } SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { - currentOp = this->currentOp; - switch(currentOpStatus) { - case(OpStatus::IDLE): - case(OpStatus::FAIL): - case(OpStatus::TIMEOUT): - case(OpStatus::SUCCESS):{ - break; - } - case(OpStatus::ONGOING): { - int result = poll(&waiter, 1, 0); - switch(result) { - case(0): { - // No data available - break; - } - case(1): { - if (waiter.revents & POLLIN) { - ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); - if(readBytes == 0) { - // Should not happen.. - sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; - } - else if(readBytes > 0) { - sif::info << currentCmd << " | " << readBuf.data() << std::endl; - } - else { - sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << - ": " << strerror(errno) << std::endl; - return OpStatus::FAIL; - } - } - else if (waiter.revents & POLLERR) { - sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; - } - else if(waiter.revents & POLLHUP) { - int result = pclose(opFile); - if(result != 0) { - sif::error << "SdCardManager::setSdCardState: pclose failed with code " << - result << ": " << strerror(result) << std::endl; - } - opFile = nullptr; - opFileNum = 0; - currentOp = Operations::IDLE; - return OpStatus::SUCCESS; - } - break; - } - default: { - sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << - "for poll call" << std::endl; - break; - } - } - } - } - return currentOpStatus; +// currentOp = this->currentOp; +// switch(currentOpStatus) { +// case(OpStatus::IDLE): +// case(OpStatus::FAIL): +// case(OpStatus::TIMEOUT): +// case(OpStatus::SUCCESS):{ +// break; +// } +// case(OpStatus::ONGOING): { +// int result = poll(&waiter, 1, 0); +// switch(result) { +// case(0): { +// // No data available +// break; +// } +// case(1): { +// if (waiter.revents & POLLIN) { +// ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); +// if(readBytes == 0) { +// // Should not happen.. +// sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; +// } +// else if(readBytes > 0) { +// sif::info << currentCmd << " | " << readBuf.data() << std::endl; +// } +// else { +// sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << +// ": " << strerror(errno) << std::endl; +// return OpStatus::FAIL; +// } +// } +// else if (waiter.revents & POLLERR) { +// sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; +// } +// else if(waiter.revents & POLLHUP) { +// int result = pclose(opFile); +// if(result != 0) { +// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << +// result << ": " << strerror(result) << std::endl; +// } +// opFile = nullptr; +// opFileNum = 0; +// currentOp = Operations::IDLE; +// return OpStatus::SUCCESS; +// } +// break; +// } +// default: { +// sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << +// "for poll call" << std::endl; +// break; +// } +// } +// } +// } +// return currentOpStatus; } -void SdCardManager::resetState() { - currentOp = Operations::IDLE; - currentOpStatus = OpStatus::IDLE; - currentOpSdCard = sd::SdCard::NONE; -} - -void SdCardManager::setBlocking(bool blocking) { - this->blocking = blocking; - if(not blocking) { - currentOp = Operations::IDLE; - currentOpStatus = OpStatus::IDLE; - } -} +//void SdCardManager::resetState() { +// currentOp = Operations::IDLE; +// currentOpStatus = OpStatus::IDLE; +// currentOpSdCard = sd::SdCard::NONE; +//} +// +//void SdCardManager::setBlocking(bool blocking) { +// this->blocking = blocking; +// if(not blocking) { +// currentOp = Operations::IDLE; +// currentOpStatus = OpStatus::IDLE; +// } +//} ReturnValue_t SdCardManager::handleCommand(std::string cmd, std::string funcName) { - currentCmd = cmd; - opFile = popen(currentCmd.c_str(), "r"); - if(opFile == nullptr) { - return POPEN_CALL_ERROR; - } - if(blocking) { - return handleBlockingOperation(funcName); - } - else { - opFileNum = fileno(opFile); - waiter.fd = opFileNum; - } +// currentCmd = cmd; +// opFile = popen(currentCmd.c_str(), "r"); +// if(opFile == nullptr) { +// return POPEN_CALL_ERROR; +// } +// if(blocking) { +// return handleBlockingOperation(funcName); +// } +// else { +// opFileNum = fileno(opFile); +// waiter.fd = opFileNum; +// } return HasReturnvaluesIF::RETURN_OK; } +void SdCardManager::setBlocking(bool blocking) { + this->blocking = blocking; +} + ReturnValue_t SdCardManager::handleBlockingOperation(std::string funcName) { - while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { - sif::info << currentCmd << " | " << readBuf.data() << std::endl; - } - int result = pclose(opFile); - if(result != 0) { - sif::error << "SdCardManager::setSdCardState: pclose failed with code " << - result << ": " << strerror(result) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } +// while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { +// sif::info << currentCmd << " | " << readBuf.data() << std::endl; +// } +// int result = pclose(opFile); +// if(result != 0) { +// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << +// result << ": " << strerror(result) << std::endl; +// return HasReturnvaluesIF::RETURN_FAILED; +// } return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index c1832e25..cd0493cf 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ +#include #include "definitions.h" #include "returnvalues/classIds.h" #include "events/subsystemIdRanges.h" @@ -191,12 +192,9 @@ public: void setBlocking(bool blocking); private: + CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; - OpStatus currentOpStatus = OpStatus::IDLE; - sd::SdCard currentOpSdCard = sd::SdCard::NONE; - FILE* opFile = nullptr; bool blocking = true; - struct pollfd waiter {}; std::array readBuf {}; std::string currentCmd; int opFileNum = 0; diff --git a/fsfw b/fsfw index 1a4a85ce..c8472beb 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 1a4a85ceb2ad665e3cd3c2042925ae2f2aae70c1 +Subproject commit c8472beb5f31b8f33491b5fccfecdd18bce26542 From 7f327c3900b5778604ac6220a0633a44c7838fe0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 16:02:35 +0200 Subject: [PATCH 03/21] bugfixes for sdc manager --- bsp_q7s/memory/SdCardManager.cpp | 150 ++++++++++--------------------- bsp_q7s/memory/SdCardManager.h | 15 ++-- fsfw | 2 +- 3 files changed, 55 insertions(+), 112 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 83d41c36..932a4217 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -129,11 +129,11 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { using namespace std; + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } string sdstring = ""; string statestring = ""; - if(currentOp != Operations::IDLE) { - return OP_ONGOING; - } if(sdCard == sd::SdCard::SLOT_0) { sdstring = "0"; } @@ -181,8 +181,8 @@ ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { using namespace std; - if(currentOp != Operations::IDLE) { - return OP_ONGOING; + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; } if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" @@ -205,6 +205,9 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { return MOUNT_ERROR; } + if(not blocking) { + currentOp = Operations::MOUNTING; + } string sdMountCommand = "mount " + mountDev + " " + mountPoint; cmdExecutor.load(sdMountCommand, blocking, true); ReturnValue_t result = cmdExecutor.execute(); @@ -215,6 +218,9 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } using namespace std; if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH" @@ -239,6 +245,9 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; + if(not blocking) { + currentOp = Operations::UNMOUNTING; + } cmdExecutor.load(sdUnmountCommand, blocking, true); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { @@ -266,6 +275,11 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard return switchOnSdCard(prefSdCard, true, statusPair); } +void SdCardManager::resetState() { + cmdExecutor.reset(); + currentOp = Operations::IDLE; +} + void SdCardManager::processSdStatusLine(std::pair &active, std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std; @@ -339,6 +353,9 @@ ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { } ReturnValue_t SdCardManager::updateSdCardStateFile() { + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } // Use q7hw utility and pipe the command output into the state file std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); cmdExecutor.load(updateCmd, blocking, true); @@ -365,107 +382,36 @@ std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { } SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { -// currentOp = this->currentOp; -// switch(currentOpStatus) { -// case(OpStatus::IDLE): -// case(OpStatus::FAIL): -// case(OpStatus::TIMEOUT): -// case(OpStatus::SUCCESS):{ -// break; -// } -// case(OpStatus::ONGOING): { -// int result = poll(&waiter, 1, 0); -// switch(result) { -// case(0): { -// // No data available -// break; -// } -// case(1): { -// if (waiter.revents & POLLIN) { -// ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); -// if(readBytes == 0) { -// // Should not happen.. -// sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; -// } -// else if(readBytes > 0) { -// sif::info << currentCmd << " | " << readBuf.data() << std::endl; -// } -// else { -// sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << -// ": " << strerror(errno) << std::endl; -// return OpStatus::FAIL; -// } -// } -// else if (waiter.revents & POLLERR) { -// sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; -// } -// else if(waiter.revents & POLLHUP) { -// int result = pclose(opFile); -// if(result != 0) { -// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << -// result << ": " << strerror(result) << std::endl; -// } -// opFile = nullptr; -// opFileNum = 0; -// currentOp = Operations::IDLE; -// return OpStatus::SUCCESS; -// } -// break; -// } -// default: { -// sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << -// "for poll call" << std::endl; -// break; -// } -// } -// } -// } -// return currentOpStatus; -} + CommandExecutor::States state = cmdExecutor.getCurrentState(); + if(state == CommandExecutor::States::IDLE or state == CommandExecutor::States::COMMAND_LOADED) { + return OpStatus::IDLE; + } + currentOp = this->currentOp; + bool bytesRead = false; -//void SdCardManager::resetState() { -// currentOp = Operations::IDLE; -// currentOpStatus = OpStatus::IDLE; -// currentOpSdCard = sd::SdCard::NONE; -//} -// -//void SdCardManager::setBlocking(bool blocking) { -// this->blocking = blocking; -// if(not blocking) { -// currentOp = Operations::IDLE; -// currentOpStatus = OpStatus::IDLE; -// } -//} - -ReturnValue_t SdCardManager::handleCommand(std::string cmd, std::string funcName) { -// currentCmd = cmd; -// opFile = popen(currentCmd.c_str(), "r"); -// if(opFile == nullptr) { -// return POPEN_CALL_ERROR; -// } -// if(blocking) { -// return handleBlockingOperation(funcName); -// } -// else { -// opFileNum = fileno(opFile); -// waiter.fd = opFileNum; -// } - return HasReturnvaluesIF::RETURN_OK; + while(true) { + ReturnValue_t result = cmdExecutor.check(bytesRead); + switch(result) { + case(CommandExecutor::BYTES_READ): { + continue; + } + case(CommandExecutor::EXECUTION_FINISHED): { + return OpStatus::SUCCESS; + } + case(HasReturnvaluesIF::RETURN_OK): { + return OpStatus::ONGOING; + } + case(HasReturnvaluesIF::RETURN_FAILED): { + return OpStatus::FAIL; + } + default: { + sif::warning << "SdCardManager::checkCurrentOp: Unhandled case" << std::endl; + } + } + } } void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; } -ReturnValue_t SdCardManager::handleBlockingOperation(std::string funcName) { -// while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { -// sif::info << currentCmd << " | " << readBuf.data() << std::endl; -// } -// int result = pclose(opFile); -// if(result != 0) { -// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << -// result << ": " << strerror(result) << std::endl; -// return HasReturnvaluesIF::RETURN_FAILED; -// } - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index cd0493cf..a6d9227a 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -30,14 +30,15 @@ public: SWITCHING_ON, SWITCHING_OFF, MOUNTING, + UNMOUNTING, IDLE }; enum class OpStatus { IDLE, - SUCCESS, TIMEOUT, ONGOING, + SUCCESS, FAIL }; @@ -130,8 +131,10 @@ public: /** * 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 + * @return + * - RETURN_OK if the state file was updated successfully + * - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending + * - RETURN_FAILED: blocking command failed */ ReturnValue_t updateSdCardStateFile(); @@ -195,9 +198,6 @@ private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; bool blocking = true; - std::array readBuf {}; - std::string currentCmd; - int opFileNum = 0; SdCardManager(); @@ -208,9 +208,6 @@ private: std::string currentPrefix; - ReturnValue_t handleCommand(std::string cmd, std::string funcName); - ReturnValue_t handleBlockingOperation(std::string funcName); - static SdCardManager* factoryInstance; }; diff --git a/fsfw b/fsfw index c8472beb..42022051 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c8472beb5f31b8f33491b5fccfecdd18bce26542 +Subproject commit 4202205182aa007b9be5279ce40056e18f0b8782 From 05088ce02c1071166eb2c721f9cf1e156bb2b481 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 18:13:32 +0200 Subject: [PATCH 04/21] SDC manager and core controller refactoring --- bsp_q7s/core/CoreController.cpp | 290 +++++++++++++++++++++------ bsp_q7s/core/CoreController.h | 32 ++- bsp_q7s/memory/FileSystemHandler.cpp | 4 +- bsp_q7s/memory/SdCardManager.cpp | 71 ++++--- bsp_q7s/memory/SdCardManager.h | 4 +- bsp_q7s/memory/definitions.h | 2 +- fsfw | 2 +- 7 files changed, 303 insertions(+), 102 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index e49f0007..0516e26f 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -12,6 +12,8 @@ #include "fsfw/osal/common/TcpTmTcBridge.h" #endif +#include "fsfw/osal/linux/Timer.h" + #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" @@ -24,8 +26,7 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), - opDivider(5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { result = initWatchdogFifo(); @@ -33,6 +34,13 @@ CoreController::CoreController(object_id_t objectId): sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << std::endl; } + sdcMan = SdCardManager::instance(); + if(sdcMan == nullptr) { + sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; + } + if(not BLOCKING_SD_INIT) { + initSdCardNonBlocking(); + } result = initBootCopy(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -50,6 +58,9 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { + if(not BLOCKING_SD_INIT and not sdInitFinished) { + initSdCardNonBlocking(); + } performWatchdogControlOperation(); } @@ -71,6 +82,10 @@ ReturnValue_t CoreController::initialize() { "count failed" << std::endl; } + if(not BLOCKING_SD_INIT) { + initSdCardNonBlocking(); + } + return ExtendedControllerBase::initialize(); } @@ -79,16 +94,11 @@ ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CoreController::initSdCard() { +ReturnValue_t CoreController::initSdCardBlocking() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; #else - SdCardManager* sdcMan = SdCardManager::instance(); - if(sdcMan == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - // Create update status file ReturnValue_t result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -96,19 +106,24 @@ ReturnValue_t CoreController::initSdCard() { << std::endl; } - auto statusPair = SdCardManager::SdStatusPair(sd::SdStatus::OFF, sd::SdStatus::OFF); + auto statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); result = sdcMan->getSdCardActiveStatus(statusPair); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - return sdCardColdRedundantInit(sdcMan, statusPair); + determinePreferredSdCard(); + sif::info << "Cold redundant SD card configuration, preferred SD card: " << + static_cast(preferredSdCard) << std::endl; + result = sdCardColdRedundantInit(sdcMan, statusPair); + // Update status file + sdcMan->updateSdCardStateFile(); + return result; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT sif::info << "Hot redundant SD card configuration" << std::endl; - - setUpSdCard(sd::SdCard::SLOT_0, sdStatus.first, "0"); - setUpSdCard(sd::SdCard::SLOT_1, sdStatus.second, "1"); + sdCardSetup(statusPair, sd::SdCard::SLOT_0, "0"); + sdCardSetup(statusPair, sd::SdCard::SLOT_1, "1"); // Update status file sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; @@ -118,9 +133,130 @@ ReturnValue_t CoreController::initSdCard() { } -ReturnValue_t CoreController::sdCardSetup(SdCardManager& sdcMan, - SdCardManager::SdStatusPair& statusPair,sd::SdCard sdCard, sd::SdStatus status, - std::string sdString) { +ReturnValue_t CoreController::initSdCardNonBlocking() { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +#else + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if(state == SdStates::START) { + sdcInitCycleCount = 0; + commandExecuted = false; + state = SdStates::GET_INFO; + } + + if(state == SdStates::GET_INFO) { + if(not commandExecuted) { + // Create update status file + result = sdcMan->updateSdCardStateFile(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + commandExecuted = true; + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + state = SdStates::SET_STATE; + commandExecuted = false; + sdcInitCycleCount = 0; + } + else if(sdcInitCycleCount > 2) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Updating SDC file takes too long" << std::endl; + } + } + } + + if(state == SdStates::SET_STATE) { + if(not commandExecuted) { + determinePreferredSdCard(); + statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); + result = sdcMan->getSdCardActiveStatus(statusPair); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Getting SD card activity status failed" << std::endl; + } + sif::info << "Cold redundant SD card configuration, preferred SD card: " << + static_cast(preferredSdCard) << std::endl; + result = sdCardColdRedundantInit(sdcMan, statusPair); + if(result == SdCardManager::ALREADY_ON) { + state = SdStates::MOUNT; + } + if(result == SdCardManager::ALREADY_MOUNTED) { + state = SdStates::UPDATE_INFO; + } + else { + commandExecuted = true; + } + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + state = SdStates::MOUNT; + commandExecuted = false; + sdcInitCycleCount = 0; + } + else if(sdcInitCycleCount > 10) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Setting SDC state takes too long" << std::endl; + } + } + } + + if(state == SdStates::MOUNT) { + if(not commandExecuted) { + result = sdCardColdRedundantInit(sdcMan, statusPair); + commandExecuted = false; + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + state = SdStates::UPDATE_INFO; + commandExecuted = false; + sdcInitCycleCount = 0; + } + else if(sdcInitCycleCount > 5) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Mounting SD card takes too long" << std::endl; + } + } + } + + if(state == SdStates::UPDATE_INFO) { + if(not commandExecuted) { + // Update status file + result = sdcMan->updateSdCardStateFile(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + commandExecuted = true; + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + sdInitFinished = true; + state = SdStates::DONE; + } + else if(sdcInitCycleCount > 2) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Updating SDC file takes too long" << std::endl; + } + } + } + + return HasReturnvaluesIF::RETURN_OK; +#endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ +} + + +ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPair, + sd::SdCard sdCard, std::string sdString) { std::string mountString; if(sdCard == sd::SdCard::SLOT_0) { mountString = SdCardManager::SD_0_MOUNT_POINT; @@ -129,27 +265,60 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager& sdcMan, 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, &statusPair); - } - else if(status == sd::SdStatus::ON) { - sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; - return sdcMan.mountSdCard(sdCard); + sd::SdState status = sd::SdState::OFF; + if(sdCard == sd::SdCard::SLOT_0) { + status = statusPair.first; } else { + status = statusPair.second; + } + if(status == sd::SdState::MOUNTED) { if(std::filesystem::exists(mountString)) { sif::info << "SD card " << sdString << " already on and mounted at " << mountString << std::endl; return SdCardManager::ALREADY_MOUNTED; } - sif::error << "SD card mounted but expected mount point " << mountString << " not found!" - << std::endl; + sif::error << "SD card mounted but expected mount point " << + mountString << " not found!" << std::endl; return SdCardManager::MOUNT_ERROR; } + + if(status == sd::SdState::OFF) { + if(BLOCKING_SD_INIT) { + sif::info << "Switching on and mounting SD card " << sdString << " at " << + mountString << std::endl; + return sdcMan->switchOnSdCard(sdCard, true, &statusPair); + } + else { + if(state == SdStates::SET_STATE) { + sif::info << "Switching on SD card" << std::endl; + return sdcMan->switchOnSdCard(sdCard, false, &statusPair); + } + } + } + + else if(status == sd::SdState::ON) { + if(BLOCKING_SD_INIT) { + sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + return sdcMan->mountSdCard(sdCard); + } + else { + if(state == SdStates::SET_STATE) { + return SdCardManager::ALREADY_ON; + } + if(state == SdStates::MOUNT) { + sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + return sdcMan->mountSdCard(sdCard); + } + } + } + else { + sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl; + } +return HasReturnvaluesIF::RETURN_OK; } + ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { switch(actionId) { @@ -166,16 +335,20 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } ReturnValue_t CoreController::initializeAfterTaskCreation() { - + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; // TODO: Do this here because this can take a longer time. Later, use non-blocking mode // to start doing stuff in ctor and initialize function. // This operation can take 1-2 seconds on reboot, and around 50-100ms if the SD // card is already on. - ReturnValue_t result = initSdCard(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + if(BLOCKING_SD_INIT) { + ReturnValue_t result = initSdCardBlocking(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + } + } + else { + initSdCardNonBlocking(); } - result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; @@ -185,29 +358,15 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { } ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair) { - sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; - ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - if(result == scratch::KEY_NOT_FOUND) { - sif::warning << "CoreController::sdCardInit: " - "Preferred SD card not set. Setting to 0" << std::endl; - sdcMan->setPreferredSdCard(preferredSdCard); - } - else { - sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" - "information from the scratch buffer" << std::endl; - } - } + SdCardManager::SdStatusPair& statusPair, SdStates step) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; std::string preferredString; - sd::SdStatus preferredStatus = sd::SdStatus::OFF; - sd::SdStatus otherStatus = sd::SdStatus::OFF; + sd::SdState otherStatus = sd::SdState::OFF; std::string otherString; sd::SdCard otherSdc = sd::SdCard::SLOT_0; if(preferredSdCard == sd::SdCard::SLOT_0) { - preferredStatus = statusPair.first; preferredString = "0"; otherSdc = sd::SdCard::SLOT_1; otherStatus = statusPair.second; @@ -215,25 +374,21 @@ ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, } else { preferredString = "1"; - preferredStatus = statusPair.second; otherStatus = statusPair.first; otherSdc = sd::SdCard::SLOT_0; otherString = "0"; } - sif::info << "Cold redundant SD card configuration, preferred SD card " << - preferredString << std::endl; - - result = sdCardSetup(*sdcMan, statusPair, preferredSdCard, preferredStatus, preferredString); + result = sdCardSetup(statusPair, preferredSdCard, 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 - sdCardSetup(*sdcMan, statusPair, preferredSdCard, preferredStatus, preferredString); + sdCardSetup(statusPair, preferredSdCard, preferredString); result = HasReturnvaluesIF::RETURN_FAILED; } - if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdStatus::OFF) { + if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::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 @@ -243,10 +398,7 @@ ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, " in cold redundant mode failed" << std::endl; } } - - // Update status file - sdcMan->updateSdCardStateFile(); - return HasReturnvaluesIF::RETURN_OK; + return result; } ReturnValue_t CoreController::incrementAllocationFailureCount() { @@ -501,6 +653,26 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si return HasActionsIF::EXECUTION_FINISHED; } +CoreController::~CoreController() { +} + +void CoreController::determinePreferredSdCard() { + if(preferredSdCard == sd::SdCard::NONE) { + ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + if(result == scratch::KEY_NOT_FOUND) { + sif::warning << "CoreController::sdCardInit: " + "Preferred SD card not set. Setting to 0" << std::endl; + sdcMan->setPreferredSdCard(preferredSdCard); + } + else { + sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" + "information from the scratch buffer" << std::endl; + } + } + } +} + void CoreController::performWatchdogControlOperation() { // Only perform each fifth iteration if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 4a71e6e7..a424a615 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -8,6 +8,8 @@ #include "events/subsystemIdRanges.h" +class Timer; +class SdCardManager; class CoreController: public ExtendedControllerBase { public: @@ -32,6 +34,7 @@ public: CoreController(object_id_t objectId); + virtual~ CoreController(); ReturnValue_t initialize() override; @@ -56,11 +59,32 @@ private: ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - ReturnValue_t initSdCard(); - ReturnValue_t sdCardSetup(SdCardManager& sdcMan, SdCardManager::SdStatusPair& statusPair, - sd::SdCard sdCard, sd::SdStatus status, std::string sdString); + // States for non-blocking setup + enum class SdStates { + NONE, + START, + GET_INFO, + SET_STATE, + MOUNT, + UPDATE_INFO, + DONE + }; + static constexpr bool BLOCKING_SD_INIT = true; + + SdCardManager* sdcMan = nullptr; + uint16_t sdcInitCycleCount = 0; + ReturnValue_t initSdCardBlocking(); + ReturnValue_t initSdCardNonBlocking(); + sd::SdCard preferredSdCard = sd::SdCard::NONE; + SdStates state = SdStates::START; + SdCardManager::SdStatusPair statusPair; + bool commandExecuted = true; + bool sdInitFinished = false; + ReturnValue_t sdCardSetup(SdCardManager::SdStatusPair& statusPair, + sd::SdCard sdCard, std::string sdString); ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair); + SdCardManager::SdStatusPair& statusPair, SdStates step = SdStates::NONE); + void determinePreferredSdCard(); ReturnValue_t initVersionFile(); ReturnValue_t initBootCopy(); diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 5a7895da..82891979 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -77,11 +77,11 @@ void FileSystemHandler::fileSystemCheckup() { sd::SdCard preferredSdCard; sdcMan->getPreferredSdCard(preferredSdCard); if((preferredSdCard == sd::SdCard::SLOT_0) and - (statusPair.first == sd::SdStatus::MOUNTED)) { + (statusPair.first == sd::SdState::MOUNTED)) { currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; } else if((preferredSdCard == sd::SdCard::SLOT_1) and - (statusPair.second == sd::SdStatus::MOUNTED)) { + (statusPair.second == sd::SdState::MOUNTED)) { currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; } else { diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 932a4217..89cdf85f 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -1,3 +1,4 @@ +#include #include "SdCardManager.h" #include "scratchApi.h" @@ -52,39 +53,35 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar return HasReturnvaluesIF::RETURN_FAILED; } - sd::SdStatus targetStatus; + sd::SdState currentState; if(sdCard == sd::SdCard::SLOT_0) { - targetStatus = statusPair->first; + currentState = statusPair->first; } else if(sdCard == sd::SdCard::SLOT_1) { - targetStatus = statusPair->second; + currentState = statusPair->second; } else { // Should not happen - targetStatus = sd::SdStatus::OFF; + currentState = sd::SdState::OFF; } - auto switchCall = [&]() { - if(targetStatus == sd::SdStatus::ON) { - if(not doMountSdCard) { - return ALREADY_ON; - } - else { - return mountSdCard(sdCard); - } - } - else if(targetStatus == sd::SdStatus::MOUNTED) { - return ALREADY_MOUNTED; - } - else if(targetStatus == sd::SdStatus::OFF) { - return setSdCardState(sdCard, true); + if(currentState == sd::SdState::ON) { + if(not doMountSdCard) { + return ALREADY_ON; } else { - return HasReturnvaluesIF::RETURN_FAILED; + return mountSdCard(sdCard); } - }; - - result = switchCall(); + } + else if(currentState == sd::SdState::MOUNTED) { + result = ALREADY_MOUNTED; + } + else if(currentState == sd::SdState::OFF) { + result = setSdCardState(sdCard, true); + } + else { + result = HasReturnvaluesIF::RETURN_FAILED; + } if(result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) { return result; @@ -95,7 +92,7 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, SdStatusPair* statusPair) { - std::pair active; + std::pair active; ReturnValue_t result = getSdCardActiveStatus(active); if(result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -107,12 +104,12 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd return HasReturnvaluesIF::RETURN_FAILED; } if(sdCard == sd::SdCard::SLOT_0) { - if(active.first == sd::SdStatus::OFF) { + if(active.first == sd::SdState::OFF) { return ALREADY_OFF; } } else if(sdCard == sd::SdCard::SLOT_1) { - if(active.second == sd::SdStatus::OFF) { + if(active.second == sd::SdState::OFF) { return ALREADY_OFF; } } @@ -268,7 +265,7 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard getSdCardActiveStatus(*statusPair); } - if(statusPair->first == sd::SdStatus::ON) { + if(statusPair->first == sd::SdState::ON) { return mountSdCard(prefSdCard); } @@ -280,7 +277,7 @@ void SdCardManager::resetState() { currentOp = Operations::IDLE; } -void SdCardManager::processSdStatusLine(std::pair &active, +void SdCardManager::processSdStatusLine(std::pair &active, std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std; istringstream iss(line); @@ -302,28 +299,28 @@ void SdCardManager::processSdStatusLine(std::pair &a if(word == "on") { if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdStatus::ON; + active.first = sd::SdState::ON; } else { - active.second = sd::SdStatus::ON; + active.second = sd::SdState::ON; } } else if (word == "off") { if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdStatus::OFF; + active.first = sd::SdState::OFF; } else { - active.second = sd::SdStatus::OFF; + active.second = sd::SdState::OFF; } } } if(mountLine) { if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdStatus::MOUNTED; + active.first = sd::SdState::MOUNTED; } else { - active.second = sd::SdStatus::MOUNTED; + active.second = sd::SdState::MOUNTED; } } @@ -389,8 +386,16 @@ SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { currentOp = this->currentOp; bool bytesRead = false; + Timer timer; + timer.setTimer(200); + uint32_t remainingTimeMs = 0; while(true) { ReturnValue_t result = cmdExecutor.check(bytesRead); + timer.getTimer(&remainingTimeMs); + if(remainingTimeMs == 0) { + sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl; + return OpStatus::FAIL; + } switch(result) { case(CommandExecutor::BYTES_READ): { continue; diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index a6d9227a..31dc740d 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -42,7 +42,7 @@ public: FAIL }; - using SdStatusPair = std::pair; + using SdStatusPair = std::pair; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; @@ -197,7 +197,7 @@ public: private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; - bool blocking = true; + bool blocking = false; SdCardManager(); diff --git a/bsp_q7s/memory/definitions.h b/bsp_q7s/memory/definitions.h index 9fcbee08..9e0bca65 100644 --- a/bsp_q7s/memory/definitions.h +++ b/bsp_q7s/memory/definitions.h @@ -5,7 +5,7 @@ namespace sd { -enum SdStatus: uint8_t { +enum SdState: uint8_t { OFF = 0, ON = 1, // A mounted SD card is on as well diff --git a/fsfw b/fsfw index 42022051..6073abb1 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4202205182aa007b9be5279ce40056e18f0b8782 +Subproject commit 6073abb12db23decbc9d69f4b6342f4f6f1247bd From f0e282c6e1079048ce3e2527bca1b019a0d78126 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 18:37:14 +0200 Subject: [PATCH 05/21] continued a bit --- bsp_q7s/core/CoreController.cpp | 50 ++++++++++++++++++-------------- bsp_q7s/core/CoreController.h | 5 ++-- bsp_q7s/memory/SdCardManager.cpp | 7 ++++- fsfw | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 4 +++ 5 files changed, 43 insertions(+), 25 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 0516e26f..4a01ca50 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -159,18 +159,18 @@ ReturnValue_t CoreController::initSdCardNonBlocking() { SdCardManager::Operations operation; SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::SET_STATE; + state = SdStates::SET_STATE_SELF; commandExecuted = false; sdcInitCycleCount = 0; } - else if(sdcInitCycleCount > 2) { + else if(sdcInitCycleCount > 4) { sif::warning << "CoreController::initSdCardNonBlocking: " "Updating SDC file takes too long" << std::endl; } } } - if(state == SdStates::SET_STATE) { + if(state == SdStates::SET_STATE_SELF) { if(not commandExecuted) { determinePreferredSdCard(); statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); @@ -250,6 +250,7 @@ ReturnValue_t CoreController::initSdCardNonBlocking() { } } + sdcInitCycleCount++; return HasReturnvaluesIF::RETURN_OK; #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } @@ -290,7 +291,7 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPai return sdcMan->switchOnSdCard(sdCard, true, &statusPair); } else { - if(state == SdStates::SET_STATE) { + if(state == SdStates::SET_STATE_SELF) { sif::info << "Switching on SD card" << std::endl; return sdcMan->switchOnSdCard(sdCard, false, &statusPair); } @@ -303,7 +304,7 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPai return sdcMan->mountSdCard(sdCard); } else { - if(state == SdStates::SET_STATE) { + if(state == SdStates::SET_STATE_SELF) { return SdCardManager::ALREADY_ON; } if(state == SdStates::MOUNT) { @@ -379,25 +380,32 @@ ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, otherString = "0"; } - result = sdCardSetup(statusPair, preferredSdCard, 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 - sdCardSetup(statusPair, preferredSdCard, preferredString); - result = HasReturnvaluesIF::RETURN_FAILED; - } - - if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::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, &statusPair); - if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_OFF) { - sif::warning << "Switching off secondary SD card " << otherString << + if(step != SdStates::SET_STATE_OTHER) { + result = sdCardSetup(statusPair, preferredSdCard, 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 + sdCardSetup(statusPair, preferredSdCard, preferredString); + result = HasReturnvaluesIF::RETURN_FAILED; } } + + if(BLOCKING_SD_INIT or (not BLOCKING_SD_INIT and state == SdStates::SET_STATE_OTHER)) { + // Don't disable other card if enabling the first one already failed + // Otherwise, try to turn off the other SD card + if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::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 worked + // without issues + ReturnValue_t result2 = sdcMan->switchOffSdCard(otherSdc, otherStatus, &statusPair); + if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { + sif::warning << "Switching off secondary SD card " << otherString << + " in cold redundant mode failed" << std::endl; + } + } + } + return result; } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index a424a615..a4f2868e 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -64,12 +64,13 @@ private: NONE, START, GET_INFO, - SET_STATE, + SET_STATE_SELF, + SET_STATE_OTHER, MOUNT, UPDATE_INFO, DONE }; - static constexpr bool BLOCKING_SD_INIT = true; + static constexpr bool BLOCKING_SD_INIT = false; SdCardManager* sdcMan = nullptr; uint16_t sdcInitCycleCount = 0; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 89cdf85f..d9442a8c 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -386,16 +386,21 @@ SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { currentOp = this->currentOp; bool bytesRead = false; +#if OBSW_ENABLE_TIMERS == 1 Timer timer; - timer.setTimer(200); + timer.setTimer(100); uint32_t remainingTimeMs = 0; +#endif while(true) { ReturnValue_t result = cmdExecutor.check(bytesRead); + // This timer can prevent deadlocks due to missconfigurations +#if OBSW_ENABLE_TIMERS == 1 timer.getTimer(&remainingTimeMs); if(remainingTimeMs == 0) { sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl; return OpStatus::FAIL; } +#endif switch(result) { case(CommandExecutor::BYTES_READ): { continue; diff --git a/fsfw b/fsfw index 6073abb1..3704d2b8 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 6073abb12db23decbc9d69f4b6342f4f6f1247bd +Subproject commit 3704d2b8295152652a4c7836b595223d8fa3767d diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 778a1611..0246ff82 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -22,6 +22,10 @@ debugging. */ #define OBSW_VERBOSE_LEVEL 1 +//! Timers can mess up the code when debugging +//! TODO: Enable for mission code, disable for debug code +#define OBSW_ENABLE_TIMERS 0 + #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 #define OBSW_ADD_TEST_PST 1 From 2fb54f7de9e2c85377aaf35161da5398d95ccee4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 6 Aug 2021 01:25:36 +0200 Subject: [PATCH 06/21] first successfull tests --- bsp_q7s/core/CoreController.cpp | 391 ++++++++++++++++----------- bsp_q7s/core/CoreController.h | 39 ++- bsp_q7s/memory/FileSystemHandler.cpp | 11 +- bsp_q7s/memory/FileSystemHandler.h | 3 + bsp_q7s/memory/SdCardManager.cpp | 47 +++- bsp_q7s/memory/SdCardManager.h | 14 +- 6 files changed, 308 insertions(+), 197 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 4a01ca50..cf99a8e9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -39,7 +39,8 @@ CoreController::CoreController(object_id_t objectId): sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } if(not BLOCKING_SD_INIT) { - initSdCardNonBlocking(); + sdInitStateMachine(); + sdcMan->setBlocking(false); } result = initBootCopy(); @@ -58,8 +59,8 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(not BLOCKING_SD_INIT and not sdInitFinished) { - initSdCardNonBlocking(); + if(not BLOCKING_SD_INIT and not sdInfo.initFinished) { + sdInitStateMachine(); } performWatchdogControlOperation(); } @@ -83,7 +84,7 @@ ReturnValue_t CoreController::initialize() { } if(not BLOCKING_SD_INIT) { - initSdCardNonBlocking(); + sdInitStateMachine(); } return ExtendedControllerBase::initialize(); @@ -106,17 +107,17 @@ ReturnValue_t CoreController::initSdCardBlocking() { << std::endl; } - auto statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); - result = sdcMan->getSdCardActiveStatus(statusPair); + result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT determinePreferredSdCard(); + updateSdInfoOther(); sif::info << "Cold redundant SD card configuration, preferred SD card: " << - static_cast(preferredSdCard) << std::endl; - result = sdCardColdRedundantInit(sdcMan, statusPair); + static_cast(sdInfo.pref) << std::endl; + result = sdColdRedundantBlockingInit(); // Update status file sdcMan->updateSdCardStateFile(); return result; @@ -133,131 +134,193 @@ ReturnValue_t CoreController::initSdCardBlocking() { } -ReturnValue_t CoreController::initSdCardNonBlocking() { +ReturnValue_t CoreController::sdInitStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; #else ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(state == SdStates::START) { - sdcInitCycleCount = 0; - commandExecuted = false; - state = SdStates::GET_INFO; + SdCardManager::Operations operation; + + auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, + uint16_t maxCycleCount, std::string opPrintout) { + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + sif::debug << "op success" << std::endl; + sdInfo.state = newStateOnSuccess; + sdInfo.commandExecuted = false; + sdInfo.cycleCount = 0; + } + else if(sdInfo.cycleCount > 4) { + sif::warning << "CoreController::sdInitStateMachine: " << opPrintout << + " takes too long" << std::endl; + } + }; + + if(sdInfo.state == SdStates::START) { + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; } - if(state == SdStates::GET_INFO) { - if(not commandExecuted) { + if(sdInfo.state == SdStates::GET_INFO) { + + if(not sdInfo.commandExecuted) { + sif::debug << "Getting info.." << std::endl; // Create update status file result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } - commandExecuted = true; + sdInfo.commandExecuted = true; } else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::SET_STATE_SELF; - commandExecuted = false; - sdcInitCycleCount = 0; - } - else if(sdcInitCycleCount > 4) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Updating SDC file takes too long" << std::endl; - } + nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file"); } } - if(state == SdStates::SET_STATE_SELF) { - if(not commandExecuted) { + if(sdInfo.state == SdStates::SET_STATE_SELF) { + if(not sdInfo.commandExecuted) { + sif::debug << "Set self state" << std::endl; + result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); determinePreferredSdCard(); - statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); - result = sdcMan->getSdCardActiveStatus(statusPair); + updateSdInfoOther(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } sif::info << "Cold redundant SD card configuration, preferred SD card: " << - static_cast(preferredSdCard) << std::endl; - result = sdCardColdRedundantInit(sdcMan, statusPair); - if(result == SdCardManager::ALREADY_ON) { - state = SdStates::MOUNT; + static_cast(sdInfo.pref) << std::endl; + if(sdInfo.prefState == sd::SdState::MOUNTED) { + sdInfo.state = SdStates::DETERMINE_OTHER; } - if(result == SdCardManager::ALREADY_MOUNTED) { - state = SdStates::UPDATE_INFO; + else if(sdInfo.prefState == sd::SdState::OFF) { + sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdInfo.commandExecuted = true; } - else { - commandExecuted = true; + else if(sdInfo.prefState == sd::SdState::ON) { + sdInfo.state = SdStates::MOUNT_SELF; } } else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::MOUNT; - commandExecuted = false; - sdcInitCycleCount = 0; - } - else if(sdcInitCycleCount > 10) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Setting SDC state takes too long" << std::endl; - } + nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state"); } } - if(state == SdStates::MOUNT) { - if(not commandExecuted) { - result = sdCardColdRedundantInit(sdcMan, statusPair); - commandExecuted = false; + if(sdInfo.state == SdStates::MOUNT_SELF) { + if(not sdInfo.commandExecuted) { + sif::debug << "Mount self" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + sdInfo.commandExecuted = true; } else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::UPDATE_INFO; - commandExecuted = false; - sdcInitCycleCount = 0; - } - else if(sdcInitCycleCount > 5) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Mounting SD card takes too long" << std::endl; - } + nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card"); } } - if(state == SdStates::UPDATE_INFO) { - if(not commandExecuted) { + if(sdInfo.state == SdStates::DETERMINE_OTHER) { + // Determine whether any additional operations have to be done for the other SD card + // 1. Cold redundant case: Other SD card needs to be unmounted and switched off + // 2. Hot redundant case: Other SD card needs to be mounted and switched on +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + if(sdInfo.otherState == sd::SdState::ON) { + sdInfo.state = SdStates::SET_STATE_OTHER; + } + else if(sdInfo.otherState == sd::SdState::MOUNTED) { + sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; + } + else { + // Is already off, update info + sdInfo.state = SdStates::UPDATE_INFO; + } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if(sdInfo.otherState == sd::SdState::OFF) { + sdInfo.state = SdStates::SET_STATE_OTHER; + } + else if(sdInfo.otherState == sd::SdState::ON) { + sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; + } + else { + // Is already on and mounted, update info + sdInfo.state = SdStates::UPDATE_INFO; + } +#endif + } + + if(sdInfo.state == SdStates::SET_STATE_OTHER) { + // Set state of other SD card to ON or OFF, depending on redundancy mode +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + if(not sdInfo.commandExecuted) { + sif::debug << "Set state other off" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::OFF, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if(not sdInfo.commandExecuted) { + sif::debug << "Set state other on" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#endif + else { + nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching off other SD card"); + } + } + + if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { + // Mount or unmount other SD card, depending on redundancy mode +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + if(not sdInfo.commandExecuted) { + sif::debug << "Unmount other" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if(not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#endif + else { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + std::string opPrint = "Switching off other SD card"; +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + std::string opPrint = "Mounting other SD card"; +#endif + nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, opPrint); + } + } + + if(sdInfo.state == SdStates::UPDATE_INFO) { + if(not sdInfo.commandExecuted) { + sif::debug << "update info" << std::endl; + // It is assumed that all tasks are running by the point this section is reached. + // Therefore, perform this operation in blocking mode because it does not take long + // and the ready state of the SD card is available sooner + sdcMan->setBlocking(true); // Update status file result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } - commandExecuted = true; - } - else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - sdInitFinished = true; - state = SdStates::DONE; - } - else if(sdcInitCycleCount > 2) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Updating SDC file takes too long" << std::endl; - } + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::DONE; + sdInfo.initFinished = true; + sdInfo.cycleCount = 0; + sdcMan->setBlocking(false); + sif::debug << "Sd init done" << std::endl; } } - sdcInitCycleCount++; + sdInfo.cycleCount++; return HasReturnvaluesIF::RETURN_OK; #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } -ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPair, - sd::SdCard sdCard, std::string sdString) { +ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, + std::string sdChar) { std::string mountString; if(sdCard == sd::SdCard::SLOT_0) { mountString = SdCardManager::SD_0_MOUNT_POINT; @@ -266,51 +329,54 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPai mountString = SdCardManager::SD_1_MOUNT_POINT; } - sd::SdState status = sd::SdState::OFF; + sd::SdState state = sd::SdState::OFF; if(sdCard == sd::SdCard::SLOT_0) { - status = statusPair.first; + state = sdInfo.currentState.first; } else { - status = statusPair.second; + state = sdInfo.currentState.second; } - if(status == sd::SdState::MOUNTED) { - if(std::filesystem::exists(mountString)) { - sif::info << "SD card " << sdString << " already on and mounted at " << - mountString << std::endl; - return SdCardManager::ALREADY_MOUNTED; + if(state == sd::SdState::MOUNTED) { + if(targetState == sd::SdState::OFF) { + sif::info << "Switching off SD card" << sdChar << std::endl; + return sdcMan->switchOffSdCard(sdCard, true, &sdInfo.currentState); } - sif::error << "SD card mounted but expected mount point " << - mountString << " not found!" << std::endl; - return SdCardManager::MOUNT_ERROR; - } - - if(status == sd::SdState::OFF) { - if(BLOCKING_SD_INIT) { - sif::info << "Switching on and mounting SD card " << sdString << " at " << - mountString << std::endl; - return sdcMan->switchOnSdCard(sdCard, true, &statusPair); + else if(targetState == sd::SdState::ON) { + sif::info << "Unmounting SD card " << sdChar << std::endl; + return sdcMan->unmountSdCard(sdCard); } else { - if(state == SdStates::SET_STATE_SELF) { - sif::info << "Switching on SD card" << std::endl; - return sdcMan->switchOnSdCard(sdCard, false, &statusPair); + if(std::filesystem::exists(mountString)) { + sif::info << "SD card " << sdChar << " already on and mounted at " << + mountString << std::endl; + return SdCardManager::ALREADY_MOUNTED; } + sif::error << "SD card mounted but expected mount point " << + mountString << " not found!" << std::endl; + return SdCardManager::MOUNT_ERROR; } } - else if(status == sd::SdState::ON) { - if(BLOCKING_SD_INIT) { - sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + if(state == sd::SdState::OFF) { + if(targetState == sd::SdState::MOUNTED) { + sif::info << "Switching on and mounting SD card " << sdChar << " at " << + mountString << std::endl; + return sdcMan->switchOnSdCard(sdCard, true, &sdInfo.currentState); + } + else if(targetState == sd::SdState::ON) { + sif::info << "Switching on SD card" << sdChar << std::endl; + return sdcMan->switchOnSdCard(sdCard, false, &sdInfo.currentState); + } + } + + else if(state == sd::SdState::ON) { + if(targetState == sd::SdState::MOUNTED) { + sif::info << "Mounting SD card " << sdChar << " at " << mountString << std::endl; return sdcMan->mountSdCard(sdCard); } - else { - if(state == SdStates::SET_STATE_SELF) { - return SdCardManager::ALREADY_ON; - } - if(state == SdStates::MOUNT) { - sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; - return sdcMan->mountSdCard(sdCard); - } + else if(targetState == sd::SdState::OFF) { + sif::info << "Switching off SD card" << sdChar << std::endl; + return sdcMan->switchOffSdCard(sdCard, false, &sdInfo.currentState); } } else { @@ -337,18 +403,16 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ ReturnValue_t CoreController::initializeAfterTaskCreation() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - // TODO: Do this here because this can take a longer time. Later, use non-blocking mode - // to start doing stuff in ctor and initialize function. - // This operation can take 1-2 seconds on reboot, and around 50-100ms if the SD - // card is already on. if(BLOCKING_SD_INIT) { ReturnValue_t result = initSdCardBlocking(); - if(result != HasReturnvaluesIF::RETURN_OK) { + if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) { sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; } } else { - initSdCardNonBlocking(); + if(not sdInfo.initFinished) { + sdInitStateMachine(); + } } result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -358,54 +422,29 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { return result; } -ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair, SdStates step) { +ReturnValue_t CoreController::sdColdRedundantBlockingInit() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - std::string preferredString; - sd::SdState otherStatus = sd::SdState::OFF; - std::string otherString; - sd::SdCard otherSdc = sd::SdCard::SLOT_0; - - if(preferredSdCard == sd::SdCard::SLOT_0) { - preferredString = "0"; - otherSdc = sd::SdCard::SLOT_1; - otherStatus = statusPair.second; - otherString = "1"; - } - else { - preferredString = "1"; - otherStatus = statusPair.first; - otherSdc = sd::SdCard::SLOT_0; - otherString = "0"; + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Setting up preferred card " << sdInfo.otherChar << + " in cold redundant mode failed" << std::endl; + // Try other SD card and mark set up operation as failed + sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + result = HasReturnvaluesIF::RETURN_FAILED; } - if(step != SdStates::SET_STATE_OTHER) { - result = sdCardSetup(statusPair, preferredSdCard, preferredString); - if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Setting up preferred card " << otherString << + if(result != HasReturnvaluesIF::RETURN_FAILED and sdInfo.otherState != sd::SdState::OFF) { + sif::info << "Switching off secondary SD card " << sdInfo.otherChar << std::endl; + // Switch off other SD card in cold redundant mode if setting up preferred one worked + // without issues + ReturnValue_t result2 = sdcMan->switchOffSdCard(sdInfo.other, + sdInfo.otherState, &sdInfo.currentState); + if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { + sif::warning << "Switching off secondary SD card " << sdInfo.otherChar << " in cold redundant mode failed" << std::endl; - // Try other SD card and mark set up operation as failed - sdCardSetup(statusPair, preferredSdCard, preferredString); - result = HasReturnvaluesIF::RETURN_FAILED; } } - - if(BLOCKING_SD_INIT or (not BLOCKING_SD_INIT and state == SdStates::SET_STATE_OTHER)) { - // Don't disable other card if enabling the first one already failed - // Otherwise, try to turn off the other SD card - if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::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 worked - // without issues - ReturnValue_t result2 = sdcMan->switchOffSdCard(otherSdc, otherStatus, &statusPair); - if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { - sif::warning << "Switching off secondary SD card " << otherString << - " in cold redundant mode failed" << std::endl; - } - } - } - return result; } @@ -665,13 +704,13 @@ CoreController::~CoreController() { } void CoreController::determinePreferredSdCard() { - if(preferredSdCard == sd::SdCard::NONE) { - ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if(sdInfo.pref == sd::SdCard::NONE) { + ReturnValue_t result = sdcMan->getPreferredSdCard(sdInfo.pref); if(result != HasReturnvaluesIF::RETURN_OK) { if(result == scratch::KEY_NOT_FOUND) { sif::warning << "CoreController::sdCardInit: " "Preferred SD card not set. Setting to 0" << std::endl; - sdcMan->setPreferredSdCard(preferredSdCard); + sdcMan->setPreferredSdCard(sdInfo.pref); } else { sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" @@ -681,6 +720,28 @@ void CoreController::determinePreferredSdCard() { } } +void CoreController::updateSdInfoOther() { + if(sdInfo.pref == sd::SdCard::SLOT_0) { + sdInfo.prefChar = "0"; + sdInfo.otherChar = "1"; + sdInfo.otherState = sdInfo.currentState.second; + sdInfo.prefState = sdInfo.currentState.first; + sdInfo.other = sd::SdCard::SLOT_1; + + } + else { + sdInfo.prefChar = "1"; + sdInfo.otherChar = "0"; + sdInfo.otherState = sdInfo.currentState.first; + sdInfo.prefState = sdInfo.currentState.second; + sdInfo.other = sd::SdCard::SLOT_0; + } +} + +bool CoreController::sdInitFinished() const { + return sdInfo.initFinished; +} + void CoreController::performWatchdogControlOperation() { // Only perform each fifth iteration if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index a4f2868e..1dec1f36 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -48,6 +48,7 @@ public: static ReturnValue_t incrementAllocationFailureCount(); static void getCurrentBootCopy(Chip& chip, Copy& copy); + bool sdInitFinished() const; private: static Chip currentChip; @@ -65,26 +66,40 @@ private: START, GET_INFO, SET_STATE_SELF, + MOUNT_SELF, + DETERMINE_OTHER, SET_STATE_OTHER, - MOUNT, + // Mount or unmount other + MOUNT_UNMOUNT_OTHER, UPDATE_INFO, DONE }; static constexpr bool BLOCKING_SD_INIT = false; SdCardManager* sdcMan = nullptr; - uint16_t sdcInitCycleCount = 0; + ReturnValue_t initSdCardBlocking(); - ReturnValue_t initSdCardNonBlocking(); - sd::SdCard preferredSdCard = sd::SdCard::NONE; - SdStates state = SdStates::START; - SdCardManager::SdStatusPair statusPair; - bool commandExecuted = true; - bool sdInitFinished = false; - ReturnValue_t sdCardSetup(SdCardManager::SdStatusPair& statusPair, - sd::SdCard sdCard, std::string sdString); - ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair, SdStates step = SdStates::NONE); + ReturnValue_t sdInitStateMachine(); + + struct SdInfo { + sd::SdCard pref = sd::SdCard::NONE; + sd::SdState prefState = sd::SdState::OFF; + sd::SdCard other = sd::SdCard::NONE; + sd::SdState otherState = sd::SdState::OFF; + std::string prefChar = "0"; + std::string otherChar = "1"; + SdStates state = SdStates::START; + bool commandExecuted = true; + bool initFinished = false; + SdCardManager::SdStatePair currentState; + uint16_t cycleCount = 0; + }; + + SdInfo sdInfo; + + void updateSdInfoOther(); + ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar); + ReturnValue_t sdColdRedundantBlockingInit(); void determinePreferredSdCard(); ReturnValue_t initVersionFile(); diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 82891979..ad8ec137 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -41,7 +41,9 @@ void FileSystemHandler::fileSystemHandlerLoop() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; while(true) { if(opCounter % 5 == 0) { - fileSystemCheckup(); + if(coreCtrl->sdInitFinished()) { + fileSystemCheckup(); + } } result = mq->receiveMessage(&filemsg); if(result == MessageQueueIF::EMPTY) { @@ -72,7 +74,7 @@ void FileSystemHandler::fileSystemHandlerLoop() { } void FileSystemHandler::fileSystemCheckup() { - SdCardManager::SdStatusPair statusPair; + SdCardManager::SdStatePair statusPair; sdcMan->getSdCardActiveStatus(statusPair); sd::SdCard preferredSdCard; sdcMan->getPreferredSdCard(preferredSdCard); @@ -111,6 +113,11 @@ MessageQueueId_t FileSystemHandler::getCommandQueue() const { } ReturnValue_t FileSystemHandler::initialize() { + coreCtrl = ObjectManager::instance()->get(objects::CORE_CONTROLLER); + if(coreCtrl == nullptr) { + sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle" << + std::endl; + } sdcMan = SdCardManager::instance(); sd::SdCard preferredSdCard; ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 22a7e7ae..1ff5d7c9 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -11,6 +11,8 @@ #include +class CoreController; + class FileSystemHandler: public SystemObject, public ExecutableObjectIF, public HasFileSystemIF { @@ -47,6 +49,7 @@ public: void* args = nullptr) override; private: + CoreController* coreCtrl = nullptr; MessageQueueIF* mq = nullptr; std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index d9442a8c..f203cb29 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -34,11 +34,18 @@ SdCardManager* SdCardManager::instance() { } ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard, - SdStatusPair* statusPair) { + SdStatePair* statusPair) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - std::unique_ptr sdStatusPtr; + if(doMountSdCard) { + if(not blocking) { + sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is" + " not configured for blocking operation. Forcing blocking mode.." << std::endl; + blocking = true; + } + } + std::unique_ptr sdStatusPtr; if(statusPair == nullptr) { - sdStatusPtr = std::make_unique(); + sdStatusPtr = std::make_unique(); statusPair = sdStatusPtr.get(); result = getSdCardActiveStatus(*statusPair); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -91,12 +98,19 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar } ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, - SdStatusPair* statusPair) { + SdStatePair* statusPair) { std::pair active; ReturnValue_t result = getSdCardActiveStatus(active); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } + if(doUnmountSdCard) { + if(not blocking) { + sif::warning << "SdCardManager::switchOffSdCard: Two-step command but manager is" + " not configured for blocking operation. Forcing blocking mode.." << std::endl; + blocking = true; + } + } // 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" @@ -155,7 +169,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { return result; } -ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { +ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatePair& active) { using namespace std; if(not filesystem::exists(SD_STATE_FILE)) { return STATUS_FILE_NEXISTS; @@ -253,23 +267,34 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { return result; } -ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard prefSdCard) { - std::unique_ptr sdStatusPtr; +ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard prefSdCard) { + std::unique_ptr sdStatusPtr; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + // Enforce blocking operation for now. Be careful to reset it when returning prematurely! + bool resetNonBlockingState = false; + if(not this->blocking) { + blocking = true; + resetNonBlockingState = true; + } if(prefSdCard == sd::SdCard::NONE) { - ReturnValue_t result = getPreferredSdCard(prefSdCard); + result = getPreferredSdCard(prefSdCard); if(result != HasReturnvaluesIF::RETURN_OK) {} } if(statusPair == nullptr) { - sdStatusPtr = std::make_unique(); + sdStatusPtr = std::make_unique(); statusPair = sdStatusPtr.get(); getSdCardActiveStatus(*statusPair); } if(statusPair->first == sd::SdState::ON) { - return mountSdCard(prefSdCard); + result = mountSdCard(prefSdCard); } - return switchOnSdCard(prefSdCard, true, statusPair); + result = switchOnSdCard(prefSdCard, true, statusPair); + if(resetNonBlockingState) { + blocking = false; + } + return result; } void SdCardManager::resetState() { diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 31dc740d..96192575 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -42,7 +42,7 @@ public: FAIL }; - using SdStatusPair = std::pair; + using SdStatePair = std::pair; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; @@ -114,7 +114,7 @@ public: * SYSTEM_CALL_ERROR on system error */ ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true, - SdStatusPair* statusPair = nullptr); + SdStatePair* statusPair = nullptr); /** * Switch off the specified SD card. @@ -126,7 +126,7 @@ public: * SYSTEM_CALL_ERROR on system error */ ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true, - SdStatusPair* statusPair = nullptr); + SdStatePair* statusPair = nullptr); /** * Update the state file or creates one if it does not exist. You need to call this @@ -149,7 +149,7 @@ public: * should call #updateSdCardStateFile again in that case * - STATUS_FILE_NEXISTS if the status file does not exist */ - ReturnValue_t getSdCardActiveStatus(SdStatusPair& active); + ReturnValue_t getSdCardActiveStatus(SdStatePair& active); /** * Mount the specified SD card. This is necessary to use it. @@ -169,13 +169,13 @@ public: * 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. + * passed into the function. For now, this operation will be enforced in blocking mode. * @param statusPair Current SD card status capture with #getSdCardActiveStatus * @param prefSdCard Preferred SD card captured with #getPreferredSdCard * @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed * @return */ - ReturnValue_t sanitizeState(SdStatusPair* statusPair = nullptr, + ReturnValue_t sanitizeState(SdStatePair* statusPair = nullptr, sd::SdCard prefSdCard = sd::SdCard::NONE); /** @@ -203,7 +203,7 @@ private: ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); - void processSdStatusLine(SdStatusPair& active, std::string& line, uint8_t& idx, + void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx, sd::SdCard& currentSd); std::string currentPrefix; From e186bff4e48b3d18492a8d2aa0be5ccc86c8b2b0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 7 Aug 2021 18:52:36 +0200 Subject: [PATCH 07/21] important bugfixes for core controller --- bsp_q7s/core/CoreController.cpp | 37 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index cf99a8e9..00179b24 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -224,9 +224,11 @@ ReturnValue_t CoreController::sdInitStateMachine() { // 2. Hot redundant case: Other SD card needs to be mounted and switched on #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(sdInfo.otherState == sd::SdState::ON) { + sif::debug << "Determine: Setting other state off" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::MOUNTED) { + sif::debug << "Determine: Unmounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { @@ -235,9 +237,11 @@ ReturnValue_t CoreController::sdInitStateMachine() { } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(sdInfo.otherState == sd::SdState::OFF) { + sif::debug << "Determine: Setting other state on" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::ON) { + sif::debug << "Determine: Mounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { @@ -252,19 +256,24 @@ ReturnValue_t CoreController::sdInitStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { sif::debug << "Set state other off" << std::endl; - result = sdCardSetup(sdInfo.pref, sd::SdState::OFF, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar); sdInfo.commandExecuted = true; } + else { + nonBlockingOpChecking(SdStates::UPDATE_INFO, 10, "Switching off other SD card"); + } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { sif::debug << "Set state other on" << std::endl; - result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } -#endif else { - nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching off other SD card"); + nonBlockingOpChecking(SdStates::SdStates::MOUNT_UNMOUNT_OTHER, 10, + "Switching on other SD card"); } +#endif + } if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { @@ -272,23 +281,21 @@ ReturnValue_t CoreController::sdInitStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { sif::debug << "Unmount other" << std::endl; - result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } + else { + nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card"); + } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar); sdInfo.commandExecuted = true; } -#endif else { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - std::string opPrint = "Switching off other SD card"; -#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT - std::string opPrint = "Mounting other SD card"; -#endif - nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, opPrint); + nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card"); } +#endif } if(sdInfo.state == SdStates::UPDATE_INFO) { @@ -338,7 +345,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS } if(state == sd::SdState::MOUNTED) { if(targetState == sd::SdState::OFF) { - sif::info << "Switching off SD card" << sdChar << std::endl; + sif::info << "Switching off SD card " << sdChar << std::endl; return sdcMan->switchOffSdCard(sdCard, true, &sdInfo.currentState); } else if(targetState == sd::SdState::ON) { @@ -375,7 +382,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS return sdcMan->mountSdCard(sdCard); } else if(targetState == sd::SdState::OFF) { - sif::info << "Switching off SD card" << sdChar << std::endl; + sif::info << "Switching off SD card " << sdChar << std::endl; return sdcMan->switchOffSdCard(sdCard, false, &sdInfo.currentState); } } From 5a4d287f676b140a5928fc27db59e3a801e9dda6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 00:11:21 +0200 Subject: [PATCH 08/21] more testing and bugfixes --- bsp_q7s/core/CoreController.cpp | 57 ++++++++++++++++++++------------ bsp_q7s/core/CoreController.h | 5 +-- bsp_q7s/memory/SdCardManager.cpp | 16 ++++++--- bsp_q7s/memory/SdCardManager.h | 2 ++ 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 00179b24..cb705930 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -39,7 +39,7 @@ CoreController::CoreController(object_id_t objectId): sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } if(not BLOCKING_SD_INIT) { - sdInitStateMachine(); + sdStateMachine(); sdcMan->setBlocking(false); } @@ -60,7 +60,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { void CoreController::performControlOperation() { if(not BLOCKING_SD_INIT and not sdInfo.initFinished) { - sdInitStateMachine(); + sdStateMachine(); } performWatchdogControlOperation(); } @@ -84,7 +84,7 @@ ReturnValue_t CoreController::initialize() { } if(not BLOCKING_SD_INIT) { - sdInitStateMachine(); + sdStateMachine(); } return ExtendedControllerBase::initialize(); @@ -134,7 +134,7 @@ ReturnValue_t CoreController::initSdCardBlocking() { } -ReturnValue_t CoreController::sdInitStateMachine() { +ReturnValue_t CoreController::sdStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; @@ -146,7 +146,6 @@ ReturnValue_t CoreController::sdInitStateMachine() { uint16_t maxCycleCount, std::string opPrintout) { SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); if(status == SdCardManager::OpStatus::SUCCESS) { - sif::debug << "op success" << std::endl; sdInfo.state = newStateOnSuccess; sdInfo.commandExecuted = false; sdInfo.cycleCount = 0; @@ -157,6 +156,15 @@ ReturnValue_t CoreController::sdInitStateMachine() { } }; + auto currentStateSetter = [&](sd::SdCard sdCard, sd::SdState newState) { + if(sdCard == sd::SdCard::SLOT_0) { + sdInfo.currentState.first = newState; + } + else { + sdInfo.currentState.second = newState; + } + }; + if(sdInfo.state == SdStates::START) { sdInfo.cycleCount = 0; sdInfo.commandExecuted = false; @@ -164,9 +172,7 @@ ReturnValue_t CoreController::sdInitStateMachine() { } if(sdInfo.state == SdStates::GET_INFO) { - if(not sdInfo.commandExecuted) { - sif::debug << "Getting info.." << std::endl; // Create update status file result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -182,20 +188,21 @@ ReturnValue_t CoreController::sdInitStateMachine() { if(sdInfo.state == SdStates::SET_STATE_SELF) { if(not sdInfo.commandExecuted) { - sif::debug << "Set self state" << std::endl; result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); determinePreferredSdCard(); updateSdInfoOther(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT sif::info << "Cold redundant SD card configuration, preferred SD card: " << static_cast(sdInfo.pref) << std::endl; +#endif if(sdInfo.prefState == sd::SdState::MOUNTED) { sdInfo.state = SdStates::DETERMINE_OTHER; } else if(sdInfo.prefState == sd::SdState::OFF) { - sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar, false); sdInfo.commandExecuted = true; } else if(sdInfo.prefState == sd::SdState::ON) { @@ -204,17 +211,20 @@ ReturnValue_t CoreController::sdInitStateMachine() { } else { nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state"); + sdInfo.prefState = sd::SdState::ON; + currentStateSetter(sdInfo.pref, sd::SdState::ON); } } if(sdInfo.state == SdStates::MOUNT_SELF) { if(not sdInfo.commandExecuted) { - sif::debug << "Mount self" << std::endl; result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card"); + sdInfo.prefState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); } } @@ -224,11 +234,9 @@ ReturnValue_t CoreController::sdInitStateMachine() { // 2. Hot redundant case: Other SD card needs to be mounted and switched on #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(sdInfo.otherState == sd::SdState::ON) { - sif::debug << "Determine: Setting other state off" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::MOUNTED) { - sif::debug << "Determine: Unmounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { @@ -255,22 +263,24 @@ ReturnValue_t CoreController::sdInitStateMachine() { // Set state of other SD card to ON or OFF, depending on redundancy mode #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { - sif::debug << "Set state other off" << std::endl; - result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar); + result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::UPDATE_INFO, 10, "Switching off other SD card"); + sdInfo.otherState = sd::SdState::OFF; + currentStateSetter(sdInfo.other, sd::SdState::OFF); } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { - sif::debug << "Set state other on" << std::endl; result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching on other SD card"); + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); } #endif @@ -280,12 +290,13 @@ ReturnValue_t CoreController::sdInitStateMachine() { // Mount or unmount other SD card, depending on redundancy mode #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { - sif::debug << "Unmount other" << std::endl; result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card"); + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { @@ -294,13 +305,14 @@ ReturnValue_t CoreController::sdInitStateMachine() { } else { nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card"); + sdInfo.otherState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); } #endif } if(sdInfo.state == SdStates::UPDATE_INFO) { if(not sdInfo.commandExecuted) { - sif::debug << "update info" << std::endl; // It is assumed that all tasks are running by the point this section is reached. // Therefore, perform this operation in blocking mode because it does not take long // and the ready state of the SD card is available sooner @@ -316,7 +328,9 @@ ReturnValue_t CoreController::sdInitStateMachine() { sdInfo.initFinished = true; sdInfo.cycleCount = 0; sdcMan->setBlocking(false); - sif::debug << "Sd init done" << std::endl; + sdcMan->getSdCardActiveStatus(sdInfo.currentState); + updateSdInfoOther(); + sif::info << "SD card initialization finished" << std::endl; } } @@ -327,8 +341,9 @@ ReturnValue_t CoreController::sdInitStateMachine() { ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, - std::string sdChar) { + std::string sdChar, bool printOutput) { std::string mountString; + sdcMan->setPrintCommandOutput(printOutput); if(sdCard == sd::SdCard::SLOT_0) { mountString = SdCardManager::SD_0_MOUNT_POINT; } @@ -371,7 +386,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS return sdcMan->switchOnSdCard(sdCard, true, &sdInfo.currentState); } else if(targetState == sd::SdState::ON) { - sif::info << "Switching on SD card" << sdChar << std::endl; + sif::info << "Switching on SD card " << sdChar << std::endl; return sdcMan->switchOnSdCard(sdCard, false, &sdInfo.currentState); } } @@ -418,7 +433,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { } else { if(not sdInfo.initFinished) { - sdInitStateMachine(); + sdStateMachine(); } } result = initVersionFile(); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 1dec1f36..f2d9a565 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -79,7 +79,7 @@ private: SdCardManager* sdcMan = nullptr; ReturnValue_t initSdCardBlocking(); - ReturnValue_t sdInitStateMachine(); + ReturnValue_t sdStateMachine(); struct SdInfo { sd::SdCard pref = sd::SdCard::NONE; @@ -98,7 +98,8 @@ private: SdInfo sdInfo; void updateSdInfoOther(); - ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar); + ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, + bool printOutput = true); ReturnValue_t sdColdRedundantBlockingInit(); void determinePreferredSdCard(); diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index f203cb29..873bb6a4 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -39,7 +39,8 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar if(doMountSdCard) { if(not blocking) { sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is" - " not configured for blocking operation. Forcing blocking mode.." << std::endl; + " not configured for blocking operation. " + "Forcing blocking mode.." << std::endl; blocking = true; } } @@ -161,7 +162,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { } ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - cmdExecutor.load(command.str(), blocking, true); + cmdExecutor.load(command.str(), blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState"); @@ -220,7 +221,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { currentOp = Operations::MOUNTING; } string sdMountCommand = "mount " + mountDev + " " + mountPoint; - cmdExecutor.load(sdMountCommand, blocking, true); + cmdExecutor.load(sdMountCommand, blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); @@ -259,7 +260,7 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { if(not blocking) { currentOp = Operations::UNMOUNTING; } - cmdExecutor.load(sdUnmountCommand, blocking, true); + cmdExecutor.load(sdUnmountCommand, blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard"); @@ -380,7 +381,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() { } // Use q7hw utility and pipe the command output into the state file std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); - cmdExecutor.load(updateCmd, blocking, true); + cmdExecutor.load(updateCmd, blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); @@ -450,3 +451,8 @@ void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; } +void SdCardManager::setPrintCommandOutput(bool print) { + this->printCmdOutput = print; + +} + diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 96192575..19024914 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -194,10 +194,12 @@ public: void resetState(); void setBlocking(bool blocking); + void setPrintCommandOutput(bool print); private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; bool blocking = false; + bool printCmdOutput = true; SdCardManager(); From 1c0ea5cbb10040b0675d0a54ac8621639dd83b01 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 00:37:07 +0200 Subject: [PATCH 09/21] tested hot redundant config as well --- bsp_q7s/core/CoreController.cpp | 58 +++++++++++++++++---------------- bsp_q7s/core/CoreController.h | 16 +++++++-- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index cb705930..6bc0abbb 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -123,8 +123,8 @@ ReturnValue_t CoreController::initSdCardBlocking() { return result; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT sif::info << "Hot redundant SD card configuration" << std::endl; - sdCardSetup(statusPair, sd::SdCard::SLOT_0, "0"); - sdCardSetup(statusPair, sd::SdCard::SLOT_1, "1"); + sdCardSetup(sd::SdCard::SLOT_0, sd::SdState::MOUNTED, "0", false); + sdCardSetup(sd::SdCard::SLOT_1, sd::SdState::MOUNTED, "1", false); // Update status file sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; @@ -240,21 +240,19 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { - // Is already off, update info - sdInfo.state = SdStates::UPDATE_INFO; + // Is already off, update info, but with a small delay + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(sdInfo.otherState == sd::SdState::OFF) { - sif::debug << "Determine: Setting other state on" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::ON) { - sif::debug << "Determine: Mounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { // Is already on and mounted, update info - sdInfo.state = SdStates::UPDATE_INFO; + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; } #endif } @@ -267,17 +265,18 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::UPDATE_INFO, 10, "Switching off other SD card"); + nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, + "Switching off other SD card"); sdInfo.otherState = sd::SdState::OFF; currentStateSetter(sdInfo.other, sd::SdState::OFF); } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false); sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::SdStates::MOUNT_UNMOUNT_OTHER, 10, + nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching on other SD card"); sdInfo.otherState = sd::SdState::ON; currentStateSetter(sdInfo.other, sd::SdState::ON); @@ -311,25 +310,28 @@ ReturnValue_t CoreController::sdStateMachine() { #endif } - if(sdInfo.state == SdStates::UPDATE_INFO) { - if(not sdInfo.commandExecuted) { - // It is assumed that all tasks are running by the point this section is reached. - // Therefore, perform this operation in blocking mode because it does not take long - // and the ready state of the SD card is available sooner - sdcMan->setBlocking(true); - // Update status file - result = sdcMan->updateSdCardStateFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Updating SD card state file failed" - << std::endl; - } - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::DONE; - sdInfo.initFinished = true; - sdInfo.cycleCount = 0; - sdcMan->setBlocking(false); - sdcMan->getSdCardActiveStatus(sdInfo.currentState); + if(sdInfo.state == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) { + sdInfo.state = SdStates::UPDATE_INFO; + } + else if(sdInfo.state == SdStates::UPDATE_INFO) { + // It is assumed that all tasks are running by the point this section is reached. + // Therefore, perform this operation in blocking mode because it does not take long + // and the ready state of the SD card is available sooner + sdcMan->setBlocking(true); + // Update status file + result = sdcMan->updateSdCardStateFile(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::DONE; + sdInfo.cycleCount = 0; + sdcMan->setBlocking(false); + sdcMan->getSdCardActiveStatus(sdInfo.currentState); + if(not sdInfo.initFinished) { updateSdInfoOther(); + sdInfo.initFinished = true; sif::info << "SD card initialization finished" << std::endl; } } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index f2d9a565..da587807 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -60,19 +60,29 @@ private: ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - // States for non-blocking setup + // States for SD state machine, which is used in non-blocking mode enum class SdStates { NONE, START, GET_INFO, SET_STATE_SELF, MOUNT_SELF, + // Determine operations for other SD card, depending on redundancy configuration DETERMINE_OTHER, SET_STATE_OTHER, // Mount or unmount other MOUNT_UNMOUNT_OTHER, + // Skip period because the shell command used to generate the info file sometimes is + // missing the last performed operation if executed too early + SKIP_CYCLE_BEFORE_INFO_UPDATE, UPDATE_INFO, - DONE + // SD initialization done + DONE, + // Used if SD switches or mount commands are issued via telecommand + SET_STATE_FROM_COMMAND, + MOUNT_FROM_COMMAND, + UNMOUNT_FROM_COMMAND, + }; static constexpr bool BLOCKING_SD_INIT = false; @@ -93,6 +103,8 @@ private: bool initFinished = false; SdCardManager::SdStatePair currentState; uint16_t cycleCount = 0; + sd::SdCard commandedCard = sd::SdCard::NONE; + sd::SdState commandedState = sd::SdState::OFF; }; SdInfo sdInfo; From f50b9de4a5acf392ab50a300fb6b5fc2d6de7502 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 01:24:18 +0200 Subject: [PATCH 10/21] extneded state machine for commanding support --- bsp_q7s/core/CoreController.cpp | 163 +++++++++++++++++++++++++------- bsp_q7s/core/CoreController.h | 13 ++- 2 files changed, 138 insertions(+), 38 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 6bc0abbb..b484c4cb 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -135,13 +135,27 @@ ReturnValue_t CoreController::initSdCardBlocking() { } ReturnValue_t CoreController::sdStateMachine() { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - return HasReturnvaluesIF::RETURN_OK; -#else ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; SdCardManager::Operations operation; + if(sdInfo.state == SdStates::IDLE) { + // Nothing to do + return result; + } + + if(sdInfo.state == SdStates::START) { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + sdInfo.state == SdStates::IDLE; + sdInfo.initFinished = true; +#else + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; + } + + // This lambda checks the non-blocking operation and assigns the new state on success. + // It returns true for an operation success and false otherwise auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount, std::string opPrintout) { SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); @@ -149,28 +163,16 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.state = newStateOnSuccess; sdInfo.commandExecuted = false; sdInfo.cycleCount = 0; + return true; } else if(sdInfo.cycleCount > 4) { sif::warning << "CoreController::sdInitStateMachine: " << opPrintout << " takes too long" << std::endl; + return false; } + return false; }; - auto currentStateSetter = [&](sd::SdCard sdCard, sd::SdState newState) { - if(sdCard == sd::SdCard::SLOT_0) { - sdInfo.currentState.first = newState; - } - else { - sdInfo.currentState.second = newState; - } - }; - - if(sdInfo.state == SdStates::START) { - sdInfo.cycleCount = 0; - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::GET_INFO; - } - if(sdInfo.state == SdStates::GET_INFO) { if(not sdInfo.commandExecuted) { // Create update status file @@ -222,9 +224,10 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card"); - sdInfo.prefState = sd::SdState::MOUNTED; - currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); + if(nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) { + sdInfo.prefState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); + } } } @@ -265,10 +268,11 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, - "Switching off other SD card"); - sdInfo.otherState = sd::SdState::OFF; - currentStateSetter(sdInfo.other, sd::SdState::OFF); + if(nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, + "Switching off other SD card")) { + sdInfo.otherState = sd::SdState::OFF; + currentStateSetter(sdInfo.other, sd::SdState::OFF); + } } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { @@ -282,7 +286,6 @@ ReturnValue_t CoreController::sdStateMachine() { currentStateSetter(sdInfo.other, sd::SdState::ON); } #endif - } if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { @@ -293,9 +296,10 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card"); - sdInfo.otherState = sd::SdState::ON; - currentStateSetter(sdInfo.other, sd::SdState::ON); + if(nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) { + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); + } } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { @@ -303,9 +307,10 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card"); - sdInfo.otherState = sd::SdState::MOUNTED; - currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); + if(nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) { + sdInfo.otherState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); + } } #endif } @@ -325,7 +330,7 @@ ReturnValue_t CoreController::sdStateMachine() { << std::endl; } sdInfo.commandExecuted = false; - sdInfo.state = SdStates::DONE; + sdInfo.state = SdStates::IDLE; sdInfo.cycleCount = 0; sdcMan->setBlocking(false); sdcMan->getSdCardActiveStatus(sdInfo.currentState); @@ -336,11 +341,100 @@ ReturnValue_t CoreController::sdStateMachine() { } } + if(sdInfo.state == SdStates::SET_STATE_FROM_COMMAND) { + if(not sdInfo.commandExecuted) { + executeNextExternalSdCommand(); + } + else { + checkExternalSdCommandStatus(); + } + } + sdInfo.cycleCount++; return HasReturnvaluesIF::RETURN_OK; #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } +void CoreController::executeNextExternalSdCommand() { + std::string sdChar; + sd::SdState currentStateOfCard = sd::SdState::OFF; + if(sdInfo.commandedCard == sd::SdCard::SLOT_0) { + sdChar = "0"; + currentStateOfCard = sdInfo.currentState.first; + } + else { + sdChar = "1"; + currentStateOfCard = sdInfo.currentState.second; + } + if(currentStateOfCard == sd::SdState::OFF) { + if(sdInfo.commandedState == sd::SdState::ON) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } + else if(sdInfo.commandedState == sd::SdState::MOUNTED) { + sdInfo.currentlyCommandedState = sd::SdState::ON; + } + else { + // SD card is already on target state + sdInfo.commandFinished = true; + sdInfo.state = SdStates::IDLE; + } + } + else if(currentStateOfCard == sd::SdState::ON) { + if(sdInfo.commandedState == sd::SdState::OFF or + sdInfo.commandedState == sd::SdState::MOUNTED) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } + else { + // Already on target state + sdInfo.commandFinished = true; + sdInfo.state = SdStates::IDLE; + } + } + else if(currentStateOfCard == sd::SdState::MOUNTED) { + if(sdInfo.commandedState == sd::SdState::ON) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } + else if(sdInfo.commandedState == sd::SdState::OFF) { + // This causes an unmount in sdCardSetup + sdInfo.currentlyCommandedState = sd::SdState::ON; + } + else { + sdInfo.commandFinished = true; + } + } + sdCardSetup(sdInfo.commandedCard, sdInfo.commandedState, sdChar); + sdInfo.commandExecuted = true; +} + +void CoreController::checkExternalSdCommandStatus() { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + if(sdInfo.currentlyCommandedState == sdInfo.commandedState) { + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; + sdInfo.commandFinished = true; + } + else { + // stay on same state machine state because the target state was not reached yet. + sdInfo.cycleCount = 0; + } + currentStateSetter(sdInfo.commandedCard, sdInfo.currentlyCommandedState); + sdInfo.commandExecuted = false; + } + else if(sdInfo.cycleCount > 4) { + sif::warning << "CoreController::sdStateMachine: Commanding SD state " + "takes too long" << std::endl; + } +} + +void CoreController::currentStateSetter(sd::SdCard sdCard, sd::SdState newState) { + if(sdCard == sd::SdCard::SLOT_0) { + sdInfo.currentState.first = newState; + } + else { + sdInfo.currentState.second = newState; + } +} ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, bool printOutput) { @@ -610,6 +704,7 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, if(RFlag) { oss << "R"; } + oss << " " << repoName << " > " << targetFileName; int result = std::system(oss.str().c_str()); if(result != 0) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index da587807..b26c99c5 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -77,12 +77,9 @@ private: SKIP_CYCLE_BEFORE_INFO_UPDATE, UPDATE_INFO, // SD initialization done - DONE, + IDLE, // Used if SD switches or mount commands are issued via telecommand SET_STATE_FROM_COMMAND, - MOUNT_FROM_COMMAND, - UNMOUNT_FROM_COMMAND, - }; static constexpr bool BLOCKING_SD_INIT = false; @@ -99,10 +96,15 @@ private: std::string prefChar = "0"; std::string otherChar = "1"; SdStates state = SdStates::START; + // Used to track whether a command was executed bool commandExecuted = true; bool initFinished = false; SdCardManager::SdStatePair currentState; uint16_t cycleCount = 0; + // These two flags are related to external commanding + bool commandIssued = false; + bool commandFinished = false; + sd::SdState currentlyCommandedState = sd::SdState::OFF; sd::SdCard commandedCard = sd::SdCard::NONE; sd::SdState commandedState = sd::SdState::OFF; }; @@ -113,7 +115,10 @@ private: ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, bool printOutput = true); ReturnValue_t sdColdRedundantBlockingInit(); + void currentStateSetter(sd::SdCard sdCard, sd::SdState newState); void determinePreferredSdCard(); + void executeNextExternalSdCommand(); + void checkExternalSdCommandStatus(); ReturnValue_t initVersionFile(); ReturnValue_t initBootCopy(); From 51dbc957504a7fd626f914d8a6b242f60be181a6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:39:53 +0200 Subject: [PATCH 11/21] fixes for NO_INIT code --- bsp_q7s/core/CoreController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b484c4cb..5f6c1ecc 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -146,8 +146,9 @@ ReturnValue_t CoreController::sdStateMachine() { if(sdInfo.state == SdStates::START) { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; - sdInfo.state == SdStates::IDLE; + sdInfo.state = SdStates::IDLE; sdInfo.initFinished = true; + return result; #else sdInfo.cycleCount = 0; sdInfo.commandExecuted = false; From 365fa0adc415970e56203603fa6259a139da0321 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:43:02 +0200 Subject: [PATCH 12/21] tweaks and fixes for state machine --- bsp_q7s/core/CoreController.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5f6c1ecc..f92e6d60 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -38,10 +38,11 @@ CoreController::CoreController(object_id_t objectId): if(sdcMan == nullptr) { sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } + if(not BLOCKING_SD_INIT) { - sdStateMachine(); sdcMan->setBlocking(false); } + sdStateMachine(); result = initBootCopy(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -59,7 +60,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(not BLOCKING_SD_INIT and not sdInfo.initFinished) { + if(not BLOCKING_SD_INIT) { sdStateMachine(); } performWatchdogControlOperation(); @@ -83,9 +84,8 @@ ReturnValue_t CoreController::initialize() { "count failed" << std::endl; } - if(not BLOCKING_SD_INIT) { - sdStateMachine(); - } + sdStateMachine(); + return ExtendedControllerBase::initialize(); } @@ -150,6 +150,13 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.initFinished = true; return result; #else + // Init will be performed by separate function + if(not BLOCKING_SD_INIT) { + sdInfo.state = SdStates::IDLE; + sdInfo.initFinished = true; + return result; + } +#endif sdInfo.cycleCount = 0; sdInfo.commandExecuted = false; sdInfo.state = SdStates::GET_INFO; From ea56a5d536f94657ffffc7db4280502c9e6f4ec8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:43:54 +0200 Subject: [PATCH 13/21] includes reordered --- bsp_q7s/core/CoreController.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index f92e6d60..f1144e4b 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -6,14 +6,13 @@ #include "fsfw/FSFWVersion.h" #include "fsfw/timemanager/Stopwatch.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/osal/linux/Timer.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" #else #include "fsfw/osal/common/TcpTmTcBridge.h" #endif -#include "fsfw/osal/linux/Timer.h" - #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" From e05c52be859c14aee9a2e15ae2108b626638b205 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:45:26 +0200 Subject: [PATCH 14/21] always performing state machine now --- bsp_q7s/core/CoreController.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index f1144e4b..d56c07ed 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -59,9 +59,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(not BLOCKING_SD_INIT) { - sdStateMachine(); - } + sdStateMachine(); performWatchdogControlOperation(); } From 0fecfab2f030dce892e2dbf139dc50a2ab71d76f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:46:24 +0200 Subject: [PATCH 15/21] minor formatting changes --- bsp_q7s/core/CoreController.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index d56c07ed..1fa1949e 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -82,8 +82,6 @@ ReturnValue_t CoreController::initialize() { } sdStateMachine(); - - return ExtendedControllerBase::initialize(); } From 22d7af4b7834e7bab860eea1cda605afe2e0d7c3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:49:04 +0200 Subject: [PATCH 16/21] always perform state machine in initAfterTaskCreation --- bsp_q7s/core/CoreController.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 1fa1949e..51c49485 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -530,11 +530,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; } } - else { - if(not sdInfo.initFinished) { - sdStateMachine(); - } - } + sdStateMachine(); result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; From 8cdb877df6538c76ae7bb6c7f34e67067300b597 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:50:45 +0200 Subject: [PATCH 17/21] removed endif block --- bsp_q7s/core/CoreController.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 51c49485..77ccbcbd 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -355,7 +355,6 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.cycleCount++; return HasReturnvaluesIF::RETURN_OK; -#endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } void CoreController::executeNextExternalSdCommand() { From 02a837c964dc74c5850bee268916e8ac5f11d03c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:59:21 +0200 Subject: [PATCH 18/21] tweaks for no-init variant --- bsp_q7s/core/CoreController.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 77ccbcbd..e1891de7 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -25,7 +25,8 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), + opDivider(5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { result = initWatchdogFifo(); @@ -91,16 +92,16 @@ ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, } ReturnValue_t CoreController::initSdCardBlocking() { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - return HasReturnvaluesIF::RETURN_OK; -#else // 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; } +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +#else result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -139,22 +140,22 @@ ReturnValue_t CoreController::sdStateMachine() { } if(sdInfo.state == SdStates::START) { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - sdInfo.state = SdStates::IDLE; - sdInfo.initFinished = true; - return result; -#else // Init will be performed by separate function - if(not BLOCKING_SD_INIT) { + if(BLOCKING_SD_INIT) { sdInfo.state = SdStates::IDLE; sdInfo.initFinished = true; return result; } + else { + // Still update SD state file +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sdInfo.state = SdStates::UPDATE_INFO; +#else + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; #endif - sdInfo.cycleCount = 0; - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::GET_INFO; + } } // This lambda checks the non-blocking operation and assigns the new state on success. @@ -502,7 +503,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS else { sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl; } -return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } From 891ba6881ba842c8d4a13c5a2dd8f80a4788627c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 13:00:11 +0200 Subject: [PATCH 19/21] reordered control operation --- bsp_q7s/core/CoreController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index e1891de7..33f2acd1 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -60,8 +60,8 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - sdStateMachine(); performWatchdogControlOperation(); + sdStateMachine(); } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, From f56c8ba1c0c6bc5c4b7696858ecb947fa4e49755 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 11:00:58 +0200 Subject: [PATCH 20/21] minor fixes and additional printout --- bsp_q7s/core/CoreController.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 33f2acd1..606646bf 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -205,6 +205,17 @@ ReturnValue_t CoreController::sdStateMachine() { static_cast(sdInfo.pref) << std::endl; #endif if(sdInfo.prefState == sd::SdState::MOUNTED) { +#if OBSW_VERBOSE_LEVEL >= 1 + std::string mountString; + if(sdInfo.pref == sd::SdCard::SLOT_0) { + mountString = SdCardManager::SD_0_MOUNT_POINT; + } + else { + mountString = SdCardManager::SD_1_MOUNT_POINT; + } + sif::info << "SD card " << sdInfo.prefChar << " already on and mounted at " << + mountString << std::endl; +#endif sdInfo.state = SdStates::DETERMINE_OTHER; } else if(sdInfo.prefState == sd::SdState::OFF) { @@ -216,9 +227,10 @@ ReturnValue_t CoreController::sdStateMachine() { } } else { - nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state"); - sdInfo.prefState = sd::SdState::ON; - currentStateSetter(sdInfo.pref, sd::SdState::ON); + if(nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) { + sdInfo.prefState = sd::SdState::ON; + currentStateSetter(sdInfo.pref, sd::SdState::ON); + } } } @@ -284,10 +296,11 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, - "Switching on other SD card"); - sdInfo.otherState = sd::SdState::ON; - currentStateSetter(sdInfo.other, sd::SdState::ON); + if(nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, + "Switching on other SD card")) { + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); + } } #endif } From 4a74a3ac3738b30404a5b614a17673670db554a6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 11:24:59 +0200 Subject: [PATCH 21/21] API change fix --- mission/devices/PlocUpdater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp index bb09a1c6..f890c239 100644 --- a/mission/devices/PlocUpdater.cpp +++ b/mission/devices/PlocUpdater.cpp @@ -174,7 +174,7 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { } bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatusPair active; + SdCardManager::SdStatePair active; ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); if (result != RETURN_OK) { sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state";