diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b9e000d7..5c4710d4 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -99,18 +99,6 @@ void CoreController::performControlOperation() { } sdStateMachine(); performMountedSdCardOperations(); - // TODO: Remove if not required. The filesystem is not re-mounted read-only - // when using ext4 -// if (sdCardCheckCd.hasTimedOut()) { -// if (shortSdCardCdCounter < 2) { -// shortSdCardCdCounter++; -// } -// if (shortSdCardCdCounter == 2) { -// sdCardCheckCd.setTimeout(DEFAULT_SD_CARD_CHECK_TIMEOUT); -// } -// performSdCardCheck(); -// sdCardCheckCd.resetTimer(); -// } readHkData(); opDivider5.checkAndIncrement(); opDivider10.checkAndIncrement(); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index b3a9e751..3092e69d 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -785,13 +785,15 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE); // Core task which handles the HK store and takes care of dumping it as TM using a VC directly new PersistentSingleTmStoreTask(objects::HK_STORE_AND_TM_TASK, args.ipcStore, - *args.stores.hkStore, *vc, *SdCardManager::instance()); + *args.stores.hkStore, *vc, persTmStore::DUMP_HK_STORE_DONE, + *SdCardManager::instance()); vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme, LINK_STATE); // Core task which handles the CFDP store and takes care of dumping it as TM using a VC directly new PersistentSingleTmStoreTask(objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, - *args.stores.cfdpStore, *vc, *SdCardManager::instance()); + *args.stores.cfdpStore, *vc, persTmStore::DUMP_CFDP_STORE_DONE, + *SdCardManager::instance()); ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); if (result != returnvalue::OK) { diff --git a/common/config/eive/resultClassIds.h b/common/config/eive/resultClassIds.h index 125dd79a..9bad9ae3 100644 --- a/common/config/eive/resultClassIds.h +++ b/common/config/eive/resultClassIds.h @@ -43,6 +43,7 @@ enum commonClassIds : uint8_t { SD_CARD_MANAGER, // SDMA LOCAL_PARAM_HANDLER, // LPH PERSISTENT_TM_STORE, // PTM + TM_SINK, // TMS COMMON_CLASS_ID_END // [EXPORT] : [END] }; } diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 35554f5d..76024784 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,8 @@ #include "objects/systemObjectList.h" #include "tmtc/pusIds.h" +using persTmStore::PersistentTmStores; + #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 // UDP server includes diff --git a/mission/core/GenericFactory.h b/mission/core/GenericFactory.h index 6fb5d73d..1c5e9ce6 100644 --- a/mission/core/GenericFactory.h +++ b/mission/core/GenericFactory.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "fsfw/objectmanager/SystemObjectIF.h" @@ -10,6 +11,8 @@ #include "fsfw_hal/common/gpio/GpioIF.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" +using persTmStore::PersistentTmStores; + class HeaterHandler; class HealthTableIF; class PusTmFunnel; @@ -36,14 +39,6 @@ const std::array, EiveMax31855::NUM_RTDS> RT {objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"}, }}; -struct PersistentTmStores { - PersistentTmStoreWithTmQueue* okStore; - PersistentTmStoreWithTmQueue* notOkStore; - PersistentTmStoreWithTmQueue* miscStore; - PersistentTmStoreWithTmQueue* hkStore; - PersistentTmStoreWithTmQueue* cfdpStore; -}; - namespace ObjectFactory { void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel, diff --git a/mission/persistentTmStoreDefs.h b/mission/persistentTmStoreDefs.h new file mode 100644 index 00000000..021f6f89 --- /dev/null +++ b/mission/persistentTmStoreDefs.h @@ -0,0 +1,41 @@ +#ifndef MISSION_PERSISTENTTMSTOREDEFS_H_ +#define MISSION_PERSISTENTTMSTOREDEFS_H_ + +#include + +#include "eive/eventSubsystemIds.h" + +namespace persTmStore { + +struct PersistentTmStores { + PersistentTmStoreWithTmQueue* okStore; + PersistentTmStoreWithTmQueue* notOkStore; + PersistentTmStoreWithTmQueue* miscStore; + PersistentTmStoreWithTmQueue* hkStore; + PersistentTmStoreWithTmQueue* cfdpStore; +}; + +static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE; + +//! [EXPORT] : [COMMENT] +//! P1: Result code of TM packet parser. +//! P2: Timestamp of possibly corrupt file as a unix timestamp. +static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); +//! [EXPORT] : [COMMENT] File in store too large. P1: Detected file size +//! P2: Allowed file size +static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW); +static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO); + +//! [EXPORT] : [COMMENT] P1: Start time as UNIX seconds. P2: End time as UNIX seconds. +static constexpr Event DUMP_OK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 3, severity::INFO); +//! [EXPORT] : [COMMENT] P1: Start time as UNIX seconds. P2: End time as UNIX seconds. +static constexpr Event DUMP_NOK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 4, severity::INFO); +//! [EXPORT] : [COMMENT] P1: Start time as UNIX seconds. P2: End time as UNIX seconds. +static constexpr Event DUMP_MISC_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO); +//! [EXPORT] : [COMMENT] P1: Start time as UNIX seconds. P2: End time as UNIX seconds. +static constexpr Event DUMP_HK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO); +//! [EXPORT] : [COMMENT] P1: Start time as UNIX seconds. P2: End time as UNIX seconds. +static constexpr Event DUMP_CFDP_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO); +}; // namespace persTmStore + +#endif /* MISSION_PERSISTENTTMSTOREDEFS_H_ */ diff --git a/mission/tmtc/DirectTmSinkIF.h b/mission/tmtc/DirectTmSinkIF.h index ae7997ca..11a17c79 100644 --- a/mission/tmtc/DirectTmSinkIF.h +++ b/mission/tmtc/DirectTmSinkIF.h @@ -3,17 +3,24 @@ #include +#include "eive/resultClassIds.h" #include "fsfw/retval.h" class DirectTmSinkIF { public: virtual ~DirectTmSinkIF() = default; + static constexpr uint8_t CLASS_ID = CLASS_ID::TM_SINK; + + static constexpr ReturnValue_t IS_BUSY = returnvalue::makeCode(CLASS_ID, 0); + /** - * @brief Implememts the functionality to write to a TM sink directly + * @brief Implements the functionality to write to a TM sink directly * * @param data Pointer to buffer holding the data to write * @param size Number of bytes to write + * @return returnvalue::OK on success, returnvalue::FAILED on failure, IS_BUSY + * if the TM sink is busy. */ virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0; diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 75bea255..3d0d99ee 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -15,15 +15,15 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { } bool someonesBusy = false; bool busy = false; - busy = handleOneStore(stores.okStore, tcHandlingCd); + busy = handleOneStore(stores.okStore, persTmStore::DUMP_OK_STORE_DONE); if (busy) { someonesBusy = true; } - busy = handleOneStore(stores.notOkStore, tcHandlingCd); + busy = handleOneStore(stores.notOkStore, persTmStore::DUMP_NOK_STORE_DONE); if (busy) { someonesBusy = true; } - busy = handleOneStore(stores.miscStore, tcHandlingCd); + busy = handleOneStore(stores.miscStore, persTmStore::DUMP_MISC_STORE_DONE); if (busy) { someonesBusy = true; } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 3cd8da37..e3e1688e 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -2,12 +2,12 @@ #include #include -PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(object_id_t objectId, - StorageManagerIF& ipcStore, - PersistentTmStoreWithTmQueue& tmStore, - VirtualChannel& channel, - SdCardMountedIF& sdcMan) - : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), storeWithQueue(tmStore) {} +PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( + object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore, + VirtualChannel& channel, Event eventIfDumpDone, SdCardMountedIF& sdcMan) + : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), + storeWithQueue(tmStore), + eventIfDumpDone(eventIfDumpDone) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { while (true) { @@ -15,7 +15,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { if (not cyclicStoreCheck()) { continue; } - bool busy = handleOneStore(storeWithQueue, tcHandlingCd); + bool busy = handleOneStore(storeWithQueue, eventIfDumpDone); if (not busy) { TaskFactory::delayTask(40); } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.h b/mission/tmtc/PersistentSingleTmStoreTask.h index d7a021d1..2fc9ece1 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.h +++ b/mission/tmtc/PersistentSingleTmStoreTask.h @@ -11,12 +11,13 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj public: PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel, - SdCardMountedIF& sdcMan); + Event eventIfDumpDone, SdCardMountedIF& sdcMan); ReturnValue_t performOperation(uint8_t opCode) override; private: PersistentTmStoreWithTmQueue& storeWithQueue; + Event eventIfDumpDone; Countdown tcHandlingCd = Countdown(400); bool initStoresIfPossible(); diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index ddd53b93..795957a6 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -12,6 +12,7 @@ #include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/tmstorage/TmStoreMessage.h" +#include "mission/persistentTmStoreDefs.h" using namespace returnvalue; @@ -65,7 +66,7 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore) SerializeIF::Endianness::NETWORK); result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds); if (result != returnvalue::OK and result == BUSY_DUMPING) { - triggerEvent(BUSY_DUMPING_EVENT); + triggerEvent(persTmStore::BUSY_DUMPING_EVENT); } } } @@ -179,7 +180,7 @@ ReturnValue_t PersistentTmStore::startDumpFromUpTo(uint32_t fromUnixSeconds, return returnvalue::FAILED; } dumpParams.dirIter = directory_iterator(basePath); - if(dumpParams.dirIter == directory_iterator()) { + if (dumpParams.dirIter == directory_iterator()) { return returnvalue::FAILED; } dumpParams.fromUnixTime = fromUnixSeconds; @@ -215,7 +216,7 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() { } if (dumpParams.fileSize > fileBuf.size()) { sif::error << "PersistentTmStore: File too large, is deleted" << std::endl; - triggerEvent(FILE_TOO_LARGE, dumpParams.fileSize, fileBuf.size()); + triggerEvent(persTmStore::FILE_TOO_LARGE, dumpParams.fileSize, fileBuf.size()); std::filesystem::remove(dumpParams.dirEntry.path(), e); continue; } @@ -258,9 +259,12 @@ ReturnValue_t PersistentTmStore::dumpNextPacket(DirectTmSinkIF& tmSink, size_t& ReturnValue_t result = reader.parseDataWithCrcCheck(); if (result == returnvalue::OK) { result = tmSink.write(fileBuf.data() + dumpParams.currentSize, reader.getFullPacketLen()); - if (result != returnvalue::OK) { + if (result == DirectTmSinkIF::IS_BUSY) { + return result; + } else if (result != returnvalue::OK) { // TODO: Event? sif::error << "PersistentTmStore: Writing to TM sink failed" << std::endl; + return result; } dumpParams.currentSize += reader.getFullPacketLen(); dumpedLen = reader.getFullPacketLen(); @@ -270,7 +274,7 @@ ReturnValue_t PersistentTmStore::dumpNextPacket(DirectTmSinkIF& tmSink, size_t& } } else { sif::error << "PersistentTmStore: Parsing of PUS TM failed with code " << result << std::endl; - triggerEvent(POSSIBLE_FILE_CORRUPTION, result, dumpParams.currentFileUnixStamp); + triggerEvent(persTmStore::POSSIBLE_FILE_CORRUPTION, result, dumpParams.currentFileUnixStamp); // Delete the file and load next. Could use better algorithm to partially // restore the file dump, but for now do not trust the file. dumpedLen = 0; @@ -338,3 +342,9 @@ ReturnValue_t PersistentTmStore::initializeTmStore() { } PersistentTmStore::State PersistentTmStore::getState() const { return state; } + +void PersistentTmStore::getStartAndEndTimeCurrentOrLastDump(uint32_t& startTime, + uint32_t& endTime) const { + startTime = dumpParams.fromUnixTime; + endTime = dumpParams.untilUnixTime; +} diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 3274a64c..994b7d30 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -45,18 +45,6 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { static constexpr ReturnValue_t DUMP_DONE = returnvalue::makeCode(INTERFACE_ID, 0); static constexpr ReturnValue_t BUSY_DUMPING = returnvalue::makeCode(INTERFACE_ID, 1); - static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE; - - //! [EXPORT] : [COMMENT] - //! P1: Result code of TM packet parser. - //! P2: Timestamp of possibly corrupt file as a unix timestamp. - static constexpr Event POSSIBLE_FILE_CORRUPTION = - event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); - //! [EXPORT] : [COMMENT] File in store too large. P1: Detected file size - //! P2: Allowed file size - static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW); - static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO); - PersistentTmStore(PersistentTmStoreArgs args); ReturnValue_t initializeTmStore(); @@ -66,8 +54,17 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { void deleteUpTo(uint32_t unixSeconds); ReturnValue_t startDumpFrom(uint32_t fromUnixSeconds); ReturnValue_t startDumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds); + /** + * + * @param tmSink + * @param dumpedLen + * @param fileHasSwapped + * @return DUMP_DONE if dump is finished, returnvalue::OK if dump of next packet was a success, + * and DirectTmSinkIF::IS_BUSY is TM sink is busy. + */ ReturnValue_t dumpNextPacket(DirectTmSinkIF& tmSink, size_t& dumpedLen, bool& fileHasSwapped); + void getStartAndEndTimeCurrentOrLastDump(uint32_t& startTime, uint32_t& endTime) const; ReturnValue_t storePacket(PusTmReader& reader); protected: diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index 008735c4..1bd34ce0 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -7,7 +7,7 @@ TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStor VirtualChannel& channel, SdCardMountedIF& sdcMan) : SystemObject(objectId), ipcStore(ipcStore), channel(channel), sdcMan(sdcMan) {} -bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, Countdown& tcHandlingCd) { +bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, Event eventIfDone) { ReturnValue_t result; bool tmToStoreReceived = true; bool tcRequestReceived = true; @@ -22,10 +22,15 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, Countd size_t dumpedLen; bool fileHasSwapped; if (not channel.isBusy()) { - // TODO: Maybe do a bit of a delay every 100-200 packets? // TODO: We could continously dump until a file swap during active downlink.. result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); - if (result == returnvalue::OK) { + if (result == PersistentTmStore::DUMP_DONE) { + uint32_t startTime; + uint32_t endTime; + store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); + triggerEvent(eventIfDone, startTime, endTime); + dumpsPerformed = true; + } else if (result == returnvalue::OK) { dumpsPerformed = true; } } diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 16042de6..aa308590 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -16,7 +16,7 @@ class TmStoreTaskBase : public SystemObject { * @param store * @return */ - bool handleOneStore(PersistentTmStoreWithTmQueue& store, Countdown& tcHandlingCd); + bool handleOneStore(PersistentTmStoreWithTmQueue& store, Event eventIfDone); /** * Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to