|
|
@ -554,21 +554,23 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// This lambda checks the non-blocking operation of the SD card manager and assigns the new
|
|
|
|
// This lambda checks the non-blocking operation of the SD card manager and assigns the new
|
|
|
|
// state on success. It returns true for an operation success and false otherwise
|
|
|
|
// state on success. It returns 0 for an operation success, -1 for failed operations, and 1
|
|
|
|
|
|
|
|
// for pending operations
|
|
|
|
auto nonBlockingSdcOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
|
|
|
auto nonBlockingSdcOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
|
|
|
std::string opPrintout) {
|
|
|
|
std::string opPrintout) {
|
|
|
|
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
|
|
|
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
|
|
|
if (status == SdCardManager::OpStatus::SUCCESS) {
|
|
|
|
if (status == SdCardManager::OpStatus::SUCCESS or sdInfo.cycleCount > 4) {
|
|
|
|
sdFsmState = newStateOnSuccess;
|
|
|
|
sdFsmState = newStateOnSuccess;
|
|
|
|
sdInfo.commandPending = false;
|
|
|
|
sdInfo.commandPending = false;
|
|
|
|
sdInfo.cycleCount = 0;
|
|
|
|
sdInfo.cycleCount = 0;
|
|
|
|
return true;
|
|
|
|
if (sdInfo.cycleCount > 4) {
|
|
|
|
} else if (sdInfo.cycleCount > 4) {
|
|
|
|
|
|
|
|
sif::warning << "CoreController::sdStateMachine: " << opPrintout << " takes too long"
|
|
|
|
sif::warning << "CoreController::sdStateMachine: " << opPrintout << " takes too long"
|
|
|
|
<< std::endl;
|
|
|
|
<< std::endl;
|
|
|
|
return false;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (sdFsmState == SdStates::UPDATE_SD_INFO_START) {
|
|
|
|
if (sdFsmState == SdStates::UPDATE_SD_INFO_START) {
|
|
|
@ -644,7 +646,7 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
sdFsmState = tgtState;
|
|
|
|
sdFsmState = tgtState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state") <= 0) {
|
|
|
|
sdInfo.activeState = sd::SdState::ON;
|
|
|
|
sdInfo.activeState = sd::SdState::ON;
|
|
|
|
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
|
|
|
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
|
|
|
// Skip the two cycles now.
|
|
|
|
// Skip the two cycles now.
|
|
|
@ -672,7 +674,7 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
|
|
|
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card") <= 0) {
|
|
|
|
sdcMan->setActiveSdCard(sdInfo.active);
|
|
|
|
sdcMan->setActiveSdCard(sdInfo.active);
|
|
|
|
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
|
|
|
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
|
|
|
sdInfo.activeState = sd::SdState::MOUNTED;
|
|
|
|
sdInfo.activeState = sd::SdState::MOUNTED;
|
|
|
@ -714,12 +716,7 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
|
|
|
"Switching off other SD card")) {
|
|
|
|
"Switching off other SD card") <= 0) {
|
|
|
|
sdInfo.otherState = sd::SdState::OFF;
|
|
|
|
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Continue.. avoid being stuck here..
|
|
|
|
|
|
|
|
sdFsmState = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE;
|
|
|
|
|
|
|
|
sdInfo.otherState = sd::SdState::OFF;
|
|
|
|
sdInfo.otherState = sd::SdState::OFF;
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -730,12 +727,7 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
|
|
|
"Switching on other SD card")) {
|
|
|
|
"Switching on other SD card") <= 0) {
|
|
|
|
sdInfo.otherState = sd::SdState::ON;
|
|
|
|
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Contnue.. avoid being stuck here.
|
|
|
|
|
|
|
|
sdFsmState = SdStates::MOUNT_UNMOUNT_OTHER;
|
|
|
|
|
|
|
|
sdInfo.otherState = sd::SdState::ON;
|
|
|
|
sdInfo.otherState = sd::SdState::ON;
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -750,7 +742,8 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
|
|
|
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card") <=
|
|
|
|
|
|
|
|
0) {
|
|
|
|
sdInfo.otherState = sd::SdState::ON;
|
|
|
|
sdInfo.otherState = sd::SdState::ON;
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -764,7 +757,8 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|
|
|
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
|
|
|
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
sdInfo.commandPending = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::UPDATE_SD_INFO_END, 4, "Mounting other SD card")) {
|
|
|
|
if (nonBlockingSdcOpChecking(SdStates::UPDATE_SD_INFO_END, 4, "Mounting other SD card") <=
|
|
|
|
|
|
|
|
0) {
|
|
|
|
sdInfo.otherState = sd::SdState::MOUNTED;
|
|
|
|
sdInfo.otherState = sd::SdState::MOUNTED;
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
|
|
|
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -840,7 +834,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS
|
|
|
|
if (state == sd::SdState::MOUNTED) {
|
|
|
|
if (state == sd::SdState::MOUNTED) {
|
|
|
|
if (targetState == sd::SdState::OFF) {
|
|
|
|
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);
|
|
|
|
return sdcMan->switchOffSdCard(sdCard, sdInfo.currentState, true);
|
|
|
|
} else if (targetState == sd::SdState::ON) {
|
|
|
|
} else if (targetState == sd::SdState::ON) {
|
|
|
|
sif::info << "Unmounting SD card " << sdChar << std::endl;
|
|
|
|
sif::info << "Unmounting SD card " << sdChar << std::endl;
|
|
|
|
return sdcMan->unmountSdCard(sdCard);
|
|
|
|
return sdcMan->unmountSdCard(sdCard);
|
|
|
@ -874,7 +868,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS
|
|
|
|
return sdcMan->mountSdCard(sdCard);
|
|
|
|
return sdcMan->mountSdCard(sdCard);
|
|
|
|
} else if (targetState == sd::SdState::OFF) {
|
|
|
|
} 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);
|
|
|
|
return sdcMan->switchOffSdCard(sdCard, sdInfo.currentState, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl;
|
|
|
|
sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl;
|
|
|
@ -898,8 +892,7 @@ ReturnValue_t CoreController::sdColdRedundantBlockingInit() {
|
|
|
|
sif::info << "Switching off secondary SD card " << sdInfo.otherChar << std::endl;
|
|
|
|
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
|
|
|
|
// Switch off other SD card in cold redundant mode if setting up preferred one worked
|
|
|
|
// without issues
|
|
|
|
// without issues
|
|
|
|
ReturnValue_t result2 =
|
|
|
|
ReturnValue_t result2 = sdcMan->switchOffSdCard(sdInfo.other, sdInfo.currentState, true);
|
|
|
|
sdcMan->switchOffSdCard(sdInfo.other, sdInfo.otherState, &sdInfo.currentState);
|
|
|
|
|
|
|
|
if (result2 != returnvalue::OK and result2 != SdCardManager::ALREADY_OFF) {
|
|
|
|
if (result2 != returnvalue::OK and result2 != SdCardManager::ALREADY_OFF) {
|
|
|
|
sif::warning << "Switching off secondary SD card " << sdInfo.otherChar
|
|
|
|
sif::warning << "Switching off secondary SD card " << sdInfo.otherChar
|
|
|
|
<< " in cold redundant mode failed" << std::endl;
|
|
|
|
<< " in cold redundant mode failed" << std::endl;
|
|
|
@ -1230,7 +1223,7 @@ ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy co
|
|
|
|
sync();
|
|
|
|
sync();
|
|
|
|
|
|
|
|
|
|
|
|
// Unmount and switch off SD cards. This could possibly fix issues with the SD card and is
|
|
|
|
// Unmount and switch off SD cards. This could possibly fix issues with the SD card and is
|
|
|
|
// the more graceful way to reboot the system.
|
|
|
|
// the more graceful way to reboot the system. This function takes around 400 ms.
|
|
|
|
ReturnValue_t result = handleSwitchingSdCardsOffNonBlocking();
|
|
|
|
ReturnValue_t result = handleSwitchingSdCardsOffNonBlocking();
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
sif::error
|
|
|
|
sif::error
|
|
|
@ -1247,6 +1240,8 @@ ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy co
|
|
|
|
// and a reboot is imminent. Use scratch buffer?
|
|
|
|
// and a reboot is imminent. Use scratch buffer?
|
|
|
|
sif::info << "Running slot was writeprotected before reboot" << std::endl;
|
|
|
|
sif::info << "Running slot was writeprotected before reboot" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that all diagnostic prinouts arrive.
|
|
|
|
|
|
|
|
TaskFactory::delayTask(50);
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2590,9 +2585,6 @@ void CoreController::announceSdInfo(SdCardManager::SdStatePair sdStates) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ReturnValue_t CoreController::handleSwitchingSdCardsOffNonBlocking() {
|
|
|
|
ReturnValue_t CoreController::handleSwitchingSdCardsOffNonBlocking() {
|
|
|
|
Countdown maxWaitTimeCd(10000);
|
|
|
|
|
|
|
|
Stopwatch watch;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sdcMan->setBlocking(false);
|
|
|
|
sdcMan->setBlocking(false);
|
|
|
|
SdCardManager::Operations op;
|
|
|
|
SdCardManager::Operations op;
|
|
|
|
std::pair<sd::SdState, sd::SdState> sdStatus;
|
|
|
|
std::pair<sd::SdState, sd::SdState> sdStatus;
|
|
|
@ -2600,42 +2592,46 @@ ReturnValue_t CoreController::handleSwitchingSdCardsOffNonBlocking() {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Countdown maxWaitTimeCd(10000);
|
|
|
|
|
|
|
|
// Stopwatch watch;
|
|
|
|
auto waitingForFinish = [&]() {
|
|
|
|
auto waitingForFinish = [&]() {
|
|
|
|
while (sdcMan->checkCurrentOp(op) == SdCardManager::OpStatus::ONGOING) {
|
|
|
|
auto currentState = sdcMan->checkCurrentOp(op);
|
|
|
|
TaskFactory::delayTask(50);
|
|
|
|
if (currentState == SdCardManager::OpStatus::IDLE) {
|
|
|
|
|
|
|
|
return returnvalue::OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
while (currentState == SdCardManager::OpStatus::ONGOING) {
|
|
|
|
if (maxWaitTimeCd.hasTimedOut()) {
|
|
|
|
if (maxWaitTimeCd.hasTimedOut()) {
|
|
|
|
return returnvalue::FAILED;
|
|
|
|
return returnvalue::FAILED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TaskFactory::delayTask(50);
|
|
|
|
|
|
|
|
currentState = sdcMan->checkCurrentOp(op);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return returnvalue::OK;
|
|
|
|
return returnvalue::OK;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
sif::debug << "hello 0" << std::endl;
|
|
|
|
|
|
|
|
if (sdStatus.first != sd::SdState::OFF) {
|
|
|
|
if (sdStatus.first != sd::SdState::OFF) {
|
|
|
|
sdcMan->unmountSdCard(sd::SdCard::SLOT_0);
|
|
|
|
sdcMan->unmountSdCard(sd::SdCard::SLOT_0);
|
|
|
|
result = waitingForFinish();
|
|
|
|
result = waitingForFinish();
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sdcMan->switchOffSdCard(sd::SdCard::SLOT_0, false);
|
|
|
|
sdcMan->switchOffSdCard(sd::SdCard::SLOT_0, sdStatus, false);
|
|
|
|
result = waitingForFinish();
|
|
|
|
result = waitingForFinish();
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sif::debug << "hello 1" << std::endl;
|
|
|
|
|
|
|
|
if (sdStatus.second != sd::SdState::OFF) {
|
|
|
|
if (sdStatus.second != sd::SdState::OFF) {
|
|
|
|
sdcMan->unmountSdCard(sd::SdCard::SLOT_1);
|
|
|
|
sdcMan->unmountSdCard(sd::SdCard::SLOT_1);
|
|
|
|
result = waitingForFinish();
|
|
|
|
result = waitingForFinish();
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sdcMan->switchOffSdCard(sd::SdCard::SLOT_1, false);
|
|
|
|
sdcMan->switchOffSdCard(sd::SdCard::SLOT_1, sdStatus, false);
|
|
|
|
result = waitingForFinish();
|
|
|
|
result = waitingForFinish();
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sif::debug << "hello 2" << std::endl;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|