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);