From 996a8a226e87e5d022a101567267354d0ecdcbfe Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 6 Jan 2022 18:05:21 +0100 Subject: [PATCH] flash write wip --- .../devicedefinitions/PlocMPSoCDefinitions.h | 57 ++++- bsp_q7s/devices/ploc/CMakeLists.txt | 1 + bsp_q7s/devices/ploc/MPSoCSequenceCount.cpp | 56 +++++ bsp_q7s/devices/ploc/MPSoCSequenceCount.h | 48 ++++ bsp_q7s/devices/ploc/PlocMPSoCHandler.cpp | 93 ++++++-- bsp_q7s/devices/ploc/PlocMPSoCHandler.h | 60 +++-- bsp_q7s/devices/ploc/PlocMPSoCHelper.cpp | 215 ++++++++++++++++++ bsp_q7s/devices/ploc/PlocMPSoCHelper.h | 143 ++++++++++++ .../startracker/StarTrackerHandler.cpp | 30 +-- .../devices/startracker/StarTrackerHandler.h | 4 +- bsp_q7s/devices/startracker/StrHelper.cpp | 28 +-- bsp_q7s/devices/startracker/StrHelper.h | 15 +- bsp_q7s/memory/FilesystemHelper.cpp | 34 +++ bsp_q7s/memory/FilesystemHelper.h | 47 ++++ common/config/commonClassIds.h | 3 + common/config/commonSubsystemIds.h | 1 + linux/fsfwconfig/OBSWConfig.h.in | 5 +- tmtc | 2 +- 18 files changed, 733 insertions(+), 109 deletions(-) create mode 100644 bsp_q7s/devices/ploc/MPSoCSequenceCount.cpp create mode 100644 bsp_q7s/devices/ploc/MPSoCSequenceCount.h create mode 100644 bsp_q7s/devices/ploc/PlocMPSoCHelper.cpp create mode 100644 bsp_q7s/devices/ploc/PlocMPSoCHelper.h create mode 100644 bsp_q7s/memory/FilesystemHelper.cpp create mode 100644 bsp_q7s/memory/FilesystemHelper.h diff --git a/bsp_q7s/devices/devicedefinitions/PlocMPSoCDefinitions.h b/bsp_q7s/devices/devicedefinitions/PlocMPSoCDefinitions.h index 97819866..4b169d5f 100644 --- a/bsp_q7s/devices/devicedefinitions/PlocMPSoCDefinitions.h +++ b/bsp_q7s/devices/devicedefinitions/PlocMPSoCDefinitions.h @@ -16,6 +16,7 @@ static const DeviceCommandId_t EXE_REPORT = 5; static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 6; static const DeviceCommandId_t TC_FLASHFOPEN = 7; static const DeviceCommandId_t TC_FLASHFCLOSE = 8; +static const DeviceCommandId_t TC_FLASHWRITE = 9; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; @@ -27,6 +28,7 @@ static const uint16_t SIZE_TM_MEM_READ_REPORT = 18; namespace apid { static const uint16_t TC_MEM_WRITE = 0x114; static const uint16_t TC_MEM_READ = 0x115; + static const uint16_t TC_FLASHWRITE = 0x117; static const uint16_t TC_FLASHFOPEN = 0x119; static const uint16_t TC_FLASHFCLOSE = 0x11A; static const uint16_t TM_MEMORY_READ_REPORT = 0x404; @@ -54,8 +56,9 @@ static const size_t MAX_FILENAME_SIZE = 256; static const uint16_t LENGTH_TC_MEM_WRITE = 12; static const uint16_t LENGTH_TC_MEM_READ = 8; -static const size_t MAX_REPLY_SIZE = SIZE_TM_MEM_READ_REPORT; -static const size_t MAX_COMMAND_SIZE = 18; +static const size_t MAX_REPLY_SIZE = SpacePacket::PACKET_MAX_SIZE; +static const size_t MAX_COMMAND_SIZE = SpacePacket::PACKET_MAX_SIZE; +static const size_t MAX_DATA_SIZE = 1016; /** * @breif Abstract base class for TC space packet of MPSoC. @@ -130,6 +133,33 @@ private: } }; +/** + * @brief Class for handling tm replies of the PLOC MPSoC. + */ +class TmPacket : public SpacePacket, public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::MPSOC_CMD; + + //! [EXPORT] : [COMMENT] CRC check of received packet failed + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0); + /** + * @brief Constructor creates idle packet and sets length field to maximum allowed size. + */ + TmPacket() : SpacePacket(PACKET_MAX_SIZE) { + } + + ReturnValue_t checkCrc() { + uint8_t crcPtr = this->getPacketData() + this->getPacketDataLength() - 1; + uint16_t receivedCrc = *(crcPtr) << 8 | *(crcPtr + 1); + uint16_t recalculatedCrc = CRC::crc16ccitt(this->localData.byteStream, this->getFullSize()); + if (recalculatedCrc != this->ge) { + return CRC_FAILURE; + } + return RETURN_OK; + } +}; + /** * @brief This class helps to build the memory read command for the PLOC. */ @@ -291,6 +321,29 @@ private: } }; +/** + * @brief Class to build flash write space packet. + */ +class FlashWrite : public TcBase { +public: + + FlashWrite(uint16_t sequenceCount) : + TcBase(apid::TC_FLASHWRITE, sequenceCount) { + } + +protected: + + ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) { + if (commandDataLen > MAX_DATA_SIZE) { + sif::debug << "FlashWrite::initPacket: Command data too big" << std::endl; + return RETURN_FAILED; + } + std::memcpy(this->getPacketData(), commandData, commandDataLen); + this->setPacketDataLength(static_cast(commandDataLen + CRC_SIZE - 1)); + return RETURN_OK; + } +}; + } #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/ploc/CMakeLists.txt b/bsp_q7s/devices/ploc/CMakeLists.txt index ab8edb36..0babd089 100644 --- a/bsp_q7s/devices/ploc/CMakeLists.txt +++ b/bsp_q7s/devices/ploc/CMakeLists.txt @@ -3,4 +3,5 @@ target_sources(${TARGET_NAME} PRIVATE PlocUpdater.cpp PlocMemoryDumper.cpp PlocMPSoCHandler.cpp + PlocMPSoCHelper.cpp ) diff --git a/bsp_q7s/devices/ploc/MPSoCSequenceCount.cpp b/bsp_q7s/devices/ploc/MPSoCSequenceCount.cpp new file mode 100644 index 00000000..88b66ad0 --- /dev/null +++ b/bsp_q7s/devices/ploc/MPSoCSequenceCount.cpp @@ -0,0 +1,56 @@ +#include "MPSoCSequenceCount.h" + +MPSoCSequenceCount::MPSoCSequenceCount() { +} + +MPSoCSequenceCount::~MPSoCSequenceCount() { +} + +MPSoCSequenceCount::increment() { + ReturnValue_t result = RETURN_OK; + result = spiMutex->lockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { + sif::warning << "MPSoCSequenceCount::increment: Failed to lock mutex" << std::endl; + return result; + } + sequenceCount = (sequenceCount + 1) & SEQUENCE_COUNT_MASK; + result = spiMutex->unlockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { + sif::warning << "MPSoCSequenceCount::increment: Failed to unlock mutex" << std::endl; + return result; + } +} + +MPSoCSequenceCount::set(uint16_t sequenceCount_) { + ReturnValue_t result = RETURN_OK; + result = spiMutex->lockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { + sif::warning << "MPSoCSequenceCount::set: Failed to lock mutex" << std::endl; + return result; + } + sequenceCount = sequenceCount_; + result = spiMutex->unlockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { + sif::warning << "MPSoCSequenceCount::set: Failed to unlock mutex" << std::endl; + return result; + } +} + +MPSoCSequenceCount::reset() { + ReturnValue_t result = RETURN_OK; + result = spiMutex->lockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { + sif::warning << "MPSoCSequenceCount::reset: Failed to lock mutex" << std::endl; + return result; + } + sequenceCount = 0; + result = spiMutex->unlockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { + sif::warning << "MPSoCSequenceCount::reset: Failed to unlock mutex" << std::endl; + return result; + } +} + +uint16_t MPSoCSequenceCount::get() { + return sequenceCount; +} diff --git a/bsp_q7s/devices/ploc/MPSoCSequenceCount.h b/bsp_q7s/devices/ploc/MPSoCSequenceCount.h new file mode 100644 index 00000000..57587d0a --- /dev/null +++ b/bsp_q7s/devices/ploc/MPSoCSequenceCount.h @@ -0,0 +1,48 @@ +#ifndef BSP_Q7S_DEVICES_PLOC_MPSOCSEQUENCECOUNT_H_ +#define BSP_Q7S_DEVICES_PLOC_MPSOCSEQUENCECOUNT_H_ + +/** + * @brief Manages incrementing, resetting and harmonization of the sequence count in the space + * packet based communication between MPSoC and OBC. + * + * @author J. Meier + */ +class MPSoCSequenceCount { +public: + MPSoCSequenceCount(); + virtual ~MPSoCSequenceCount(); + + /** + * @brief Increments the sequence count. + */ + void increment(); + + /** + * @brief Sets the value of the sequence count + * + * @param sequenceCount The sequence count to set + */ + void set(uint16_t sequenceCount_); + + /** + * @brief Resets the sequence count to zero + */ + void reset(); + + /** + * @brief Returns the current value sequence count + */ + uint16_t get(); + +private: + + MutexIF* spiMutex = nullptr; + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 20; + + static const uint16_t SEQUENCE_COUNT_MASK = 0x3FFF; + + uint16_t sequenceCount = 0x3FFF; +}; + +#endif /* BSP_Q7S_DEVICES_PLOC_MPSOCSEQUENCECOUNT_H_ */ diff --git a/bsp_q7s/devices/ploc/PlocMPSoCHandler.cpp b/bsp_q7s/devices/ploc/PlocMPSoCHandler.cpp index 7f6905a4..c9daad77 100644 --- a/bsp_q7s/devices/ploc/PlocMPSoCHandler.cpp +++ b/bsp_q7s/devices/ploc/PlocMPSoCHandler.cpp @@ -1,13 +1,11 @@ -#include "../../bsp_q7s/devices/ploc/PlocMPSoCHandler.h" - #include "OBSWConfig.h" - -#include -#include +#include "PlocMPSoCHandler.h" +#include "fsfw/globalfunctions/CRC.h" +#include "fsfw/datapool/PoolReadGuard.h" PlocMPSoCHandler::PlocMPSoCHandler(object_id_t objectId, object_id_t uartComIFid, - CookieIF * comCookie) : - DeviceHandlerBase(objectId, uartComIFid, comCookie) { + CookieIF * comCookie, PlocMPSoCHelper* plocMPSoCHelper) : + DeviceHandlerBase(objectId, uartComIFid, comCookie), plocMPSoCHelper(plocMPSoCHelper) { if (comCookie == NULL) { sif::error << "PlocMPSoCHandler: Invalid com cookie" << std::endl; } @@ -27,9 +25,66 @@ ReturnValue_t PlocMPSoCHandler::initialize() { sif::warning << "PlocMPSoCHandler::initialize: Invalid uart com if" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; } + +EventManagerIF* manager = ObjectManager::instance()->get( + objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PlocMPSoCHandler::initialize: Invalid event manager" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED;; + } + result = manager->registerListener(eventQueue->getId()); + if (result != RETURN_OK) { + return result; + } + result = manager->subscribeToEventRange(eventQueue->getId(), + event::getEventId(PlocMPSoCHelper::FLASH_WRITE_FAILED), + event::getEventId(PlocMPSoCHelper::FLASH_WRITE_SUCCESSFUL)); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "PlocMPSoCHandler::initialize: Failed to subscribe to events from " + " ploc mpsoc helper" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + result = plocMPSoCHelper->setComIF(communicationInterface); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + plocMPSoCHelper->setComCookie(comCookie); + plocMPSoCHelper->setSequenceCount(&sequenceCount); return result; } +ReturnValue_t PlocMPSoCHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) { + ReturnValue_t result = RETURN_OK; + + if (plocMPSoCHelperExecuting) { + return MPSOC_HELPER_EXECUTING; + } + + switch(actionId) { + case mpsoc::TC_FLASHWRITE: { + if (size > config::MAX_PATH_SIZE + config::MAX_FILE_NAME) { + return FILENAME_TOO_LONG; + } + result = plocMPSoCHelper->startFlashWrite( + std::string(reinterpret_cast(data), size)); + if (result != RETURN_OK) { + return result; + } + plocMPSoCHelperExecuting = true; + break; + } + default: + break; + } + return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); +} + void PlocMPSoCHandler::doStartUp(){ #if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 @@ -179,15 +234,11 @@ ReturnValue_t PlocMPSoCHandler::initializeLocalDataPool(localpool::DataPool& loc return HasReturnvaluesIF::RETURN_OK; } -void PlocMPSoCHandler::setModeNormal() { - mode = MODE_NORMAL; -} - ReturnValue_t PlocMPSoCHandler::prepareTcMemWriteCommand(const uint8_t * commandData, size_t commandDataLen) { ReturnValue_t result = RETURN_OK; - packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK; - mpsoc::TcMemWrite tcMemWrite(packetSequenceCount); + sequenceCount.increment(); + mpsoc::TcMemWrite tcMemWrite(sequenceCount.get()); result = tcMemWrite.createPacket(commandData, commandDataLen); if (result != RETURN_OK) { return result; @@ -199,8 +250,8 @@ ReturnValue_t PlocMPSoCHandler::prepareTcMemWriteCommand(const uint8_t * command ReturnValue_t PlocMPSoCHandler::prepareTcMemReadCommand(const uint8_t * commandData, size_t commandDataLen) { ReturnValue_t result = RETURN_OK; - packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK; - mpsoc::TcMemRead tcMemRead(packetSequenceCount); + sequenceCount.increment(); + mpsoc::TcMemRead tcMemRead(sequenceCount.get()); result = tcMemRead.createPacket(commandData, commandDataLen); if (result != RETURN_OK) { return result; @@ -212,8 +263,8 @@ ReturnValue_t PlocMPSoCHandler::prepareTcMemReadCommand(const uint8_t * commandD ReturnValue_t PlocMPSoCHandler::prepareFlashFopenCmd(const uint8_t * commandData, size_t commandDataLen) { ReturnValue_t result = RETURN_OK; - packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK; - mpsoc::FlashFopen flashFopen(packetSequenceCount); + sequenceCount.increment(); + mpsoc::FlashFopen flashFopen(sequenceCount.get()); result = flashFopen.createPacket(commandData, commandDataLen); if (result != RETURN_OK) { return result; @@ -225,8 +276,8 @@ ReturnValue_t PlocMPSoCHandler::prepareFlashFopenCmd(const uint8_t * commandData ReturnValue_t PlocMPSoCHandler::prepareFlashFcloseCmd(const uint8_t * commandData, size_t commandDataLen) { ReturnValue_t result = RETURN_OK; - packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK; - mpsoc::FlashFclose flashFclose(packetSequenceCount); + sequenceCount.increment(); + mpsoc::FlashFclose flashFclose(sequenceCount.get()); result = flashFclose.createPacket(commandData, commandDataLen); if (result != RETURN_OK) { return result; @@ -534,13 +585,13 @@ void PlocMPSoCHandler::disableExeReportReply() { ReturnValue_t PlocMPSoCHandler::checkPacketSequenceCount(const uint8_t* data) { uint16_t receivedSeqCnt = (*(data + 2) << 8 | *(data + 3)) & PACKET_SEQUENCE_COUNT_MASK; - uint16_t expectedSeqCnt = ((packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK); + uint16_t expectedSeqCnt = sequenceCount.get(); if (receivedSeqCnt != expectedSeqCnt) { sif::warning << "PlocMPSoCHandler::checkPacketSequenceCount: Packet sequence count " "mismatch. Received: " << receivedSeqCnt << ", Expected: " << expectedSeqCnt << std::endl; triggerEvent(SEQ_CNT_MISMATCH, expectedSeqCnt, receivedSeqCnt); } - packetSequenceCount = receivedSeqCnt; + sequenceCount.set(receivedSeqCnt); return RETURN_OK; } diff --git a/bsp_q7s/devices/ploc/PlocMPSoCHandler.h b/bsp_q7s/devices/ploc/PlocMPSoCHandler.h index 7239e399..55be8102 100644 --- a/bsp_q7s/devices/ploc/PlocMPSoCHandler.h +++ b/bsp_q7s/devices/ploc/PlocMPSoCHandler.h @@ -1,22 +1,24 @@ #ifndef BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ #define BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ -#include -#include +#include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "devicedefinitions/PlocMPSoCDefinitions.h" +#include "fsfw_hal/linux/uart/UartComIF.h" +#include "MPSoCSequenceCount.h" +#include "PlocMPSoCHelper.h" #include -#include /** - * @brief This is the device handler for the MPSoC which is programmed by the ILH of the - * university of stuttgart. + * @brief This is the device handler for the MPSoC of the payload computer. + * + * @details The PLOC uses the space packet protocol for communication. On each command the PLOC + * answers with at least one acknowledgment and one execution report. + * Flight manual: https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_MPSoC + * ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_TAS-ILH-IRS/ICD-PLOC/ILH&fileid=1030263 + * + * @note The sequence count in the space packets must be incremented with each received and sent + * packet. * - * @details - * The PLOC uses the space packet protocol for communication. To each command the PLOC - * answers with at least one acknowledgment and one execution report. - * Flight manual: - * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_Commands - * ILH ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/ - * Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960 * @author J. Meier */ class PlocMPSoCHandler: public DeviceHandlerBase { @@ -34,15 +36,17 @@ public: static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3); //! [EXPORT] : [COMMENT] Received command with invalid length static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xA4); + //! [EXPORT] : [COMMENT] Received command with invalid filename + static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] MPSoC helper is currently executing a command + static const ReturnValue_t MPSOC_HELPER_EXECUTING = MAKE_RETURN_CODE(0xA6); - PlocMPSoCHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie); + PlocMPSoCHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie, + PlocMPSoCHelper* plocMPSoCHelper); virtual ~PlocMPSoCHandler(); - virtual ReturnValue_t initialize() override; - /** - * @brief Sets mode to MODE_NORMAL. Can be used for debugging. - */ - void setModeNormal(); + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; protected: void doStartUp() override; @@ -83,22 +87,11 @@ private: static const Event SEQ_CNT_MISMATCH = MAKE_EVENT(5, severity::LOW); static const uint16_t APID_MASK = 0x7FF; - static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF; + + MPSoCSequenceCount sequenceCount; uint8_t commandBuffer[mpsoc::MAX_COMMAND_SIZE]; - /** - * @brief This object is incremented each time a packet is sent or received. By checking the - * packet sequence count of a received packet, no packets can be lost without noticing - * it. Only the least significant 14 bits represent the packet sequence count in a - * space packet. Thus the maximum value amounts to 16383 (0x3FFF). - * @note Normally this should never happen because the PLOC replies are always sent in a - * fixed order. However, the PLOC software checks this value and will return an ACK - * failure report in case the sequence count is not incremented with each transferred - * space packet. - */ - uint16_t packetSequenceCount = 0x3FFF; - /** * This variable is used to store the id of the next reply to receive. This is necessary * because the PLOC sends as reply to each command at least one acknowledgment and execution @@ -108,6 +101,11 @@ private: UartComIF* uartComIf = nullptr; + PlocMPSoCHelper* plocMPSoCHelper = nullptr; + + // Used to block incoming commands when MPSoC helper class is currently executing a command + bool plocMPSoCHelperExecuting = false; + ReturnValue_t prepareTcMemWriteCommand(const uint8_t * commandData, size_t commandDataLen); ReturnValue_t prepareTcMemReadCommand(const uint8_t * commandData, size_t commandDataLen); ReturnValue_t prepareFlashFopenCmd(const uint8_t * commandData, size_t commandDataLen); diff --git a/bsp_q7s/devices/ploc/PlocMPSoCHelper.cpp b/bsp_q7s/devices/ploc/PlocMPSoCHelper.cpp new file mode 100644 index 00000000..06151c33 --- /dev/null +++ b/bsp_q7s/devices/ploc/PlocMPSoCHelper.cpp @@ -0,0 +1,215 @@ +#include "PlocMPSoCHelper.h" +#include "mission/utility/Timestamp.h" +#include +#include + +PlocMPSoCHelper::PlocMPSoCHelper(object_id_t objectId) : SystemObject(objectId){ + +} + +PlocMPSoCHelper::~PlocMPSoCHelper() { +} + +ReturnValue_t PlocMPSoCHelper::initialize() { + sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "PlocMPSoCHelper::initialize: Invalid SD Card Manager" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t PlocMPSoCHelper::performOperation(uint8_t operationCode) { + ReturnValue_t result = RETURN_OK; + semaphore.acquire(); + while(true) { + switch(internalState) { + case InternalState::IDLE: { + semaphore.acquire(); + break; + } + case InternalState::FLASH_WRITE: { + result = performFlashWrite(); + if (result == RETURN_OK){ + triggerEvent(FLASH_WRITE_SUCCESSFUL); + } + else { + triggerEvent(FLASH_WRITE_FAILED); + } + internalState = InternalState::IDLE; + break; + } + default: + sif::debug << "PlocMPSoCHelper::performOperation: Invalid state" << std::endl; + break; + } + } +} + +ReturnValue_t PlocMPSoCHelper::setComIF(DeviceCommunicationIF* communicationInterface_) { + uartComIF = dynamic_cast(communicationInterface_); + if (uartComIF == nullptr) { + sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +void PlocMPSoCHelper::setComCookie(CookieIF* comCookie_) { + comCookie = comCookie_; +} + +void PlocMPSoCHelper::setSequenceCount(MPSoCSequenceCount* sequenceCount_) { + sequenceCount = sequenceCount_; +} + +ReturnValue_t PlocMPSoCHelper::startFlashWrite(std::string file) { + ReturnValue_t result = FilesystemHelper::checkPath(file); + if (result != RETURN_OK) { + return result; + } + result = FilesystemHelper::fileExists(file); + if (result != RETURN_OK) { + return result; + } + flashWrite.file = file; + internalState = InternalState::FLASH_WRITE; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +void PlocMPSoCHelper::stopProcess() { + terminate = true; +} + +ReturnValue_t PlocMPSoCHelper::performFlashWrite() { + ReturnValue_t result = RETURN_OK; + std::ifstream file(flashWrite.file, std::ifstream::binary); + // Set position of next character to end of file input stream + file.seekg(0, file.end); + // tellg returns position of character in input stream + imageSize = file.tellg(); + sequenceCount->increment(); + mpsoc::FlashWrite tc(sequenceCount->get()); + result = sendCommand(tc); + if (result != REUTRN_OK) { + return result; + } + result = handleAck(); + if (result != RETURN_OK) { + return result; + } + result = handleExe(); + if (result != RETURN_OK) { + return result; + } + return result; +} + +ReturnValue_t PlocMPSoCHelper::sendCommand(TcBase* tc) { + ReturnValue_t result = RETURN_OK; + result = uartComIF->sendMessage(comCookie, tc->getWholeData(), tc->getFullSize()); + if (result != RETURN_OK) { + sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl; + triggerEvent(SENDING_COMMAND_FAILED, result, internalState); + return result; + } + return result; +} + +ReturnValue_t PlocMPSoCHelper::handleAck() { + ReturnValue_t result = RETURN_OK; + mpsoc::TmPacket tmPacket; + result = handleTmReception(tmPacket, mpsoc::SIZE_ACK_REPORT); + if (result != RETURN_OK) { + return result; + } + uint16_t apid = tmPacket.getAPID(); + if (apid != mpsoc::apid::ACK_SUCCESS) { + handleAckApidFailure(apid); + return RETURN_FAILED; + } + return RETURN_OK; +} + +void PlocMPSoCHelper::handleAckApidFailure(uint16_t apid) { + if (apid == mpsoc::apid::ACK_FAILURE) { + triggerEvent(ACK_FAILURE_REPORT, internalState); + sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Received acknowledgement failure " + << "report" << std::endl; + } + else { + triggerEvent(ACK_INVALID_APID, apid, internalState); + sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected acknowledgement report " + << "but received space packet with apid " << std::hex << apid << std::endl; + } +} + +ReturnValue_t PlocMPSoCHelper::handleExe() { + ReturnValue_t result = RETURN_OK; + mpsoc::TmPacket tmPacket; + result = handleTmReception(tmPacket, mpsoc::SIZE_EXE_REPORT); + if (result != RETURN_OK) { + return result; + } + uint16_t apid = tmPacket.getAPID(); + if (apid != mpsoc::apid::EXE_SUCCESS) { + handleExeApidFailure(apid); + return RETURN_FAILED; + } + return RETURN_OK; +} + +void PlocMPSoCHelper::handleExeApidFailure(uint16_t apid) { + if (apid == mpsoc::apid::EXE_FAILURE) { + triggerEvent(EXE_FAILURE_REPORT, internalState); + sif::warning << "PlocMPSoCHelper::handleExeApidFailure: Received execution failure " + << "report" << std::endl; + } + else { + triggerEvent(EXE_INVALID_APID, apid, internalState); + sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected execution report " + << "but received space packet with apid " << std::hex << apid << std::endl; + } +} + +ReturnValue_t PlocMPSoCHelper::handleTmReception(TmPacket* tmPacket, size_t remainingBytes) { + size_t readBytes = 0; + for(int retries = 0; retries < RETRIES; retries++) { + result = receive(tmPacket->getWholeData(), readBytes, remainingBytes); + if (result != RETURN_OK) { + return result; + } + remainingBytes = remainingBytes - readBytes; + if (remainingBytes == 0) { + break; + } + } + if (remainingBytes != 0) { + sif::warning << "PlocMPSoCHelper::handleTmReception: Failed to receive reply" << std::endl; + triggerEvent(MISSING_EXE, remainingBytes, internalState); + return RETURN_FAILED; + } + result = tmPacket->checkCrc(); + if (result != RETURN_OK) { + sif::warning << "PlocMPSoCHelper::handleTmReception: CRC check failed" << std::endl; + return result; + } +} + +ReturnValue_t PlocMPSoCHelper::receive(uint8_t* data, size_t* readBytes, size_t requestBytes) { + ReturnValue_t result = RETURN_OK; + result = uartComIF->requestReceiveMessage(comCookie, requestBytes); + if (result != RETURN_OK) { + sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl; + triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result, internalState); + return RETURN_FAILED; + } + result = uartComIF->readReceivedMessage(comCookie, &data, readBytes); + if (result != RETURN_OK) { + sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl; + triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, internalState); + return RETURN_FAILED; + } +} diff --git a/bsp_q7s/devices/ploc/PlocMPSoCHelper.h b/bsp_q7s/devices/ploc/PlocMPSoCHelper.h new file mode 100644 index 00000000..ee399a51 --- /dev/null +++ b/bsp_q7s/devices/ploc/PlocMPSoCHelper.h @@ -0,0 +1,143 @@ +#ifndef BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ +#define BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ + +#include +#include "fsfw/osal/linux/BinarySemaphore.h" +#include "bsp_q7s/memory/SdCardManager.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw_hal/linux/uart/UartComIF.h" +#include "fsfw/devicehandlers/CookieIF.h" +#include "bsp_q7s/devices/devicedefinitions/PlocMPSoCDefinitions.h" +#include "MPSoCSequenceCount.h" + +/** + * @brief Helper class for MPSoC of PLOC intended to accelerate large data transfers between + * MPSoC and OBC. + * @author J. Meier + */ +class PlocMPSoCHelper: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { +public: + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HELPER; + + //! [EXPORT] : [COMMENT] Flash write fails + static const Event FLASH_WRITE_FAILED = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Flash write successful + static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] Communication interface returned failure when trying to send the command ot the PLOC + //!P1: Return value returned by the communication interface sendMessage function + //!P2: Internal state of MPSoC helper + static const Event SENDING_COMMAND_FAILED = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Request receive message of communication interface failed + //!P1: Return value returned by the communication interface requestReceiveMessage function + //!P2: Internal state of MPSoC helper + static const Event MPSOC_HELPER_REQUESTING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Reading receive message of communication interface failed + //!P1: Return value returned by the communication interface readingReceivedMessage function + //!P2: Internal state of MPSoC helper + static const Event MPSOC_HELPER_REQUESTING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW); + //! [EXPORT] : [COMMENT] Did not receive acknowledgement report + //!P1: Number of bytes missing + //!P2: Internal state of MPSoC helper + static const Event MISSING_ACK = MAKE_EVENT(5, severity::LOW); + //! [EXPORT] : [COMMENT] Did not receive execution report + //!P1: Number of bytes missing + //!P2: Internal state of MPSoC helper + static const Event MISSING_EXE = MAKE_EVENT(6, severity::LOW); + //! [EXPORT] : [COMMENT] Received acknowledgement failure report + //!P1: Internal state of MPSoC + static const Event ACK_FAILURE_REPORT = MAKE_EVENT(7, severity::LOW); + //! [EXPORT] : [COMMENT] Received execution failure report + //!P1: Internal state of MPSoC + static const Event EXE_FAILURE_REPORT = MAKE_EVENT(8, severity::LOW); + //! [EXPORT] : [COMMENT] Expected acknowledgement report but received space packet with other apid + //!P1: Apid of received space packet + //!P2: Internal state of MPSoC + static const Event ACK_INVALID_APID = MAKE_EVENT(9, severity::LOW); + //! [EXPORT] : [COMMENT] Expected execution report but received space packet with other apid + //!P1: Apid of received space packet + //!P2: Internal state of MPSoC + static const Event EXE_INVALID_APID = MAKE_EVENT(10, severity::LOW); + + PlocMPSoCHelper(object_id_t objectId); + virtual ~PlocMPSoCHelper(); + + ReturnValue_t initialize() override; + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_); + void setComCookie(CookieIF* comCookie_); + + /** + * @brief Starts flash write sequence + * + * @param file File with data to write + * + * @return RETURN_OK if successful, otherwise error return value + */ + ReturnValue_t startFlashWrite(std::string file); + + /** + * @brief Can be used to interrupt a running data transfer. + */ + void stopProcess(); + + /** + * @brief Sets the sequence count object responsible for the sequence count handling + */ + void setSequenceCount(MPSoCSequenceCount* sequenceCount_); + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER; + + // Maximum number of times the communication interface retries polling data from the reply + // buffer + static const int RETRIES = 3; + + class FlashWrite { + public: + static const std::string file; + }; + + FlashWrite flashWrite; + + enum class InternalState { + IDLE, + FLASH_WRITE, + FLASH_READ + }; + + InternalState internalState = InternalState::IDLE; + + BinarySemaphore semaphore; + + SdCardManager* sdcMan = nullptr; + + uint8_t commandBuffer[mpsoc::MAX_COMMAND_SIZE]; + + bool terminate = false; + + /** + * Communication interface of MPSoC responsible for low level access. Must be set by the + * MPSoC Handler. + */ + UartComIF* uartComIF = nullptr; + // Communication cookie. Must be set by the MPSoC Handler + CookieIF* comCookie = nullptr; + // Sequence count, must be set by Ploc MPSoC Handler + MPSoCSequenceCount* sequenceCount; + + ReturnValue_t performFlashWrite(); + ReturnValue_t sendCommand(TcBase* tc); + ReturnValue_t receive(uint8_t* data, size_t* readBytes, size_t requestBytes); + ReturnValue_t handleAck(); + ReturnValue_t handleExe(); + void handleAckApidFailure(uint16_t apid); + void handleExeApidFailure(uint16_t apid); + ReturnValue_t handleTmReception(TmPacket* tmPacket, size_t remainingBytes); +}; + +#endif /* BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp index de70037a..85fb415b 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -81,7 +81,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu return EXECUTION_FINISHED; } case(StarTracker::SET_JSON_FILE_NAME): { - if (size > MAX_PATH_SIZE) { + if (size > config::MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } paramJsonFile = std::string(reinterpret_cast(data), size); @@ -91,8 +91,8 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu break; } - if (strHelperExecuting == true) { - return IMAGE_LOADER_EXECUTING; + if (strHelperExecuting) { + return STR_HELPER_EXECUTING; } result = checkMode(actionId); @@ -107,7 +107,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu if (result != RETURN_OK) { return result; } - if (size > MAX_PATH_SIZE + MAX_FILE_NAME) { + if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { return FILE_PATH_TOO_LONG; } result = strHelper->startImageUpload( @@ -123,7 +123,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu if (result != RETURN_OK) { return result; } - if (size > MAX_PATH_SIZE) { + if (size > config::MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } result = strHelper->startImageDownload( @@ -160,7 +160,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu return EXECUTION_FINISHED; } case(StarTracker::CHANGE_DOWNLOAD_FILE): { - if (size > MAX_FILE_NAME) { + if (size > config::MAX_FILENAME_SIZE) { return FILENAME_TOO_LONG; } strHelper->setDownloadImageName( @@ -168,14 +168,14 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu return EXECUTION_FINISHED; } case(StarTracker::CHANGE_FPGA_DOWNLOAD_FILE): { - if (size > MAX_FILE_NAME) { + if (size > config::MAX_FILENAME_SIZE) { return FILENAME_TOO_LONG; } strHelper->setDownloadFpgaImage(std::string(reinterpret_cast(data), size)); return EXECUTION_FINISHED; } case(StarTracker::SET_READ_FILENAME): { - if (size > MAX_FILE_NAME) { + if (size > config::MAX_FILENAME_SIZE) { return FILENAME_TOO_LONG; } strHelper->setDownloadImageName( @@ -187,7 +187,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu if (result != RETURN_OK) { return result; } - if (size > MAX_PATH_SIZE) { + if (size > config::MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } result = executeFpgaDownloadCommand(data, size); @@ -202,7 +202,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu if (result != RETURN_OK) { return result; } - if (size > MAX_PATH_SIZE + MAX_FILE_NAME) { + if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { return FILE_PATH_TOO_LONG; } result = strHelper->startFpgaUpload(std::string(reinterpret_cast(data), size)); @@ -1170,7 +1170,7 @@ ReturnValue_t StarTrackerHandler::executeWriteCommand(const uint8_t* commandData << std::endl; return result; } - if (commandDataLen - sizeof(address) - sizeof(region) > MAX_PATH_SIZE) { + if (commandDataLen - sizeof(address) - sizeof(region) > config::MAX_PATH_SIZE) { sif::warning << "StarTrackerHandler::executeWriteCommand: Received command with invalid" << " path and filename" << std::endl; return FILE_PATH_TOO_LONG; @@ -1211,7 +1211,7 @@ ReturnValue_t StarTrackerHandler::executeFpgaDownloadCommand(const uint8_t* comm << std::endl; return result; } - if (commandDataLen - sizeof(position) - sizeof(length) > MAX_PATH_SIZE) { + if (commandDataLen - sizeof(position) - sizeof(length) > config::MAX_PATH_SIZE) { sif::warning << "StarTrackerHandler::executeFpgaDownloadCommand: Received command with " " invalid path and filename" << std::endl; return FILE_PATH_TOO_LONG; @@ -1253,7 +1253,7 @@ ReturnValue_t StarTrackerHandler::executeReadCommand(const uint8_t* commandData, << std::endl; return result; } - if (commandDataLen - sizeof(address) - sizeof(region) - sizeof(length) > MAX_PATH_SIZE) { + if (commandDataLen - sizeof(address) - sizeof(region) - sizeof(length) > config::MAX_PATH_SIZE) { sif::warning << "StarTrackerHandler::executeReadCommand: Received command with invalid" << " path and filename" << std::endl; return FILE_PATH_TOO_LONG; @@ -1397,7 +1397,7 @@ ReturnValue_t StarTrackerHandler::prepareDownloadCentroidCommand(const uint8_t* ReturnValue_t StarTrackerHandler::prepareUploadCentroidCommand(const uint8_t* commandData, size_t commandDataLen) { - if (commandDataLen > MAX_PATH_SIZE) { + if (commandDataLen > config::MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } ReturnValue_t result = RETURN_OK; @@ -1616,7 +1616,7 @@ void StarTrackerHandler::prepareErrorResetRequest() { ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, ArcsecJsonParamBase& paramSet) { ReturnValue_t result = RETURN_OK; - if (commandDataLen > MAX_PATH_SIZE) { + if (commandDataLen > config::MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } std::string fullName(reinterpret_cast(commandData), commandDataLen); diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.h b/bsp_q7s/devices/startracker/StarTrackerHandler.h index 65bd65b8..2f58a145 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.h +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.h @@ -78,8 +78,8 @@ private: static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB0); //! [EXPORT] : [COMMENT] Received reply with invalid CRC static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB1); - //! [EXPORT] : [COMMENT] Image loader executing - static const ReturnValue_t IMAGE_LOADER_EXECUTING = MAKE_RETURN_CODE(0xB2); + //! [EXPORT] : [COMMENT] Star tracker helper class currently executing a command + static const ReturnValue_t STR_HELPER_EXECUTING = MAKE_RETURN_CODE(0xB2); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; diff --git a/bsp_q7s/devices/startracker/StrHelper.cpp b/bsp_q7s/devices/startracker/StrHelper.cpp index 0be38ad7..8e1f2622 100644 --- a/bsp_q7s/devices/startracker/StrHelper.cpp +++ b/bsp_q7s/devices/startracker/StrHelper.cpp @@ -1,7 +1,6 @@ #include "StrHelper.h" - #include "mission/utility/Timestamp.h" - +#include "bsp_q7s/memory/FilesystemHelper.h" #include #include @@ -117,7 +116,7 @@ void StrHelper::setComCookie(CookieIF* comCookie_) { } ReturnValue_t StrHelper::startImageUpload(std::string fullname) { - ReturnValue_t result = checkPath(fullname); + ReturnValue_t result = FilesystemHelper::checkPath(fullname); if (result != RETURN_OK) { return result; } @@ -132,7 +131,7 @@ ReturnValue_t StrHelper::startImageUpload(std::string fullname) { } ReturnValue_t StrHelper::startImageDownload(std::string path) { - ReturnValue_t result = checkPath(path); + ReturnValue_t result = FilesystemHelper::checkPath(path); if (result != RETURN_OK) { return result; } @@ -164,7 +163,7 @@ void StrHelper::setDownloadFpgaImage(std::string filename) { ReturnValue_t StrHelper::startFlashWrite(std::string fullname, uint8_t region, uint32_t address) { - ReturnValue_t result = checkPath(fullname); + ReturnValue_t result = FilesystemHelper::checkPath(fullname); if (result != RETURN_OK) { return result; } @@ -182,7 +181,7 @@ ReturnValue_t StrHelper::startFlashWrite(std::string fullname, uint8_t region, ReturnValue_t StrHelper::startFlashRead(std::string path, uint8_t region, uint32_t address, uint32_t length) { - ReturnValue_t result = checkPath(path); + ReturnValue_t result = FilesystemHelper::checkPath(path); if (result != RETURN_OK) { return result; } @@ -683,20 +682,3 @@ ReturnValue_t StrHelper::checkFpgaActionReply(uint32_t expectedPosition, } return result; } - -ReturnValue_t StrHelper::checkPath(std::string name) { - if (name.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) - == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StrHelper::checkPath: SD card 0 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } else if (name.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) - == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StrHelper::checkPath: SD card 1 not mounted" << std::endl; - return SD_NOT_MOUNTED; - } - } - return RETURN_OK; -} diff --git a/bsp_q7s/devices/startracker/StrHelper.h b/bsp_q7s/devices/startracker/StrHelper.h index 7f8ba654..c8aa7393 100644 --- a/bsp_q7s/devices/startracker/StrHelper.h +++ b/bsp_q7s/devices/startracker/StrHelper.h @@ -60,11 +60,11 @@ public: //!P1: Position of upload or download packet for which no reply was sent static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(14, severity::LOW); //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred - //P1: Return value of decoding function - //P2: Position of upload/download packet, or address of flash write/read request + //!P1: Return value of decoding function + //!P2: Position of upload/download packet, or address of flash write/read request static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(15, severity::LOW); //! [EXPORT] : [COMMENT] Position mismatch - //! P1: The expected position and thus the position for which the image upload/download failed + //!P1: The expected position and thus the position for which the image upload/download failed static const Event POSITION_MISMATCH = MAKE_EVENT(16, severity::LOW); //! [EXPORT] : [COMMENT] Specified file does not exist //!P1: Internal state of str helper @@ -163,8 +163,6 @@ private: static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; - //! [EXPORT] : [COMMENT] SD card specified in path string not mounted - static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); //! [EXPORT] : [COMMENT] Specified path does not exist @@ -382,13 +380,6 @@ private: * @param expectedLength The expected length field in the reply */ ReturnValue_t checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength); - - /** - * @brief Checks if a path points to an sd card and whether the SD card is monuted. - * - * @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK - */ - ReturnValue_t checkPath(std::string name); }; #endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */ diff --git a/bsp_q7s/memory/FilesystemHelper.cpp b/bsp_q7s/memory/FilesystemHelper.cpp new file mode 100644 index 00000000..7413541f --- /dev/null +++ b/bsp_q7s/memory/FilesystemHelper.cpp @@ -0,0 +1,34 @@ +#include "FilesystemHelper.h" +#include "bsp_q7s/memory/SdCardManager.h" + +FilesystemHelper::FilesystemHelper() { +} + +FilesystemHelper::~FilesystemHelper() { +} + +ReturnValue_t FilesystemHelper::checkPath(std::string path) { + SdCardManager sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "FilesystemHelper::checkPath: Invalid SD card manager" << std::endl; + return RETURN_FAILED; + } + if (path.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) + == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "FilesystemHelper::checkPath: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } else if (path.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) + == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "FilesystemHelper::checkPath: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + return RETURN_OK; +} + +ReturnValue_t FilesystemHelper::fileExists(std::string file) { + +} diff --git a/bsp_q7s/memory/FilesystemHelper.h b/bsp_q7s/memory/FilesystemHelper.h new file mode 100644 index 00000000..4efe74c0 --- /dev/null +++ b/bsp_q7s/memory/FilesystemHelper.h @@ -0,0 +1,47 @@ +#ifndef BSP_Q7S_MEMORY_FILESYSTEMHELPER_H_ +#define BSP_Q7S_MEMORY_FILESYSTEMHELPER_H_ + +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +/** + * @brief This class implements often used functions concerning the file system management. + * + * @author J. Meier + */ +class FilesystemHelper : public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::FILE_SYSTEM_HELPER; + + //! [EXPORT] : [COMMENT] SD card specified with path string not mounted + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); + + FilesystemHelper(); + virtual ~FilesystemHelper(); + + /** + * @brief In case the path points to a directory on the sd card the function checks if the + * appropriate SD card is mounted. + * + * @param path Path to check + * + * @return RETURN_OK if path points to SD card and the appropriate SD card is mounted or if + * path does not point to SD card. + * Return error code if path points to SD card and the corresponding SD card is not + * mounted. + */ + static const ReturnValue_t checkPath(std::string path); + + /** + * @brief Checks if the file exists on the filesystem. + * + * param file File to check + * + * @return RETURN_OK if fiel exists, otherwise return error code. + */ + static const ReturnValue_t fileExists(std::string file); +}; + +#endif /* BSP_Q7S_MEMORY_FILESYSTEMHELPER_H_ */ diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 06ee63b6..aff16097 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -15,6 +15,7 @@ enum commonClassIds: uint8_t { STR_HANDLER, //STRH PLOC_MPSOC_HANDLER, //PLMP MPSOC_CMD, //MPCMD + MPSOC_TM, //MPTM PLOC_SUPERVISOR_HANDLER, //PLSV SUS_HANDLER, //SUSS CCSDS_IP_CORE_BRIDGE, //IPCI @@ -27,6 +28,8 @@ enum commonClassIds: uint8_t { CCSDS_HANDLER, //CCSDS ARCSEC_JSON_BASE, //JSONBASE NVM_PARAM_BASE, //NVMB + FILE_SYSTEM_HELPER, //FSHLP + PLOC_MPSOC_HELPER, // PLMPHLP COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 55a4bed4..2e07f887 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -19,6 +19,7 @@ enum: uint8_t { PLOC_MEMORY_DUMPER = 118, PDEC_HANDLER = 119, STR_HELPER = 120, + PLOC_MPSOC_HELPER = 121, COMMON_SUBSYSTEM_ID_END }; } diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 4a7bca35..30192ead 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -131,8 +131,9 @@ namespace config { /* Add mission configuration flags here */ static constexpr uint32_t OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE = 50; static constexpr uint32_t PLOC_UPDATER_QUEUE_SIZE = 50; -static constexpr uint32_t STR_IMG_HELPER_QUEUE_SIZE = 50; - +/* Global config values to check validity of received file path strings and filenames */ +static constexpr uint32_t MAX_PATH_SIZE = 100; +static constexpr uint32_t MAX_FILENAME_SIZE = 50; static constexpr uint8_t LIVE_TM = 0; #ifdef __cplusplus diff --git a/tmtc b/tmtc index 734dc5ae..5816f05c 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 734dc5aef88d9fef4ad59817b6ea315db954205c +Subproject commit 5816f05ccf8971f3cf2dd1d603dd3f5a33f6f504