From eb7b0770a00d1770e147318a9d94b0e4eaf1353f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Jul 2021 17:23:32 +0200 Subject: [PATCH] starting file system handler --- bsp_q7s/memory/FileSystemHandler.cpp | 126 +++++++++++++++++++++------ bsp_q7s/memory/FileSystemHandler.h | 12 ++- bsp_q7s/memory/SdCardManager.cpp | 23 +++++ bsp_q7s/memory/SdCardManager.h | 13 +++ fsfw | 2 +- 5 files changed, 149 insertions(+), 27 deletions(-) diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 473a5167..ba64a991 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -15,33 +15,85 @@ FileSystemHandler::~FileSystemHandler() { ReturnValue_t FileSystemHandler::performOperation(uint8_t unsignedChar) { while(true) { - CommandMessage filemsg; - ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - while(true) { - result = mq->receiveMessage(&filemsg); - if(result == MessageQueueIF::EMPTY) { - break; - } - else if(result != HasReturnvaluesIF::RETURN_FAILED) { - sif::warning << "FileSystemHandler::performOperation: Message reception failed!" - << std::endl; - break; - } - Command_t command = filemsg.getCommand(); - switch(command) { - case(GenericFileSystemMessage::CMD_CREATE_DIRECTORY): { - break; - } - case(GenericFileSystemMessage::CMD_CREATE_FILE): { - break; - } - } + try { + fileSystemHandlerLoop(); } + catch(std::bad_alloc& e) { + // Restart OBSW, hints at a memory leak + sif::error << "Allocation error in FileSystemHandler::performOperation" + << e.what() << std::endl; + // TODO: If we trigger an event, it might not get sent because were restarting + // Set up an error file or a special flag in the scratch buffer. + // TODO: CoreController: Implement function to restart OBC + } + } +} - // This task will have a low priority and will run permanently in the background - // so we will just run in a permanent loop here and check file system - // messages permanently - TaskFactory::instance()->delayTask(1000); + +void FileSystemHandler::fileSystemHandlerLoop() { + CommandMessage filemsg; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + while(true) { + if(opCounter % 5 == 0) { + fileSystemCheckup(); + } + result = mq->receiveMessage(&filemsg); + if(result == MessageQueueIF::EMPTY) { + break; + } + else if(result != HasReturnvaluesIF::RETURN_FAILED) { + sif::warning << "FileSystemHandler::performOperation: Message reception failed!" + << std::endl; + break; + } + Command_t command = filemsg.getCommand(); + switch(command) { + case(GenericFileSystemMessage::CMD_CREATE_DIRECTORY): { + break; + } + case(GenericFileSystemMessage::CMD_CREATE_FILE): { + break; + } + } + opCounter++; + } + + // This task will have a low priority and will run permanently in the background + // so we will just run in a permanent loop here and check file system + // messages permanently + TaskFactory::instance()->delayTask(1000); +} + +void FileSystemHandler::fileSystemCheckup() { + SdCardManager::SdStatusPair statusPair; + sdcMan->getSdCardActiveStatus(statusPair); + sd::SdCard preferredSdCard; + sdcMan->getPreferredSdCard(preferredSdCard); + if((preferredSdCard == sd::SdCard::SLOT_0) and + (statusPair.first == sd::SdStatus::MOUNTED)) { + currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + } + if((preferredSdCard == sd::SdCard::SLOT_1) and + (statusPair.second == sd::SdStatus::MOUNTED)) { + currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; + } + else { + std::string sdString; + if(preferredSdCard == sd::SdCard::SLOT_0) { + sdString = "0"; + } + else { + sdString = "1"; + } + sif::warning << "FileSystemHandler::performOperation: Inconsistent" << + " state detected. Preferred SD card is " << sdString << + " but does not appear to be mounted. Attempting fix.." << std::endl; + // This function will appear to fix the inconsistent state + ReturnValue_t result = sdcMan->sanitizeState(&preferredSdCard, &statusPair); + if(result != HasReturnvaluesIF::RETURN_OK) { + // Oh no. Trigger medium severity event + sif::error << "Fix failed" << std::endl; + } } } @@ -49,6 +101,22 @@ MessageQueueId_t FileSystemHandler::getCommandQueue() const { return mq->getId(); } +ReturnValue_t FileSystemHandler::initialize() { + sdcMan = SdCardManager::instance(); + sd::SdCard preferredSdCard; + ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if(preferredSdCard == sd::SdCard::SLOT_0) { + currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; + } + else if(preferredSdCard == sd::SdCard::SLOT_1) { + currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; + } + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t FileSystemHandler::appendToFile(const char *repositoryPath, const char *filename, const uint8_t *data, size_t size, uint16_t packetNumber, void *args) { return HasReturnvaluesIF::RETURN_OK; @@ -63,3 +131,11 @@ ReturnValue_t FileSystemHandler::deleteFile(const char *repositoryPath, const ch void *args) { return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t FileSystemHandler::createDirectory(const char *repositoryPath, void *args) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t FileSystemHandler::removeDirectory(const char *repositoryPath, void *args) { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 803e52b7..9d3285b1 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ #define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_ +#include #include "OBSWConfig.h" #include "fsfw/ipc/MessageQueueIF.h" @@ -19,6 +20,8 @@ public: ReturnValue_t performOperation(uint8_t) override; + ReturnValue_t initialize() override; + /** * Function to get the MessageQueueId_t of the implementing object * @return MessageQueueId_t of the object @@ -27,8 +30,13 @@ public: private: MessageQueueIF* mq = nullptr; - std::string currentMountPrefix; + std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; + SdCardManager* sdcMan = nullptr; + uint8_t opCounter = 0; + + void fileSystemHandlerLoop(); + void fileSystemCheckup(); ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data, size_t size, @@ -38,6 +46,8 @@ private: size_t size = 0, void* args = nullptr) override; ReturnValue_t deleteFile(const char* repositoryPath, const char* filename, void* args = nullptr) override; + ReturnValue_t createDirectory(const char* repositoryPath, void* args = nullptr) override; + ReturnValue_t removeDirectory(const char* repositoryPath, void* args = nullptr) override; }; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 36d8f67b..5a50665b 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -7,6 +7,7 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include +#include #include SdCardManager* SdCardManager::factoryInstance = nullptr; @@ -225,6 +226,28 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t SdCardManager::sanitizeState(sd::SdCard* prefSdCard, SdStatusPair* statusPair) { + if(prefSdCard == nullptr) { + prefSdCard = std::make_unique(sd::SdCard::SLOT_0).get(); + getPreferredSdCard(*prefSdCard); + } + if(statusPair == nullptr) { + statusPair = std::make_unique().get(); + getSdCardActiveStatus(*statusPair); + } + + auto sanitizerFunc = [&](sd::SdCard prefSdCard) { + if(statusPair->first == sd::SdStatus::ON) { + return mountSdCard(prefSdCard); + } + else { + return switchOnSdCard(prefSdCard, true, statusPair); + } + }; + + return sanitizerFunc(*prefSdCard); +} + void SdCardManager::processSdStatusLine(std::pair &active, std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std; diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index d47b5322..966e6e2a 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -132,6 +132,19 @@ public: */ ReturnValue_t unmountSdCard(sd::SdCard sdCard); + /** + * 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. + * @param prefSdCard Preferred SD card captured with #getPreferredSdCard + * @param statusPair Current SD card status capture with #getSdCardActiveStatus + * @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed + * @return + */ + ReturnValue_t sanitizeState(sd::SdCard* prefSdCard = nullptr, + SdStatusPair* statusPair = nullptr); + private: SdCardManager(); diff --git a/fsfw b/fsfw index eef2fd3b..323577cd 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit eef2fd3b7ac764f06ed5d9a3c97c894d92a515fa +Subproject commit 323577cdc69ee2d863e6e61cebd71a8aa75c6d2b