From 53c839e3890ec0668516bceb50218a1373b94f2f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 14:53:18 +0200 Subject: [PATCH 01/53] proper fault/ext ctrl handling for dual side --- mission/system/acs/AcsBoardAssembly.cpp | 34 ++++++++++++++----------- mission/system/acs/SusAssembly.cpp | 25 +++++++++++++----- tmtc | 2 +- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/mission/system/acs/AcsBoardAssembly.cpp b/mission/system/acs/AcsBoardAssembly.cpp index 2441beda..08711f76 100644 --- a/mission/system/acs/AcsBoardAssembly.cpp +++ b/mission/system/acs/AcsBoardAssembly.cpp @@ -289,25 +289,29 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode) { using namespace returnvalue; ReturnValue_t status = returnvalue::OK; - auto overwriteHealthForOneDev = [&](object_id_t dev) { - HealthState health = healthHelper.healthTable->getHealth(dev); - if (health == FAULTY or health == PERMANENT_FAULTY) { - overwriteDeviceHealth(dev, health); - status = NEED_TO_CHANGE_HEALTH; - } else if (health == EXTERNAL_CONTROL) { + auto checkAcsBoardSensorGroup = [&](object_id_t o0, object_id_t o1, object_id_t o2, + object_id_t o3) { + HealthState h0 = healthHelper.healthTable->getHealth(o0); + HealthState h1 = healthHelper.healthTable->getHealth(o1); + HealthState h2 = healthHelper.healthTable->getHealth(o2); + HealthState h3 = healthHelper.healthTable->getHealth(o3); + if ((h0 == FAULTY or h0 == PERMANENT_FAULTY) and (h1 == FAULTY or h1 == PERMANENT_FAULTY) and + (h2 == FAULTY or h2 == PERMANENT_FAULTY) and (h3 == FAULTY or h3 == PERMANENT_FAULTY)) { + overwriteDeviceHealth(o0, h0); + overwriteDeviceHealth(o1, h1); + overwriteDeviceHealth(o2, h2); + overwriteDeviceHealth(o3, h3); + } + if (h0 == EXTERNAL_CONTROL or h1 == EXTERNAL_CONTROL or h2 == EXTERNAL_CONTROL or + h3 == EXTERNAL_CONTROL) { modeHelper.setForced(true); } }; if (deviceSubmode == duallane::DUAL_MODE) { - overwriteHealthForOneDev(helper.mgm0Lis3IdSideA); - overwriteHealthForOneDev(helper.mgm1Rm3100IdSideA); - overwriteHealthForOneDev(helper.mgm2Lis3IdSideB); - overwriteHealthForOneDev(helper.mgm3Rm3100IdSideB); - overwriteHealthForOneDev(helper.gyro0AdisIdSideA); - overwriteHealthForOneDev(helper.gyro1L3gIdSideA); - overwriteHealthForOneDev(helper.gyro2AdisIdSideB); - overwriteHealthForOneDev(helper.gyro3L3gIdSideB); - overwriteHealthForOneDev(helper.gpsId); + checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA, + helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB); + checkAcsBoardSensorGroup(helper.gyro0AdisIdSideA, helper.gyro1L3gIdSideA, + helper.gyro2AdisIdSideB, helper.gyro3L3gIdSideB); } return status; } diff --git a/mission/system/acs/SusAssembly.cpp b/mission/system/acs/SusAssembly.cpp index 9008e7e0..45123ce4 100644 --- a/mission/system/acs/SusAssembly.cpp +++ b/mission/system/acs/SusAssembly.cpp @@ -158,18 +158,29 @@ void SusAssembly::refreshHelperModes() { ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode) { using namespace returnvalue; ReturnValue_t status = returnvalue::OK; - auto overwriteHealthForOneDev = [&](object_id_t dev) { + auto checkSusGroup = [&](object_id_t devNom, object_id_t devRed) { + HealthState healthNom = healthHelper.healthTable->getHealth(devNom); + HealthState healthRed = healthHelper.healthTable->getHealth(devRed); + if ((healthNom == FAULTY or healthNom == PERMANENT_FAULTY) and + (healthRed == FAULTY or healthRed == PERMANENT_FAULTY)) { + overwriteDeviceHealth(devNom, healthNom); + overwriteDeviceHealth(devRed, healthRed); + } + }; + auto checkHealthForOneDev = [&](object_id_t dev) { HealthState health = healthHelper.healthTable->getHealth(dev); - if (health == FAULTY or health == PERMANENT_FAULTY) { - overwriteDeviceHealth(dev, health); - status = NEED_TO_CHANGE_HEALTH; - } else if (health == EXTERNAL_CONTROL) { + if (health == EXTERNAL_CONTROL) { modeHelper.setForced(true); } }; if (deviceSubmode == duallane::DUAL_MODE) { - for (uint8_t idx = 0; idx < 12; idx++) { - overwriteHealthForOneDev(helper.susIds[idx]); + uint8_t idx = 0; + for (idx = 0; idx < 6; idx++) { + checkSusGroup(helper.susIds[idx], helper.susIds[idx + 6]); + checkHealthForOneDev(helper.susIds[idx]); + } + for (idx = 6; idx < 12; idx++) { + checkHealthForOneDev(helper.susIds[idx]); } } return status; diff --git a/tmtc b/tmtc index f6fcb2fb..333faaa5 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f6fcb2fb282d79b1e250722eba46a319603b0232 +Subproject commit 333faaa5f70646bfde1101f8e0538505574d1d7e From c53c052876eade22eda09ff92dab7b9e96ccabae Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 17:02:02 +0200 Subject: [PATCH 02/53] lower delays --- linux/ipcore/PapbVcInterface.cpp | 17 ++++++++++------- linux/ipcore/PapbVcInterface.h | 4 +++- mission/tmtc/PersistentLogTmStoreTask.cpp | 8 ++------ mission/tmtc/PersistentSingleTmStoreTask.cpp | 10 ++-------- mission/tmtc/PersistentTmStore.cpp | 2 +- tmtc | 2 +- 6 files changed, 19 insertions(+), 24 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 8c98df90..57dcb963 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -26,20 +26,20 @@ ReturnValue_t PapbVcInterface::initialize() { } ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { - if (pollPapbBusySignal(0, 0) == returnvalue::OK) { + if (pollPapbBusySignal(0) == returnvalue::OK) { startPacketTransfer(); } else { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - if (pollPapbBusySignal(10, 10) == returnvalue::OK) { + if (pollPapbBusySignal(5) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - if (pollPapbBusySignal(10, 10) == returnvalue::OK) { + if (pollPapbBusySignal(5) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); @@ -52,11 +52,11 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; } void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } -ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries, - uint32_t retryDelayUs) const { +ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const { gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; + uint32_t nextDelay = 1; while (true) { /** Check if PAPB interface is ready to receive data */ @@ -75,7 +75,10 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries, return PAPB_BUSY; } - usleep(retryDelayUs); + usleep(nextDelay); + if (nextDelay * 2 <= MAX_DELAY_PAPB_POLLING_US) { + nextDelay *= 2; + } } return returnvalue::OK; } @@ -100,7 +103,7 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() { return; } -bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0, 0) == PAPB_BUSY; } +bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0) == PAPB_BUSY; } void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); } diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 7491398c..f0cd327b 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -76,6 +76,8 @@ class PapbVcInterface : public VirtualChannelIF { */ static const int DATA_REG_OFFSET = 256; + static constexpr uint32_t MAX_DELAY_PAPB_POLLING_US = 4; + LinuxLibgpioIF* gpioComIF = nullptr; /** Pulled to low when virtual channel not ready to receive data */ @@ -111,7 +113,7 @@ class PapbVcInterface : public VirtualChannelIF { * * @return returnvalue::OK when ready to receive data else PAPB_BUSY. */ - ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries, uint32_t retryDelayUs) const; + ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries) const; /** * @brief This function can be used for debugging to check whether there are packets in diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index ccabb16d..2b7e1333 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -33,12 +33,8 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext)); if (not someonesBusy) { TaskFactory::delayTask(100); - } else /* and graceDelayDuringDumping.hasTimedOut()*/ { - if (someFileWasSwapped) { - TaskFactory::delayTask(20); - } - // TaskFactory::delayTask(2); - // graceDelayDuringDumping.resetTimer(); + } else if (someFileWasSwapped) { + TaskFactory::delayTask(2); } } } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index a814694e..32ae06c4 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -18,14 +18,8 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { TaskFactory::delayTask(100); - } else { - if (fileHasSwapped) { - TaskFactory::delayTask(20); - } - // if (fileHasSwapped and graceDelayDuringDumping.hasTimedOut()) { - // TaskFactory::delayTask(2); - // graceDelayDuringDumping.resetTimer(); - // } + } else if (fileHasSwapped) { + TaskFactory::delayTask(2); } } } diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 6cbcac86..949657d5 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -212,7 +212,7 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() { sif::error << "PersistentTmStore: Could not retrieve file size: " << e.message() << std::endl; continue; } - sif::debug << "Path: " << dumpParams.dirEntry.path() << std::endl; + // sif::debug << "Path: " << dumpParams.dirEntry.path() << std::endl; // File empty or can't even read CCSDS header. if (dumpParams.fileSize <= 6) { diff --git a/tmtc b/tmtc index f6fcb2fb..3f352346 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f6fcb2fb282d79b1e250722eba46a319603b0232 +Subproject commit 3f3523465a141bc2a2c36cbc9cbbf6ab7b3a9d70 From 1a0e632d2f442f13a439a35fa8d270641d041568 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 17:42:54 +0200 Subject: [PATCH 03/53] go down to nanoseconds --- linux/ipcore/PapbVcInterface.cpp | 9 +++++---- linux/ipcore/PapbVcInterface.h | 3 ++- mission/tmtc/PersistentLogTmStoreTask.cpp | 2 +- mission/tmtc/PersistentSingleTmStoreTask.cpp | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 57dcb963..e41bf23b 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -3,6 +3,7 @@ #include #include "fsfw/serviceinterface/ServiceInterface.h" +#include PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, gpioId_t papbEmptyId, std::string uioFile, int mapNum) @@ -56,7 +57,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; - uint32_t nextDelay = 1; + struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 10}; while (true) { /** Check if PAPB interface is ready to receive data */ @@ -75,9 +76,9 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const return PAPB_BUSY; } - usleep(nextDelay); - if (nextDelay * 2 <= MAX_DELAY_PAPB_POLLING_US) { - nextDelay *= 2; + nanosleep(&nextDelay, const_cast(&remDelay)); + if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { + nextDelay.tv_nsec *= 2; } } return returnvalue::OK; diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index f0cd327b..59200207 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -76,7 +76,7 @@ class PapbVcInterface : public VirtualChannelIF { */ static const int DATA_REG_OFFSET = 256; - static constexpr uint32_t MAX_DELAY_PAPB_POLLING_US = 4; + static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; LinuxLibgpioIF* gpioComIF = nullptr; @@ -87,6 +87,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; + struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 2b7e1333..2f30dafc 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -34,7 +34,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { if (not someonesBusy) { TaskFactory::delayTask(100); } else if (someFileWasSwapped) { - TaskFactory::delayTask(2); + TaskFactory::delayTask(1); } } } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 32ae06c4..693d2c2c 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -19,7 +19,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { if (not busy) { TaskFactory::delayTask(100); } else if (fileHasSwapped) { - TaskFactory::delayTask(2); + TaskFactory::delayTask(1); } } } From 363fc892099ae38aa286f4c81974606a663c9574 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 17:43:52 +0200 Subject: [PATCH 04/53] thsi is cleaner --- linux/ipcore/PapbVcInterface.cpp | 3 ++- linux/ipcore/PapbVcInterface.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index e41bf23b..586bf9b3 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -76,7 +76,8 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const return PAPB_BUSY; } - nanosleep(&nextDelay, const_cast(&remDelay)); + // Ignore signal handling here for now. + nanosleep(&nextDelay, &remDelay); if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { nextDelay.tv_nsec *= 2; } diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 59200207..3d150806 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -87,7 +87,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; - struct timespec remDelay; + mutable struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; From fcb5613aa84c908fbee909d4b69db4671faa2dae Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 17:44:51 +0200 Subject: [PATCH 05/53] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb32c1f..ab321fec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ will consitute of a breaking change warranting a new major release: - Proper Faulty/External Control handling for the dual lane assemblies. - ACS board devices: Go to ON mode instead of going to NORMAL mode directly. - SUS device handlers: Go to ON mode on startup instead of NORMAL mode. +- Tweaks for the delay handling for the persistent TM stores. This allows pushing the full + high datarate when dumping telemetry. ## Changed From f1774fe80f6e5d421ecb385dc99d91ca417e0a20 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 18:13:00 +0200 Subject: [PATCH 06/53] docs --- linux/ipcore/PapbVcInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 586bf9b3..e0773afe 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -78,6 +78,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const // Ignore signal handling here for now. nanosleep(&nextDelay, &remDelay); + // Adaptive delay. if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { nextDelay.tv_nsec *= 2; } From 1727168ee5a200bbd6bc006d300fe28b0379df86 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 18:39:53 +0200 Subject: [PATCH 07/53] now its getitng weird --- linux/ipcore/PapbVcInterface.cpp | 6 +++--- linux/ipcore/PapbVcInterface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index e0773afe..11c520de 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -33,14 +33,14 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - if (pollPapbBusySignal(5) == returnvalue::OK) { + if (pollPapbBusySignal(10) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - if (pollPapbBusySignal(5) == returnvalue::OK) { + if (pollPapbBusySignal(10) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); @@ -57,7 +57,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; - struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 10}; + struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 1000}; while (true) { /** Check if PAPB interface is ready to receive data */ diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 3d150806..17bc6f94 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -76,7 +76,7 @@ class PapbVcInterface : public VirtualChannelIF { */ static const int DATA_REG_OFFSET = 256; - static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; + static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 4000; LinuxLibgpioIF* gpioComIF = nullptr; From 7023fe5c4299521d16aee0ce6b35a258bb73b597 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 18:59:31 +0200 Subject: [PATCH 08/53] this is weird --- linux/ipcore/PapbVcInterface.cpp | 6 +++--- linux/ipcore/PapbVcInterface.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 11c520de..d9ff4ce5 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -33,14 +33,14 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - if (pollPapbBusySignal(10) == returnvalue::OK) { + if (pollPapbBusySignal(20) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - if (pollPapbBusySignal(10) == returnvalue::OK) { + if (pollPapbBusySignal(20) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); @@ -57,7 +57,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; - struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 1000}; + nextDelay.tv_nsec = 1000; while (true) { /** Check if PAPB interface is ready to receive data */ diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 17bc6f94..484390b2 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -87,6 +87,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; + mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 1000}; mutable struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; From fb324516bb497af4541d51017c184d077e63fe47 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 21:23:09 +0200 Subject: [PATCH 09/53] this is insane --- linux/ipcore/PapbVcInterface.cpp | 4 ++-- mission/tmtc/PersistentLogTmStoreTask.cpp | 2 +- mission/tmtc/PersistentSingleTmStoreTask.cpp | 21 +++++++++++++++++++- mission/tmtc/TmStoreTaskBase.cpp | 17 +++++++++++++++- mission/tmtc/TmStoreTaskBase.h | 4 +++- mission/tmtc/VirtualChannel.cpp | 16 +++++++-------- mission/tmtc/VirtualChannel.h | 2 +- 7 files changed, 51 insertions(+), 15 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index d9ff4ce5..df9df839 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -33,14 +33,14 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - if (pollPapbBusySignal(20) == returnvalue::OK) { + if (pollPapbBusySignal(5) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - if (pollPapbBusySignal(20) == returnvalue::OK) { + if (pollPapbBusySignal(5) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 2f30dafc..2b7e1333 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -34,7 +34,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { if (not someonesBusy) { TaskFactory::delayTask(100); } else if (someFileWasSwapped) { - TaskFactory::delayTask(1); + TaskFactory::delayTask(2); } } } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 693d2c2c..01a7c206 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -1,6 +1,7 @@ #include #include #include +#include PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore, @@ -10,6 +11,7 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( dumpContext(eventIfDumpDone) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { + uint32_t dummy = 0; while (true) { // Delay done by the check if (not cyclicStoreCheck()) { @@ -18,9 +20,26 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { TaskFactory::delayTask(100); + } else if(dumpContext.vcBusyDuringDump) { + TaskFactory::delayTask(30); } else if (fileHasSwapped) { - TaskFactory::delayTask(1); + TaskFactory::delayTask(30); + } else if(dumpContext.packetWasDumped and dumpContext.numberOfDumpedPackets % 5 == 0) { + TaskFactory::delayTask(30); + } else { +// dummy++; +// if(dummy % 2000 == 0) { +// sif::warning << "persistent tm store is stupid" << std::endl; +// } + TaskFactory::delayTask(2); +// continue; } + dummy = 0; + //else if(dumpContext.numberOfDumpedPackets % 20 == 0) { + // Manual load management because I don't know what the scheduler is doing.. + // Removing this delay can lead to evil side effects. + //TaskFactory::delayTask(5); + //} } } diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index eefe9dc6..dc32d6e2 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -17,23 +17,33 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, bool tmToStoreReceived = false; bool tcRequestReceived = false; bool dumpsPerformed = false; + fileHasSwapped = false; + // Store TM persistently result = store.handleNextTm(); if (result == returnvalue::OK) { tmToStoreReceived = true; } + dumpContext.vcBusyDuringDump = false; // Dump TMs when applicable if (store.getState() == PersistentTmStore::State::DUMPING) { size_t dumpedLen = 0; if (not channel.isBusy()) { + dumpContext.ptmeBusyCounter = 0; tmSinkBusyCd.resetTimer(); - result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); + bool fileHasSwappedLocal = false; + result = store.dumpNextPacket(channel, dumpedLen, fileHasSwappedLocal); if (result == DirectTmSinkIF::IS_BUSY) { sif::warning << "Unexpected PAPB busy" << std::endl; } if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK) and dumpedLen > 0) { dumpContext.dumpedBytes += dumpedLen; dumpContext.numberOfDumpedPackets += 1; + dumpContext.packetWasDumped = true; + // Only register file swaps if more than 0 bytes were dumped. + if(fileHasSwappedLocal) { + fileHasSwapped = true; + } } if (result == PersistentTmStore::DUMP_DONE) { uint32_t startTime; @@ -46,11 +56,16 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, dumpsPerformed = true; } } else { + dumpContext.vcBusyDuringDump = true; dumpContext.ptmeBusyCounter++; if (dumpContext.ptmeBusyCounter == 50) { + // If this happens, something is probably wrong. sif::warning << "PTME busy for longer period. Dumped length so far: " << dumpContext.dumpedBytes << std::endl; dumpContext.ptmeBusyCounter = 0; + triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); + store.cancelDump(); + channel.cancelTransfer(); } } if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index aa0efbb4..b9a81bec 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -17,6 +17,8 @@ class TmStoreTaskBase : public SystemObject { uint32_t numberOfDumpedPackets = 0; uint32_t dumpedBytes = 0; uint32_t ptmeBusyCounter = 0; + bool packetWasDumped = false; + bool vcBusyDuringDump = false; }; TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel, @@ -43,7 +45,7 @@ class TmStoreTaskBase : public SystemObject { // 20 minutes are allowed as maximum dump time. Countdown cancelDumpCd = Countdown(60 * 20 * 1000); // If the TM sink is busy for 1 minute for whatever reason, cancel the dump. - Countdown tmSinkBusyCd = Countdown(60 * 1000); + Countdown tmSinkBusyCd = Countdown(60 * 20 * 1000);//Countdown(60 * 1000 ); VirtualChannel& channel; bool storesInitialized = false; bool fileHasSwapped = false; diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 4fed30b1..2c03f361 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -1,12 +1,12 @@ #include "VirtualChannel.h" VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme, - const std::atomic_bool& linkStateProvider) + const std::atomic_bool& txOn) : SystemObject(objectId), ptme(ptme), vcId(vcId), vcName(vcName), - linkStateProvider(linkStateProvider) {} + txOn(txOn) {} ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; } @@ -15,10 +15,10 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) { } ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) { - if (linkStateProvider.load()) { + //if (txOn) { return ptme.writeToVc(vcId, data, size); - } - return returnvalue::OK; + //} + //return returnvalue::OK; } uint8_t VirtualChannel::getVcid() const { return vcId; } @@ -27,9 +27,9 @@ const char* VirtualChannel::getName() const { return vcName.c_str(); } bool VirtualChannel::isBusy() const { // Data is discarded, so channel is not busy. - if (linkStateProvider.load()) { - return false; - } + //if (not txOn) { + // return false; + //} return ptme.isBusy(vcId); } diff --git a/mission/tmtc/VirtualChannel.h b/mission/tmtc/VirtualChannel.h index 4cad3305..7de0633f 100644 --- a/mission/tmtc/VirtualChannel.h +++ b/mission/tmtc/VirtualChannel.h @@ -37,5 +37,5 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF { PtmeIF& ptme; uint8_t vcId = 0; std::string vcName; - const std::atomic_bool& linkStateProvider; + const std::atomic_bool& txOn; }; From 00214dc378027835db8cb69bbecc14a000f9ddfe Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 21:39:37 +0200 Subject: [PATCH 10/53] found some more bugs --- linux/ipcore/PapbVcInterface.cpp | 7 ++--- mission/tmtc/PersistentSingleTmStoreTask.cpp | 27 ++++++++------------ mission/tmtc/TmStoreTaskBase.cpp | 16 ++++++------ mission/tmtc/TmStoreTaskBase.h | 7 ++++- mission/tmtc/VirtualChannel.cpp | 14 ++++------ 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index df9df839..1808d935 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -2,9 +2,10 @@ #include #include -#include "fsfw/serviceinterface/ServiceInterface.h" #include +#include "fsfw/serviceinterface/ServiceInterface.h" + PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId, gpioId_t papbEmptyId, std::string uioFile, int mapNum) : gpioComIF(gpioComIF), @@ -33,14 +34,14 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - if (pollPapbBusySignal(5) == returnvalue::OK) { + if (pollPapbBusySignal(3) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - if (pollPapbBusySignal(5) == returnvalue::OK) { + if (pollPapbBusySignal(3) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 01a7c206..8b7272c4 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -11,7 +11,6 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( dumpContext(eventIfDumpDone) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { - uint32_t dummy = 0; while (true) { // Delay done by the check if (not cyclicStoreCheck()) { @@ -20,25 +19,19 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { TaskFactory::delayTask(100); - } else if(dumpContext.vcBusyDuringDump) { - TaskFactory::delayTask(30); + } else if (dumpContext.vcBusyDuringDump) { + TaskFactory::delayTask(10); } else if (fileHasSwapped) { - TaskFactory::delayTask(30); - } else if(dumpContext.packetWasDumped and dumpContext.numberOfDumpedPackets % 5 == 0) { - TaskFactory::delayTask(30); + TaskFactory::delayTask(10); + } else if (dumpContext.packetWasDumped and dumpContext.numberOfDumpedPackets % 50 == 0) { + TaskFactory::delayTask(10); } else { -// dummy++; -// if(dummy % 2000 == 0) { -// sif::warning << "persistent tm store is stupid" << std::endl; -// } - TaskFactory::delayTask(2); -// continue; + // TaskFactory::delayTask(5); } - dummy = 0; - //else if(dumpContext.numberOfDumpedPackets % 20 == 0) { - // Manual load management because I don't know what the scheduler is doing.. - // Removing this delay can lead to evil side effects. - //TaskFactory::delayTask(5); + // else if(dumpContext.numberOfDumpedPackets % 20 == 0) { + // Manual load management because I don't know what the scheduler is doing.. + // Removing this delay can lead to evil side effects. + // TaskFactory::delayTask(5); //} } } diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index dc32d6e2..2175b164 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -18,21 +18,21 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, bool tcRequestReceived = false; bool dumpsPerformed = false; fileHasSwapped = false; + dumpContext.packetWasDumped = false; + dumpContext.vcBusyDuringDump = false; // Store TM persistently result = store.handleNextTm(); if (result == returnvalue::OK) { tmToStoreReceived = true; } - dumpContext.vcBusyDuringDump = false; // Dump TMs when applicable if (store.getState() == PersistentTmStore::State::DUMPING) { size_t dumpedLen = 0; if (not channel.isBusy()) { dumpContext.ptmeBusyCounter = 0; tmSinkBusyCd.resetTimer(); - bool fileHasSwappedLocal = false; - result = store.dumpNextPacket(channel, dumpedLen, fileHasSwappedLocal); + result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); if (result == DirectTmSinkIF::IS_BUSY) { sif::warning << "Unexpected PAPB busy" << std::endl; } @@ -40,10 +40,6 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, dumpContext.dumpedBytes += dumpedLen; dumpContext.numberOfDumpedPackets += 1; dumpContext.packetWasDumped = true; - // Only register file swaps if more than 0 bytes were dumped. - if(fileHasSwappedLocal) { - fileHasSwapped = true; - } } if (result == PersistentTmStore::DUMP_DONE) { uint32_t startTime; @@ -51,6 +47,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, dumpContext.dumpedBytes); + dumpContext.reset(); dumpsPerformed = true; } else if (result == returnvalue::OK) { dumpsPerformed = true; @@ -62,14 +59,15 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, // If this happens, something is probably wrong. sif::warning << "PTME busy for longer period. Dumped length so far: " << dumpContext.dumpedBytes << std::endl; - dumpContext.ptmeBusyCounter = 0; triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); + dumpContext.reset(); store.cancelDump(); channel.cancelTransfer(); } } if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); + dumpDoneHandler(dumpContext); store.cancelDump(); } } else { @@ -109,3 +107,5 @@ bool TmStoreTaskBase::cyclicStoreCheck() { } return true; } + +void TmStoreTaskBase::dumpDoneHandler(DumpContext& ctx) { ctx.reset(); } diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index b9a81bec..d911c343 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -12,6 +12,9 @@ class TmStoreTaskBase : public SystemObject { void reset() { numberOfDumpedPackets = 0; dumpedBytes = 0; + vcBusyDuringDump = false; + packetWasDumped = false; + ptmeBusyCounter = 0; } const Event eventIfDone; uint32_t numberOfDumpedPackets = 0; @@ -45,11 +48,13 @@ class TmStoreTaskBase : public SystemObject { // 20 minutes are allowed as maximum dump time. Countdown cancelDumpCd = Countdown(60 * 20 * 1000); // If the TM sink is busy for 1 minute for whatever reason, cancel the dump. - Countdown tmSinkBusyCd = Countdown(60 * 20 * 1000);//Countdown(60 * 1000 ); + Countdown tmSinkBusyCd = Countdown(60 * 20 * 1000); // Countdown(60 * 1000 ); VirtualChannel& channel; bool storesInitialized = false; bool fileHasSwapped = false; SdCardMountedIF& sdcMan; + + void dumpDoneHandler(DumpContext& ctx); }; #endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */ diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 2c03f361..94d05678 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -2,11 +2,7 @@ VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme, const std::atomic_bool& txOn) - : SystemObject(objectId), - ptme(ptme), - vcId(vcId), - vcName(vcName), - txOn(txOn) {} + : SystemObject(objectId), ptme(ptme), vcId(vcId), vcName(vcName), txOn(txOn) {} ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; } @@ -15,10 +11,10 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) { } ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) { - //if (txOn) { - return ptme.writeToVc(vcId, data, size); + // if (txOn) { + return ptme.writeToVc(vcId, data, size); //} - //return returnvalue::OK; + // return returnvalue::OK; } uint8_t VirtualChannel::getVcid() const { return vcId; } @@ -27,7 +23,7 @@ const char* VirtualChannel::getName() const { return vcName.c_str(); } bool VirtualChannel::isBusy() const { // Data is discarded, so channel is not busy. - //if (not txOn) { + // if (not txOn) { // return false; //} return ptme.isBusy(vcId); From bc72f59abbc1bd56a6684b16e9e05b83603aba20 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 21:46:12 +0200 Subject: [PATCH 11/53] now its just trying things out --- mission/tmtc/PersistentSingleTmStoreTask.cpp | 12 +++++++----- mission/tmtc/TmStoreTaskBase.h | 6 ++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 8b7272c4..2584d975 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -20,13 +20,15 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { if (not busy) { TaskFactory::delayTask(100); } else if (dumpContext.vcBusyDuringDump) { - TaskFactory::delayTask(10); + TaskFactory::delayTask(20); } else if (fileHasSwapped) { - TaskFactory::delayTask(10); - } else if (dumpContext.packetWasDumped and dumpContext.numberOfDumpedPackets % 50 == 0) { - TaskFactory::delayTask(10); + TaskFactory::delayTask(20); + } else if (dumpContext.packetWasDumped and + dumpContext.numberOfDumpedPackets - dumpContext.bytesDumpedAtLastDelay >= 2048) { + dumpContext.bytesDumpedAtLastDelay = dumpContext.dumpedBytes; + TaskFactory::delayTask(20); } else { - // TaskFactory::delayTask(5); + TaskFactory::delayTask(10); } // else if(dumpContext.numberOfDumpedPackets % 20 == 0) { // Manual load management because I don't know what the scheduler is doing.. diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index d911c343..780210b8 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -14,11 +14,13 @@ class TmStoreTaskBase : public SystemObject { dumpedBytes = 0; vcBusyDuringDump = false; packetWasDumped = false; + bytesDumpedAtLastDelay = 0; ptmeBusyCounter = 0; } const Event eventIfDone; - uint32_t numberOfDumpedPackets = 0; - uint32_t dumpedBytes = 0; + size_t numberOfDumpedPackets = 0; + size_t bytesDumpedAtLastDelay = 0; + size_t dumpedBytes = 0; uint32_t ptmeBusyCounter = 0; bool packetWasDumped = false; bool vcBusyDuringDump = false; From 9613d4aa5156f4536e2c4cb705719bfda3986128 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 22:06:16 +0200 Subject: [PATCH 12/53] add single store delay handling for log store as well --- mission/tmtc/PersistentLogTmStoreTask.cpp | 27 ++++++++++++++++---- mission/tmtc/PersistentSingleTmStoreTask.cpp | 10 +++----- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 2b7e1333..906c7547 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -14,13 +14,22 @@ PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, Storage ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { bool someonesBusy = false; - auto stateHandlingForStore = [&](bool storeIsBusy) { + bool vcBusyDuringDump = false; + bool byteFlowControl = false; + auto stateHandlingForStore = [&](bool storeIsBusy, DumpContext& ctx) { if (storeIsBusy) { someonesBusy = true; } if (fileHasSwapped) { someFileWasSwapped = fileHasSwapped; } + if(ctx.vcBusyDuringDump) { + vcBusyDuringDump = true; + } + if(ctx.dumpedBytes - ctx.bytesDumpedAtLastDelay >= 2048) { + byteFlowControl = true; + ctx.bytesDumpedAtLastDelay = ctx.dumpedBytes; + } }; while (true) { if (not cyclicStoreCheck()) { @@ -28,13 +37,21 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { } someonesBusy = false; someFileWasSwapped = false; - stateHandlingForStore(handleOneStore(stores.okStore, okStoreContext)); - stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext)); - stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext)); + vcBusyDuringDump = false; + stateHandlingForStore(handleOneStore(stores.okStore, okStoreContext), okStoreContext); + stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext), notOkStoreContext); + stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext), miscStoreContext); if (not someonesBusy) { TaskFactory::delayTask(100); } else if (someFileWasSwapped) { - TaskFactory::delayTask(2); + TaskFactory::delayTask(20); + } else if(vcBusyDuringDump) { + TaskFactory::delayTask(20); + } else if(byteFlowControl) { + TaskFactory::delayTask(10); + } else { + // TODO: Lower this as much as possible... + TaskFactory::delayTask(10); } } } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 2584d975..ae6b8700 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -24,17 +24,13 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { } else if (fileHasSwapped) { TaskFactory::delayTask(20); } else if (dumpContext.packetWasDumped and - dumpContext.numberOfDumpedPackets - dumpContext.bytesDumpedAtLastDelay >= 2048) { + dumpContext.dumpedBytes - dumpContext.bytesDumpedAtLastDelay >= 2048) { dumpContext.bytesDumpedAtLastDelay = dumpContext.dumpedBytes; TaskFactory::delayTask(20); } else { - TaskFactory::delayTask(10); + // TODO: Lower this as much as possible... + TaskFactory::delayTask(5); } - // else if(dumpContext.numberOfDumpedPackets % 20 == 0) { - // Manual load management because I don't know what the scheduler is doing.. - // Removing this delay can lead to evil side effects. - // TaskFactory::delayTask(5); - //} } } From 534945cfeca2b9d90f467d200af33134f4d90606 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 22:57:01 +0200 Subject: [PATCH 13/53] last know working cfg for slow downlink --- linux/ipcore/PapbVcInterface.cpp | 6 ++++-- linux/ipcore/PapbVcInterface.h | 3 ++- mission/tmtc/PersistentSingleTmStoreTask.cpp | 14 ++++++++------ mission/tmtc/TmStoreTaskBase.cpp | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 1808d935..5d88de94 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -58,7 +58,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; - nextDelay.tv_nsec = 1000; + nextDelay.tv_nsec = 0; while (true) { /** Check if PAPB interface is ready to receive data */ @@ -80,7 +80,9 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const // Ignore signal handling here for now. nanosleep(&nextDelay, &remDelay); // Adaptive delay. - if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { + if(nextDelay.tv_nsec == 0) { + nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; + } else if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { nextDelay.tv_nsec *= 2; } } diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 484390b2..8545a7ec 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -76,6 +76,7 @@ class PapbVcInterface : public VirtualChannelIF { */ static const int DATA_REG_OFFSET = 256; + static constexpr long int FIRST_NON_NULL_DELAY_NS = 1000; static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 4000; LinuxLibgpioIF* gpioComIF = nullptr; @@ -87,7 +88,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; - mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 1000}; + mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; mutable struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index ae6b8700..ec507a44 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -11,6 +11,7 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( dumpContext(eventIfDumpDone) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { + ReturnValue_t result = returnvalue::OK; while (true) { // Delay done by the check if (not cyclicStoreCheck()) { @@ -18,18 +19,19 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { } bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { - TaskFactory::delayTask(100); + result = TaskFactory::delayTask(100); } else if (dumpContext.vcBusyDuringDump) { - TaskFactory::delayTask(20); - } else if (fileHasSwapped) { - TaskFactory::delayTask(20); + result = TaskFactory::delayTask(10); } else if (dumpContext.packetWasDumped and dumpContext.dumpedBytes - dumpContext.bytesDumpedAtLastDelay >= 2048) { dumpContext.bytesDumpedAtLastDelay = dumpContext.dumpedBytes; - TaskFactory::delayTask(20); + result = TaskFactory::delayTask(10); } else { // TODO: Lower this as much as possible... - TaskFactory::delayTask(5); + result = TaskFactory::delayTask(10); + } + if(result != returnvalue::OK) { + sif::warning << "TmStoreTask: Delay failed" << std::endl; } } } diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index 2175b164..d2fff5e7 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -55,7 +55,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, } else { dumpContext.vcBusyDuringDump = true; dumpContext.ptmeBusyCounter++; - if (dumpContext.ptmeBusyCounter == 50) { + if (dumpContext.ptmeBusyCounter == 100) { // If this happens, something is probably wrong. sif::warning << "PTME busy for longer period. Dumped length so far: " << dumpContext.dumpedBytes << std::endl; From 437288de1eb34aa91b45bfaf713aaf9a338577a3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 27 Mar 2023 23:09:26 +0200 Subject: [PATCH 14/53] small fix --- mission/tmtc/PersistentTmStore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 949657d5..bf8f2a4f 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -171,7 +171,7 @@ void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { // Convert file time to the UNIX epoch struct tm fileTime {}; if (pathToTime(file.path(), fileTime) != returnvalue::OK) { - sif::error << "Time extraction for " << file << "failed" << std::endl; + sif::error << "Time extraction for " << file << " failed" << std::endl; continue; } time_t fileEpoch = timegm(&fileTime); From 746254a8385d9bbf34d8a103924b3c6b7131bdb3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 10:13:39 +0200 Subject: [PATCH 15/53] cancel transfer on TX disabled --- mission/tmtc/TmStoreTaskBase.cpp | 21 +++++++++++++++------ mission/tmtc/TmStoreTaskBase.h | 2 +- mission/tmtc/VirtualChannel.cpp | 22 ++++++++++++++-------- mission/tmtc/VirtualChannel.h | 1 + 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index d2fff5e7..ea1153ff 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -28,6 +28,12 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, } // Dump TMs when applicable if (store.getState() == PersistentTmStore::State::DUMPING) { + // The PTME might have been reset an transmitter state change, so there is + // not point in continuing the dump. + if(not channel.isTxOn()) { + cancelDump(dumpContext, store, false); + return returnvalue::OK; + } size_t dumpedLen = 0; if (not channel.isBusy()) { dumpContext.ptmeBusyCounter = 0; @@ -60,15 +66,12 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, sif::warning << "PTME busy for longer period. Dumped length so far: " << dumpContext.dumpedBytes << std::endl; triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); - dumpContext.reset(); - store.cancelDump(); - channel.cancelTransfer(); + cancelDump(dumpContext, store, channel.isTxOn()); } } if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); - dumpDoneHandler(dumpContext); - store.cancelDump(); + cancelDump(dumpContext, store, channel.isTxOn()); } } else { Command_t execCmd; @@ -108,4 +111,10 @@ bool TmStoreTaskBase::cyclicStoreCheck() { return true; } -void TmStoreTaskBase::dumpDoneHandler(DumpContext& ctx) { ctx.reset(); } +void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) { + ctx.reset(); + store.cancelDump(); + if(isTxOn) { + channel.cancelTransfer(); + } +} diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 780210b8..149f0804 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -56,7 +56,7 @@ class TmStoreTaskBase : public SystemObject { bool fileHasSwapped = false; SdCardMountedIF& sdcMan; - void dumpDoneHandler(DumpContext& ctx); + void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn); }; #endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */ diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 94d05678..5724ae69 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -11,10 +11,10 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) { } ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) { - // if (txOn) { - return ptme.writeToVc(vcId, data, size); - //} - // return returnvalue::OK; + if (txOn) { + return ptme.writeToVc(vcId, data, size); + } + return returnvalue::OK; } uint8_t VirtualChannel::getVcid() const { return vcId; } @@ -23,10 +23,16 @@ const char* VirtualChannel::getName() const { return vcName.c_str(); } bool VirtualChannel::isBusy() const { // Data is discarded, so channel is not busy. - // if (not txOn) { - // return false; - //} + if (not txOn) { + return false; + } return ptme.isBusy(vcId); } -void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); } +void VirtualChannel::cancelTransfer() { + ptme.cancelTransfer(vcId); +} + +bool VirtualChannel::isTxOn() const { + return txOn; +} diff --git a/mission/tmtc/VirtualChannel.h b/mission/tmtc/VirtualChannel.h index 7de0633f..98aba903 100644 --- a/mission/tmtc/VirtualChannel.h +++ b/mission/tmtc/VirtualChannel.h @@ -30,6 +30,7 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF { ReturnValue_t write(const uint8_t* data, size_t size) override; void cancelTransfer() override; uint8_t getVcid() const; + bool isTxOn() const; const char* getName() const; From 1f6c986a0cf6542e48fc7ef7ae4427b63c6a7989 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 14:59:31 +0200 Subject: [PATCH 16/53] add instrumentation code --- linux/ipcore/PapbVcInterface.cpp | 2 +- mission/tmtc/PersistentLogTmStoreTask.cpp | 8 +- mission/tmtc/PersistentSingleTmStoreTask.cpp | 18 +++- mission/tmtc/TmStoreTaskBase.cpp | 107 +++++++++++-------- mission/tmtc/TmStoreTaskBase.h | 3 + mission/tmtc/VirtualChannel.cpp | 8 +- mission/tmtc/VirtualChannelWithQueue.cpp | 10 +- 7 files changed, 89 insertions(+), 67 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 5d88de94..b7081f0f 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -80,7 +80,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const // Ignore signal handling here for now. nanosleep(&nextDelay, &remDelay); // Adaptive delay. - if(nextDelay.tv_nsec == 0) { + if (nextDelay.tv_nsec == 0) { nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; } else if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { nextDelay.tv_nsec *= 2; diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 906c7547..84886cf6 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -23,10 +23,10 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { if (fileHasSwapped) { someFileWasSwapped = fileHasSwapped; } - if(ctx.vcBusyDuringDump) { + if (ctx.vcBusyDuringDump) { vcBusyDuringDump = true; } - if(ctx.dumpedBytes - ctx.bytesDumpedAtLastDelay >= 2048) { + if (ctx.dumpedBytes - ctx.bytesDumpedAtLastDelay >= 2048) { byteFlowControl = true; ctx.bytesDumpedAtLastDelay = ctx.dumpedBytes; } @@ -45,9 +45,9 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { TaskFactory::delayTask(100); } else if (someFileWasSwapped) { TaskFactory::delayTask(20); - } else if(vcBusyDuringDump) { + } else if (vcBusyDuringDump) { TaskFactory::delayTask(20); - } else if(byteFlowControl) { + } else if (byteFlowControl) { TaskFactory::delayTask(10); } else { // TODO: Lower this as much as possible... diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index ec507a44..121df1b7 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -12,6 +12,10 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { ReturnValue_t result = returnvalue::OK; + uint32_t delaysVcBusyDuringDump = 0; + uint32_t delaysFlowControl = 0; + uint32_t delayNotBusy = 0; + uint32_t delayHotLoop = 0; while (true) { // Delay done by the check if (not cyclicStoreCheck()) { @@ -20,17 +24,27 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { result = TaskFactory::delayTask(100); + delayNotBusy++; } else if (dumpContext.vcBusyDuringDump) { + delaysVcBusyDuringDump++; result = TaskFactory::delayTask(10); } else if (dumpContext.packetWasDumped and dumpContext.dumpedBytes - dumpContext.bytesDumpedAtLastDelay >= 2048) { dumpContext.bytesDumpedAtLastDelay = dumpContext.dumpedBytes; result = TaskFactory::delayTask(10); + delaysFlowControl++; } else { // TODO: Lower this as much as possible... - result = TaskFactory::delayTask(10); + result = TaskFactory::delayTask(5); + delayHotLoop++; } - if(result != returnvalue::OK) { + if ((delaysVcBusyDuringDump + delaysFlowControl + delayNotBusy + delayHotLoop) % 2000000 == 0) { + sif::debug << "DLY NBUSY: " << delayNotBusy << std::endl; + sif::debug << "DLY FLCTRL: " << delaysFlowControl << std::endl; + sif::debug << "DLY BUSYDUMP: " << delaysVcBusyDuringDump << std::endl; + sif::debug << "DLY HOTLOOP: " << delayHotLoop << std::endl; + } + if (result != returnvalue::OK) { sif::warning << "TmStoreTask: Delay failed" << std::endl; } } diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index ea1153ff..d0787535 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -16,7 +16,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, ReturnValue_t result; bool tmToStoreReceived = false; bool tcRequestReceived = false; - bool dumpsPerformed = false; + bool dumpPerformed = false; fileHasSwapped = false; dumpContext.packetWasDumped = false; dumpContext.vcBusyDuringDump = false; @@ -28,50 +28,8 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, } // Dump TMs when applicable if (store.getState() == PersistentTmStore::State::DUMPING) { - // The PTME might have been reset an transmitter state change, so there is - // not point in continuing the dump. - if(not channel.isTxOn()) { - cancelDump(dumpContext, store, false); - return returnvalue::OK; - } - size_t dumpedLen = 0; - if (not channel.isBusy()) { - dumpContext.ptmeBusyCounter = 0; - tmSinkBusyCd.resetTimer(); - result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); - if (result == DirectTmSinkIF::IS_BUSY) { - sif::warning << "Unexpected PAPB busy" << std::endl; - } - if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK) and dumpedLen > 0) { - dumpContext.dumpedBytes += dumpedLen; - dumpContext.numberOfDumpedPackets += 1; - dumpContext.packetWasDumped = true; - } - if (result == PersistentTmStore::DUMP_DONE) { - uint32_t startTime; - uint32_t endTime; - store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); - triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, - dumpContext.dumpedBytes); - dumpContext.reset(); - dumpsPerformed = true; - } else if (result == returnvalue::OK) { - dumpsPerformed = true; - } - } else { - dumpContext.vcBusyDuringDump = true; - dumpContext.ptmeBusyCounter++; - if (dumpContext.ptmeBusyCounter == 100) { - // If this happens, something is probably wrong. - sif::warning << "PTME busy for longer period. Dumped length so far: " - << dumpContext.dumpedBytes << std::endl; - triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); - cancelDump(dumpContext, store, channel.isTxOn()); - } - } - if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { - triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); - cancelDump(dumpContext, store, channel.isTxOn()); + if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) { + return result; } } else { Command_t execCmd; @@ -86,7 +44,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, tcRequestReceived = true; } } - if (tcRequestReceived or tmToStoreReceived or dumpsPerformed) { + if (tcRequestReceived or tmToStoreReceived or dumpPerformed) { return true; } return false; @@ -114,7 +72,62 @@ bool TmStoreTaskBase::cyclicStoreCheck() { void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) { ctx.reset(); store.cancelDump(); - if(isTxOn) { + if (isTxOn) { channel.cancelTransfer(); } } + +ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store, + DumpContext& dumpContext, bool& dumpPerformed) { + ReturnValue_t result = returnvalue::OK; + // The PTME might have been reset an transmitter state change, so there is + // not point in continuing the dump. + if (not channel.isTxOn()) { + cancelDump(dumpContext, store, false); + return returnvalue::FAILED; + } + size_t dumpedLen = 0; + if (not channel.isBusy()) { + // Dump the next packet into the PTME. + dumpContext.ptmeBusyCounter = 0; + tmSinkBusyCd.resetTimer(); + result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); + if (result == DirectTmSinkIF::IS_BUSY) { + sif::warning << "Unexpected PAPB busy" << std::endl; + } + if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) { + dumpPerformed = true; + if (dumpedLen > 0) { + dumpContext.dumpedBytes += dumpedLen; + dumpContext.numberOfDumpedPackets += 1; + dumpContext.packetWasDumped = true; + } + } + if (result == PersistentTmStore::DUMP_DONE) { + uint32_t startTime; + uint32_t endTime; + store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); + triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, + dumpContext.dumpedBytes); + dumpContext.reset(); + } + } else { + // The PTME might be at full load, so it might sense to delay for a bit to let it do + // its work until some more bandwidth is available. Set a flag here so the upper layer can + // do ths. + dumpContext.vcBusyDuringDump = true; + dumpContext.ptmeBusyCounter++; + if (dumpContext.ptmeBusyCounter == 100) { + // If this happens, something is probably wrong. + sif::warning << "PTME busy for longer period. Dumped length so far: " + << dumpContext.dumpedBytes << std::endl; + triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); + cancelDump(dumpContext, store, channel.isTxOn()); + } + } + if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { + triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); + cancelDump(dumpContext, store, channel.isTxOn()); + } + return result; +} diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 149f0804..c75ac8e4 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -37,6 +37,9 @@ class TmStoreTaskBase : public SystemObject { */ bool handleOneStore(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext); + ReturnValue_t handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext, + bool& dumpPerformed); + /** * Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to * be used again and re-initialize stores. Returns whether store is okay to be used. diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 5724ae69..8e225674 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -29,10 +29,6 @@ bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); } -void VirtualChannel::cancelTransfer() { - ptme.cancelTransfer(vcId); -} +void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); } -bool VirtualChannel::isTxOn() const { - return txOn; -} +bool VirtualChannel::isTxOn() const { return txOn; } diff --git a/mission/tmtc/VirtualChannelWithQueue.cpp b/mission/tmtc/VirtualChannelWithQueue.cpp index bfc74907..44a20031 100644 --- a/mission/tmtc/VirtualChannelWithQueue.cpp +++ b/mission/tmtc/VirtualChannelWithQueue.cpp @@ -37,14 +37,10 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() { } result = write(data, size); - if (result != returnvalue::OK) { - return result; - } + // Try delete in any case, ignore failures (which should not happen), it is more important to + // propagate write errors. tmStore.deleteData(storeId); - if (result != returnvalue::OK) { - return result; - } - return returnvalue::OK; + return result; } MessageQueueId_t VirtualChannelWithQueue::getReportReceptionQueue(uint8_t virtualChannel) const { From 0bba9b53ba016877c38eb97a5fb83476c6ae7781 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 15:03:34 +0200 Subject: [PATCH 17/53] some more documentation --- mission/tmtc/TmStoreTaskBase.cpp | 4 ++-- mission/tmtc/TmStoreTaskBase.h | 30 ++++++++++++++++++------------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index d0787535..191272ed 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -80,8 +80,8 @@ void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, boo ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext, bool& dumpPerformed) { ReturnValue_t result = returnvalue::OK; - // The PTME might have been reset an transmitter state change, so there is - // not point in continuing the dump. + // The PTME might have been reset an transmitter state change, so there is no point in continuing + // the dump. if (not channel.isTxOn()) { cancelDump(dumpContext, store, false); return returnvalue::FAILED; diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index c75ac8e4..319e3361 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -5,6 +5,10 @@ #include #include +/** + * Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping + * the TM store into the virtual channel directly. + */ class TmStoreTaskBase : public SystemObject { public: struct DumpContext { @@ -30,7 +34,21 @@ class TmStoreTaskBase : public SystemObject { SdCardMountedIF& sdcMan); protected: + StorageManagerIF& ipcStore; + Countdown sdCardCheckCd = Countdown(800); + // 20 minutes are allowed as maximum dump time. + Countdown cancelDumpCd = Countdown(60 * 20 * 1000); + // If the TM sink is busy for 1 minute for whatever reason, cancel the dump. + // TODO: Reset this to default value. + Countdown tmSinkBusyCd = Countdown(60 * 20 * 1000); // Countdown(60 * 1000 ); + VirtualChannel& channel; + bool storesInitialized = false; + bool fileHasSwapped = false; + SdCardMountedIF& sdcMan; + + void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn); /** + * * Handling for one store. Returns if anything was done. * @param store * @return @@ -48,18 +66,6 @@ class TmStoreTaskBase : public SystemObject { virtual bool initStoresIfPossible() = 0; - StorageManagerIF& ipcStore; - Countdown sdCardCheckCd = Countdown(800); - // 20 minutes are allowed as maximum dump time. - Countdown cancelDumpCd = Countdown(60 * 20 * 1000); - // If the TM sink is busy for 1 minute for whatever reason, cancel the dump. - Countdown tmSinkBusyCd = Countdown(60 * 20 * 1000); // Countdown(60 * 1000 ); - VirtualChannel& channel; - bool storesInitialized = false; - bool fileHasSwapped = false; - SdCardMountedIF& sdcMan; - - void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn); }; #endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */ From 0adfb0cd3c60b3f0d3b35492beac8fcd64181c06 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 15:06:03 +0200 Subject: [PATCH 18/53] add missing override specifiers --- mission/tmtc/PersistentLogTmStoreTask.h | 2 +- mission/tmtc/PersistentSingleTmStoreTask.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/tmtc/PersistentLogTmStoreTask.h b/mission/tmtc/PersistentLogTmStoreTask.h index cb87ba6c..116b369e 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.h +++ b/mission/tmtc/PersistentLogTmStoreTask.h @@ -35,7 +35,7 @@ class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObject Countdown graceDelayDuringDumping = Countdown(200); bool someFileWasSwapped = false; - bool initStoresIfPossible(); + bool initStoresIfPossible() override; }; #endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */ diff --git a/mission/tmtc/PersistentSingleTmStoreTask.h b/mission/tmtc/PersistentSingleTmStoreTask.h index 7a4dd7ca..07e0f05f 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.h +++ b/mission/tmtc/PersistentSingleTmStoreTask.h @@ -21,7 +21,7 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj Countdown tcHandlingCd = Countdown(400); Countdown graceDelayDuringDumping = Countdown(100); - bool initStoresIfPossible(); + bool initStoresIfPossible() override; }; #endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */ From 33babebb6f554abedec11d2fbea2f0ba310d91ab Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 15:15:38 +0200 Subject: [PATCH 19/53] cancel events --- bsp_q7s/core/ObjectFactory.cpp | 4 ++-- mission/persistentTmStoreDefs.h | 13 +++++++++++-- mission/tmtc/PersistentLogTmStoreTask.cpp | 6 +++--- mission/tmtc/PersistentSingleTmStoreTask.cpp | 4 ++-- mission/tmtc/PersistentSingleTmStoreTask.h | 3 ++- mission/tmtc/TmStoreTaskBase.cpp | 6 ++---- mission/tmtc/TmStoreTaskBase.h | 5 +++-- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 3845a294..313c7aa6 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -808,14 +808,14 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { // 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, persTmStore::DUMP_HK_STORE_DONE, - *SdCardManager::instance()); + 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, persTmStore::DUMP_CFDP_STORE_DONE, - *SdCardManager::instance()); + persTmStore::DUMP_CFDP_CANCELLED, *SdCardManager::instance()); ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); if (result != returnvalue::OK) { diff --git a/mission/persistentTmStoreDefs.h b/mission/persistentTmStoreDefs.h index 2498536d..8b8873de 100644 --- a/mission/persistentTmStoreDefs.h +++ b/mission/persistentTmStoreDefs.h @@ -25,8 +25,6 @@ static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID, //! 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] Dump was cancelled. P1: Object ID of store. -static constexpr Event DUMP_WAS_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW); //! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. static constexpr Event DUMP_OK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO); @@ -38,6 +36,17 @@ static constexpr Event DUMP_MISC_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 7, static constexpr Event DUMP_HK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO); //! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. static constexpr Event DUMP_CFDP_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 9, severity::INFO); + +//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. +static constexpr Event DUMP_OK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW); +//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. +static constexpr Event DUMP_NOK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW); +//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. +static constexpr Event DUMP_MISC_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 12, severity::LOW); +//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. +static constexpr Event DUMP_HK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 13, severity::LOW); +//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes. +static constexpr Event DUMP_CFDP_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 14, severity::LOW); }; // namespace persTmStore #endif /* MISSION_PERSISTENTTMSTOREDEFS_H_ */ diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 84886cf6..67371ab0 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -8,9 +8,9 @@ PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, Storage SdCardMountedIF& sdcMan) : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), stores(stores), - okStoreContext(persTmStore::DUMP_OK_STORE_DONE), - notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE), - miscStoreContext(persTmStore::DUMP_MISC_STORE_DONE) {} + okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED), + notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED), + miscStoreContext(persTmStore::DUMP_MISC_STORE_DONE, persTmStore::DUMP_MISC_CANCELLED) {} ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { bool someonesBusy = false; diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 121df1b7..2e57ceea 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -5,10 +5,10 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore, - VirtualChannel& channel, Event eventIfDumpDone, SdCardMountedIF& sdcMan) + VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan) : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), storeWithQueue(tmStore), - dumpContext(eventIfDumpDone) {} + dumpContext(eventIfDumpDone, eventIfCancelled) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { ReturnValue_t result = returnvalue::OK; diff --git a/mission/tmtc/PersistentSingleTmStoreTask.h b/mission/tmtc/PersistentSingleTmStoreTask.h index 07e0f05f..1529928f 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.h +++ b/mission/tmtc/PersistentSingleTmStoreTask.h @@ -11,7 +11,8 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj public: PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel, - Event eventIfDumpDone, SdCardMountedIF& sdcMan); + Event eventIfDumpDone, Event eventIfCancelled, + SdCardMountedIF& sdcMan); ReturnValue_t performOperation(uint8_t opCode) override; diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index 191272ed..7ca03488 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -70,6 +70,7 @@ bool TmStoreTaskBase::cyclicStoreCheck() { } void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) { + triggerEvent(ctx.eventIfCancelled, ctx.numberOfDumpedPackets, ctx.dumpedBytes); ctx.reset(); store.cancelDump(); if (isTxOn) { @@ -119,14 +120,11 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store dumpContext.ptmeBusyCounter++; if (dumpContext.ptmeBusyCounter == 100) { // If this happens, something is probably wrong. - sif::warning << "PTME busy for longer period. Dumped length so far: " - << dumpContext.dumpedBytes << std::endl; - triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); + sif::warning << "PTME busy for longer period. Cancelling dump" << std::endl; cancelDump(dumpContext, store, channel.isTxOn()); } } if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { - triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); cancelDump(dumpContext, store, channel.isTxOn()); } return result; diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 319e3361..54dcc6a4 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -12,7 +12,8 @@ class TmStoreTaskBase : public SystemObject { public: struct DumpContext { - DumpContext(Event eventIfDone) : eventIfDone(eventIfDone) {} + DumpContext(Event eventIfDone, Event eventIfCancelled) + : eventIfDone(eventIfDone), eventIfCancelled(eventIfCancelled) {} void reset() { numberOfDumpedPackets = 0; dumpedBytes = 0; @@ -22,6 +23,7 @@ class TmStoreTaskBase : public SystemObject { ptmeBusyCounter = 0; } const Event eventIfDone; + const Event eventIfCancelled; size_t numberOfDumpedPackets = 0; size_t bytesDumpedAtLastDelay = 0; size_t dumpedBytes = 0; @@ -65,7 +67,6 @@ class TmStoreTaskBase : public SystemObject { bool cyclicStoreCheck(); virtual bool initStoresIfPossible() = 0; - }; #endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */ From c474d6ed1d4a75972c09dee183c4f32d880e354e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 19:50:19 +0200 Subject: [PATCH 20/53] bump tmtc --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 3f352346..f2897fa6 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3f3523465a141bc2a2c36cbc9cbbf6ab7b3a9d70 +Subproject commit f2897fa6060e178ef8d11c9d29faa058896c9253 From d09b53f6df97379e5efdea7404509d576f746927 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 21:45:04 +0200 Subject: [PATCH 21/53] ns delay between gpio polls solves it --- linux/ipcore/PapbVcInterface.cpp | 8 ++++-- linux/ipcore/PapbVcInterface.h | 7 ++--- mission/tmtc/PersistentLogTmStoreTask.cpp | 8 +----- mission/tmtc/PersistentSingleTmStoreTask.cpp | 28 +++++++------------- 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index b7081f0f..3e7210cc 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -34,14 +34,18 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { - if (pollPapbBusySignal(3) == returnvalue::OK) { + // This delay is super-important, DO NOT REMOVE! + // Polling the GPIO + nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + if (pollPapbBusySignal(2) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - if (pollPapbBusySignal(3) == returnvalue::OK) { + nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + if (pollPapbBusySignal(2) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 8545a7ec..b4454dae 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -76,8 +76,8 @@ class PapbVcInterface : public VirtualChannelIF { */ static const int DATA_REG_OFFSET = 256; - static constexpr long int FIRST_NON_NULL_DELAY_NS = 1000; - static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 4000; + static constexpr long int FIRST_NON_NULL_DELAY_NS = 10; + static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; LinuxLibgpioIF* gpioComIF = nullptr; @@ -89,6 +89,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; + const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 5}; mutable struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; @@ -116,7 +117,7 @@ class PapbVcInterface : public VirtualChannelIF { * * @return returnvalue::OK when ready to receive data else PAPB_BUSY. */ - ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries) const; + inline ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries) const; /** * @brief This function can be used for debugging to check whether there are packets in diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index 67371ab0..c13b88f6 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -43,15 +43,9 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext), miscStoreContext); if (not someonesBusy) { TaskFactory::delayTask(100); - } else if (someFileWasSwapped) { - TaskFactory::delayTask(20); } else if (vcBusyDuringDump) { + // TODO: Might not be necessary TaskFactory::delayTask(20); - } else if (byteFlowControl) { - TaskFactory::delayTask(10); - } else { - // TODO: Lower this as much as possible... - TaskFactory::delayTask(10); } } } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 2e57ceea..33492d43 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -23,30 +23,22 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { } bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { - result = TaskFactory::delayTask(100); + TaskFactory::delayTask(100); delayNotBusy++; } else if (dumpContext.vcBusyDuringDump) { + // TODO: Might not be necessary delaysVcBusyDuringDump++; - result = TaskFactory::delayTask(10); - } else if (dumpContext.packetWasDumped and - dumpContext.dumpedBytes - dumpContext.bytesDumpedAtLastDelay >= 2048) { - dumpContext.bytesDumpedAtLastDelay = dumpContext.dumpedBytes; - result = TaskFactory::delayTask(10); - delaysFlowControl++; + TaskFactory::delayTask(10); } else { - // TODO: Lower this as much as possible... - result = TaskFactory::delayTask(5); delayHotLoop++; } - if ((delaysVcBusyDuringDump + delaysFlowControl + delayNotBusy + delayHotLoop) % 2000000 == 0) { - sif::debug << "DLY NBUSY: " << delayNotBusy << std::endl; - sif::debug << "DLY FLCTRL: " << delaysFlowControl << std::endl; - sif::debug << "DLY BUSYDUMP: " << delaysVcBusyDuringDump << std::endl; - sif::debug << "DLY HOTLOOP: " << delayHotLoop << std::endl; - } - if (result != returnvalue::OK) { - sif::warning << "TmStoreTask: Delay failed" << std::endl; - } + // if ((delaysVcBusyDuringDump + delaysFlowControl + delayNotBusy + delayHotLoop) % 2000 == + // 0) { + // sif::debug << "DLY NBUSY: " << delayNotBusy << std::endl; + // sif::debug << "DLY FLCTRL: " << delaysFlowControl << std::endl; + // sif::debug << "DLY BUSYDUMP: " << delaysVcBusyDuringDump << std::endl; + // sif::debug << "DLY HOTLOOP: " << delayHotLoop << std::endl; + // } } } From 053cfed0934809faa7581768367010a42d0ccb5d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 21:49:16 +0200 Subject: [PATCH 22/53] docs --- linux/ipcore/PapbVcInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 3e7210cc..c130d31e 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -35,7 +35,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { } for (size_t idx = 0; idx < size; idx++) { // This delay is super-important, DO NOT REMOVE! - // Polling the GPIO + // Polling the GPIO too often can mess up the scheduler. nanosleep(&BETWEEN_POLL_DELAY, &remDelay); if (pollPapbBusySignal(2) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); From 4d1fbbcabda165ddf2c842df6a04f79d11a5d71c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 21:51:54 +0200 Subject: [PATCH 23/53] re-generate files --- .../fsfwconfig/events/translateEvents.cpp | 25 +++++++++++---- .../fsfwconfig/objects/translateObjects.cpp | 2 +- generators/bsp_hosted_events.csv | 6 +++- generators/bsp_hosted_returnvalues.csv | 28 ++++++++-------- generators/bsp_q7s_events.csv | 6 +++- generators/bsp_q7s_returnvalues.csv | 32 +++++++++---------- generators/events/translateEvents.cpp | 22 ++++++++++--- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 25 +++++++++++---- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- tmtc | 2 +- 11 files changed, 95 insertions(+), 57 deletions(-) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index c3d0a8a8..1be6ee7c 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 279 translations. + * @brief Auto-generated event translation file. Contains 283 translations. * @details - * Generated on: 2023-03-26 16:40:57 + * Generated on: 2023-03-28 21:50:28 */ #include "translateEvents.h" @@ -212,8 +212,7 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_ const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; -const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = - "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; +const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; @@ -279,12 +278,16 @@ const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON"; const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION"; const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE"; const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT"; -const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED"; const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE"; const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE"; const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE"; const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE"; const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE"; +const char *DUMP_OK_CANCELLED_STRING = "DUMP_OK_CANCELLED"; +const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED"; +const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED"; +const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED"; +const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -834,8 +837,6 @@ const char *translateEvents(Event event) { return FILE_TOO_LARGE_STRING; case (14302): return BUSY_DUMPING_EVENT_STRING; - case (14303): - return DUMP_WAS_CANCELLED_STRING; case (14305): return DUMP_OK_STORE_DONE_STRING; case (14306): @@ -846,6 +847,16 @@ const char *translateEvents(Event event) { return DUMP_HK_STORE_DONE_STRING; case (14309): return DUMP_CFDP_STORE_DONE_STRING; + case (14310): + return DUMP_OK_CANCELLED_STRING; + case (14311): + return DUMP_NOK_CANCELLED_STRING; + case (14312): + return DUMP_MISC_CANCELLED_STRING; + case (14313): + return DUMP_HK_CANCELLED_STRING; + case (14314): + return DUMP_CFDP_CANCELLED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 0b3c7d14..694fbf85 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 169 translations. - * Generated on: 2023-03-26 16:40:57 + * Generated on: 2023-03-28 21:50:28 */ #include "translateObjects.h" diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index 19f38913..45403043 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -272,9 +272,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h 14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h 14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h -14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h 14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14310;0x37e6;DUMP_OK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14311;0x37e7;DUMP_NOK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h diff --git a/generators/bsp_hosted_returnvalues.csv b/generators/bsp_hosted_returnvalues.csv index 09429179..dc960aa3 100644 --- a/generators/bsp_hosted_returnvalues.csv +++ b/generators/bsp_hosted_returnvalues.csv @@ -291,8 +291,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x2e02;HPA_InvalidDomainId;No description;2;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h 0x2e03;HPA_InvalidValue;No description;3;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h 0x2e05;HPA_ReadOnly;No description;5;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h -0x2f01;ASC_NoPacketFound;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h -0x2f02;ASC_PossiblePacketLoss;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x2f01;ASC_TooLongForTargetType;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h +0x2f02;ASC_InvalidCharacters;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h 0x2f03;ASC_BufferTooSmall;No description;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h 0x3001;POS_InPowerTransition;No description;1;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h 0x3002;POS_SwitchStateMismatch;No description;2;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h @@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h -0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h +0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h 0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h @@ -402,9 +402,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4500;HSPI_HalTimeoutRetval;No description;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4501;HSPI_HalBusyRetval;No description;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4502;HSPI_HalErrorRetval;No description;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h 0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h @@ -415,12 +415,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x4805;HGIO_GpioDuplicateDetected;No description;5;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h 0x4806;HGIO_GpioInitFailed;No description;6;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h 0x4807;HGIO_GpioGetValueFailed;No description;7;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4aa0;MGMLIS3_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa1;MGMLIS3_InvalidRampTime;Action Message with invalid ramp time was received.;161;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa2;MGMLIS3_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa3;MGMLIS3_ExecutionFailed;Command execution failed;163;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa4;MGMLIS3_CrcError;Reaction wheel reply has invalid crc;164;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa5;MGMLIS3_ValueNotRead;No description;165;MGM_LIS3MDL;mission/acs/RwHandler.h 0x4c00;SPPA_NoPacketFound;No description;0;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h 0x4c01;SPPA_SplitPacket;No description;1;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h 0x4fa1;HEATER_CommandNotSupported;No description;161;HEATER_HANDLER;mission/tcs/HeaterHandler.h @@ -480,8 +474,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x53b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;182;STR_HANDLER;mission/acs/str/StarTrackerHandler.h 0x53b7;STRH_StartrackerNotRunningFirmware;Star tracker must be in firmware mode to run this command;183;STR_HANDLER;mission/acs/str/StarTrackerHandler.h 0x53b8;STRH_StartrackerNotRunningBootloader;Star tracker must be in bootloader mode to run this command;184;STR_HANDLER;mission/acs/str/StarTrackerHandler.h -0x58a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h -0x58a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h +0x58a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h +0x58a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h +0x58a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h +0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h +0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h +0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h 0x5d00;GOMS_PacketTooLong;No description;0;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5d01;GOMS_InvalidTableId;No description;1;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5d02;GOMS_InvalidAddress;No description;2;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 19f38913..45403043 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -272,9 +272,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h 14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h 14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h -14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h 14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h 14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14310;0x37e6;DUMP_OK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14311;0x37e7;DUMP_NOK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h +14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index d91b080f..9f6f0379 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -291,8 +291,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x2e02;HPA_InvalidDomainId;No description;2;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h 0x2e03;HPA_InvalidValue;No description;3;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h 0x2e05;HPA_ReadOnly;No description;5;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h -0x2f01;ASC_NoPacketFound;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h -0x2f02;ASC_PossiblePacketLoss;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x2f01;ASC_TooLongForTargetType;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h +0x2f02;ASC_InvalidCharacters;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h 0x2f03;ASC_BufferTooSmall;No description;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h 0x3001;POS_InPowerTransition;No description;1;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h 0x3002;POS_SwitchStateMismatch;No description;2;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h @@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h -0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h +0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h 0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h @@ -402,9 +402,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4500;HSPI_HalTimeoutRetval;No description;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4501;HSPI_HalBusyRetval;No description;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4502;HSPI_HalErrorRetval;No description;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h 0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h @@ -415,12 +415,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x4805;HGIO_GpioDuplicateDetected;No description;5;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h 0x4806;HGIO_GpioInitFailed;No description;6;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h 0x4807;HGIO_GpioGetValueFailed;No description;7;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4aa0;MGMLIS3_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa1;MGMLIS3_InvalidRampTime;Action Message with invalid ramp time was received.;161;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa2;MGMLIS3_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa3;MGMLIS3_ExecutionFailed;Command execution failed;163;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa4;MGMLIS3_CrcError;Reaction wheel reply has invalid crc;164;MGM_LIS3MDL;mission/acs/RwHandler.h -0x4aa5;MGMLIS3_ValueNotRead;No description;165;MGM_LIS3MDL;mission/acs/RwHandler.h 0x4c00;SPPA_NoPacketFound;No description;0;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h 0x4c01;SPPA_SplitPacket;No description;1;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h 0x4fa1;HEATER_CommandNotSupported;No description;161;HEATER_HANDLER;mission/tcs/HeaterHandler.h @@ -492,12 +486,16 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x57a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h 0x57a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h 0x57a3;PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;163;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h -0x58a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h -0x58a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h +0x58a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h +0x58a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h +0x58a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h +0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h +0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h +0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h +0x5900;IPCI_NoReplyAvailable;No description;0;CCSDS_IP_CORE_BRIDGE;linux/acs/ImtqPollingTask.h 0x5901;IPCI_NoPacketFound;No description;1;CCSDS_IP_CORE_BRIDGE;linux/com/SyrlinksComHandler.h 0x59a0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h 0x5aa0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h -0x5c00;STRHLP_NoReplyAvailable;No description;0;STR_HELPER;linux/acs/ImtqPollingTask.h 0x5c01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h 0x5c02;STRHLP_FileNotExists;Specified file does not exist on filesystem;2;STR_HELPER;linux/acs/StrComHandler.h 0x5c03;STRHLP_PathNotExists;Specified path does not exist;3;STR_HELPER;linux/acs/StrComHandler.h @@ -515,7 +513,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x5d03;GOMS_InvalidParamSize;No description;3;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5d04;GOMS_InvalidPayloadSize;No description;4;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h -0x5e02;PLMEMDUMP_InvalidCrc;No description;2;PLOC_MEMORY_DUMPER;linux/payload/ScexHelper.h 0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h 0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h 0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/PdecHandler.h @@ -544,6 +541,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h 0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h 0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h +0x6502;PLMPHLP_InvalidCrc;No description;2;PLOC_MPSOC_HELPER;linux/payload/ScexHelper.h 0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h 0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 45bee897..1be6ee7c 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 279 translations. + * @brief Auto-generated event translation file. Contains 283 translations. * @details - * Generated on: 2023-03-26 16:40:57 + * Generated on: 2023-03-28 21:50:28 */ #include "translateEvents.h" @@ -278,12 +278,16 @@ const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON"; const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION"; const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE"; const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT"; -const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED"; const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE"; const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE"; const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE"; const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE"; const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE"; +const char *DUMP_OK_CANCELLED_STRING = "DUMP_OK_CANCELLED"; +const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED"; +const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED"; +const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED"; +const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -833,8 +837,6 @@ const char *translateEvents(Event event) { return FILE_TOO_LARGE_STRING; case (14302): return BUSY_DUMPING_EVENT_STRING; - case (14303): - return DUMP_WAS_CANCELLED_STRING; case (14305): return DUMP_OK_STORE_DONE_STRING; case (14306): @@ -845,6 +847,16 @@ const char *translateEvents(Event event) { return DUMP_HK_STORE_DONE_STRING; case (14309): return DUMP_CFDP_STORE_DONE_STRING; + case (14310): + return DUMP_OK_CANCELLED_STRING; + case (14311): + return DUMP_NOK_CANCELLED_STRING; + case (14312): + return DUMP_MISC_CANCELLED_STRING; + case (14313): + return DUMP_HK_CANCELLED_STRING; + case (14314): + return DUMP_CFDP_CANCELLED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 8d3455e3..682e515a 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 173 translations. - * Generated on: 2023-03-26 16:40:57 + * Generated on: 2023-03-28 21:50:28 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index c3d0a8a8..1be6ee7c 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 279 translations. + * @brief Auto-generated event translation file. Contains 283 translations. * @details - * Generated on: 2023-03-26 16:40:57 + * Generated on: 2023-03-28 21:50:28 */ #include "translateEvents.h" @@ -212,8 +212,7 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_ const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; -const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = - "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; +const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; @@ -279,12 +278,16 @@ const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON"; const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION"; const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE"; const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT"; -const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED"; const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE"; const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE"; const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE"; const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE"; const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE"; +const char *DUMP_OK_CANCELLED_STRING = "DUMP_OK_CANCELLED"; +const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED"; +const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED"; +const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED"; +const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -834,8 +837,6 @@ const char *translateEvents(Event event) { return FILE_TOO_LARGE_STRING; case (14302): return BUSY_DUMPING_EVENT_STRING; - case (14303): - return DUMP_WAS_CANCELLED_STRING; case (14305): return DUMP_OK_STORE_DONE_STRING; case (14306): @@ -846,6 +847,16 @@ const char *translateEvents(Event event) { return DUMP_HK_STORE_DONE_STRING; case (14309): return DUMP_CFDP_STORE_DONE_STRING; + case (14310): + return DUMP_OK_CANCELLED_STRING; + case (14311): + return DUMP_NOK_CANCELLED_STRING; + case (14312): + return DUMP_MISC_CANCELLED_STRING; + case (14313): + return DUMP_HK_CANCELLED_STRING; + case (14314): + return DUMP_CFDP_CANCELLED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 8d3455e3..682e515a 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 173 translations. - * Generated on: 2023-03-26 16:40:57 + * Generated on: 2023-03-28 21:50:28 */ #include "translateObjects.h" diff --git a/tmtc b/tmtc index f2897fa6..e0a31cb9 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f2897fa6060e178ef8d11c9d29faa058896c9253 +Subproject commit e0a31cb992bbf0884d4b2b10ffcdca30b0ec9351 From 4c57e4839947a92f8a795ab3be46466c7922c515 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 21:58:04 +0200 Subject: [PATCH 24/53] cleaning up --- mission/tmtc/PersistentLogTmStoreTask.cpp | 7 +------ mission/tmtc/PersistentSingleTmStoreTask.cpp | 16 ---------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/tmtc/PersistentLogTmStoreTask.cpp index c13b88f6..dcd78b54 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/tmtc/PersistentLogTmStoreTask.cpp @@ -15,7 +15,6 @@ PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, Storage ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { bool someonesBusy = false; bool vcBusyDuringDump = false; - bool byteFlowControl = false; auto stateHandlingForStore = [&](bool storeIsBusy, DumpContext& ctx) { if (storeIsBusy) { someonesBusy = true; @@ -26,10 +25,6 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { if (ctx.vcBusyDuringDump) { vcBusyDuringDump = true; } - if (ctx.dumpedBytes - ctx.bytesDumpedAtLastDelay >= 2048) { - byteFlowControl = true; - ctx.bytesDumpedAtLastDelay = ctx.dumpedBytes; - } }; while (true) { if (not cyclicStoreCheck()) { @@ -45,7 +40,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { TaskFactory::delayTask(100); } else if (vcBusyDuringDump) { // TODO: Might not be necessary - TaskFactory::delayTask(20); + TaskFactory::delayTask(10); } } } diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index 33492d43..a2d57208 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -11,11 +11,6 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( dumpContext(eventIfDumpDone, eventIfCancelled) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { - ReturnValue_t result = returnvalue::OK; - uint32_t delaysVcBusyDuringDump = 0; - uint32_t delaysFlowControl = 0; - uint32_t delayNotBusy = 0; - uint32_t delayHotLoop = 0; while (true) { // Delay done by the check if (not cyclicStoreCheck()) { @@ -24,21 +19,10 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { bool busy = handleOneStore(storeWithQueue, dumpContext); if (not busy) { TaskFactory::delayTask(100); - delayNotBusy++; } else if (dumpContext.vcBusyDuringDump) { // TODO: Might not be necessary - delaysVcBusyDuringDump++; TaskFactory::delayTask(10); - } else { - delayHotLoop++; } - // if ((delaysVcBusyDuringDump + delaysFlowControl + delayNotBusy + delayHotLoop) % 2000 == - // 0) { - // sif::debug << "DLY NBUSY: " << delayNotBusy << std::endl; - // sif::debug << "DLY FLCTRL: " << delaysFlowControl << std::endl; - // sif::debug << "DLY BUSYDUMP: " << delaysVcBusyDuringDump << std::endl; - // sif::debug << "DLY HOTLOOP: " << delayHotLoop << std::endl; - // } } } From eafc47f7a17b39accf71f278db63ce307aec33ac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 21:59:38 +0200 Subject: [PATCH 25/53] some more cleaning up --- mission/tmtc/TmStoreTaskBase.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 54dcc6a4..5fef74ff 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -41,8 +41,7 @@ class TmStoreTaskBase : public SystemObject { // 20 minutes are allowed as maximum dump time. Countdown cancelDumpCd = Countdown(60 * 20 * 1000); // If the TM sink is busy for 1 minute for whatever reason, cancel the dump. - // TODO: Reset this to default value. - Countdown tmSinkBusyCd = Countdown(60 * 20 * 1000); // Countdown(60 * 1000 ); + Countdown tmSinkBusyCd = Countdown(60 * 1000); VirtualChannel& channel; bool storesInitialized = false; bool fileHasSwapped = false; From 9cfee1277461323a95e1b72f0d8218fd386b0bd5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 22:04:40 +0200 Subject: [PATCH 26/53] docs + TODO --- linux/ipcore/PapbVcInterface.cpp | 3 +++ mission/tmtc/TmStoreTaskBase.h | 1 + 2 files changed, 4 insertions(+) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index c130d31e..eacfce33 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -36,6 +36,9 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { for (size_t idx = 0; idx < size; idx++) { // This delay is super-important, DO NOT REMOVE! // Polling the GPIO too often can mess up the scheduler. + // TODO: Maybe this should not be done like this. It would be better if there was a custom + // FPGA module which can accept packets and then takes care of dumping that packet into + // the PTME. DMA would be an ideal solution for this. nanosleep(&BETWEEN_POLL_DELAY, &remDelay); if (pollPapbBusySignal(2) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 5fef74ff..7ef34c9a 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -36,6 +36,7 @@ class TmStoreTaskBase : public SystemObject { SdCardMountedIF& sdcMan); protected: + StorageManagerIF& ipcStore; Countdown sdCardCheckCd = Countdown(800); // 20 minutes are allowed as maximum dump time. From f29163e8a9879c4b56a1a3544db2ed3175fc9fdd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 22:08:08 +0200 Subject: [PATCH 27/53] changelog note --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab321fec..13b0af36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,9 @@ will consitute of a breaking change warranting a new major release: - ACS board devices: Go to ON mode instead of going to NORMAL mode directly. - SUS device handlers: Go to ON mode on startup instead of NORMAL mode. - Tweaks for the delay handling for the persistent TM stores. This allows pushing the full - high datarate when dumping telemetry. + high datarate when dumping telemetry. The most important and interesting fix is that + there needs to be a small delay between the polling of the GPIO. Polling the GPIO + without any delay consecutively can lead to scheduling issues. ## Changed From 9c743eb0d9c0372070b4c16e390d24c014607907 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 22:17:54 +0200 Subject: [PATCH 28/53] bump fsfw and changelog --- CHANGELOG.md | 2 ++ fsfw | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13b0af36..0b68b945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ will consitute of a breaking change warranting a new major release: high datarate when dumping telemetry. The most important and interesting fix is that there needs to be a small delay between the polling of the GPIO. Polling the GPIO without any delay consecutively can lead to scheduling issues. +- Bump FSFW for fix of `ControllerBase` class `startTransition` implementation. +- Bump FSFW for possible fix of `PowerSwitcherComponent`: Initial mode `MODE_UNDEFINED`. ## Changed diff --git a/fsfw b/fsfw index 314f0fa2..4f632e2c 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 314f0fa2cde749ee1021d311e222bb0044cc2e5b +Subproject commit 4f632e2c6866cee88dd9920a965aa0d079799aa3 From 0c3c61c686c1e9726ea52aa8e37813c4348b69c5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 22:26:23 +0200 Subject: [PATCH 29/53] prep v1.41.0 --- CHANGELOG.md | 5 +++++ CMakeLists.txt | 2 +- tmtc | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b68b945..4d7808b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +# [v1.41.0] 2023-03-28 + +eive-tmtc: v2.20.0 +q7s-package: v2.2.0 + ## Fixed - Proper Faulty/External Control handling for the dual lane assemblies. diff --git a/CMakeLists.txt b/CMakeLists.txt index c71f8360..e0ec4dd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 1) -set(OBSW_VERSION_MINOR 40) +set(OBSW_VERSION_MINOR 41) set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE) diff --git a/tmtc b/tmtc index e0a31cb9..e8ccb470 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e0a31cb992bbf0884d4b2b10ffcdca30b0ec9351 +Subproject commit e8ccb4700a34c549eb7d943ee4a401258c69d8cb From e2b36313c1921a1b21af72f3f9669c8a62b5a0a7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 22:28:58 +0200 Subject: [PATCH 30/53] afmt --- bsp_hosted/fsfwconfig/events/translateEvents.cpp | 5 +++-- bsp_hosted/fsfwconfig/objects/translateObjects.cpp | 2 +- generators/events/translateEvents.cpp | 2 +- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 5 +++-- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- mission/tmtc/TmStoreTaskBase.h | 1 - 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 1be6ee7c..e89c7276 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 283 translations. * @details - * Generated on: 2023-03-28 21:50:28 + * Generated on: 2023-03-28 22:20:01 */ #include "translateEvents.h" @@ -212,7 +212,8 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_ const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; -const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; +const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = + "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 694fbf85..6db8614c 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 169 translations. - * Generated on: 2023-03-28 21:50:28 + * Generated on: 2023-03-28 22:20:01 */ #include "translateObjects.h" diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 1be6ee7c..c7a92358 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 283 translations. * @details - * Generated on: 2023-03-28 21:50:28 + * Generated on: 2023-03-28 22:20:01 */ #include "translateEvents.h" diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 682e515a..7e6d913b 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 173 translations. - * Generated on: 2023-03-28 21:50:28 + * Generated on: 2023-03-28 22:20:01 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 1be6ee7c..e89c7276 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 283 translations. * @details - * Generated on: 2023-03-28 21:50:28 + * Generated on: 2023-03-28 22:20:01 */ #include "translateEvents.h" @@ -212,7 +212,8 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_ const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; -const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; +const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = + "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 682e515a..7e6d913b 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 173 translations. - * Generated on: 2023-03-28 21:50:28 + * Generated on: 2023-03-28 22:20:01 */ #include "translateObjects.h" diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/tmtc/TmStoreTaskBase.h index 7ef34c9a..5fef74ff 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/tmtc/TmStoreTaskBase.h @@ -36,7 +36,6 @@ class TmStoreTaskBase : public SystemObject { SdCardMountedIF& sdcMan); protected: - StorageManagerIF& ipcStore; Countdown sdCardCheckCd = Countdown(800); // 20 minutes are allowed as maximum dump time. From b7c17fdf0f483417babe407222d46359c8fc3f61 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 29 Mar 2023 11:41:42 +0200 Subject: [PATCH 31/53] scex update --- CHANGELOG.md | 4 ++++ mission/payload/ScexDeviceHandler.cpp | 24 ++++++++++++------------ mission/payload/ScexDeviceHandler.h | 8 ++++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d7808b5..85b96c32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Changed + +- SCEX filename updates. Also use T as the file ID / date separator between date and time. + # [v1.41.0] 2023-03-28 eive-tmtc: v2.20.0 diff --git a/mission/payload/ScexDeviceHandler.cpp b/mission/payload/ScexDeviceHandler.cpp index 7ef070a9..2b3f69f7 100644 --- a/mission/payload/ScexDeviceHandler.cpp +++ b/mission/payload/ScexDeviceHandler.cpp @@ -205,7 +205,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons using namespace scex; ReturnValue_t status = OK; - auto oneFileHandler = [&](std::string cmdName) { + auto oneFileHandler = [&](const char* cmdName) { auto activeSd = sdcMan.getActiveSdCard(); if (not activeSd) { return HasFileSystemIF::FILESYSTEM_INACTIVE; @@ -216,7 +216,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons if (prefix == nullptr) { return returnvalue::FAILED; } - oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin"; + oss << prefix << "/scex/scex-" << cmdName << "-" << fileId << ".bin"; fileName = oss.str(); ofstream out(fileName, ofstream::binary); if (out.bad()) { @@ -227,7 +227,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons out << helper; return OK; }; - auto multiFileHandler = [&](std::string cmdName) { + auto multiFileHandler = [&](const char* cmdName) { if ((helper.getPacketCounter() == 1) or (not fileNameSet)) { auto activeSd = sdcMan.getActiveSdCard(); if (not activeSd) { @@ -264,31 +264,31 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons id = helper.getCmd(); switch (id) { case (PING): { - status = oneFileHandler("ping_"); + status = oneFileHandler(PING_IDLE_BASE_NAME); break; } case (ION_CMD): { - status = oneFileHandler("ion_"); + status = oneFileHandler(ION_BASE_NAME); break; } case (TEMP_CMD): { - status = oneFileHandler("temp_"); + status = oneFileHandler(TEMPERATURE_BASE_NAME); break; } case (EXP_STATUS_CMD): { - status = oneFileHandler("exp_status_"); + status = oneFileHandler(EXP_STATUS_BASE_NAME); break; } case (FRAM): { - status = multiFileHandler("fram_"); + status = multiFileHandler(FRAM_BASE_NAME); break; } case (ONE_CELL): { - status = multiFileHandler("one_cell_"); + status = multiFileHandler(ONE_CELL_BASE_NAME); break; } case (ALL_CELLS_CMD): { - status = multiFileHandler("multi_cell_"); + status = multiFileHandler(ALL_CELLS_BASE_NAME); break; } default: @@ -362,9 +362,9 @@ std::string ScexDeviceHandler::date_time_string() { ostringstream oss(std::ostringstream::ate); if (tod.hour < 10) { - oss << tod.year << tod.month << tod.day << "_0" << tod.hour; + oss << tod.year << tod.month << tod.day << "T0" << tod.hour; } else { - oss << tod.year << tod.month << tod.day << "_" << tod.hour; + oss << tod.year << tod.month << tod.day << "T" << tod.hour; } if (tod.minute < 10) { oss << 0 << tod.minute; diff --git a/mission/payload/ScexDeviceHandler.h b/mission/payload/ScexDeviceHandler.h index 089a9005..8a8dcbd2 100644 --- a/mission/payload/ScexDeviceHandler.h +++ b/mission/payload/ScexDeviceHandler.h @@ -13,6 +13,14 @@ class SdCardMountedIF; class ScexDeviceHandler : public DeviceHandlerBase { public: + static constexpr char *FRAM_BASE_NAME = "framContent"; + static constexpr char *ION_BASE_NAME = "ion"; + static constexpr char *TEMPERATURE_BASE_NAME = "temperature"; + static constexpr char *EXP_STATUS_BASE_NAME = "expStatus"; + static constexpr char *ONE_CELL_BASE_NAME = "oneCell"; + static constexpr char *ALL_CELLS_BASE_NAME = "allCells"; + static constexpr char *PING_IDLE_BASE_NAME = "pingIdle"; + ScexDeviceHandler(object_id_t objectId, ScexUartReader &reader, CookieIF *cookie, SdCardMountedIF &sdcMan); void setPowerSwitcher(PowerSwitchIF &powerSwitcher, power::Switch_t switchId); From a72805d137c2a0869117775fb5a1844549389aab Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 29 Mar 2023 11:44:13 +0200 Subject: [PATCH 32/53] move STR assy --- bsp_q7s/core/ObjectFactory.cpp | 2 +- dummies/helpers.cpp | 2 +- mission/system/acs/CMakeLists.txt | 1 + mission/system/{objects => acs}/StrAssembly.cpp | 0 mission/system/{objects => acs}/StrAssembly.h | 0 mission/system/objects/CMakeLists.txt | 1 - 6 files changed, 3 insertions(+), 3 deletions(-) rename mission/system/{objects => acs}/StrAssembly.cpp (100%) rename mission/system/{objects => acs}/StrAssembly.h (100%) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 313c7aa6..00e87330 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index e0880ab9..1a541dfd 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -27,8 +27,8 @@ #include #include #include +#include #include -#include #include #include "TemperatureSensorInserter.h" diff --git a/mission/system/acs/CMakeLists.txt b/mission/system/acs/CMakeLists.txt index 70e11e59..e5ef2cb8 100644 --- a/mission/system/acs/CMakeLists.txt +++ b/mission/system/acs/CMakeLists.txt @@ -2,6 +2,7 @@ target_sources( ${LIB_EIVE_MISSION} PRIVATE AcsBoardAssembly.cpp AcsSubsystem.cpp + StrAssembly.cpp DualLaneAssemblyBase.cpp ImtqAssembly.cpp RwAssembly.cpp diff --git a/mission/system/objects/StrAssembly.cpp b/mission/system/acs/StrAssembly.cpp similarity index 100% rename from mission/system/objects/StrAssembly.cpp rename to mission/system/acs/StrAssembly.cpp diff --git a/mission/system/objects/StrAssembly.h b/mission/system/acs/StrAssembly.h similarity index 100% rename from mission/system/objects/StrAssembly.h rename to mission/system/acs/StrAssembly.h diff --git a/mission/system/objects/CMakeLists.txt b/mission/system/objects/CMakeLists.txt index e23a82c7..53cc200d 100644 --- a/mission/system/objects/CMakeLists.txt +++ b/mission/system/objects/CMakeLists.txt @@ -5,6 +5,5 @@ target_sources( TcsSubsystem.cpp PayloadSubsystem.cpp Stack5VHandler.cpp - StrAssembly.cpp PowerStateMachineBase.cpp TcsBoardAssembly.cpp) From 770fee009770abf35f006038a5377ffc3cf24053 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 29 Mar 2023 17:38:38 +0200 Subject: [PATCH 33/53] some minor tweaks --- bsp_q7s/core/ObjectFactory.cpp | 2 +- linux/ipcore/PapbVcInterface.cpp | 6 ++---- linux/ipcore/PapbVcInterface.h | 4 ++-- mission/com/CcsdsIpCoreHandler.cpp | 18 +++++++++++++----- mission/com/CcsdsIpCoreHandler.h | 2 +- mission/tmtc/PersistentSingleTmStoreTask.cpp | 3 ++- mission/tmtc/TmStoreTaskBase.cpp | 4 ++-- 7 files changed, 23 insertions(+), 16 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 00e87330..8ed42ff9 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -21,9 +21,9 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index eacfce33..5849aecd 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -65,7 +65,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; - nextDelay.tv_nsec = 0; + nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS; while (true) { /** Check if PAPB interface is ready to receive data */ @@ -87,9 +87,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const // Ignore signal handling here for now. nanosleep(&nextDelay, &remDelay); // Adaptive delay. - if (nextDelay.tv_nsec == 0) { - nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; - } else if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { + if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { nextDelay.tv_nsec *= 2; } } diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index b4454dae..cfc885fc 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -76,7 +76,7 @@ class PapbVcInterface : public VirtualChannelIF { */ static const int DATA_REG_OFFSET = 256; - static constexpr long int FIRST_NON_NULL_DELAY_NS = 10; + static constexpr long int FIRST_DELAY_PAPB_POLLING_NS = 10; static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40; LinuxLibgpioIF* gpioComIF = nullptr; @@ -89,7 +89,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; - const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 5}; + const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 2}; mutable struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; diff --git a/mission/com/CcsdsIpCoreHandler.cpp b/mission/com/CcsdsIpCoreHandler.cpp index 806096b8..212acd8d 100644 --- a/mission/com/CcsdsIpCoreHandler.cpp +++ b/mission/com/CcsdsIpCoreHandler.cpp @@ -165,9 +165,11 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu break; } case EN_TRANSMITTER: { - enableTransmit(); if (mode == HasModesIF::MODE_OFF) { + enableTransmit(true); mode = HasModesIF::MODE_ON; + } else { + enableTransmit(false); } return EXECUTION_FINISHED; } @@ -205,9 +207,11 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; } -void CcsdsIpCoreHandler::enableTransmit() { - // Reset PTME on each transmit enable. - updateBatPriorityFromParam(); +void CcsdsIpCoreHandler::enableTransmit(bool resetPtmeUpdateParams) { + if (resetPtmeUpdateParams) { + // Reset PTME on each transmit enable. + updateBatPriorityFromParam(); + } #ifndef TE0720_1CFA gpioIF->pullHigh(ptmeGpios.enableTxClock); gpioIF->pullHigh(ptmeGpios.enableTxData); @@ -243,7 +247,11 @@ void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) { } }; if (mode == HasModesIF::MODE_ON) { - enableTransmit(); + if (this->mode != HasModesIF::MODE_ON) { + enableTransmit(true); + } else { + enableTransmit(false); + } if (submode == static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { com::Datarate currentDatarate = com::getCurrentDatarate(); if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { diff --git a/mission/com/CcsdsIpCoreHandler.h b/mission/com/CcsdsIpCoreHandler.h index 0fad0aae..f01d7ab3 100644 --- a/mission/com/CcsdsIpCoreHandler.h +++ b/mission/com/CcsdsIpCoreHandler.h @@ -172,7 +172,7 @@ class CcsdsIpCoreHandler : public SystemObject, /** * @brief Starts transmit timer and enables transmitter. */ - void enableTransmit(); + void enableTransmit(bool resetPtmeUpdateParams); /** * @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/tmtc/PersistentSingleTmStoreTask.cpp index a2d57208..1c93f14e 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/tmtc/PersistentSingleTmStoreTask.cpp @@ -20,8 +20,9 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { if (not busy) { TaskFactory::delayTask(100); } else if (dumpContext.vcBusyDuringDump) { + sif::debug << "VC busy, delaying" << std::endl; // TODO: Might not be necessary - TaskFactory::delayTask(10); + TaskFactory::delayTask(2); } } } diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/tmtc/TmStoreTaskBase.cpp index 7ca03488..993c127d 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/tmtc/TmStoreTaskBase.cpp @@ -115,10 +115,10 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store } else { // The PTME might be at full load, so it might sense to delay for a bit to let it do // its work until some more bandwidth is available. Set a flag here so the upper layer can - // do ths. + // do this. dumpContext.vcBusyDuringDump = true; dumpContext.ptmeBusyCounter++; - if (dumpContext.ptmeBusyCounter == 100) { + if (dumpContext.ptmeBusyCounter == 200) { // If this happens, something is probably wrong. sif::warning << "PTME busy for longer period. Cancelling dump" << std::endl; cancelDump(dumpContext, store, channel.isTxOn()); From 27370fcd44a94015f66ef0a9afea25386b2b2a47 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 30 Mar 2023 13:36:44 +0200 Subject: [PATCH 34/53] multi byte write support but does not work.. --- linux/ipcore/PapbVcInterface.cpp | 45 +++++++++++++++++++++++++++++--- linux/ipcore/PapbVcInterface.h | 8 +++--- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 5849aecd..4aeba804 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "fsfw/serviceinterface/ServiceInterface.h" @@ -28,11 +29,46 @@ ReturnValue_t PapbVcInterface::initialize() { } ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { + // There are no packets smaller than 4, this is considered a configuration error. + if (size < 4) { + return returnvalue::FAILED; + } if (pollPapbBusySignal(0) == returnvalue::OK) { - startPacketTransfer(); + startPacketTransfer(ByteWidthCfg::ONE); } else { return DirectTmSinkIF::IS_BUSY; } + // TODO: This should work but does not.. + // size_t idx = 0; + // while (idx < size) { + // + // nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + // if ((size - idx) < 4) { + // *vcBaseReg = CONFIG_DATA_INPUT | (size - idx - 1); + // usleep(1); + // } + // if (pollPapbBusySignal(2) == returnvalue::OK) { + // // vcBaseReg + DATA_REG_OFFSET + 3 = static_cast(data + idx); + // // vcBaseReg + DATA_REG_OFFSET + 2 = static_cast(data + idx + 1); + // // vcBaseReg + DATA_REG_OFFSET + 1 = static_cast(data + idx + 2); + // // vcBaseReg + DATA_REG_OFFSET = static_cast(data + idx + 3); + // + // // std::memcpy((vcBaseReg + DATA_REG_OFFSET), data + idx , nextWriteSize); + // *(vcBaseReg + DATA_REG_OFFSET) = *reinterpret_cast(data + idx); + // //uint8_t* byteReg = reinterpret_cast(vcBaseReg + DATA_REG_OFFSET); + // + // //byteReg[0] = data[idx]; + // //byteReg[1] = data[idx]; + // } else { + // abortPacketTransfer(); + // return returnvalue::FAILED; + // } + // // TODO: Change this after the bugfix. Right now, the PAPB ignores the content of the byte + // // width configuration.5 + // // It's okay to increment by a larger amount for the last segment here, loop will be over + // // in any case. + // idx += 4; + // } for (size_t idx = 0; idx < size; idx++) { // This delay is super-important, DO NOT REMOVE! // Polling the GPIO too often can mess up the scheduler. @@ -40,6 +76,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { // FPGA module which can accept packets and then takes care of dumping that packet into // the PTME. DMA would be an ideal solution for this. nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + if (pollPapbBusySignal(2) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { @@ -57,7 +94,9 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return returnvalue::OK; } -void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; } +void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) { + *vcBaseReg = CONFIG_DATA_INPUT | initWidth; +} void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } @@ -65,7 +104,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const gpio::Levels papbBusyState = gpio::Levels::LOW; ReturnValue_t result; uint32_t busyIdx = 0; - nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS; + nextDelay.tv_nsec = 0; while (true) { /** Check if PAPB interface is ready to receive data */ diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index cfc885fc..61999c7d 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -50,13 +50,14 @@ class PapbVcInterface : public VirtualChannelIF { static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0); + enum ByteWidthCfg : uint32_t { ONE = 0b00, TWO = 0b01, THREE = 0b10, FOUR = 0b11 }; /** * Configuration bits: * bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00 * bit[2]: Set this bit to 1 to abort a transferred packet * bit[3]: Signals to VcInterface the start of a new telemetry packet */ - static constexpr uint32_t CONFIG_START = 0b00001000; + static constexpr uint32_t CONFIG_DATA_INPUT = 0b00001000; /** * Abort a transferred packet. @@ -88,11 +89,12 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; + volatile uint32_t dummy = 0; mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 2}; mutable struct timespec remDelay; - volatile uint32_t* vcBaseReg = nullptr; + uint32_t* vcBaseReg = nullptr; uint32_t vcOffset = 0; @@ -100,7 +102,7 @@ class PapbVcInterface : public VirtualChannelIF { * @brief This function sends the config byte to the virtual channel of the PTME IP Core * to initiate a packet transfer. */ - void startPacketTransfer(); + void startPacketTransfer(ByteWidthCfg initWidth); void abortPacketTransfer(); From 15413767019151c0b9bb6745aff4902694e72e34 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 30 Mar 2023 13:41:14 +0200 Subject: [PATCH 35/53] minor tweak for device handler --- mission/payload/ScexDeviceHandler.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mission/payload/ScexDeviceHandler.h b/mission/payload/ScexDeviceHandler.h index 8a8dcbd2..f95169b9 100644 --- a/mission/payload/ScexDeviceHandler.h +++ b/mission/payload/ScexDeviceHandler.h @@ -13,13 +13,13 @@ class SdCardMountedIF; class ScexDeviceHandler : public DeviceHandlerBase { public: - static constexpr char *FRAM_BASE_NAME = "framContent"; - static constexpr char *ION_BASE_NAME = "ion"; - static constexpr char *TEMPERATURE_BASE_NAME = "temperature"; - static constexpr char *EXP_STATUS_BASE_NAME = "expStatus"; - static constexpr char *ONE_CELL_BASE_NAME = "oneCell"; - static constexpr char *ALL_CELLS_BASE_NAME = "allCells"; - static constexpr char *PING_IDLE_BASE_NAME = "pingIdle"; + static constexpr char FRAM_BASE_NAME[] = "framContent"; + static constexpr char ION_BASE_NAME[] = "ion"; + static constexpr char TEMPERATURE_BASE_NAME[] = "temperature"; + static constexpr char EXP_STATUS_BASE_NAME[] = "expStatus"; + static constexpr char ONE_CELL_BASE_NAME[] = "oneCell"; + static constexpr char ALL_CELLS_BASE_NAME[] = "allCells"; + static constexpr char PING_IDLE_BASE_NAME[] = "pingIdle"; ScexDeviceHandler(object_id_t objectId, ScexUartReader &reader, CookieIF *cookie, SdCardMountedIF &sdcMan); From 5f6f85a7781ebb4b9908481bfc6230dad51958a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 30 Mar 2023 17:16:59 +0200 Subject: [PATCH 36/53] done --- CHANGELOG.md | 11 ++ bsp_q7s/core/ObjectFactory.cpp | 5 +- bsp_q7s/core/scheduling.cpp | 8 ++ common/config/eive/objects.h | 2 + linux/acs/GpsHyperionLinuxController.cpp | 1 + mission/acs/GyrAdis1650XHandler.cpp | 3 +- mission/acs/GyrL3gCustomHandler.cpp | 5 +- mission/genericFactory.cpp | 3 +- mission/system/acs/AcsBoardAssembly.cpp | 107 +++++++++++--------- mission/system/acs/AcsBoardAssembly.h | 12 ++- mission/system/acs/DualLaneAssemblyBase.cpp | 13 +-- mission/system/acs/DualLaneAssemblyBase.h | 4 +- tmtc | 2 +- 13 files changed, 108 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85b96c32..3d982765 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,17 @@ will consitute of a breaking change warranting a new major release: - SCEX filename updates. Also use T as the file ID / date separator between date and time. +## Fixed + +- Bugfix for side lane transitions of the dual lane assemblies, which only worked when the + assembly was directly commanded + +## Added + +- Added GPS0 and GPS1 health device which are used by the ACS board assembly when deciding whether + to change to the other side or to go to dual side directly. Setting the health devices to faulty + should also trigger a side switch or a switch to dual mode. + # [v1.41.0] 2023-03-28 eive-tmtc: v2.20.0 diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 00e87330..e7a5fca0 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,5 +1,6 @@ #include "ObjectFactory.h" +#include #include #include #include @@ -21,9 +22,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -516,6 +517,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS); + new HealthDevice(objects::GPS_0_HEALTH_DEV, objects::ACS_BOARD_ASS); + new HealthDevice(objects::GPS_1_HEALTH_DEV, objects::ACS_BOARD_ASS); ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF); #endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index 25f8ede4..2d767687 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -291,6 +291,14 @@ void scheduling::initTasks() { if (result != returnvalue::OK) { scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY); } + result = acsSysTask->addComponent(objects::GPS_0_HEALTH_DEV); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("GPS_0_HEALTH_DEV", objects::GPS_0_HEALTH_DEV); + } + result = acsSysTask->addComponent(objects::GPS_1_HEALTH_DEV); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("GPS_1_HEALTH_DEV", objects::GPS_1_HEALTH_DEV); + } PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask( "TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING); diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 667067bb..0cc4b9d9 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -43,6 +43,8 @@ enum commonObjects : uint32_t { RW4 = 0x44120350, STAR_TRACKER = 0x44130001, GPS_CONTROLLER = 0x44130045, + GPS_0_HEALTH_DEV = 0x44130046, + GPS_1_HEALTH_DEV = 0x44130047, IMTQ_POLLING = 0x44140013, IMTQ_HANDLER = 0x44140014, diff --git a/linux/acs/GpsHyperionLinuxController.cpp b/linux/acs/GpsHyperionLinuxController.cpp index 0b971f49..b5dc8a1f 100644 --- a/linux/acs/GpsHyperionLinuxController.cpp +++ b/linux/acs/GpsHyperionLinuxController.cpp @@ -99,6 +99,7 @@ void GpsHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) { handleQueue(); poolManager.performHkOperation(); + while (true) { #if OBSW_THREAD_TRACING == 1 trace::threadTrace(opCounter, "GPS CTRL"); diff --git a/mission/acs/GyrAdis1650XHandler.cpp b/mission/acs/GyrAdis1650XHandler.cpp index 63a28366..57033e80 100644 --- a/mission/acs/GyrAdis1650XHandler.cpp +++ b/mission/acs/GyrAdis1650XHandler.cpp @@ -87,12 +87,11 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem getMode() == _MODE_POWER_DOWN) { return IGNORE_FULL_PACKET; } + *foundLen = remainingSize; if (remainingSize != sizeof(acs::Adis1650XReply)) { - *foundLen = remainingSize; return returnvalue::FAILED; } *foundId = adis1650x::REPLY; - *foundLen = remainingSize; if (internalState == InternalState::SHUTDOWN) { commandExecuted = true; } diff --git a/mission/acs/GyrL3gCustomHandler.cpp b/mission/acs/GyrL3gCustomHandler.cpp index fd576791..934fba99 100644 --- a/mission/acs/GyrL3gCustomHandler.cpp +++ b/mission/acs/GyrL3gCustomHandler.cpp @@ -99,12 +99,11 @@ ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) { return IGNORE_FULL_PACKET; } + *foundLen = len; if (len != sizeof(acs::GyroL3gReply)) { - *foundLen = len; return returnvalue::FAILED; } - *foundId = l3gd20h::REPLY; - *foundLen = len; + *foundId = adis1650x::REPLY; if (internalState == InternalState::SHUTDOWN) { commandExecuted = true; } diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index f93e4df6..e29d1b0f 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -347,7 +347,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, AcsBoardHelper acsBoardHelper = AcsBoardHelper( objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER, objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER, - objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER); + objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER, + objects::GPS_0_HEALTH_DEV, objects::GPS_1_HEALTH_DEV); auto acsAss = new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF); for (auto& assChild : assemblyDhbs) { diff --git a/mission/system/acs/AcsBoardAssembly.cpp b/mission/system/acs/AcsBoardAssembly.cpp index 08711f76..6c4023f8 100644 --- a/mission/system/acs/AcsBoardAssembly.cpp +++ b/mission/system/acs/AcsBoardAssembly.cpp @@ -77,14 +77,16 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or - helper.gpsMode != MODE_ON) { + (helper.gpsMode != MODE_ON) or + (healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY)) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return returnvalue::OK; } else if (wantedSubmode == B_SIDE) { if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or - helper.gpsMode != MODE_ON) { + (helper.gpsMode != MODE_ON) or + (healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY)) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return returnvalue::OK; @@ -126,12 +128,33 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) { if (mode == devMode) { modeTable[tableIdx].setMode(mode); - } else if (isUseable(objectId, devMode)) { + } else if (isModeCommandable(objectId, devMode)) { modeTable[tableIdx].setMode(mode); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } }; - bool gpsUsable = isUseable(helper.gpsId, helper.gpsMode); + bool gpsUsable = isModeCommandable(helper.gpsId, helper.gpsMode); + auto gpsCmd = [&](bool gnss0NReset, bool gnss1NReset, uint8_t gnssSelect) { + if (gpsUsable) { + if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) { + modeTable[ModeTableIdx::GPS].setMode(MODE_ON); + } else if (mode == MODE_OFF) { + gnss0NReset = true; + gnss1NReset = true; + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + } + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); + + gpioHandler(gpioIds::GNSS_0_NRESET, gnss0NReset, + "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" + "of GNSS 0"); + gpioHandler(gpioIds::GNSS_1_NRESET, gnss1NReset, + "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" + "of GNSS 1"); + gpioHandler(gpioIds::GNSS_SELECT, gnssSelect, + "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select"); + } + }; switch (submode) { case (A_SIDE): { modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); @@ -146,16 +169,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A); - if (gpsUsable) { - gpioHandler(gpioIds::GNSS_0_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 0 high (used GNSS)"); - gpioHandler(gpioIds::GNSS_1_NRESET, false, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 1 low (unused GNSS)"); - gpioHandler(gpioIds::GNSS_SELECT, false, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low"); - } + gpsCmd(true, false, 0); break; } case (B_SIDE): { @@ -171,20 +185,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); - if (gpsUsable) { - gpioHandler(gpioIds::GNSS_0_NRESET, false, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 0 low (unused GNSS)"); - gpioHandler(gpioIds::GNSS_1_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 1 high (used GNSS)"); - gpioHandler(gpioIds::GNSS_SELECT, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high"); - } + gpsCmd(false, true, 1); break; } case (DUAL_MODE): { - cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); @@ -193,26 +197,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); - ReturnValue_t status = returnvalue::OK; - if (gpsUsable) { - gpioHandler(gpioIds::GNSS_0_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 0 high (used GNSS)"); - gpioHandler(gpioIds::GNSS_1_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 1 high (used GNSS)"); - if (defaultSubmode == Submodes::A_SIDE) { - status = gpioIF->pullLow(gpioIds::GNSS_SELECT); - } else { - status = gpioIF->pullHigh(gpioIds::GNSS_SELECT); - } - if (status != returnvalue::OK) { -#if OBSW_VERBOSE_LEVEL >= 1 - sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to" - "default side for dual mode" - << std::endl; -#endif - } + if (defaultSubmode == Submodes::A_SIDE) { + gpsCmd(true, true, 0); + } else { + gpsCmd(true, true, 1); } break; } @@ -220,10 +208,6 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl; } } - if (gpsUsable) { - modeTable[ModeTableIdx::GPS].setMode(MODE_ON); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); - } if (needsSecondStep) { result = NEED_SECOND_STEP; } @@ -307,6 +291,9 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, modeHelper.setForced(true); } }; + if (healthHelper.healthTable->getHealth(helper.gpsId) == EXTERNAL_CONTROL) { + modeHelper.setForced(true); + } if (deviceSubmode == duallane::DUAL_MODE) { checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA, helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB); @@ -315,3 +302,25 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, } return status; } + +void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { + using namespace duallane; + // Special handling to account for GPS devices being faulty. If the GPS device on the other + // side is marked faulty, directly to to dual side. + if (submode == Submodes::A_SIDE) { + if (healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY or + healthHelper.healthTable->getHealth(helper.healthDevGps1) == PERMANENT_FAULTY) { + triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0); + startTransition(mode, Submodes::DUAL_MODE); + return; + } + } else if (submode == Submodes::B_SIDE) { + if (healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY or + healthHelper.healthTable->getHealth(helper.healthDevGps0) == PERMANENT_FAULTY) { + triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0); + startTransition(mode, Submodes::DUAL_MODE); + return; + } + } + DualLaneAssemblyBase::handleChildrenLostMode(result); +} diff --git a/mission/system/acs/AcsBoardAssembly.h b/mission/system/acs/AcsBoardAssembly.h index 7427e808..b9255704 100644 --- a/mission/system/acs/AcsBoardAssembly.h +++ b/mission/system/acs/AcsBoardAssembly.h @@ -12,7 +12,7 @@ struct AcsBoardHelper { AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id, object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id, - object_id_t gpsId) + object_id_t gpsId, object_id_t gps0HealthDev, object_id_t gps1HealthDev) : mgm0Lis3IdSideA(mgm0Id), mgm1Rm3100IdSideA(mgm1Id), mgm2Lis3IdSideB(mgm2Id), @@ -35,6 +35,9 @@ struct AcsBoardHelper { object_id_t gpsId = objects::NO_OBJECT; + object_id_t healthDevGps0 = objects::NO_OBJECT; + object_id_t healthDevGps1 = objects::NO_OBJECT; + Mode_t gyro0SideAMode = HasModesIF::MODE_OFF; Mode_t gyro1SideAMode = HasModesIF::MODE_OFF; Mode_t gyro2SideBMode = HasModesIF::MODE_OFF; @@ -91,6 +94,11 @@ class AcsBoardAssembly : public DualLaneAssemblyBase { //! desired mode/submode combination static constexpr Event SIDE_SWITCH_TRANSITION_NOT_ALLOWED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW); + //! [EXPORT] : [COMMENT] This is triggered when the assembly would have normally switched + //! the board side, but the GPS device of the other side was marked faulty. + //! P1: Current submode. + static constexpr Event DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY = + event::makeEvent(SUBSYSTEM_ID, 4, severity::MEDIUM); static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; @@ -120,6 +128,8 @@ class AcsBoardAssembly : public DualLaneAssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + void handleChildrenLostMode(ReturnValue_t result) override; + ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode); void refreshHelperModes(); diff --git a/mission/system/acs/DualLaneAssemblyBase.cpp b/mission/system/acs/DualLaneAssemblyBase.cpp index 18369924..e32717de 100644 --- a/mission/system/acs/DualLaneAssemblyBase.cpp +++ b/mission/system/acs/DualLaneAssemblyBase.cpp @@ -46,6 +46,9 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { AssemblyBase::startTransition(mode, submode); return; } + if (sideSwitchState == SideSwitchState::NONE and sideSwitchTransition(mode, submode)) { + sideSwitchState = SideSwitchState::REQUESTED; + } uint8_t pwrSubmode = submode; if (sideSwitchState == SideSwitchState::REQUESTED) { pwrSubmode = duallane::DUAL_MODE; @@ -61,7 +64,7 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { } } -bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) { +bool DualLaneAssemblyBase::isModeCommandable(object_id_t object, Mode_t mode) { if (healthHelper.healthTable->isFaulty(object)) { return false; } @@ -70,10 +73,7 @@ bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) { if (childrenMap[object].mode == mode) { return true; } - - if (healthHelper.healthTable->isCommandable(object)) { - return true; - } + // Check for external control health state is done by base class. return false; } @@ -115,9 +115,6 @@ ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_ if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { return returnvalue::FAILED; } - if (sideSwitchTransition(mode, submode)) { - sideSwitchState = SideSwitchState::REQUESTED; - } return returnvalue::OK; } diff --git a/mission/system/acs/DualLaneAssemblyBase.h b/mission/system/acs/DualLaneAssemblyBase.h index d7ea31aa..fb17365c 100644 --- a/mission/system/acs/DualLaneAssemblyBase.h +++ b/mission/system/acs/DualLaneAssemblyBase.h @@ -49,12 +49,12 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF { MessageQueueIF* eventQueue = nullptr; /** - * Check whether it makes sense to send mode commands to the device + * Check whether it makes sense to send mode commands to the device. * @param object * @param mode * @return */ - bool isUseable(object_id_t object, Mode_t mode); + bool isModeCommandable(object_id_t object, Mode_t mode); /** * Thin wrapper function which is required because the helper class diff --git a/tmtc b/tmtc index e8ccb470..1f491a72 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e8ccb4700a34c549eb7d943ee4a401258c69d8cb +Subproject commit 1f491a72a346eb7801d20eb56b2aafd1dea2d6f0 From 74a38dc76b662ead3f507ebb57a6b1041ed1de21 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 30 Mar 2023 17:22:28 +0200 Subject: [PATCH 37/53] re-run generators --- bsp_hosted/fsfwconfig/events/translateEvents.cpp | 8 ++++++-- bsp_hosted/fsfwconfig/objects/translateObjects.cpp | 10 ++++++++-- generators/bsp_hosted_events.csv | 1 + generators/bsp_hosted_objects.csv | 2 ++ generators/bsp_q7s_events.csv | 1 + generators/bsp_q7s_objects.csv | 2 ++ generators/events/translateEvents.cpp | 7 +++++-- generators/objects/translateObjects.cpp | 10 ++++++++-- linux/fsfwconfig/events/translateEvents.cpp | 8 ++++++-- linux/fsfwconfig/objects/translateObjects.cpp | 10 ++++++++-- tmtc | 2 +- 11 files changed, 48 insertions(+), 13 deletions(-) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index e89c7276..7fcdfe4c 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 283 translations. + * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-28 22:20:01 + * Generated on: 2023-03-30 17:19:31 */ #include "translateEvents.h" @@ -209,6 +209,8 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = + "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY"; const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; @@ -700,6 +702,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12803): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12804): + return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING; case (12900): return TRANSITION_OTHER_SIDE_FAILED_12900_STRING; case (12901): diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 6db8614c..264f2581 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 169 translations. - * Generated on: 2023-03-28 22:20:01 + * Contains 171 translations. + * Generated on: 2023-03-30 17:19:31 */ #include "translateObjects.h" @@ -38,6 +38,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER"; +const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV"; +const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV"; const char *IMTQ_POLLING_STRING = "IMTQ_POLLING"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; @@ -242,6 +244,10 @@ const char *translateObject(object_id_t object) { return STAR_TRACKER_STRING; case 0x44130045: return GPS_CONTROLLER_STRING; + case 0x44130046: + return GPS_0_HEALTH_DEV_STRING; + case 0x44130047: + return GPS_1_HEALTH_DEV_STRING; case 0x44140013: return IMTQ_POLLING_STRING; case 0x44140014: diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index 45403043..7184d8ce 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h 12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h 12803;0x3203;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/AcsBoardAssembly.h +12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h 12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;HIGH;No description;mission/system/acs/SusAssembly.h 12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h 12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h diff --git a/generators/bsp_hosted_objects.csv b/generators/bsp_hosted_objects.csv index a30fc9d8..3faac37c 100644 --- a/generators/bsp_hosted_objects.csv +++ b/generators/bsp_hosted_objects.csv @@ -30,6 +30,8 @@ 0x44120350;RW4 0x44130001;STAR_TRACKER 0x44130045;GPS_CONTROLLER +0x44130046;GPS_0_HEALTH_DEV +0x44130047;GPS_1_HEALTH_DEV 0x44140013;IMTQ_POLLING 0x44140014;IMTQ_HANDLER 0x442000A1;PCDU_HANDLER diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 45403043..7184d8ce 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h 12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h 12803;0x3203;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/AcsBoardAssembly.h +12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h 12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;HIGH;No description;mission/system/acs/SusAssembly.h 12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h 12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 68be8ef2..eedafc52 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -29,6 +29,8 @@ 0x44120350;RW4 0x44130001;STAR_TRACKER 0x44130045;GPS_CONTROLLER +0x44130046;GPS_0_HEALTH_DEV +0x44130047;GPS_1_HEALTH_DEV 0x44140013;IMTQ_POLLING 0x44140014;IMTQ_HANDLER 0x442000A1;PCDU_HANDLER diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index c7a92358..84da4990 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 283 translations. + * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-28 22:20:01 + * Generated on: 2023-03-30 17:19:31 */ #include "translateEvents.h" @@ -209,6 +209,7 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY"; const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; @@ -699,6 +700,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12803): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12804): + return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING; case (12900): return TRANSITION_OTHER_SIDE_FAILED_12900_STRING; case (12901): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 7e6d913b..dcbbdb75 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 173 translations. - * Generated on: 2023-03-28 22:20:01 + * Contains 175 translations. + * Generated on: 2023-03-30 17:19:31 */ #include "translateObjects.h" @@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER"; +const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV"; +const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV"; const char *IMTQ_POLLING_STRING = "IMTQ_POLLING"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; @@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) { return STAR_TRACKER_STRING; case 0x44130045: return GPS_CONTROLLER_STRING; + case 0x44130046: + return GPS_0_HEALTH_DEV_STRING; + case 0x44130047: + return GPS_1_HEALTH_DEV_STRING; case 0x44140013: return IMTQ_POLLING_STRING; case 0x44140014: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index e89c7276..7fcdfe4c 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 283 translations. + * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-28 22:20:01 + * Generated on: 2023-03-30 17:19:31 */ #include "translateEvents.h" @@ -209,6 +209,8 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = + "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY"; const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; @@ -700,6 +702,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12803): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12804): + return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING; case (12900): return TRANSITION_OTHER_SIDE_FAILED_12900_STRING; case (12901): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 7e6d913b..dcbbdb75 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 173 translations. - * Generated on: 2023-03-28 22:20:01 + * Contains 175 translations. + * Generated on: 2023-03-30 17:19:31 */ #include "translateObjects.h" @@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER"; +const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV"; +const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV"; const char *IMTQ_POLLING_STRING = "IMTQ_POLLING"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; @@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) { return STAR_TRACKER_STRING; case 0x44130045: return GPS_CONTROLLER_STRING; + case 0x44130046: + return GPS_0_HEALTH_DEV_STRING; + case 0x44130047: + return GPS_1_HEALTH_DEV_STRING; case 0x44140013: return IMTQ_POLLING_STRING; case 0x44140014: diff --git a/tmtc b/tmtc index 1f491a72..aab50dce 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1f491a72a346eb7801d20eb56b2aafd1dea2d6f0 +Subproject commit aab50dce5ace6878432377fff5e6b2cd1c485213 From f6f4db525cac3a589eeae1103753a52249cb2213 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 30 Mar 2023 23:52:37 +0200 Subject: [PATCH 38/53] read reg instead of polling GPIO --- bsp_q7s/core/ObjectFactory.cpp | 4 +--- linux/ipcore/PapbVcInterface.cpp | 19 ++++++------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index e7a5fca0..76bb39f3 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -754,10 +754,8 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3"); gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio); - // Initialise to low and then pull high to do a PTME reset, which puts the PTME in reset - // state. It will be put out of reset in the CCSDS handler initialize function. gpio = new GpiodRegularByLineName(q7s::gpioNames::PTME_RESETN, "PTME RESETN", - gpio::Direction::OUT, gpio::Levels::LOW); + gpio::Direction::OUT, gpio::Levels::HIGH); gpioCookiePtmeIp->addGpio(gpioIds::PTME_RESETN, gpio); gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs"); diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index eacfce33..e2c0805c 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -18,12 +18,11 @@ PapbVcInterface::~PapbVcInterface() {} ReturnValue_t PapbVcInterface::initialize() { UioMapper uioMapper(uioFile, mapNum); - uint32_t* baseReg; - ReturnValue_t result = uioMapper.getMappedAdress(&baseReg, UioMapper::Permissions::WRITE_ONLY); + ReturnValue_t result = uioMapper.getMappedAdress(const_cast(&vcBaseReg), + UioMapper::Permissions::WRITE_ONLY); if (result != returnvalue::OK) { return result; } - vcBaseReg = baseReg; return returnvalue::OK; } @@ -62,20 +61,14 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; } void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const { - gpio::Levels papbBusyState = gpio::Levels::LOW; - ReturnValue_t result; uint32_t busyIdx = 0; nextDelay.tv_nsec = 0; while (true) { - /** Check if PAPB interface is ready to receive data */ - result = gpioComIF->readGpio(papbBusyId, papbBusyState); - if (result != returnvalue::OK) { - sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal" - << std::endl; - return returnvalue::FAILED; - } - if (papbBusyState == gpio::Levels::HIGH) { + // Check if PAPB interface is ready to receive data. Use the configuration register for this. + // Bit 5, see PTME ptme_001_01-0-7-r2 Table 31. + bool busy = ((*vcBaseReg) >> 5) & 0b1; + if (not busy) { return returnvalue::OK; } From 4b1221ab998689a6a5940835bd80bd0428aadc7c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 01:14:59 +0200 Subject: [PATCH 39/53] modes for VC/stores --- CHANGELOG.md | 4 + bsp_q7s/core/ObjectFactory.cpp | 8 +- bsp_q7s/core/ObjectFactory.h | 2 +- linux/ipcore/PapbVcInterface.cpp | 6 +- linux/ipcore/PapbVcInterface.h | 2 + mission/com/CMakeLists.txt | 13 ++- mission/com/CcsdsIpCoreHandler.h | 2 +- mission/com/LiveTmTask.cpp | 101 ++++++++++++++++++ mission/com/LiveTmTask.h | 55 ++++++++++ .../PersistentLogTmStoreTask.cpp | 16 +++ .../{tmtc => com}/PersistentLogTmStoreTask.h | 5 +- .../PersistentSingleTmStoreTask.cpp | 17 ++- .../PersistentSingleTmStoreTask.h | 7 +- mission/{tmtc => com}/TmStoreTaskBase.cpp | 68 +++++++++++- mission/{tmtc => com}/TmStoreTaskBase.h | 33 +++++- mission/{tmtc => com}/VirtualChannel.cpp | 0 mission/{tmtc => com}/VirtualChannel.h | 0 .../{tmtc => com}/VirtualChannelWithQueue.cpp | 8 +- .../{tmtc => com}/VirtualChannelWithQueue.h | 4 +- mission/config/comCfg.cpp | 2 + mission/system/com/comModeTree.cpp | 24 ++++- mission/tmtc/CMakeLists.txt | 8 +- mission/tmtc/LiveTmTask.cpp | 27 ----- mission/tmtc/LiveTmTask.h | 25 ----- 24 files changed, 347 insertions(+), 90 deletions(-) create mode 100644 mission/com/LiveTmTask.cpp create mode 100644 mission/com/LiveTmTask.h rename mission/{tmtc => com}/PersistentLogTmStoreTask.cpp (79%) rename mission/{tmtc => com}/PersistentLogTmStoreTask.h (90%) rename mission/{tmtc => com}/PersistentSingleTmStoreTask.cpp (72%) rename mission/{tmtc => com}/PersistentSingleTmStoreTask.h (85%) rename mission/{tmtc => com}/TmStoreTaskBase.cpp (67%) rename mission/{tmtc => com}/TmStoreTaskBase.h (66%) rename mission/{tmtc => com}/VirtualChannel.cpp (100%) rename mission/{tmtc => com}/VirtualChannel.h (100%) rename mission/{tmtc => com}/VirtualChannelWithQueue.cpp (91%) rename mission/{tmtc => com}/VirtualChannelWithQueue.h (93%) delete mode 100644 mission/tmtc/LiveTmTask.cpp delete mode 100644 mission/tmtc/LiveTmTask.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d982765..dd4976a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ will consitute of a breaking change warranting a new major release: ## Changed - SCEX filename updates. Also use T as the file ID / date separator between date and time. +- COM TM store and dump handling: Introduce modes for all 4 TM VC/store tasks. The OFF mode can be + used to disable ongoing dumps or to prevent writes to the PTME VC. This allows cleaner reset + handling of the PTME. All 4 VC/store tasks were attached to the COM mode tree and are commanded + as part of the COM sequence as well to ensure consistent state with the CCSDS IP core handler. ## Fixed diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 76bb39f3..26d19dcd 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -20,15 +20,15 @@ #include #include #include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include #include "OBSWConfig.h" #include "bsp_q7s/boardtest/Q7STestTask.h" @@ -81,6 +81,7 @@ using gpio::Levels; #include #include #include +#include #include #include #include @@ -96,7 +97,6 @@ using gpio::Levels; #include #include #include -#include #include diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index dc65e1f4..1d971a5e 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -4,11 +4,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index e2c0805c..446e3afd 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -19,7 +19,7 @@ PapbVcInterface::~PapbVcInterface() {} ReturnValue_t PapbVcInterface::initialize() { UioMapper uioMapper(uioFile, mapNum); ReturnValue_t result = uioMapper.getMappedAdress(const_cast(&vcBaseReg), - UioMapper::Permissions::WRITE_ONLY); + UioMapper::Permissions::WRITE_ONLY); if (result != returnvalue::OK) { return result; } @@ -38,7 +38,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { // TODO: Maybe this should not be done like this. It would be better if there was a custom // FPGA module which can accept packets and then takes care of dumping that packet into // the PTME. DMA would be an ideal solution for this. - nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + // nanosleep(&BETWEEN_POLL_DELAY, &remDelay); if (pollPapbBusySignal(2) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { @@ -46,7 +46,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { return returnvalue::FAILED; } } - nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + // nanosleep(&BETWEEN_POLL_DELAY, &remDelay); if (pollPapbBusySignal(2) == returnvalue::OK) { completePacketTransfer(); } else { diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index b4454dae..22b8ee5f 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -5,6 +5,8 @@ #include #include +#include + #include "OBSWConfig.h" #include "fsfw/returnvalues/returnvalue.h" diff --git a/mission/com/CMakeLists.txt b/mission/com/CMakeLists.txt index 94d3e7f0..90e90c88 100644 --- a/mission/com/CMakeLists.txt +++ b/mission/com/CMakeLists.txt @@ -1,2 +1,11 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE SyrlinksHandler.cpp - CcsdsIpCoreHandler.cpp) +target_sources( + ${LIB_EIVE_MISSION} + PRIVATE SyrlinksHandler.cpp + CcsdsIpCoreHandler.cpp + LiveTmTask.cpp + PersistentLogTmStoreTask.cpp + TmStoreTaskBase.cpp + VirtualChannel.cpp + VirtualChannelWithQueue.cpp + PersistentSingleTmStoreTask.cpp + LiveTmTask.cpp) diff --git a/mission/com/CcsdsIpCoreHandler.h b/mission/com/CcsdsIpCoreHandler.h index 0fad0aae..fc686230 100644 --- a/mission/com/CcsdsIpCoreHandler.h +++ b/mission/com/CcsdsIpCoreHandler.h @@ -2,7 +2,7 @@ #define CCSDSHANDLER_H_ #include -#include +#include #include #include diff --git a/mission/com/LiveTmTask.cpp b/mission/com/LiveTmTask.cpp new file mode 100644 index 00000000..70e8303f --- /dev/null +++ b/mission/com/LiveTmTask.cpp @@ -0,0 +1,101 @@ +#include "LiveTmTask.h" + +#include +#include +#include +#include + +LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, + VirtualChannelWithQueue& channel) + : SystemObject(objectId), + modeHelper(this), + pusFunnel(pusFunnel), + cfdpFunnel(cfdpFunnel), + channel(channel) { + requestQueue = QueueFactory::instance()->createMessageQueue(); +} + +ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) { + readCommandQueue(); + while (true) { + bool performWriteOp = true; + if (mode == MODE_OFF) { + performWriteOp = false; + } + + // The funnel tasks are scheduled here directly as well. + ReturnValue_t result = channel.handleNextTm(performWriteOp); + if (result == DirectTmSinkIF::IS_BUSY) { + sif::error << "Lost live TM, PAPB busy" << std::endl; + } + if (result == MessageQueueIF::EMPTY) { + if (tmFunnelCd.hasTimedOut()) { + pusFunnel.performOperation(0); + cfdpFunnel.performOperation(0); + tmFunnelCd.resetTimer(); + } + // Read command queue during idle times. + readCommandQueue(); + // 40 ms IDLE delay. Might tweak this in the future. + TaskFactory::delayTask(40); + } else { + packetCounter++; + } + } +} + +MessageQueueId_t LiveTmTask::getCommandQueue() const { return requestQueue->getId(); } + +void LiveTmTask::getMode(Mode_t* mode, Submode_t* submode) { + if (mode != nullptr) { + *mode = this->mode; + } + if (submode != nullptr) { + *submode = SUBMODE_NONE; + } +} + +ReturnValue_t LiveTmTask::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) { + if (mode == MODE_ON or mode == MODE_OFF) { + return returnvalue::OK; + } + return returnvalue::FAILED; +} + +void LiveTmTask::startTransition(Mode_t mode, Submode_t submode) { + this->mode = mode; + modeHelper.modeChanged(mode, submode); + announceMode(false); +} + +void LiveTmTask::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); } + +object_id_t LiveTmTask::getObjectId() const { return SystemObject::getObjectId(); } + +const HasHealthIF* LiveTmTask::getOptHealthIF() const { return nullptr; } + +const HasModesIF& LiveTmTask::getModeIF() const { return *this; } + +ReturnValue_t LiveTmTask::connectModeTreeParent(HasModeTreeChildrenIF& parent) { + return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper); +} + +void LiveTmTask::readCommandQueue(void) { + CommandMessage commandMessage; + ReturnValue_t result = returnvalue::FAILED; + + result = requestQueue->receiveMessage(&commandMessage); + if (result == returnvalue::OK) { + result = modeHelper.handleModeCommand(&commandMessage); + if (result == returnvalue::OK) { + return; + } + CommandMessage reply; + reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand()); + requestQueue->reply(&reply); + return; + } +} + +ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; } diff --git a/mission/com/LiveTmTask.h b/mission/com/LiveTmTask.h new file mode 100644 index 00000000..e8eb7fc0 --- /dev/null +++ b/mission/com/LiveTmTask.h @@ -0,0 +1,55 @@ +#ifndef MISSION_TMTC_LIVETMTASK_H_ +#define MISSION_TMTC_LIVETMTASK_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class LiveTmTask : public SystemObject, + public HasModesIF, + public ExecutableObjectIF, + public ModeTreeChildIF, + public ModeTreeConnectionIF { + public: + LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, + VirtualChannelWithQueue& channel); + + ReturnValue_t performOperation(uint8_t opCode) override; + + private: + MessageQueueIF* requestQueue; + ModeHelper modeHelper; + Mode_t mode = HasModesIF::MODE_OFF; + Countdown tmFunnelCd = Countdown(100); + PusTmFunnel& pusFunnel; + CfdpTmFunnel& cfdpFunnel; + VirtualChannelWithQueue& channel; + uint32_t packetCounter = 0; + + void readCommandQueue(void); + + MessageQueueId_t getCommandQueue() const override; + + void getMode(Mode_t* mode, Submode_t* submode) override; + + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) override; + + void startTransition(Mode_t mode, Submode_t submode) override; + + void announceMode(bool recursive) override; + + object_id_t getObjectId() const override; + const HasHealthIF* getOptHealthIF() const override; + const HasModesIF& getModeIF() const override; + ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; + ModeTreeChildIF& getModeTreeChildIF() override; +}; + +#endif /* MISSION_TMTC_LIVETMTASK_H_ */ diff --git a/mission/tmtc/PersistentLogTmStoreTask.cpp b/mission/com/PersistentLogTmStoreTask.cpp similarity index 79% rename from mission/tmtc/PersistentLogTmStoreTask.cpp rename to mission/com/PersistentLogTmStoreTask.cpp index dcd78b54..07fe5ad6 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.cpp +++ b/mission/com/PersistentLogTmStoreTask.cpp @@ -27,6 +27,8 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { } }; while (true) { + readCommandQueue(); + if (not cyclicStoreCheck()) { continue; } @@ -54,3 +56,17 @@ bool PersistentLogTmStoreTask::initStoresIfPossible() { } return false; } + +void PersistentLogTmStoreTask::startTransition(Mode_t mode, Submode_t submode) { + if (mode == MODE_OFF) { + bool channelIsOn = channel.isTxOn(); + cancelDump(okStoreContext, stores.okStore, channelIsOn); + cancelDump(notOkStoreContext, stores.notOkStore, channelIsOn); + cancelDump(miscStoreContext, stores.miscStore, channelIsOn); + this->mode = MODE_OFF; + } else if (mode == MODE_ON) { + this->mode = MODE_ON; + } + modeHelper.modeChanged(mode, submode); + announceMode(false); +} diff --git a/mission/tmtc/PersistentLogTmStoreTask.h b/mission/com/PersistentLogTmStoreTask.h similarity index 90% rename from mission/tmtc/PersistentLogTmStoreTask.h rename to mission/com/PersistentLogTmStoreTask.h index 116b369e..51431e2f 100644 --- a/mission/tmtc/PersistentLogTmStoreTask.h +++ b/mission/com/PersistentLogTmStoreTask.h @@ -5,11 +5,11 @@ #include #include #include +#include +#include #include #include #include -#include -#include struct LogStores { LogStores(PersistentTmStores& stores) @@ -36,6 +36,7 @@ class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObject bool someFileWasSwapped = false; bool initStoresIfPossible() override; + void startTransition(Mode_t mode, Submode_t submode) override; }; #endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */ diff --git a/mission/tmtc/PersistentSingleTmStoreTask.cpp b/mission/com/PersistentSingleTmStoreTask.cpp similarity index 72% rename from mission/tmtc/PersistentSingleTmStoreTask.cpp rename to mission/com/PersistentSingleTmStoreTask.cpp index a2d57208..f84738ad 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.cpp +++ b/mission/com/PersistentSingleTmStoreTask.cpp @@ -1,17 +1,21 @@ +#include "PersistentSingleTmStoreTask.h" + #include #include -#include #include PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore, VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan) : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), + modeHelper(this), storeWithQueue(tmStore), dumpContext(eventIfDumpDone, eventIfCancelled) {} ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { while (true) { + readCommandQueue(); + // Delay done by the check if (not cyclicStoreCheck()) { continue; @@ -33,3 +37,14 @@ bool PersistentSingleTmStoreTask::initStoresIfPossible() { } return false; } + +void PersistentSingleTmStoreTask::startTransition(Mode_t mode, Submode_t submode) { + if (mode == MODE_OFF) { + cancelDump(dumpContext, storeWithQueue, channel.isTxOn()); + this->mode = MODE_OFF; + } else if (mode == MODE_ON) { + this->mode = MODE_ON; + } + modeHelper.modeChanged(mode, submode); + announceMode(false); +} diff --git a/mission/tmtc/PersistentSingleTmStoreTask.h b/mission/com/PersistentSingleTmStoreTask.h similarity index 85% rename from mission/tmtc/PersistentSingleTmStoreTask.h rename to mission/com/PersistentSingleTmStoreTask.h index 1529928f..d8a1979b 100644 --- a/mission/tmtc/PersistentSingleTmStoreTask.h +++ b/mission/com/PersistentSingleTmStoreTask.h @@ -3,9 +3,9 @@ #include #include +#include +#include #include -#include -#include class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF { public: @@ -17,12 +17,15 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj ReturnValue_t performOperation(uint8_t opCode) override; private: + ModeHelper modeHelper; PersistentTmStoreWithTmQueue& storeWithQueue; DumpContext dumpContext; Countdown tcHandlingCd = Countdown(400); Countdown graceDelayDuringDumping = Countdown(100); bool initStoresIfPossible() override; + + void startTransition(Mode_t mode, Submode_t submode) override; }; #endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */ diff --git a/mission/tmtc/TmStoreTaskBase.cpp b/mission/com/TmStoreTaskBase.cpp similarity index 67% rename from mission/tmtc/TmStoreTaskBase.cpp rename to mission/com/TmStoreTaskBase.cpp index 7ca03488..b2f21a83 100644 --- a/mission/tmtc/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -1,6 +1,8 @@ #include "TmStoreTaskBase.h" #include +#include +#include #include #include #include @@ -9,7 +11,13 @@ TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel, SdCardMountedIF& sdcMan) - : SystemObject(objectId), ipcStore(ipcStore), channel(channel), sdcMan(sdcMan) {} + : SystemObject(objectId), + modeHelper(this), + ipcStore(ipcStore), + channel(channel), + sdcMan(sdcMan) { + requestQueue = QueueFactory::instance()->createMessageQueue(10); +} bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext) { @@ -26,8 +34,8 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, if (result == returnvalue::OK) { tmToStoreReceived = true; } - // Dump TMs when applicable - if (store.getState() == PersistentTmStore::State::DUMPING) { + // Dump TMs when applicable and allowed (mode is on) + if (mode == MODE_ON and store.getState() == PersistentTmStore::State::DUMPING) { if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) { return result; } @@ -129,3 +137,57 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store } return result; } + +ReturnValue_t TmStoreTaskBase::initialize() { + modeHelper.initialize(); + return returnvalue::OK; +} + +void TmStoreTaskBase::getMode(Mode_t* mode, Submode_t* submode) { + if (mode != nullptr) { + *mode = this->mode; + } + if (submode != nullptr) { + *submode = SUBMODE_NONE; + } +} + +ReturnValue_t TmStoreTaskBase::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) { + if (mode == MODE_ON or mode == MODE_OFF) { + return returnvalue::OK; + } + return returnvalue::FAILED; +} + +MessageQueueId_t TmStoreTaskBase::getCommandQueue() const { return requestQueue->getId(); } + +void TmStoreTaskBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); } + +object_id_t TmStoreTaskBase::getObjectId() const { return SystemObject::getObjectId(); } + +const HasHealthIF* TmStoreTaskBase::getOptHealthIF() const { return nullptr; } + +const HasModesIF& TmStoreTaskBase::getModeIF() const { return *this; } + +ReturnValue_t TmStoreTaskBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) { + return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper); +} + +ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; } +void TmStoreTaskBase::readCommandQueue(void) { + CommandMessage commandMessage; + ReturnValue_t result = returnvalue::FAILED; + + result = requestQueue->receiveMessage(&commandMessage); + if (result == returnvalue::OK) { + result = modeHelper.handleModeCommand(&commandMessage); + if (result == returnvalue::OK) { + return; + } + CommandMessage reply; + reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand()); + requestQueue->reply(&reply); + return; + } +} diff --git a/mission/tmtc/TmStoreTaskBase.h b/mission/com/TmStoreTaskBase.h similarity index 66% rename from mission/tmtc/TmStoreTaskBase.h rename to mission/com/TmStoreTaskBase.h index 5fef74ff..c9f0b9a3 100644 --- a/mission/tmtc/TmStoreTaskBase.h +++ b/mission/com/TmStoreTaskBase.h @@ -1,15 +1,21 @@ #ifndef MISSION_TMTC_TMSTORETASKBASE_H_ #define MISSION_TMTC_TMSTORETASKBASE_H_ +#include +#include +#include #include +#include #include -#include /** * Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping * the TM store into the virtual channel directly. */ -class TmStoreTaskBase : public SystemObject { +class TmStoreTaskBase : public SystemObject, + public HasModesIF, + public ModeTreeChildIF, + public ModeTreeConnectionIF { public: struct DumpContext { DumpContext(Event eventIfDone, Event eventIfCancelled) @@ -35,8 +41,13 @@ class TmStoreTaskBase : public SystemObject { TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel, SdCardMountedIF& sdcMan); + ReturnValue_t initialize() override; + protected: + MessageQueueIF* requestQueue; + ModeHelper modeHelper; StorageManagerIF& ipcStore; + Mode_t mode = HasModesIF::MODE_OFF; Countdown sdCardCheckCd = Countdown(800); // 20 minutes are allowed as maximum dump time. Countdown cancelDumpCd = Countdown(60 * 20 * 1000); @@ -47,6 +58,11 @@ class TmStoreTaskBase : public SystemObject { bool fileHasSwapped = false; SdCardMountedIF& sdcMan; + void readCommandQueue(void); + + virtual bool initStoresIfPossible() = 0; + virtual void startTransition(Mode_t mode, Submode_t submode) = 0; + void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn); /** * @@ -65,7 +81,18 @@ class TmStoreTaskBase : public SystemObject { */ bool cyclicStoreCheck(); - virtual bool initStoresIfPossible() = 0; + MessageQueueId_t getCommandQueue() const override; + + void getMode(Mode_t* mode, Submode_t* submode) override; + + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) override; + void announceMode(bool recursive) override; + object_id_t getObjectId() const override; + const HasHealthIF* getOptHealthIF() const override; + const HasModesIF& getModeIF() const override; + ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; + ModeTreeChildIF& getModeTreeChildIF() override; }; #endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */ diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/com/VirtualChannel.cpp similarity index 100% rename from mission/tmtc/VirtualChannel.cpp rename to mission/com/VirtualChannel.cpp diff --git a/mission/tmtc/VirtualChannel.h b/mission/com/VirtualChannel.h similarity index 100% rename from mission/tmtc/VirtualChannel.h rename to mission/com/VirtualChannel.h diff --git a/mission/tmtc/VirtualChannelWithQueue.cpp b/mission/com/VirtualChannelWithQueue.cpp similarity index 91% rename from mission/tmtc/VirtualChannelWithQueue.cpp rename to mission/com/VirtualChannelWithQueue.cpp index 44a20031..a90829ab 100644 --- a/mission/tmtc/VirtualChannelWithQueue.cpp +++ b/mission/com/VirtualChannelWithQueue.cpp @@ -1,4 +1,4 @@ -#include +#include "VirtualChannelWithQueue.h" #include "OBSWConfig.h" #include "fsfw/ipc/QueueFactory.h" @@ -19,7 +19,7 @@ VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t v const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); } -ReturnValue_t VirtualChannelWithQueue::sendNextTm() { +ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) { TmTcMessage message; ReturnValue_t result = tmQueue->receiveMessage(&message); if (result == MessageQueueIF::EMPTY) { @@ -36,7 +36,9 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() { return result; } - result = write(data, size); + if (performWriteOp) { + result = write(data, size); + } // Try delete in any case, ignore failures (which should not happen), it is more important to // propagate write errors. tmStore.deleteData(storeId); diff --git a/mission/tmtc/VirtualChannelWithQueue.h b/mission/com/VirtualChannelWithQueue.h similarity index 93% rename from mission/tmtc/VirtualChannelWithQueue.h rename to mission/com/VirtualChannelWithQueue.h index 0c060a06..04c7f965 100644 --- a/mission/tmtc/VirtualChannelWithQueue.h +++ b/mission/com/VirtualChannelWithQueue.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include @@ -34,7 +34,7 @@ class VirtualChannelWithQueue : public VirtualChannel, public AcceptsTelemetryIF MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override; [[nodiscard]] const char* getName() const override; - ReturnValue_t sendNextTm(); + ReturnValue_t handleNextTm(bool performWriteOp); private: MessageQueueIF* tmQueue = nullptr; diff --git a/mission/config/comCfg.cpp b/mission/config/comCfg.cpp index 8387214d..664a2e55 100644 --- a/mission/config/comCfg.cpp +++ b/mission/config/comCfg.cpp @@ -3,6 +3,8 @@ #include #include +#include + com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK; MutexIF* DATARATE_LOCK = nullptr; diff --git a/mission/system/com/comModeTree.cpp b/mission/system/com/comModeTree.cpp index 9501262d..bb9a8d10 100644 --- a/mission/system/com/comModeTree.cpp +++ b/mission/system/com/comModeTree.cpp @@ -22,7 +22,7 @@ auto COM_SEQUENCE_RX_ONLY = auto COM_TABLE_RX_ONLY_TGT = std::make_pair( static_cast(::com::Submode::RX_ONLY << 24) | 1, FixedArrayList()); auto COM_TABLE_RX_ONLY_TRANS_0 = std::make_pair( - static_cast(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList()); + static_cast(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList()); auto COM_TABLE_RX_ONLY_TRANS_1 = std::make_pair( static_cast(::com::Submode::RX_ONLY << 24) | 3, FixedArrayList()); @@ -36,7 +36,7 @@ auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 = FixedArrayList()); auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 = std::make_pair(static_cast(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3, - FixedArrayList()); + FixedArrayList()); auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE = std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList()); @@ -48,7 +48,7 @@ auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 = FixedArrayList()); auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 = std::make_pair(static_cast(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3, - FixedArrayList()); + FixedArrayList()); auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE = std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList()); @@ -60,7 +60,7 @@ auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 = FixedArrayList()); auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 = std::make_pair(static_cast(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3, - FixedArrayList()); + FixedArrayList()); namespace { @@ -110,6 +110,10 @@ void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) { // Build RX Only transition 0 iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TRANS_0.second); + iht(objects::LOG_STORE_AND_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second); + iht(objects::HK_STORE_AND_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second); + iht(objects::CFDP_STORE_AND_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second); + iht(objects::LIVE_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second); check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_0.first, &COM_TABLE_RX_ONLY_TRANS_0.second)), ctxc); @@ -165,6 +169,10 @@ void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh) { // Build TX and RX low transition 1 iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); + iht(objects::LOG_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); + iht(objects::HK_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); + iht(objects::CFDP_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); + iht(objects::LIVE_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first, &COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)), ctxc); @@ -217,6 +225,10 @@ void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh) { // Build TX and RX high transition 1 iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); + iht(objects::LOG_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); + iht(objects::HK_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); + iht(objects::CFDP_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); + iht(objects::LIVE_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first, &COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)), ctxc); @@ -271,6 +283,10 @@ void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh) { // Build TX and RX default transition 1 iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); + iht(objects::LOG_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); + iht(objects::HK_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); + iht(objects::CFDP_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); + iht(objects::LIVE_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first, &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)), ctxc); diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index c797e315..a8388d83 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -1,17 +1,11 @@ target_sources( ${LIB_EIVE_MISSION} - PRIVATE VirtualChannelWithQueue.cpp - PersistentTmStoreWithTmQueue.cpp - LiveTmTask.cpp - VirtualChannel.cpp + PRIVATE PersistentTmStoreWithTmQueue.cpp TmFunnelHandler.cpp TmFunnelBase.cpp CfdpTmFunnel.cpp tmFilters.cpp PusLiveDemux.cpp - PersistentSingleTmStoreTask.cpp - PersistentLogTmStoreTask.cpp - TmStoreTaskBase.cpp PusPacketFilter.cpp PusTmRouteByFilterHelper.cpp Service15TmStorage.cpp diff --git a/mission/tmtc/LiveTmTask.cpp b/mission/tmtc/LiveTmTask.cpp deleted file mode 100644 index 7e6d3de6..00000000 --- a/mission/tmtc/LiveTmTask.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "LiveTmTask.h" - -#include -#include - -LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, - VirtualChannelWithQueue& channel) - : SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel), channel(channel) {} - -ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) { - while (true) { - // The funnel tasks are scheduled here directly as well. - ReturnValue_t result = channel.sendNextTm(); - if (result == DirectTmSinkIF::IS_BUSY) { - sif::error << "Lost live TM, PAPB busy" << std::endl; - } - if (result == MessageQueueIF::EMPTY) { - if (tmFunnelCd.hasTimedOut()) { - pusFunnel.performOperation(0); - cfdpFunnel.performOperation(0); - tmFunnelCd.resetTimer(); - } - // 40 ms IDLE delay. Might tweak this in the future. - TaskFactory::delayTask(40); - } - } -} diff --git a/mission/tmtc/LiveTmTask.h b/mission/tmtc/LiveTmTask.h deleted file mode 100644 index a0ca6b83..00000000 --- a/mission/tmtc/LiveTmTask.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MISSION_TMTC_LIVETMTASK_H_ -#define MISSION_TMTC_LIVETMTASK_H_ - -#include -#include -#include -#include -#include -#include - -class LiveTmTask : public SystemObject, public ExecutableObjectIF { - public: - LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, - VirtualChannelWithQueue& channel); - - ReturnValue_t performOperation(uint8_t opCode) override; - - private: - Countdown tmFunnelCd = Countdown(100); - PusTmFunnel& pusFunnel; - CfdpTmFunnel& cfdpFunnel; - VirtualChannelWithQueue& channel; -}; - -#endif /* MISSION_TMTC_LIVETMTASK_H_ */ From 795486ae6c8dbc7924063707716968b1409f08dd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 12:11:31 +0200 Subject: [PATCH 40/53] trying to find out whats wrong --- CMakeLists.txt | 3 ++- bsp_q7s/core/ObjectFactory.cpp | 24 ++++++++++++++-------- bsp_q7s/em/emObjectFactory.cpp | 2 +- dummies/CMakeLists.txt | 2 +- dummies/{helpers.cpp => helperFactory.cpp} | 5 ++++- dummies/{helpers.h => helperFactory.h} | 0 mission/com/LiveTmTask.cpp | 5 +++++ mission/com/LiveTmTask.h | 3 ++- mission/com/SyrlinksHandler.cpp | 18 ++++++++++++++-- mission/com/SyrlinksHandler.h | 1 + mission/com/TmStoreTaskBase.cpp | 7 +++++-- mission/com/TmStoreTaskBase.h | 2 +- mission/pollingSeqTables.cpp | 6 ++++-- 13 files changed, 57 insertions(+), 21 deletions(-) rename dummies/{helpers.cpp => helperFactory.cpp} (98%) rename dummies/{helpers.h => helperFactory.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0ec4dd7..3a2842a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -486,7 +486,8 @@ endif() target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_FSFW_NAME} ${LIB_OS_NAME}) -target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_FSFW_NAME} ${LIB_JSON_NAME}) +target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_EIVE_MISSION} + ${LIB_FSFW_NAME} ${LIB_JSON_NAME}) target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_EIVE_MISSION} ${LIB_DUMMIES}) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 26d19dcd..629cf44c 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -795,28 +795,34 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme, LINK_STATE, args.tmStore, 500); args.liveDestination = vcWithQueue; - new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue); + auto* liveTask = + new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue); + liveTask->connectModeTreeParent(satsystem::com::SUBSYSTEM); // Set up log store. auto* vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme, LINK_STATE); LogStores logStores(args.stores); // Core task which handles the LOG store and takes care of dumping it as TM using a VC directly - new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc, - *SdCardManager::instance()); + auto* logStore = new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, + logStores, *vc, *SdCardManager::instance()); + logStore->connectModeTreeParent(satsystem::com::SUBSYSTEM); 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, persTmStore::DUMP_HK_STORE_DONE, - persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance()); + auto* hkStore = new PersistentSingleTmStoreTask( + objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc, + persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance()); + hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM); 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, persTmStore::DUMP_CFDP_STORE_DONE, - persTmStore::DUMP_CFDP_CANCELLED, *SdCardManager::instance()); + auto* cfdpTask = new PersistentSingleTmStoreTask( + objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, *args.stores.cfdpStore, *vc, + persTmStore::DUMP_CFDP_STORE_DONE, persTmStore::DUMP_CFDP_CANCELLED, + *SdCardManager::instance()); + cfdpTask->connectModeTreeParent(satsystem::com::SUBSYSTEM); ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); if (result != returnvalue::OK) { diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index c0852c05..1f873b99 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -13,7 +13,7 @@ #include "bsp_q7s/core/ObjectFactory.h" #include "busConf.h" #include "devConf.h" -#include "dummies/helpers.h" +#include "dummies/helperFactory.h" #include "eive/objects.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" #include "linux/ObjectFactory.h" diff --git a/dummies/CMakeLists.txt b/dummies/CMakeLists.txt index 75dd1364..6a49fcc6 100644 --- a/dummies/CMakeLists.txt +++ b/dummies/CMakeLists.txt @@ -26,6 +26,6 @@ target_sources( CoreControllerDummy.cpp PlocMpsocDummy.cpp PlocSupervisorDummy.cpp - helpers.cpp + helperFactory.cpp MgmRm3100Dummy.cpp Tmp1075Dummy.cpp) diff --git a/dummies/helpers.cpp b/dummies/helperFactory.cpp similarity index 98% rename from dummies/helpers.cpp rename to dummies/helperFactory.cpp index 1a541dfd..c0390a5e 100644 --- a/dummies/helpers.cpp +++ b/dummies/helperFactory.cpp @@ -1,4 +1,4 @@ -#include "helpers.h" +#include "helperFactory.h" #include #include @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,8 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio new GyroAdisDummy(objects::GYRO_2_ADIS_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); assemblyDhbs[7] = new GyroL3GD20Dummy(objects::GYRO_3_L3G_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + new HealthDevice(objects::GPS_0_HEALTH_DEV, objects::ACS_BOARD_ASS); + new HealthDevice(objects::GPS_1_HEALTH_DEV, objects::ACS_BOARD_ASS); auto* gpsCtrl = new GpsCtrlDummy(objects::GPS_CONTROLLER); ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyDhbs, gpsCtrl, gpioIF); } diff --git a/dummies/helpers.h b/dummies/helperFactory.h similarity index 100% rename from dummies/helpers.h rename to dummies/helperFactory.h diff --git a/mission/com/LiveTmTask.cpp b/mission/com/LiveTmTask.cpp index 70e8303f..236a3292 100644 --- a/mission/com/LiveTmTask.cpp +++ b/mission/com/LiveTmTask.cpp @@ -99,3 +99,8 @@ void LiveTmTask::readCommandQueue(void) { } ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; } + +ReturnValue_t LiveTmTask::initialize() { + modeHelper.initialize(); + return returnvalue::OK; +} diff --git a/mission/com/LiveTmTask.h b/mission/com/LiveTmTask.h index e8eb7fc0..ca63cd02 100644 --- a/mission/com/LiveTmTask.h +++ b/mission/com/LiveTmTask.h @@ -21,6 +21,8 @@ class LiveTmTask : public SystemObject, VirtualChannelWithQueue& channel); ReturnValue_t performOperation(uint8_t opCode) override; + ReturnValue_t initialize() override; + ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; private: MessageQueueIF* requestQueue; @@ -48,7 +50,6 @@ class LiveTmTask : public SystemObject, object_id_t getObjectId() const override; const HasHealthIF* getOptHealthIF() const override; const HasModesIF& getModeIF() const override; - ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; ModeTreeChildIF& getModeTreeChildIF() override; }; diff --git a/mission/com/SyrlinksHandler.cpp b/mission/com/SyrlinksHandler.cpp index 5065f219..84eebeda 100644 --- a/mission/com/SyrlinksHandler.cpp +++ b/mission/com/SyrlinksHandler.cpp @@ -21,6 +21,7 @@ SyrlinksHandler::~SyrlinksHandler() = default; void SyrlinksHandler::doStartUp() { if (internalState == InternalState::OFF) { + transitionCommandPending = false; internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION; commandExecuted = false; } @@ -38,6 +39,7 @@ void SyrlinksHandler::doShutDown() { // In any case, always disable TX first. if (internalState != InternalState::SET_TX_STANDBY) { internalState = InternalState::SET_TX_STANDBY; + transitionCommandPending = false; commandExecuted = false; } if (internalState == InternalState::SET_TX_STANDBY) { @@ -97,6 +99,10 @@ ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { } ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + if (transitionCommandPending) { + return NOTHING_TO_SEND; + } + transitionCommandPending = true; switch (internalState) { case InternalState::ENABLE_TEMPERATURE_PROTECTION: { *id = syrlinks::WRITE_LCL_CONFIG; @@ -122,8 +128,10 @@ ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* i *id = syrlinks::SET_TX_MODE_STANDBY; return buildCommandFromCommand(*id, nullptr, 0); } - default: + default: { + transitionCommandPending = false; break; + } } return NOTHING_TO_SEND; } @@ -442,7 +450,6 @@ ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; } } - return returnvalue::OK; } @@ -682,6 +689,9 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) { } break; } + default: { + sif::error << "Syrlinks: Unexpected ACK reply" << std::endl; + } } switch (rememberCommandId) { case (syrlinks::SET_TX_MODE_STANDBY): { @@ -728,16 +738,19 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { Mode_t tgtMode = getBaseMode(getMode()); auto commandDone = [&]() { setMode(tgtMode); + transitionCommandPending = false; internalState = InternalState::IDLE; }; auto txOnHandler = [&](InternalState selMod) { if (internalState == InternalState::IDLE) { + transitionCommandPending = false; commandExecuted = false; internalState = selMod; } // Select modulation first (BPSK or 0QPSK). if (internalState == selMod) { if (commandExecuted) { + transitionCommandPending = false; internalState = InternalState::SET_TX_MODULATION; commandExecuted = false; } @@ -753,6 +766,7 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { }; auto txStandbyHandler = [&]() { if (internalState == InternalState::IDLE) { + transitionCommandPending = false; internalState = InternalState::SET_TX_STANDBY; commandExecuted = false; } diff --git a/mission/com/SyrlinksHandler.h b/mission/com/SyrlinksHandler.h index 7d2d7227..97541ecb 100644 --- a/mission/com/SyrlinksHandler.h +++ b/mission/com/SyrlinksHandler.h @@ -112,6 +112,7 @@ class SyrlinksHandler : public DeviceHandlerBase { float tempPowerAmplifier = 0; float tempBasebandBoard = 0; bool commandExecuted = false; + bool transitionCommandPending = false; uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE]; diff --git a/mission/com/TmStoreTaskBase.cpp b/mission/com/TmStoreTaskBase.cpp index b2f21a83..e5e3e241 100644 --- a/mission/com/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -35,7 +35,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, tmToStoreReceived = true; } // Dump TMs when applicable and allowed (mode is on) - if (mode == MODE_ON and store.getState() == PersistentTmStore::State::DUMPING) { + if (store.getState() == PersistentTmStore::State::DUMPING) { if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) { return result; } @@ -78,8 +78,10 @@ bool TmStoreTaskBase::cyclicStoreCheck() { } void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) { - triggerEvent(ctx.eventIfCancelled, ctx.numberOfDumpedPackets, ctx.dumpedBytes); ctx.reset(); + if (store.getState() == PersistentTmStore::State::DUMPING) { + triggerEvent(ctx.eventIfCancelled, ctx.numberOfDumpedPackets, ctx.dumpedBytes); + } store.cancelDump(); if (isTxOn) { channel.cancelTransfer(); @@ -175,6 +177,7 @@ ReturnValue_t TmStoreTaskBase::connectModeTreeParent(HasModeTreeChildrenIF& pare } ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; } + void TmStoreTaskBase::readCommandQueue(void) { CommandMessage commandMessage; ReturnValue_t result = returnvalue::FAILED; diff --git a/mission/com/TmStoreTaskBase.h b/mission/com/TmStoreTaskBase.h index c9f0b9a3..1cb16439 100644 --- a/mission/com/TmStoreTaskBase.h +++ b/mission/com/TmStoreTaskBase.h @@ -42,6 +42,7 @@ class TmStoreTaskBase : public SystemObject, SdCardMountedIF& sdcMan); ReturnValue_t initialize() override; + ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; protected: MessageQueueIF* requestQueue; @@ -91,7 +92,6 @@ class TmStoreTaskBase : public SystemObject, object_id_t getObjectId() const override; const HasHealthIF* getOptHealthIF() const override; const HasModesIF& getModeIF() const override; - ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; ModeTreeChildIF& getModeTreeChildIF() override; }; diff --git a/mission/pollingSeqTables.cpp b/mission/pollingSeqTables.cpp index 8d172132..4225e977 100644 --- a/mission/pollingSeqTables.cpp +++ b/mission/pollingSeqTables.cpp @@ -26,10 +26,12 @@ ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, + DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ); static_cast(length); From a1380a6e3a6010a5cbb24a27d6b5a296c2ba479e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 12:11:55 +0200 Subject: [PATCH 41/53] syrlinks bugfix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd4976a7..c3edceff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ will consitute of a breaking change warranting a new major release: - Bugfix for side lane transitions of the dual lane assemblies, which only worked when the assembly was directly commanded +- Syrlinks Handler: Only send transition commands once. ## Added From e0f94039b46ed3939d4b5c5e2a8fbe8193154262 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 12:47:55 +0200 Subject: [PATCH 42/53] found some bugs --- mission/com/PersistentSingleTmStoreTask.cpp | 1 - mission/com/PersistentSingleTmStoreTask.h | 1 - mission/com/SyrlinksHandler.cpp | 5 ----- 3 files changed, 7 deletions(-) diff --git a/mission/com/PersistentSingleTmStoreTask.cpp b/mission/com/PersistentSingleTmStoreTask.cpp index f84738ad..2d05b25f 100644 --- a/mission/com/PersistentSingleTmStoreTask.cpp +++ b/mission/com/PersistentSingleTmStoreTask.cpp @@ -8,7 +8,6 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore, VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan) : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), - modeHelper(this), storeWithQueue(tmStore), dumpContext(eventIfDumpDone, eventIfCancelled) {} diff --git a/mission/com/PersistentSingleTmStoreTask.h b/mission/com/PersistentSingleTmStoreTask.h index d8a1979b..4cbf1544 100644 --- a/mission/com/PersistentSingleTmStoreTask.h +++ b/mission/com/PersistentSingleTmStoreTask.h @@ -17,7 +17,6 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj ReturnValue_t performOperation(uint8_t opCode) override; private: - ModeHelper modeHelper; PersistentTmStoreWithTmQueue& storeWithQueue; DumpContext dumpContext; Countdown tcHandlingCd = Countdown(400); diff --git a/mission/com/SyrlinksHandler.cpp b/mission/com/SyrlinksHandler.cpp index 84eebeda..297ffd88 100644 --- a/mission/com/SyrlinksHandler.cpp +++ b/mission/com/SyrlinksHandler.cpp @@ -99,10 +99,6 @@ ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { } ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { - if (transitionCommandPending) { - return NOTHING_TO_SEND; - } - transitionCommandPending = true; switch (internalState) { case InternalState::ENABLE_TEMPERATURE_PROTECTION: { *id = syrlinks::WRITE_LCL_CONFIG; @@ -129,7 +125,6 @@ ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* i return buildCommandFromCommand(*id, nullptr, 0); } default: { - transitionCommandPending = false; break; } } From 3871c8b8dee7496462decf1993bbc3a3c4fbf659 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 13:17:15 +0200 Subject: [PATCH 43/53] change layering --- mission/com/TmStoreTaskBase.cpp | 78 ++++++++++++++++++++---------- mission/com/TmStoreTaskBase.h | 10 +++- mission/tmtc/PersistentTmStore.cpp | 40 +++++++-------- mission/tmtc/PersistentTmStore.h | 29 +++++++---- 4 files changed, 98 insertions(+), 59 deletions(-) diff --git a/mission/com/TmStoreTaskBase.cpp b/mission/com/TmStoreTaskBase.cpp index e5e3e241..91555f04 100644 --- a/mission/com/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -14,6 +14,7 @@ TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStor : SystemObject(objectId), modeHelper(this), ipcStore(ipcStore), + tmReader(&timeReader), channel(channel), sdcMan(sdcMan) { requestQueue = QueueFactory::instance()->createMessageQueue(10); @@ -34,7 +35,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store, if (result == returnvalue::OK) { tmToStoreReceived = true; } - // Dump TMs when applicable and allowed (mode is on) + // Dump TMs if (store.getState() == PersistentTmStore::State::DUMPING) { if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) { return result; @@ -93,35 +94,13 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store ReturnValue_t result = returnvalue::OK; // The PTME might have been reset an transmitter state change, so there is no point in continuing // the dump. + // TODO: Will be solved in a cleaner way, this is kind of a hack. if (not channel.isTxOn()) { cancelDump(dumpContext, store, false); return returnvalue::FAILED; } - size_t dumpedLen = 0; if (not channel.isBusy()) { - // Dump the next packet into the PTME. - dumpContext.ptmeBusyCounter = 0; - tmSinkBusyCd.resetTimer(); - result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); - if (result == DirectTmSinkIF::IS_BUSY) { - sif::warning << "Unexpected PAPB busy" << std::endl; - } - if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) { - dumpPerformed = true; - if (dumpedLen > 0) { - dumpContext.dumpedBytes += dumpedLen; - dumpContext.numberOfDumpedPackets += 1; - dumpContext.packetWasDumped = true; - } - } - if (result == PersistentTmStore::DUMP_DONE) { - uint32_t startTime; - uint32_t endTime; - store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); - triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, - dumpContext.dumpedBytes); - dumpContext.reset(); - } + performDump(store, dumpContext, dumpPerformed); } else { // The PTME might be at full load, so it might sense to delay for a bit to let it do // its work until some more bandwidth is available. Set a flag here so the upper layer can @@ -140,6 +119,55 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store return result; } +ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store, + DumpContext& dumpContext, bool& dumpPerformed) { + size_t dumpedLen = 0; + + auto dumpDoneHandler = [&]() { + uint32_t startTime; + uint32_t endTime; + store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime); + triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, + dumpContext.dumpedBytes); + dumpContext.reset(); + }; + // Dump the next packet into the PTME. + dumpContext.ptmeBusyCounter = 0; + tmSinkBusyCd.resetTimer(); + ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped); + if (result != returnvalue::OK) { + sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl; + } else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) { + // This can happen if a file is corrupted and the next file swap completes the dump. + dumpDoneHandler(); + return returnvalue::OK; + } + // Only write to VC if mode is on, but always confirm the dump. + // If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written + // (e.g. to confirm a reset or the transmitter is off anyway). + if (mode == MODE_ON) { + result = channel.write(tmReader.getFullData(), tmReader.getFullPacketLen()); + if (result == DirectTmSinkIF::IS_BUSY) { + sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl; + } else if (result != returnvalue::OK) { + sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl; + } + } + result = store.confirmDump(tmReader, fileHasSwapped); + if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) { + dumpPerformed = true; + if (dumpedLen > 0) { + dumpContext.dumpedBytes += dumpedLen; + dumpContext.numberOfDumpedPackets += 1; + dumpContext.packetWasDumped = true; + } + } + if (result == PersistentTmStore::DUMP_DONE) { + dumpDoneHandler(); + } + return returnvalue::OK; +} + ReturnValue_t TmStoreTaskBase::initialize() { modeHelper.initialize(); return returnvalue::OK; diff --git a/mission/com/TmStoreTaskBase.h b/mission/com/TmStoreTaskBase.h index 1cb16439..55448cde 100644 --- a/mission/com/TmStoreTaskBase.h +++ b/mission/com/TmStoreTaskBase.h @@ -45,16 +45,20 @@ class TmStoreTaskBase : public SystemObject, ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; protected: - MessageQueueIF* requestQueue; ModeHelper modeHelper; + MessageQueueIF* requestQueue; StorageManagerIF& ipcStore; + PusTmReader tmReader; + CdsShortTimeStamper timeReader; + VirtualChannel& channel; + Mode_t mode = HasModesIF::MODE_OFF; Countdown sdCardCheckCd = Countdown(800); // 20 minutes are allowed as maximum dump time. Countdown cancelDumpCd = Countdown(60 * 20 * 1000); // If the TM sink is busy for 1 minute for whatever reason, cancel the dump. Countdown tmSinkBusyCd = Countdown(60 * 1000); - VirtualChannel& channel; + bool storesInitialized = false; bool fileHasSwapped = false; SdCardMountedIF& sdcMan; @@ -75,6 +79,8 @@ class TmStoreTaskBase : public SystemObject, ReturnValue_t handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext, bool& dumpPerformed); + ReturnValue_t performDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext, + bool& dumpPerformed); /** * Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index bf8f2a4f..a5f0ec66 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -251,41 +251,37 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() { return DUMP_DONE; } -ReturnValue_t PersistentTmStore::dumpNextPacket(DirectTmSinkIF& tmSink, size_t& dumpedLen, - bool& fileHasSwapped) { - if (state == State::IDLE) { +ReturnValue_t PersistentTmStore::getNextDumpPacket(PusTmReader& reader, bool& fileHasSwapped) { + if (state == State::IDLE or dumpParams.pendingPacketDump) { return returnvalue::FAILED; } - PusTmReader reader(&timeReader, fileBuf.data() + dumpParams.currentSize, - fileBuf.size() - dumpParams.currentSize); + reader.setReadOnlyData(fileBuf.data() + dumpParams.currentSize, + fileBuf.size() - dumpParams.currentSize); // CRC check to fully ensure this is a valid TM ReturnValue_t result = reader.parseDataWithCrcCheck(); - if (result == returnvalue::OK) { - result = tmSink.write(fileBuf.data() + dumpParams.currentSize, reader.getFullPacketLen()); - 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(); - if (dumpParams.currentSize >= dumpParams.fileSize) { - fileHasSwapped = true; - return loadNextDumpFile(); - } - } else { + if (result != returnvalue::OK) { sif::error << "PersistentTmStore: Parsing of PUS TM failed with code " << result << std::endl; 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; std::error_code e; std::filesystem::remove(dumpParams.dirEntry.path().c_str(), e); fileHasSwapped = true; return loadNextDumpFile(); } + fileHasSwapped = false; + dumpParams.pendingPacketDump = true; + return returnvalue::OK; +} + +ReturnValue_t PersistentTmStore::confirmDump(const PusTmReader& reader, bool& fileHasSwapped) { + dumpParams.pendingPacketDump = false; + dumpParams.currentSize += reader.getFullPacketLen(); + if (dumpParams.currentSize >= dumpParams.fileSize) { + fileHasSwapped = true; + return loadNextDumpFile(); + } + fileHasSwapped = false; return returnvalue::OK; } diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index a0910026..4839f2fb 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -4,12 +4,10 @@ #include #include #include -#include #include #include #include #include -#include #include @@ -57,13 +55,25 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { 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. + * @param tmReader: Next packet will be loaded into the PUS TM reader. A CRC check will be + * performed on the packet. If that check fails, the file is considered corrupted and will + * be deleted for now. + * @param fileHasSwapped: If the CRC check fails, the file will be deleted and a new one has to + * be loaded. The dump can reach completion during that process. If a file is swapped, this + * boolean is set to true + * @return DUMP_DONE if dump is finished, returnvalue::OK if the next packet was loaded into the + * TM reader, and the returnvalue of the file swap operation if the CRC check failed and + * a new file was loaded. */ - ReturnValue_t dumpNextPacket(DirectTmSinkIF& tmSink, size_t& dumpedLen, bool& fileHasSwapped); + ReturnValue_t getNextDumpPacket(PusTmReader& tmReader, bool& fileHasSwapped); + /** + * Confirm the dump to advance the dump state machine. + * @param tmReader + * @param fileHasSwapped: If the confirmed dumps completes the current file, a new file will + * be loaded and this parameter will be set to true. + * @return If a file is swapped, the retrunvalue of the file swap operation. + */ + ReturnValue_t confirmDump(const PusTmReader& tmReader, bool& fileHasSwapped); void getStartAndEndTimeCurrentOrLastDump(uint32_t& startTime, uint32_t& endTime) const; ReturnValue_t storePacket(PusTmReader& reader); @@ -83,8 +93,6 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { MessageQueueIF* tcQueue; State state = State::IDLE; - // PacketFilter filter; - CdsShortTimeStamper timeReader; bool baseDirUninitialized = true; const char* baseDir; std::string baseName; @@ -96,6 +104,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { timeval activeFileTv{}; struct ActiveDumpParams { + bool pendingPacketDump = false; uint32_t fromUnixTime = 0; uint32_t untilUnixTime = 0; uint32_t currentFileUnixStamp = 0; From 76ea3f79797b26819f2aaecf7b0ac313a9e5db28 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 13:21:38 +0200 Subject: [PATCH 44/53] compile fixes --- bsp_hosted/ObjectFactory.cpp | 2 +- mission/com/TmStoreTaskBase.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index b49bbf61..77ea7828 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -29,7 +29,7 @@ #include #include -#include "dummies/helpers.h" +#include "dummies/helperFactory.h" #ifdef PLATFORM_UNIX #include diff --git a/mission/com/TmStoreTaskBase.h b/mission/com/TmStoreTaskBase.h index 55448cde..440e142e 100644 --- a/mission/com/TmStoreTaskBase.h +++ b/mission/com/TmStoreTaskBase.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include From 6ee3fe2eefac2d20e67c80294aca20e42aab40db Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 13:22:07 +0200 Subject: [PATCH 45/53] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3edceff..86aa5b6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ will consitute of a breaking change warranting a new major release: - Bugfix for side lane transitions of the dual lane assemblies, which only worked when the assembly was directly commanded -- Syrlinks Handler: Only send transition commands once. +- Syrlinks Handler: Bugfix so transition command is only sent once. ## Added From caa7c20adf03443e5aaded9b15091ff93d54392c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 15:12:05 +0200 Subject: [PATCH 46/53] tweaks --- linux/ipcore/PapbVcInterface.cpp | 30 ++++++++++++--------- linux/ipcore/PapbVcInterface.h | 4 +-- mission/com/PersistentSingleTmStoreTask.cpp | 3 +++ mission/com/TmStoreTaskBase.cpp | 3 ++- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 446e3afd..c0deb5fc 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -27,27 +27,27 @@ ReturnValue_t PapbVcInterface::initialize() { } ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { - if (pollPapbBusySignal(0) == returnvalue::OK) { + if (pollInterfaceReadiness(0, true) == returnvalue::OK) { startPacketTransfer(); } else { return DirectTmSinkIF::IS_BUSY; } for (size_t idx = 0; idx < size; idx++) { // This delay is super-important, DO NOT REMOVE! - // Polling the GPIO too often can mess up the scheduler. + // Polling the GPIO or the config register too often messes up the scheduler. // TODO: Maybe this should not be done like this. It would be better if there was a custom // FPGA module which can accept packets and then takes care of dumping that packet into // the PTME. DMA would be an ideal solution for this. - // nanosleep(&BETWEEN_POLL_DELAY, &remDelay); - if (pollPapbBusySignal(2) == returnvalue::OK) { + nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + if (pollInterfaceReadiness(2, false) == returnvalue::OK) { *(vcBaseReg + DATA_REG_OFFSET) = static_cast(data[idx]); } else { abortPacketTransfer(); return returnvalue::FAILED; } } - // nanosleep(&BETWEEN_POLL_DELAY, &remDelay); - if (pollPapbBusySignal(2) == returnvalue::OK) { + nanosleep(&BETWEEN_POLL_DELAY, &remDelay); + if (pollInterfaceReadiness(2, false) == returnvalue::OK) { completePacketTransfer(); } else { abortPacketTransfer(); @@ -60,17 +60,23 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; } void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } -ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const { +ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries, + bool checkReadyState) const { uint32_t busyIdx = 0; - nextDelay.tv_nsec = 0; + nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; while (true) { // Check if PAPB interface is ready to receive data. Use the configuration register for this. // Bit 5, see PTME ptme_001_01-0-7-r2 Table 31. - bool busy = ((*vcBaseReg) >> 5) & 0b1; + uint32_t reg = *vcBaseReg; + bool busy = (reg >> 5) & 0b1; + bool ready = (reg >> 6) & 0b1; if (not busy) { return returnvalue::OK; } + if(checkReadyState and not ready) { + return PAPB_BUSY; + } busyIdx++; if (busyIdx >= maxPollRetries) { @@ -80,9 +86,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const // Ignore signal handling here for now. nanosleep(&nextDelay, &remDelay); // Adaptive delay. - if (nextDelay.tv_nsec == 0) { - nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; - } else if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { + if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) { nextDelay.tv_nsec *= 2; } } @@ -109,7 +113,7 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() { return; } -bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0) == PAPB_BUSY; } +bool PapbVcInterface::isBusy() const { return pollInterfaceReadiness(0, true) == PAPB_BUSY; } void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); } diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 22b8ee5f..42cfbc19 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -91,7 +91,7 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; - const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 5}; + const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10}; mutable struct timespec remDelay; volatile uint32_t* vcBaseReg = nullptr; @@ -119,7 +119,7 @@ class PapbVcInterface : public VirtualChannelIF { * * @return returnvalue::OK when ready to receive data else PAPB_BUSY. */ - inline ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries) const; + inline ReturnValue_t pollInterfaceReadiness(uint32_t maxPollRetries, bool checkReadyState) const; /** * @brief This function can be used for debugging to check whether there are packets in diff --git a/mission/com/PersistentSingleTmStoreTask.cpp b/mission/com/PersistentSingleTmStoreTask.cpp index 2d05b25f..421f2a74 100644 --- a/mission/com/PersistentSingleTmStoreTask.cpp +++ b/mission/com/PersistentSingleTmStoreTask.cpp @@ -25,6 +25,9 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { } else if (dumpContext.vcBusyDuringDump) { // TODO: Might not be necessary TaskFactory::delayTask(10); + } else { + // TODO: Would be best to remove this, but not delaying here can lead to evil issues. + TaskFactory::delayTask(2); } } } diff --git a/mission/com/TmStoreTaskBase.cpp b/mission/com/TmStoreTaskBase.cpp index 91555f04..d6db4095 100644 --- a/mission/com/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -142,11 +142,12 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store, dumpDoneHandler(); return returnvalue::OK; } + dumpedLen = tmReader.getFullPacketLen(); // Only write to VC if mode is on, but always confirm the dump. // If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written // (e.g. to confirm a reset or the transmitter is off anyway). if (mode == MODE_ON) { - result = channel.write(tmReader.getFullData(), tmReader.getFullPacketLen()); + result = channel.write(tmReader.getFullData(), dumpedLen); if (result == DirectTmSinkIF::IS_BUSY) { sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl; } else if (result != returnvalue::OK) { From 55a22c840cca3c002073dc76fd151b9e0bdee791 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 16:51:30 +0200 Subject: [PATCH 47/53] PTME_LOCK atomic boolean and related handling --- CHANGELOG.md | 3 + bsp_q7s/core/ObjectFactory.cpp | 17 +- bsp_q7s/core/ObjectFactory.h | 1 + linux/ipcore/PapbVcInterface.cpp | 4 +- mission/com/CcsdsIpCoreHandler.cpp | 178 ++++++++++++-------- mission/com/CcsdsIpCoreHandler.h | 23 ++- mission/com/LiveTmTask.cpp | 7 +- mission/com/LiveTmTask.h | 3 +- mission/com/PersistentLogTmStoreTask.cpp | 5 +- mission/com/PersistentLogTmStoreTask.h | 3 +- mission/com/PersistentSingleTmStoreTask.cpp | 7 +- mission/com/PersistentSingleTmStoreTask.h | 2 +- mission/com/TmStoreTaskBase.cpp | 9 +- mission/com/TmStoreTaskBase.h | 5 +- 14 files changed, 165 insertions(+), 102 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86aa5b6e..b69ce243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ will consitute of a breaking change warranting a new major release: used to disable ongoing dumps or to prevent writes to the PTME VC. This allows cleaner reset handling of the PTME. All 4 VC/store tasks were attached to the COM mode tree and are commanded as part of the COM sequence as well to ensure consistent state with the CCSDS IP core handler. +- Added `PTME_LOCKED` boolean lock which is used to lock the PTME so it is not used by the VC tasks + anymore. This lock will be controlled by the CCSDS IP core handler and is locked when the PTME + needs to be reset. Examples for this are datarate changes. ## Fixed diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 629cf44c..c1b8ea4e 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -125,6 +125,7 @@ using gpio::Levels; ResetArgs RESET_ARGS_GNSS; std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN; +std::atomic_bool PTME_LOCKED = false; std::atomic_uint16_t I2C_FATAL_ERRORS = 0; void Factory::setStaticFrameworkObjectIds() { @@ -789,14 +790,14 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { *args.ipCoreHandler = new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig, - LINK_STATE, &args.gpioComIF, gpios); + LINK_STATE, &args.gpioComIF, gpios, PTME_LOCKED); // This VC will receive all live TM auto* vcWithQueue = new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme, LINK_STATE, args.tmStore, 500); args.liveDestination = vcWithQueue; - auto* liveTask = - new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue); + auto* liveTask = new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, + *vcWithQueue, PTME_LOCKED); liveTask->connectModeTreeParent(satsystem::com::SUBSYSTEM); // Set up log store. @@ -804,15 +805,17 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { LINK_STATE); LogStores logStores(args.stores); // Core task which handles the LOG store and takes care of dumping it as TM using a VC directly - auto* logStore = new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, - logStores, *vc, *SdCardManager::instance()); + auto* logStore = + new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc, + *SdCardManager::instance(), PTME_LOCKED); logStore->connectModeTreeParent(satsystem::com::SUBSYSTEM); 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 auto* hkStore = new PersistentSingleTmStoreTask( objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc, - persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance()); + persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance(), + PTME_LOCKED); hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM); vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme, @@ -821,7 +824,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { auto* cfdpTask = new PersistentSingleTmStoreTask( objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, *args.stores.cfdpStore, *vc, persTmStore::DUMP_CFDP_STORE_DONE, persTmStore::DUMP_CFDP_CANCELLED, - *SdCardManager::instance()); + *SdCardManager::instance(), PTME_LOCKED); cfdpTask->connectModeTreeParent(satsystem::com::SUBSYSTEM); ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 1d971a5e..b7380f2a 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -24,6 +24,7 @@ class AcsBoardAssembly; class GpioIF; extern std::atomic_uint16_t I2C_FATAL_ERRORS; +extern std::atomic_bool PTME_LOCKED; namespace ObjectFactory { diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index c0deb5fc..f00475c8 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -61,7 +61,7 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; } void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries, - bool checkReadyState) const { + bool checkReadyState) const { uint32_t busyIdx = 0; nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; @@ -74,7 +74,7 @@ ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries, if (not busy) { return returnvalue::OK; } - if(checkReadyState and not ready) { + if (checkReadyState and not ready) { return PAPB_BUSY; } diff --git a/mission/com/CcsdsIpCoreHandler.cpp b/mission/com/CcsdsIpCoreHandler.cpp index 806096b8..d4608191 100644 --- a/mission/com/CcsdsIpCoreHandler.cpp +++ b/mission/com/CcsdsIpCoreHandler.cpp @@ -15,9 +15,11 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig, std::atomic_bool& linkState, - GpioIF* gpioIF, PtmeGpios gpioIds) + GpioIF* gpioIF, PtmeGpios gpioIds, + std::atomic_bool& ptmeLocked) : SystemObject(objectId), linkState(linkState), + ptmeLocked(ptmeLocked), tcDestination(tcDestination), parameterHelper(this), actionHelper(this, nullptr), @@ -35,6 +37,7 @@ CcsdsIpCoreHandler::~CcsdsIpCoreHandler() = default; ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) { readCommandQueue(); + performPtmeUpdateWhenApplicable(); return returnvalue::OK; } @@ -127,10 +130,15 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI return HasParametersIF::INVALID_VALUE; } parameterWrapper->set(batPriorityParam); - if (mode == MODE_ON) { - updateBatPriorityOnTxOff = true; - } else if (mode == MODE_OFF) { - updateBatPriorityFromParam(); + if (newVal != batPriorityParam) { + // This ensures that the BAT priority is updated at some point when an update of the PTME is + // allowed + updateContext.updateBatPrio = true; + // If we are off, we can do the update after X cycles. Otherwise, wait until the transmitter + // goes off. + if (mode == MODE_OFF) { + initPtmeUpdateAfterXCycles(); + } } return returnvalue::OK; } @@ -148,36 +156,12 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu const uint8_t* data, size_t size) { ReturnValue_t result = returnvalue::OK; switch (actionId) { - case SET_LOW_RATE: { - submode = static_cast(com::CcsdsSubmode::DATARATE_LOW); - result = ptmeConfig.setRate(RATE_100KBPS); - break; - } - case SET_HIGH_RATE: { - submode = static_cast(com::CcsdsSubmode::DATARATE_HIGH); - result = ptmeConfig.setRate(RATE_500KBPS); - break; - } case ARBITRARY_RATE: { uint32_t bitrate = 0; SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG); result = ptmeConfig.setRate(bitrate); break; } - case EN_TRANSMITTER: { - enableTransmit(); - if (mode == HasModesIF::MODE_OFF) { - mode = HasModesIF::MODE_ON; - } - return EXECUTION_FINISHED; - } - case DISABLE_TRANSMITTER: { - disableTransmit(); - if (mode == HasModesIF::MODE_ON) { - mode = HasModesIF::MODE_OFF; - } - return EXECUTION_FINISHED; - } case ENABLE_TX_CLK_MANIPULATOR: { result = ptmeConfig.configTxManipulator(true); break; @@ -206,12 +190,8 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; } void CcsdsIpCoreHandler::enableTransmit() { - // Reset PTME on each transmit enable. - updateBatPriorityFromParam(); -#ifndef TE0720_1CFA gpioIF->pullHigh(ptmeGpios.enableTxClock); gpioIF->pullHigh(ptmeGpios.enableTxData); -#endif linkState = LINK_UP; } @@ -236,34 +216,23 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod } void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) { - auto rateSet = [&](uint32_t rate) { - ReturnValue_t result = ptmeConfig.setRate(rate); - if (result == returnvalue::OK) { - this->mode = HasModesIF::MODE_ON; - } - }; + triggerEvent(CHANGING_MODE, mode, submode); if (mode == HasModesIF::MODE_ON) { - enableTransmit(); - if (submode == static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { - com::Datarate currentDatarate = com::getCurrentDatarate(); - if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { - rateSet(RATE_100KBPS); - } else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) { - rateSet(RATE_500KBPS); - } - } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_HIGH)) { - rateSet(RATE_500KBPS); - } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_LOW)) { - rateSet(RATE_100KBPS); + if (this->submode != submode) { + initPtmeUpdateAfterXCycles(); + updateContext.enableTransmitAfterPtmeUpdate = true; + updateContext.updateClockRate = true; + this->submode = submode; + this->mode = mode; + updateContext.setModeAfterUpdate = true; + return; } - + // No rate change, so enable transmitter right away. + enableTransmit(); } else if (mode == HasModesIF::MODE_OFF) { disableTransmit(); - this->mode = HasModesIF::MODE_OFF; } - this->submode = submode; - modeHelper.modeChanged(mode, submode); - announceMode(false); + setMode(mode, submode); } void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); } @@ -274,9 +243,9 @@ void CcsdsIpCoreHandler::disableTransmit() { gpioIF->pullLow(ptmeGpios.enableTxData); #endif linkState = LINK_DOWN; - if (updateBatPriorityOnTxOff) { - updateBatPriorityFromParam(); - updateBatPriorityOnTxOff = false; + // Some parameters need update and transmitter is off now. + if (updateContext.updateBatPrio or updateContext.updateClockRate) { + initPtmeUpdateAfterXCycles(); } } @@ -294,21 +263,9 @@ ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; } object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); } -void CcsdsIpCoreHandler::enablePrioritySelectMode() { - ptmeConfig.enableBatPriorityBit(true); - // Reset the PTME - gpioIF->pullLow(ptmeGpios.ptmeResetn); - usleep(10); - gpioIF->pullHigh(ptmeGpios.ptmeResetn); -} +void CcsdsIpCoreHandler::enablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(true); } -void CcsdsIpCoreHandler::disablePrioritySelectMode() { - ptmeConfig.enableBatPriorityBit(false); - // Reset the PTME - gpioIF->pullLow(ptmeGpios.ptmeResetn); - usleep(10); - gpioIF->pullHigh(ptmeGpios.ptmeResetn); -} +void CcsdsIpCoreHandler::disablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(false); } void CcsdsIpCoreHandler::updateBatPriorityFromParam() { if (batPriorityParam == 0) { @@ -317,3 +274,78 @@ void CcsdsIpCoreHandler::updateBatPriorityFromParam() { enablePrioritySelectMode(); } } + +void CcsdsIpCoreHandler::setMode(Mode_t mode, Submode_t submode) { + this->submode = submode; + this->mode = mode; + modeHelper.modeChanged(mode, submode); + announceMode(false); +} + +void CcsdsIpCoreHandler::performPtmeUpdateWhenApplicable() { + if (not updateContext.performPtmeUpdateAfterXCycles) { + return; + } + if (updateContext.ptmeUpdateCycleCount >= 2) { + if (updateContext.updateBatPrio) { + updateBatPriorityFromParam(); + updateContext.updateBatPrio = false; + } + ReturnValue_t result; + if (updateContext.updateClockRate) { + if (submode == static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { + com::Datarate currentDatarate = com::getCurrentDatarate(); + if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { + result = ptmeConfig.setRate(RATE_100KBPS); + } else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) { + result = ptmeConfig.setRate(RATE_500KBPS); + } + } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_HIGH)) { + result = ptmeConfig.setRate(RATE_500KBPS); + } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_LOW)) { + result = ptmeConfig.setRate(RATE_100KBPS); + } + if (result != returnvalue::OK) { + sif::error << "CcsdsIpCoreHandler: Setting datarate failed" << std::endl; + } + updateContext.updateClockRate = false; + } + bool doResetPtme = true; + if (not updateContext.updateBatPrio and not updateContext.updateClockRate) { + doResetPtme = false; + } + finishPtmeUpdateAfterXCycles(doResetPtme); + return; + } + updateContext.ptmeUpdateCycleCount++; +} + +void CcsdsIpCoreHandler::resetPtme() { + gpioIF->pullLow(ptmeGpios.ptmeResetn); + usleep(10); + gpioIF->pullHigh(ptmeGpios.ptmeResetn); +} + +void CcsdsIpCoreHandler::initPtmeUpdateAfterXCycles() { + if (not updateContext.performPtmeUpdateAfterXCycles) { + updateContext.performPtmeUpdateAfterXCycles = true; + updateContext.ptmeUpdateCycleCount = 0; + } +} + +void CcsdsIpCoreHandler::finishPtmeUpdateAfterXCycles(bool doResetPtme) { + if (doResetPtme) { + resetPtme(); + } + ptmeLocked = false; + updateContext.performPtmeUpdateAfterXCycles = false; + updateContext.ptmeUpdateCycleCount = 0; + if (updateContext.enableTransmitAfterPtmeUpdate) { + enableTransmit(); + updateContext.enableTransmitAfterPtmeUpdate = false; + } + if (updateContext.setModeAfterUpdate) { + setMode(mode, submode); + updateContext.setModeAfterUpdate = false; + } +} diff --git a/mission/com/CcsdsIpCoreHandler.h b/mission/com/CcsdsIpCoreHandler.h index fc686230..785f84a5 100644 --- a/mission/com/CcsdsIpCoreHandler.h +++ b/mission/com/CcsdsIpCoreHandler.h @@ -79,7 +79,8 @@ class CcsdsIpCoreHandler : public SystemObject, * @param enTxData GPIO ID of RS485 tx data enable */ CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig, - std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds); + std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds, + std::atomic_bool& ptmeLocked); ~CcsdsIpCoreHandler(); @@ -137,9 +138,8 @@ class CcsdsIpCoreHandler : public SystemObject, //! [EXPORT] : [COMMENT] Received action message with unknown action id static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0); - // using VirtualChannelMap = std::unordered_map; - // VirtualChannelMap virtualChannelMap; std::atomic_bool& linkState; + std::atomic_bool& ptmeLocked; object_id_t tcDestination; @@ -158,7 +158,15 @@ class CcsdsIpCoreHandler : public SystemObject, PtmeGpios ptmeGpios; // BAT priority bit on by default to enable priority selection mode for the PTME. uint8_t batPriorityParam = 0; - bool updateBatPriorityOnTxOff = false; + + struct UpdateContext { + bool updateBatPrio = false; + bool updateClockRate = false; + bool enableTransmitAfterPtmeUpdate = false; + uint8_t ptmeUpdateCycleCount = 0; + bool performPtmeUpdateAfterXCycles = false; + bool setModeAfterUpdate = false; + } updateContext{}; GpioIF* gpioIF = nullptr; @@ -180,6 +188,8 @@ class CcsdsIpCoreHandler : public SystemObject, */ void disableTransmit(); + void performPtmeUpdateWhenApplicable(); + /** * The following set of functions configure the mode of the PTME bandwith allocation table (BAT) * module. This consists of the following 2 steps: @@ -189,6 +199,11 @@ class CcsdsIpCoreHandler : public SystemObject, void enablePrioritySelectMode(); void disablePrioritySelectMode(); void updateBatPriorityFromParam(); + + void setMode(Mode_t mode, Submode_t submode); + void resetPtme(); + void initPtmeUpdateAfterXCycles(); + void finishPtmeUpdateAfterXCycles(bool doResetPtme); }; #endif /* CCSDSHANDLER_H_ */ diff --git a/mission/com/LiveTmTask.cpp b/mission/com/LiveTmTask.cpp index 236a3292..d09c6ced 100644 --- a/mission/com/LiveTmTask.cpp +++ b/mission/com/LiveTmTask.cpp @@ -6,12 +6,13 @@ #include LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, - VirtualChannelWithQueue& channel) + VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked) : SystemObject(objectId), modeHelper(this), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel), - channel(channel) { + channel(channel), + ptmeLocked(ptmeLocked) { requestQueue = QueueFactory::instance()->createMessageQueue(); } @@ -19,7 +20,7 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) { readCommandQueue(); while (true) { bool performWriteOp = true; - if (mode == MODE_OFF) { + if (mode == MODE_OFF or ptmeLocked) { performWriteOp = false; } diff --git a/mission/com/LiveTmTask.h b/mission/com/LiveTmTask.h index ca63cd02..c203f1de 100644 --- a/mission/com/LiveTmTask.h +++ b/mission/com/LiveTmTask.h @@ -18,7 +18,7 @@ class LiveTmTask : public SystemObject, public ModeTreeConnectionIF { public: LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, - VirtualChannelWithQueue& channel); + VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked); ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initialize() override; @@ -33,6 +33,7 @@ class LiveTmTask : public SystemObject, CfdpTmFunnel& cfdpFunnel; VirtualChannelWithQueue& channel; uint32_t packetCounter = 0; + const std::atomic_bool& ptmeLocked; void readCommandQueue(void); diff --git a/mission/com/PersistentLogTmStoreTask.cpp b/mission/com/PersistentLogTmStoreTask.cpp index 07fe5ad6..8ba7200f 100644 --- a/mission/com/PersistentLogTmStoreTask.cpp +++ b/mission/com/PersistentLogTmStoreTask.cpp @@ -5,8 +5,9 @@ PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores stores, VirtualChannel& channel, - SdCardMountedIF& sdcMan) - : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), + SdCardMountedIF& sdcMan, + const std::atomic_bool& ptmeLocked) + : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked), stores(stores), okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED), notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED), diff --git a/mission/com/PersistentLogTmStoreTask.h b/mission/com/PersistentLogTmStoreTask.h index 51431e2f..18da93f5 100644 --- a/mission/com/PersistentLogTmStoreTask.h +++ b/mission/com/PersistentLogTmStoreTask.h @@ -22,7 +22,8 @@ struct LogStores { class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF { public: PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore, - VirtualChannel& channel, SdCardMountedIF& sdcMan); + VirtualChannel& channel, SdCardMountedIF& sdcMan, + const std::atomic_bool& ptmeLocked); ReturnValue_t performOperation(uint8_t opCode) override; diff --git a/mission/com/PersistentSingleTmStoreTask.cpp b/mission/com/PersistentSingleTmStoreTask.cpp index 421f2a74..10bedee5 100644 --- a/mission/com/PersistentSingleTmStoreTask.cpp +++ b/mission/com/PersistentSingleTmStoreTask.cpp @@ -6,8 +6,9 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask( object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore, - VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan) - : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan), + VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan, + const std::atomic_bool& ptmeLocked) + : TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked), storeWithQueue(tmStore), dumpContext(eventIfDumpDone, eventIfCancelled) {} @@ -27,7 +28,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) { TaskFactory::delayTask(10); } else { // TODO: Would be best to remove this, but not delaying here can lead to evil issues. - TaskFactory::delayTask(2); + TaskFactory::delayTask(10); } } } diff --git a/mission/com/PersistentSingleTmStoreTask.h b/mission/com/PersistentSingleTmStoreTask.h index 4cbf1544..1a4c8683 100644 --- a/mission/com/PersistentSingleTmStoreTask.h +++ b/mission/com/PersistentSingleTmStoreTask.h @@ -12,7 +12,7 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, - SdCardMountedIF& sdcMan); + SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked); ReturnValue_t performOperation(uint8_t opCode) override; diff --git a/mission/com/TmStoreTaskBase.cpp b/mission/com/TmStoreTaskBase.cpp index d6db4095..6598225d 100644 --- a/mission/com/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -10,13 +10,15 @@ #include "mission/persistentTmStoreDefs.h" TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, - VirtualChannel& channel, SdCardMountedIF& sdcMan) + VirtualChannel& channel, SdCardMountedIF& sdcMan, + const std::atomic_bool& ptmeLocked) : SystemObject(objectId), modeHelper(this), ipcStore(ipcStore), tmReader(&timeReader), channel(channel), - sdcMan(sdcMan) { + sdcMan(sdcMan), + ptmeLocked(ptmeLocked) { requestQueue = QueueFactory::instance()->createMessageQueue(10); } @@ -99,7 +101,8 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store cancelDump(dumpContext, store, false); return returnvalue::FAILED; } - if (not channel.isBusy()) { + // It is assumed that the PTME will only be locked for a short period (e.g. to change datarate). + if (not channel.isBusy() and not ptmeLocked) { performDump(store, dumpContext, dumpPerformed); } else { // The PTME might be at full load, so it might sense to delay for a bit to let it do diff --git a/mission/com/TmStoreTaskBase.h b/mission/com/TmStoreTaskBase.h index 440e142e..ef61bd19 100644 --- a/mission/com/TmStoreTaskBase.h +++ b/mission/com/TmStoreTaskBase.h @@ -40,7 +40,7 @@ class TmStoreTaskBase : public SystemObject, }; TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel, - SdCardMountedIF& sdcMan); + SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked); ReturnValue_t initialize() override; ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; @@ -52,6 +52,8 @@ class TmStoreTaskBase : public SystemObject, PusTmReader tmReader; CdsShortTimeStamper timeReader; VirtualChannel& channel; + SdCardMountedIF& sdcMan; + const std::atomic_bool& ptmeLocked; Mode_t mode = HasModesIF::MODE_OFF; Countdown sdCardCheckCd = Countdown(800); @@ -62,7 +64,6 @@ class TmStoreTaskBase : public SystemObject, bool storesInitialized = false; bool fileHasSwapped = false; - SdCardMountedIF& sdcMan; void readCommandQueue(void); From f16d92c1b18a85efe239c1880887f7af8d8f79a8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 17:05:01 +0200 Subject: [PATCH 48/53] some more lock handling --- mission/com/CcsdsIpCoreHandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mission/com/CcsdsIpCoreHandler.cpp b/mission/com/CcsdsIpCoreHandler.cpp index d4608191..84c49e8b 100644 --- a/mission/com/CcsdsIpCoreHandler.cpp +++ b/mission/com/CcsdsIpCoreHandler.cpp @@ -31,6 +31,7 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDesti auto mqArgs = MqArgs(objectId, static_cast(this)); eventQueue = QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs); + ptmeLocked = true; } CcsdsIpCoreHandler::~CcsdsIpCoreHandler() = default; @@ -79,6 +80,8 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() { } else { enablePrioritySelectMode(); } + resetPtme(); + ptmeLocked = false; #if OBSW_SYRLINKS_SIMULATED == 1 // Update data on rising edge @@ -330,6 +333,7 @@ void CcsdsIpCoreHandler::initPtmeUpdateAfterXCycles() { if (not updateContext.performPtmeUpdateAfterXCycles) { updateContext.performPtmeUpdateAfterXCycles = true; updateContext.ptmeUpdateCycleCount = 0; + ptmeLocked = true; } } From 6c8eeeab315576498b60bfd25c6603302a1e8e2b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 17:12:11 +0200 Subject: [PATCH 49/53] init result --- mission/com/CcsdsIpCoreHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/com/CcsdsIpCoreHandler.cpp b/mission/com/CcsdsIpCoreHandler.cpp index 84c49e8b..d260d50e 100644 --- a/mission/com/CcsdsIpCoreHandler.cpp +++ b/mission/com/CcsdsIpCoreHandler.cpp @@ -294,7 +294,7 @@ void CcsdsIpCoreHandler::performPtmeUpdateWhenApplicable() { updateBatPriorityFromParam(); updateContext.updateBatPrio = false; } - ReturnValue_t result; + ReturnValue_t result = returnvalue::OK; if (updateContext.updateClockRate) { if (submode == static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { com::Datarate currentDatarate = com::getCurrentDatarate(); From bb7a6162835767f38a9465915814bd037971cb5e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 17:35:53 +0200 Subject: [PATCH 50/53] some minor tweaks --- linux/ipcore/PapbVcInterface.cpp | 2 +- linux/ipcore/PapbVcInterface.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index e7d6fd3d..0a7a15fc 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -37,7 +37,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { } else { return DirectTmSinkIF::IS_BUSY; } - // TODO: This should work but does not.. + // TODO: This should work but does not.. :( // size_t idx = 0; // while (idx < size) { // diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 82bad56a..1fed52ef 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -91,7 +91,6 @@ class PapbVcInterface : public VirtualChannelIF { std::string uioFile; int mapNum = 0; - volatile uint32_t dummy = 0; mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10}; mutable struct timespec remDelay; From f51656a8134cd81d017cd940f25c862a8d17bf21 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 17:36:49 +0200 Subject: [PATCH 51/53] add back volatile keyword --- linux/ipcore/PapbVcInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/ipcore/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h index 1fed52ef..e54def5d 100644 --- a/linux/ipcore/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -95,7 +95,7 @@ class PapbVcInterface : public VirtualChannelIF { const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10}; mutable struct timespec remDelay; - uint32_t* vcBaseReg = nullptr; + volatile uint32_t* vcBaseReg = nullptr; uint32_t vcOffset = 0; From fcf3437410881a0d7d16bb1f68b56b0f19495cd6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 17:39:13 +0200 Subject: [PATCH 52/53] some more tweaks --- mission/com/CcsdsIpCoreHandler.h | 2 +- mission/com/PersistentLogTmStoreTask.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mission/com/CcsdsIpCoreHandler.h b/mission/com/CcsdsIpCoreHandler.h index 520403a5..785f84a5 100644 --- a/mission/com/CcsdsIpCoreHandler.h +++ b/mission/com/CcsdsIpCoreHandler.h @@ -180,7 +180,7 @@ class CcsdsIpCoreHandler : public SystemObject, /** * @brief Starts transmit timer and enables transmitter. */ - void enableTransmit(bool resetPtmeUpdateParams); + void enableTransmit(); /** * @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the diff --git a/mission/com/PersistentLogTmStoreTask.cpp b/mission/com/PersistentLogTmStoreTask.cpp index 8ba7200f..0fc02461 100644 --- a/mission/com/PersistentLogTmStoreTask.cpp +++ b/mission/com/PersistentLogTmStoreTask.cpp @@ -43,6 +43,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) { TaskFactory::delayTask(100); } else if (vcBusyDuringDump) { // TODO: Might not be necessary + sif::debug << "VC busy, delaying" << std::endl; TaskFactory::delayTask(10); } } From 2f9de8c36e9c87555ab63c0ba1dea8950cb3d56c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 31 Mar 2023 17:41:01 +0200 Subject: [PATCH 53/53] some tweaks --- linux/ipcore/PapbVcInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/ipcore/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp index 0a7a15fc..60968cc6 100644 --- a/linux/ipcore/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -101,7 +101,7 @@ void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries, bool checkReadyState) const { uint32_t busyIdx = 0; - nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS; + nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS; while (true) { // Check if PAPB interface is ready to receive data. Use the configuration register for this.