bugfix and simplifications for SDC state machine
This commit is contained in:
parent
310f8f5f3c
commit
10f552f56a
@ -54,7 +54,6 @@ CoreController::CoreController(object_id_t objectId, bool enableHkSet)
|
||||
// Set up state of SD card manager and own initial state.
|
||||
// Stopwatch watch;
|
||||
sdcMan->updateSdCardStateFile();
|
||||
sdcMan->updateSdStatePair();
|
||||
SdCardManager::SdStatePair sdStates;
|
||||
sdcMan->getSdCardsStatus(sdStates);
|
||||
auto sdCard = sdcMan->getPreferredSdCard();
|
||||
@ -368,7 +367,7 @@ ReturnValue_t CoreController::initSdCardBlocking() {
|
||||
}
|
||||
|
||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||
updateSdInfoOther();
|
||||
updateInternalSdInfo();
|
||||
sif::info << "Cold redundant SD card configuration, preferred SD card: "
|
||||
<< static_cast<int>(sdInfo.active) << std::endl;
|
||||
result = sdColdRedundantBlockingInit();
|
||||
@ -404,23 +403,23 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
} else {
|
||||
// Still update SD state file
|
||||
if (sdInfo.cfgMode == SdCfgMode::PASSIVE) {
|
||||
sdFsmState = SdStates::UPDATE_INFO;
|
||||
sdFsmState = SdStates::UPDATE_SD_INFO_END;
|
||||
} else {
|
||||
sdInfo.cycleCount = 0;
|
||||
sdInfo.commandExecuted = false;
|
||||
sdFsmState = SdStates::GET_INFO;
|
||||
sdInfo.commandPending = false;
|
||||
sdFsmState = SdStates::UPDATE_SD_INFO_START;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// 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
|
||||
auto nonBlockingSdcOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
||||
std::string opPrintout) {
|
||||
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
||||
if (status == SdCardManager::OpStatus::SUCCESS) {
|
||||
sdFsmState = newStateOnSuccess;
|
||||
sdInfo.commandExecuted = false;
|
||||
sdInfo.commandPending = false;
|
||||
sdInfo.cycleCount = 0;
|
||||
return true;
|
||||
} else if (sdInfo.cycleCount > 4) {
|
||||
@ -431,26 +430,16 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
return false;
|
||||
};
|
||||
|
||||
if (sdFsmState == SdStates::GET_INFO) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
if (sdFsmState == SdStates::UPDATE_SD_INFO_START) {
|
||||
if (not sdInfo.commandPending) {
|
||||
// Create updated status file
|
||||
result = sdcMan->updateSdCardStateFile();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
|
||||
<< std::endl;
|
||||
}
|
||||
sdFsmState = SdStates::SET_STATE_SELF;
|
||||
sdInfo.commandExecuted = false;
|
||||
sdInfo.cycleCount = 0;
|
||||
} else {
|
||||
nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file");
|
||||
}
|
||||
}
|
||||
|
||||
if (sdFsmState == SdStates::SET_STATE_SELF) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
result = sdcMan->getSdCardsStatus(sdInfo.currentState);
|
||||
updateSdInfoOther();
|
||||
updateInternalSdInfo();
|
||||
if (sdInfo.active != sd::SdCard::SLOT_0 and sdInfo.active != sd::SdCard::SLOT_1) {
|
||||
sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl;
|
||||
sdInfo.active = sd::SdCard::SLOT_0;
|
||||
@ -478,12 +467,12 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
sdFsmState = SdStates::DETERMINE_OTHER;
|
||||
} else if (sdInfo.activeState == sd::SdState::OFF) {
|
||||
sdCardSetup(sdInfo.active, sd::SdState::ON, sdInfo.activeChar, false);
|
||||
sdInfo.commandExecuted = true;
|
||||
sdInfo.commandPending = true;
|
||||
} else if (sdInfo.activeState == sd::SdState::ON) {
|
||||
sdFsmState = SdStates::MOUNT_SELF;
|
||||
}
|
||||
} else {
|
||||
if (nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
||||
if (nonBlockingSdcOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
||||
sdInfo.activeState = sd::SdState::ON;
|
||||
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
||||
}
|
||||
@ -491,11 +480,11 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
}
|
||||
|
||||
if (sdFsmState == SdStates::MOUNT_SELF) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
if (not sdInfo.commandPending) {
|
||||
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
||||
sdInfo.commandExecuted = true;
|
||||
sdInfo.commandPending = true;
|
||||
} else {
|
||||
if (nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
||||
if (nonBlockingSdcOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
||||
sdcMan->setActiveSdCard(sdInfo.active);
|
||||
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
||||
sdInfo.activeState = sd::SdState::MOUNTED;
|
||||
@ -532,23 +521,23 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
if (sdFsmState == SdStates::SET_STATE_OTHER) {
|
||||
// Set state of other SD card to ON or OFF, depending on redundancy mode
|
||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
if (not sdInfo.commandPending) {
|
||||
result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false);
|
||||
sdInfo.commandExecuted = true;
|
||||
sdInfo.commandPending = true;
|
||||
} else {
|
||||
if (nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
||||
"Switching off other SD card")) {
|
||||
if (nonBlockingSdcOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
||||
"Switching off other SD card")) {
|
||||
sdInfo.otherState = sd::SdState::OFF;
|
||||
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
||||
}
|
||||
}
|
||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
if (not sdInfo.commandPending) {
|
||||
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false);
|
||||
sdInfo.commandExecuted = true;
|
||||
sdInfo.commandPending = true;
|
||||
} else {
|
||||
if (nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
||||
"Switching on other SD card")) {
|
||||
if (nonBlockingSdcOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
||||
"Switching on other SD card")) {
|
||||
sdInfo.otherState = sd::SdState::ON;
|
||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||
}
|
||||
@ -559,21 +548,25 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
if (sdFsmState == SdStates::MOUNT_UNMOUNT_OTHER) {
|
||||
// Mount or unmount other SD card, depending on redundancy mode
|
||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
if (not sdInfo.commandPending) {
|
||||
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
||||
sdInfo.commandExecuted = true;
|
||||
sdInfo.commandPending = true;
|
||||
} else {
|
||||
if (nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
||||
if (nonBlockingSdcOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
||||
sdInfo.otherState = sd::SdState::ON;
|
||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||
} else {
|
||||
sdInfo.otherState = sd::SdState::ON;
|
||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||
sdFsmState = SdStates::SET_STATE_OTHER;
|
||||
}
|
||||
}
|
||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||
if (not sdInfo.commandExecuted) {
|
||||
if (not sdInfo.commandPending) {
|
||||
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
||||
sdInfo.commandExecuted = true;
|
||||
sdInfo.commandPending = true;
|
||||
} else {
|
||||
if (nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) {
|
||||
if (nonBlockingSdcOpChecking(SdStates::UPDATE_SD_INFO_END, 4, "Mounting other SD card")) {
|
||||
sdInfo.otherState = sd::SdState::MOUNTED;
|
||||
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
||||
}
|
||||
@ -582,14 +575,15 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
}
|
||||
|
||||
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
|
||||
sdFsmState = SdStates::UPDATE_INFO;
|
||||
} else if (sdFsmState == SdStates::UPDATE_INFO) {
|
||||
sdFsmState = SdStates::UPDATE_SD_INFO_END;
|
||||
} else if (sdFsmState == SdStates::UPDATE_SD_INFO_END) {
|
||||
// Update status file
|
||||
result = sdcMan->updateSdCardStateFile();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "CoreController: Updating SD card state file failed" << std::endl;
|
||||
}
|
||||
sdInfo.commandExecuted = false;
|
||||
updateInternalSdInfo();
|
||||
sdInfo.commandPending = false;
|
||||
sdFsmState = SdStates::IDLE;
|
||||
sdInfo.cycleCount = 0;
|
||||
sdcMan->setBlocking(false);
|
||||
@ -599,9 +593,16 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
actionHelper.finish(true, sdCommandingInfo.commander, sdCommandingInfo.actionId,
|
||||
returnvalue::OK);
|
||||
}
|
||||
sif::info << "SD card update finished" << std::endl;
|
||||
const char *modeStr = "UNKNOWN";
|
||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||
modeStr = "COLD REDUNDANT";
|
||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||
modeStr = "HOT REDUNDANT";
|
||||
}
|
||||
sif::info << "SD card update into " << modeStr
|
||||
<< " mode finished. Active SD: " << sdInfo.activeChar << std::endl;
|
||||
if (not sdInfo.initFinished) {
|
||||
updateSdInfoOther();
|
||||
updateInternalSdInfo();
|
||||
sdInfo.initFinished = true;
|
||||
sif::info << "SD card initialization finished" << std::endl;
|
||||
}
|
||||
@ -978,7 +979,7 @@ ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy co
|
||||
return result;
|
||||
}
|
||||
|
||||
void CoreController::updateSdInfoOther() {
|
||||
void CoreController::updateInternalSdInfo() {
|
||||
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
||||
sdInfo.activeChar = "0";
|
||||
sdInfo.otherChar = "1";
|
||||
|
@ -129,8 +129,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
enum class SdStates {
|
||||
NONE,
|
||||
START,
|
||||
GET_INFO,
|
||||
SET_STATE_SELF,
|
||||
UPDATE_SD_INFO_START,
|
||||
MOUNT_SELF,
|
||||
// Determine operations for other SD card, depending on redundancy configuration
|
||||
DETERMINE_OTHER,
|
||||
@ -140,7 +139,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
// 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,
|
||||
UPDATE_SD_INFO_END,
|
||||
// SD initialization done
|
||||
IDLE
|
||||
};
|
||||
@ -159,13 +158,12 @@ class CoreController : public ExtendedControllerBase {
|
||||
SdCfgMode cfgMode = SdCfgMode::COLD_REDUNDANT;
|
||||
sd::SdCard active = sd::SdCard::NONE;
|
||||
sd::SdCard other = sd::SdCard::NONE;
|
||||
sd::SdState activeState = sd::SdState::OFF;
|
||||
sd::SdState otherState = sd::SdState::OFF;
|
||||
std::string activeChar = "0";
|
||||
std::string otherChar = "1";
|
||||
sd::SdState activeState = sd::SdState::OFF;
|
||||
sd::SdState otherState = sd::SdState::OFF;
|
||||
std::pair<bool, bool> mountSwitch = {true, true};
|
||||
// Used to track whether a command was executed
|
||||
bool commandExecuted = true;
|
||||
bool commandPending = true;
|
||||
bool initFinished = false;
|
||||
SdCardManager::SdStatePair currentState;
|
||||
uint16_t cycleCount = 0;
|
||||
@ -232,7 +230,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
void initPrint();
|
||||
|
||||
ReturnValue_t sdStateMachine();
|
||||
void updateSdInfoOther();
|
||||
void updateInternalSdInfo();
|
||||
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
||||
bool printOutput = true);
|
||||
ReturnValue_t executeSwUpdate(SwUpdateSources sourceDir, const uint8_t* data, size_t size);
|
||||
|
@ -309,32 +309,6 @@ void SdCardManager::resetState() {
|
||||
currentOp = Operations::IDLE;
|
||||
}
|
||||
|
||||
ReturnValue_t SdCardManager::updateSdStatePair() {
|
||||
using namespace std;
|
||||
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
|
||||
// Now the file should exist in any case. Still check whether it exists.
|
||||
fstream sdStatus(SD_STATE_FILE);
|
||||
if (not sdStatus.good()) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
string line;
|
||||
uint8_t idx = 0;
|
||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||
// Process status file line by line
|
||||
while (std::getline(sdStatus, line)) {
|
||||
processSdStatusLine(line, idx, currentSd);
|
||||
}
|
||||
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
||||
sdCardActive = false;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
||||
using namespace std;
|
||||
istringstream iss(line);
|
||||
@ -407,6 +381,7 @@ ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
|
||||
}
|
||||
|
||||
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||
using namespace std;
|
||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||
return CommandExecutor::COMMAND_PENDING;
|
||||
}
|
||||
@ -414,10 +389,31 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
||||
cmdExecutor.load(updateCmd, true, printCmdOutput);
|
||||
ReturnValue_t result = cmdExecutor.execute();
|
||||
if (blocking and result != returnvalue::OK) {
|
||||
if (result != returnvalue::OK) {
|
||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
||||
}
|
||||
return result;
|
||||
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
|
||||
// Now the file should exist in any case. Still check whether it exists.
|
||||
fstream sdStatus(SD_STATE_FILE);
|
||||
if (not sdStatus.good()) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
string line;
|
||||
uint8_t idx = 0;
|
||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||
// Process status file line by line
|
||||
while (std::getline(sdStatus, line)) {
|
||||
processSdStatusLine(line, idx, currentSd);
|
||||
}
|
||||
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
||||
sdCardActive = false;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
const char* SdCardManager::getCurrentMountPrefix() const {
|
||||
|
@ -117,16 +117,6 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
||||
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
||||
SdStatePair* statusPair = nullptr);
|
||||
|
||||
/**
|
||||
* Update the state file or creates one if it does not exist. You need to call this
|
||||
* function before calling #sdCardActive
|
||||
* @return
|
||||
* - returnvalue::OK if the state file was updated successfully
|
||||
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
||||
* - returnvalue::FAILED: blocking command failed
|
||||
*/
|
||||
ReturnValue_t updateSdCardStateFile();
|
||||
|
||||
/**
|
||||
* Get the state of the SD cards. If the state file does not exist, this function will
|
||||
* take care of updating it. If it does not, the function will use the state file to get
|
||||
@ -234,7 +224,15 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
||||
|
||||
SdCardManager();
|
||||
|
||||
ReturnValue_t updateSdStatePair();
|
||||
/**
|
||||
* Update the state file or creates one if it does not exist. You need to call this
|
||||
* function before calling #sdCardActive
|
||||
* @return
|
||||
* - returnvalue::OK if the state file was updated successfully
|
||||
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
||||
* - returnvalue::FAILED: blocking command failed
|
||||
*/
|
||||
ReturnValue_t updateSdCardStateFile();
|
||||
|
||||
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
||||
|
||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
||||
Subproject commit 92ce64cd39fb5d74af1358a436113322d9711dfb
|
||||
Subproject commit 43b530cdb7dfe6774962bf4b8a880e1c9a6e6580
|
Loading…
Reference in New Issue
Block a user