cold redundant and hot redundant configuration

This commit is contained in:
Robin Müller 2021-07-12 14:32:20 +02:00
parent a15e0bbaa5
commit bd505f35e2
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
7 changed files with 149 additions and 45 deletions

View File

@ -4,6 +4,17 @@
#include <cstdint>
#cmakedefine01 Q7S_SIMPLE_MODE
#define Q7S_SD_NONE 0
#define Q7S_SD_COLD_REDUNDANT 1
#define Q7S_SD_HOT_REDUNDANT 2
// The OBSW will perform different actions to set up the SD cards depending on the flag set here
// Set to Q7S_SD_NONE: Don't do anything
// Set to Q7S_COLD_REDUNDANT: On startup, get the prefered SD card, turn it on and mount it, and
// turn off the second SD card if it is on
// Set to Q7S_HOT_REDUNDANT: On startup, turn on both SD cards and mount them
#define Q7S_SD_CARD_CONFIG 1
#define Q7S_ADD_RTD_DEVICES 0
/* Only one of those 2 should be enabled! */

View File

@ -1,8 +1,10 @@
#include "CoreController.h"
#include "q7sConfig.h"
#include "../memory/SdCardManager.h"
CoreController::CoreController(object_id_t objectId):
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
}
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
@ -22,15 +24,19 @@ LocalPoolDataSetBase* CoreController::getDataSetHandle(sid_t sid) {
}
ReturnValue_t CoreController::initialize() {
// Find a way to store this non-volatile outside of SD cards (ProASIC?)
sd::SdCard preferredSdCard = sd::SdCard::SLOT_0;
std::string printoutString;
if(preferredSdCard == sd::SdCard::SLOT_0) {
printoutString = "0";
}
else {
printoutString = "1";
}
return sdCardInit();
}
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CoreController::sdCardInit() {
#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE
sif::info << "No SD card initialization will be performed" << std::endl;
return HasReturnvaluesIF::RETURN_OK;
#else
// Creator or update status file
ReturnValue_t result = SdCardManager::instance()->updateSdCardStateFile();
if(result != HasReturnvaluesIF::RETURN_OK) {
@ -38,26 +44,99 @@ ReturnValue_t CoreController::initialize() {
<< std::endl;
}
sif::info << "Switching on SD card " << printoutString << ".." << std::endl;
SdCardManager* sdcMan = SdCardManager::instance();
auto sdStatus = std::pair<sd::SdStatus, sd::SdStatus>(sd::SdStatus::OFF, sd::SdStatus::OFF);
result = sdcMan->getSdCardActiveStatus(sdStatus);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Getting SD card activity status failed" << std::endl;
}
result = SdCardManager::instance()->switchOnSdCard(preferredSdCard, true);
if(result == SdCardManager::ALREADY_MOUNTED) {
sif::info << "SD card " << printoutString << " is already on and mounted" << std::endl;
}
else if(result == SdCardManager::ALREADY_ON) {
sif::info << "SD card " << printoutString << " is already on" << std::endl;
}
else if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "CoreController::initialize: Turning SD card on failed"
#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT
sif::info << "Cold redundant SD card configuration" << std::endl;
sd::SdCard preferredSdCard = sd::SdCard::SLOT_0;
result = sdcMan->getPreferredSdCard(preferredSdCard);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Could not get prefered SD card information from the scratch buffer"
<< std::endl;
}
sd::SdCard otherSdc = sd::SdCard::SLOT_0;
std::string printoutString;
std::string otherString;
if(preferredSdCard == sd::SdCard::SLOT_0) {
printoutString = "0";
otherSdc = sd::SdCard::SLOT_1;
otherString = "1";
}
else {
sif::info << "SD card " << printoutString << " was switched on and mounted" << std::endl;
printoutString = "1";
otherSdc = sd::SdCard::SLOT_0;
otherString = "0";
}
sd::SdStatus targetStatus = sd::SdStatus::OFF;
if(preferredSdCard == sd::SdCard::SLOT_0) {
targetStatus = sdStatus.first;
}
else if(preferredSdCard == sd::SdCard::SLOT_1) {
targetStatus = sdStatus.second;
}
if(targetStatus == sd::SdStatus::MOUNTED) {
sif::info << "SD card " << printoutString << " is already switched on and mounted" <<
std::endl;
result = HasReturnvaluesIF::RETURN_OK;
}
else if(targetStatus == sd::SdStatus::ON) {
sif::info << "Mounting SD card " << printoutString << std::endl;
result = sdcMan->mountSdCard(preferredSdCard);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Mounting SD card failed" << std::endl;
}
}
else if(targetStatus == sd::SdStatus::OFF) {
sif::info << "Switching on and mounting SD card " << printoutString << std::endl;
result = sdcMan->switchOnSdCard(preferredSdCard, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Switching on and mounting SD card failed" << std::endl;
}
}
if(result != HasReturnvaluesIF::RETURN_OK) {
// This should not happen.. Switch on other SD card for now
sdcMan->switchOnSdCard(otherSdc, true);
return HasReturnvaluesIF::RETURN_FAILED;
}
sif::info << "Switching off SD card " << otherString << std::endl;
// Switch off other SD card in cold-redundant mode
result = sdcMan->switchOffSdCard(otherSdc, true);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Switching off SD card " << otherString << " failed" << std::endl;
}
return HasReturnvaluesIF::RETURN_OK;
}
#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT
sif::info << "Hot redundant SD card configuration" << std::endl;
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
// Use a lambda to avoid duplicate code
auto setUpSdCard = [sdcMan](sd::SdCard sdCard, sd::SdStatus status, std::string sdString) {
if(status == sd::SdStatus::OFF) {
sif::info << "Switching on and mounting SD card " << sdString << std::endl;
sdcMan->switchOnSdCard(sdCard, true);
}
else if(status == sd::SdStatus::ON) {
sif::info << "Mounting SD card " << sdString << std::endl;
sdcMan->mountSdCard(sdCard);
}
else {
sif::info << "SD card " << sdString << " already on and mounted" << std::endl;
}
};
setUpSdCard(sd::SdCard::SLOT_0, sdStatus.first, "0");
setUpSdCard(sd::SdCard::SLOT_1, sdStatus.second, "1");
return HasReturnvaluesIF::RETURN_OK;
#endif
#endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */
}

