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;