Improve SD card manager #454

Merged
muellerr merged 4 commits from improve_sd_card_manager into develop 2023-03-10 11:36:37 +01:00
4 changed files with 67 additions and 54 deletions

View File

@ -22,6 +22,10 @@ will consitute of a breaking change warranting a new major release:
## Changed ## Changed
- More fixes and improvements for SD card handling. Extend SD card setup in core controller to
create full initial state for SD card manager are core controller as early as possible, turn
execution of setup file update blocking. This might solve the issue with the SD card manager
sometimes blocking for a long time.
- Request raw MTM measurement twice for IMTQ, might reduce number of times measurement could not - Request raw MTM measurement twice for IMTQ, might reduce number of times measurement could not
be retrieved. be retrieved.

View File

@ -42,6 +42,12 @@ CoreController::CoreController(object_id_t objectId)
if (not BLOCKING_SD_INIT) { if (not BLOCKING_SD_INIT) {
sdcMan->setBlocking(false); sdcMan->setBlocking(false);
} }
// 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(); auto sdCard = sdcMan->getPreferredSdCard();
if (not sdCard.has_value()) { if (not sdCard.has_value()) {
sif::error << "CoreController::initializeAfterTaskCreation: " sif::error << "CoreController::initializeAfterTaskCreation: "
@ -50,7 +56,11 @@ CoreController::CoreController(object_id_t objectId)
sdCard = sd::SdCard::SLOT_0; sdCard = sd::SdCard::SLOT_0;
} }
sdInfo.active = sdCard.value(); sdInfo.active = sdCard.value();
sdcMan->setActiveSdCard(sdInfo.active); if (sdStates.first == sd::SdState::MOUNTED) {
sdcMan->setActiveSdCard(sd::SdCard::SLOT_0);
} else if (sdStates.second == sd::SdState::MOUNTED) {
sdcMan->setActiveSdCard(sd::SdCard::SLOT_1);
}
currMntPrefix = sdcMan->getCurrentMountPrefix(); currMntPrefix = sdcMan->getCurrentMountPrefix();
getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY); getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY);
@ -400,7 +410,9 @@ ReturnValue_t CoreController::sdStateMachine() {
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed" sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
<< std::endl; << std::endl;
} }
sdInfo.commandExecuted = true; sdFsmState = SdStates::SET_STATE_SELF;
sdInfo.commandExecuted = false;
sdInfo.cycleCount = 0;
} else { } else {
nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file"); nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file");
} }
@ -543,10 +555,6 @@ ReturnValue_t CoreController::sdStateMachine() {
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) { if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
sdFsmState = SdStates::UPDATE_INFO; sdFsmState = SdStates::UPDATE_INFO;
} else if (sdFsmState == SdStates::UPDATE_INFO) { } else if (sdFsmState == 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 // Update status file
result = sdcMan->updateSdCardStateFile(); result = sdcMan->updateSdCardStateFile();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {

View File

@ -195,29 +195,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
return result; return result;
} }
ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& active) { ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& sdStates) {
using namespace std;
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
std::error_code e; sdStates = this->sdStates;
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(active, line, idx, currentSd);
}
if (active.first != sd::SdState::MOUNTED && active.second != sd::SdState::MOUNTED) {
sdCardActive = false;
}
return returnvalue::OK; return returnvalue::OK;
} }
@ -309,10 +289,9 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard p
resetNonBlockingState = true; resetNonBlockingState = true;
} }
if (statusPair == nullptr) { if (statusPair == nullptr) {
sdStatusPtr = std::make_unique<SdStatePair>(); return returnvalue::FAILED;
statusPair = sdStatusPtr.get();
getSdCardsStatus(*statusPair);
} }
getSdCardsStatus(*statusPair);
if (statusPair->first == sd::SdState::ON) { if (statusPair->first == sd::SdState::ON) {
result = mountSdCard(prefSdCard); result = mountSdCard(prefSdCard);
@ -330,8 +309,34 @@ void SdCardManager::resetState() {
currentOp = Operations::IDLE; currentOp = Operations::IDLE;
} }
void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& active, ReturnValue_t SdCardManager::updateSdStatePair() {
std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std;
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
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; using namespace std;
istringstream iss(line); istringstream iss(line);
string word; string word;
@ -352,24 +357,24 @@ void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& act
if (word == "on") { if (word == "on") {
if (currentSd == sd::SdCard::SLOT_0) { if (currentSd == sd::SdCard::SLOT_0) {
active.first = sd::SdState::ON; sdStates.first = sd::SdState::ON;
} else { } else {
active.second = sd::SdState::ON; sdStates.second = sd::SdState::ON;
} }
} else if (word == "off") { } else if (word == "off") {
if (currentSd == sd::SdCard::SLOT_0) { if (currentSd == sd::SdCard::SLOT_0) {
active.first = sd::SdState::OFF; sdStates.first = sd::SdState::OFF;
} else { } else {
active.second = sd::SdState::OFF; sdStates.second = sd::SdState::OFF;
} }
} }
} }
if (mountLine) { if (mountLine) {
if (currentSd == sd::SdCard::SLOT_0) { if (currentSd == sd::SdCard::SLOT_0) {
active.first = sd::SdState::MOUNTED; sdStates.first = sd::SdState::MOUNTED;
} else { } else {
active.second = sd::SdState::MOUNTED; sdStates.second = sd::SdState::MOUNTED;
} }
} }
@ -407,7 +412,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
// Use q7hw utility and pipe the command output into the state file // Use q7hw utility and pipe the command output into the state file
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
cmdExecutor.load(updateCmd, blocking, printCmdOutput); cmdExecutor.load(updateCmd, true, printCmdOutput);
ReturnValue_t result = cmdExecutor.execute(); ReturnValue_t result = cmdExecutor.execute();
if (blocking and result != returnvalue::OK) { if (blocking and result != returnvalue::OK) {
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
@ -475,35 +480,29 @@ bool SdCardManager::isSdCardUsable(std::optional<sd::SdCard> sdCard) {
} }
} }
SdCardManager::SdStatePair active; MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
ReturnValue_t result = this->getSdCardsStatus(active);
if (result != returnvalue::OK) {
sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state";
return false;
}
if (not sdCard) { if (not sdCard) {
if (active.first == sd::MOUNTED or active.second == sd::MOUNTED) { if (sdStates.first == sd::MOUNTED or sdStates.second == sd::MOUNTED) {
return true; return true;
} }
return false; return false;
} }
if (sdCard == sd::SLOT_0) { if (sdCard == sd::SLOT_0) {
if (active.first == sd::MOUNTED) { if (sdStates.first == sd::MOUNTED) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
if (sdCard == sd::SLOT_1) { if (sdCard == sd::SLOT_1) {
if (active.second == sd::MOUNTED) { if (sdStates.second == sd::MOUNTED) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
if (sdCard == sd::BOTH) { if (sdCard == sd::BOTH) {
if (active.first == sd::MOUNTED && active.second == sd::MOUNTED) { if (sdStates.first == sd::MOUNTED && sdStates.second == sd::MOUNTED) {
return true; return true;
} }
} }

View File

@ -25,7 +25,7 @@ class MutexIF;
* state * state
*/ */
class SdCardManager : public SystemObject, public SdCardMountedIF { class SdCardManager : public SystemObject, public SdCardMountedIF {
friend class SdCardAccess; friend class CoreController;
public: public:
using mountInitCb = ReturnValue_t (*)(void* args); using mountInitCb = ReturnValue_t (*)(void* args);
@ -218,6 +218,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
private: private:
CommandExecutor cmdExecutor; CommandExecutor cmdExecutor;
SdStatePair sdStates;
Operations currentOp = Operations::IDLE; Operations currentOp = Operations::IDLE;
bool blocking = false; bool blocking = false;
bool sdCardActive = true; bool sdCardActive = true;
@ -233,10 +234,11 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
SdCardManager(); SdCardManager();
ReturnValue_t updateSdStatePair();
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx, void processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd);
sd::SdCard& currentSd);
std::optional<std::string> currentPrefix; std::optional<std::string> currentPrefix;