View File

@ -17,6 +17,8 @@ private:
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode);
ReturnValue_t sdCardInit();
};

View File

@ -1,4 +1,6 @@
#include "SdCardManager.h"
#include "scratchApi.h"
#include "linux/utility/utility.h"
#include "fsfw/ipc/MutexFactory.h"
@ -28,7 +30,7 @@ SdCardManager* SdCardManager::instance() {
ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard) {
std::pair<sd::SdStatus, sd::SdStatus> active;
ReturnValue_t result = sdCardActive(active);
ReturnValue_t result = getSdCardActiveStatus(active);
// Not allowed, this function turns on one SD card
if(sdCard == sd::SdCard::BOTH) {
sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH"
@ -67,7 +69,7 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar
ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard) {
std::pair<sd::SdStatus, sd::SdStatus> active;
ReturnValue_t result = sdCardActive(active);
ReturnValue_t result = getSdCardActiveStatus(active);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
@ -99,8 +101,9 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd
}
ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
std::string sdstring = "";
std::string statestring = "";
using namespace std;
string sdstring = "";
string statestring = "";
if(sdCard == sd::SdCard::SLOT_0) {
sdstring = "0";
}
@ -113,9 +116,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
else {
statestring = "off";
}
std::ostringstream command;
ostringstream command;
command << "q7hw sd set " << sdstring << " " << statestring;
int result = std::system(command.str().c_str());
int result = system(command.str().c_str());
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
@ -124,7 +127,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
return SYSTEM_CALL_ERROR;
}
ReturnValue_t SdCardManager::sdCardActive(std::pair<sd::SdStatus, sd::SdStatus>& active) {
ReturnValue_t SdCardManager::getSdCardActiveStatus(std::pair<sd::SdStatus, sd::SdStatus>& active) {
using namespace std;
if(not filesystem::exists(SD_STATE_FILE)) {
return STATUS_FILE_NEXISTS;
@ -152,8 +155,8 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) {
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
std::string mountDev;
std::string mountPoint;
string mountDev;
string mountPoint;
if(sdCard == sd::SdCard::SLOT_0) {
mountDev = SD_0_DEV_NAME;
mountPoint = SD_0_MOUNT_POINT;
@ -162,7 +165,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) {
mountDev = SD_0_DEV_NAME;
mountPoint = SD_1_MOUNT_POINT;
}
if(not std::filesystem::exists(mountDev)) {
if(not filesystem::exists(mountDev)) {
sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to"
" turn on the SD card" << std::endl;
return MOUNT_ERROR;
@ -197,6 +200,7 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) {
sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl;
}
string sdUnmountCommand = "umount " + mountPoint;
sif::debug << sdUnmountCommand << std::endl;
int result = system(sdUnmountCommand.c_str());
if (result != 0) {
utility::handleSystemError(result, "SdCardManager::unmountSdCard");
@ -260,13 +264,21 @@ void SdCardManager::processSdStatusLine(std::pair<sd::SdStatus, sd::SdStatus> &a
idx++;
}
sd::SdCard SdCardManager::getPreferredSdCard() const {
//int result = std::system("xsc_scratch read PREFSD > /tmp/pref_sd.txt");
return preferredSdCard;
ReturnValue_t SdCardManager::getPreferredSdCard(sd::SdCard& sdCard) const {
uint8_t prefSdCard = 0;
ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
sdCard = static_cast<sd::SdCard>(prefSdCard);
return HasReturnvaluesIF::RETURN_OK;
}
void SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
preferredSdCard = sdCard;
ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
if(sdCard == sd::SdCard::BOTH) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sdCard));
}
ReturnValue_t SdCardManager::updateSdCardStateFile() {

View File

@ -54,9 +54,9 @@ public:
*/
static SdCardManager* instance();
void setPreferredSdCard(sd::SdCard sdCard);
ReturnValue_t setPreferredSdCard(sd::SdCard sdCard);
sd::SdCard getPreferredSdCard() const;
ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const;
/**
* Switch on the specified SD card.
@ -97,7 +97,7 @@ public:
* should call #updateSdCardStateFile again in that case
* - STATUS_FILE_NEXISTS if the status file does not exist
*/
ReturnValue_t sdCardActive(std::pair<sd::SdStatus, sd::SdStatus>& active);
ReturnValue_t getSdCardActiveStatus(std::pair<sd::SdStatus, sd::SdStatus>& active);
/**
* Mount the specified SD card. This is necessary to use it.
@ -113,8 +113,6 @@ public:
*/
ReturnValue_t unmountSdCard(sd::SdCard sdCard);
sd::SdCard getPreferedSdCard() const;
private:
SdCardManager();

View File

@ -12,7 +12,7 @@ enum SdStatus: uint8_t {
MOUNTED = 2
};
enum SdCard {
enum SdCard: uint8_t {
SLOT_0,
SLOT_1,
BOTH

View File

@ -16,6 +16,8 @@
*/
namespace scratch {
static constexpr char PREFERED_SDC_KEY[] = "PREFSD";
namespace {
static uint8_t counter = 0;
}