PTME rework reset handling #542
@ -19,6 +19,10 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
- SCEX filename updates. Also use T as the file ID / date separator between date and time.
|
- 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
|
## Fixed
|
||||||
|
|
||||||
|
@ -20,15 +20,15 @@
|
|||||||
#include <mission/acs/MgmRm3100CustomHandler.h>
|
#include <mission/acs/MgmRm3100CustomHandler.h>
|
||||||
#include <mission/acs/str/StarTrackerHandler.h>
|
#include <mission/acs/str/StarTrackerHandler.h>
|
||||||
#include <mission/acs/str/strHelpers.h>
|
#include <mission/acs/str/strHelpers.h>
|
||||||
|
#include <mission/com/LiveTmTask.h>
|
||||||
|
#include <mission/com/PersistentLogTmStoreTask.h>
|
||||||
|
#include <mission/com/PersistentSingleTmStoreTask.h>
|
||||||
#include <mission/power/CspCookie.h>
|
#include <mission/power/CspCookie.h>
|
||||||
#include <mission/system/acs/ImtqAssembly.h>
|
#include <mission/system/acs/ImtqAssembly.h>
|
||||||
#include <mission/system/acs/StrAssembly.h>
|
#include <mission/system/acs/StrAssembly.h>
|
||||||
#include <mission/system/fdir/StrFdir.h>
|
#include <mission/system/fdir/StrFdir.h>
|
||||||
#include <mission/system/objects/CamSwitcher.h>
|
#include <mission/system/objects/CamSwitcher.h>
|
||||||
#include <mission/system/objects/SyrlinksAssembly.h>
|
#include <mission/system/objects/SyrlinksAssembly.h>
|
||||||
#include <mission/tmtc/LiveTmTask.h>
|
|
||||||
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
|
||||||
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
|
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||||
@ -81,6 +81,7 @@ using gpio::Levels;
|
|||||||
#include <mission/acs/ImtqHandler.h>
|
#include <mission/acs/ImtqHandler.h>
|
||||||
#include <mission/acs/rwHelpers.h>
|
#include <mission/acs/rwHelpers.h>
|
||||||
#include <mission/com/SyrlinksHandler.h>
|
#include <mission/com/SyrlinksHandler.h>
|
||||||
|
#include <mission/com/VirtualChannelWithQueue.h>
|
||||||
#include <mission/payload/PayloadPcduHandler.h>
|
#include <mission/payload/PayloadPcduHandler.h>
|
||||||
#include <mission/payload/RadiationSensorHandler.h>
|
#include <mission/payload/RadiationSensorHandler.h>
|
||||||
#include <mission/payload/payloadPcduDefinitions.h>
|
#include <mission/payload/payloadPcduDefinitions.h>
|
||||||
@ -96,7 +97,6 @@ using gpio::Levels;
|
|||||||
#include <mission/tcs/Max31865Definitions.h>
|
#include <mission/tcs/Max31865Definitions.h>
|
||||||
#include <mission/tcs/Max31865PT1000Handler.h>
|
#include <mission/tcs/Max31865PT1000Handler.h>
|
||||||
#include <mission/tcs/Tmp1075Handler.h>
|
#include <mission/tcs/Tmp1075Handler.h>
|
||||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
#include <fsfw/returnvalues/returnvalue.h>
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
#include <mission/com/CcsdsIpCoreHandler.h>
|
#include <mission/com/CcsdsIpCoreHandler.h>
|
||||||
|
#include <mission/com/PersistentLogTmStoreTask.h>
|
||||||
#include <mission/genericFactory.h>
|
#include <mission/genericFactory.h>
|
||||||
#include <mission/system/objects/Stack5VHandler.h>
|
#include <mission/system/objects/Stack5VHandler.h>
|
||||||
#include <mission/tcs/HeaterHandler.h>
|
#include <mission/tcs/HeaterHandler.h>
|
||||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||||
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
|
||||||
#include <mission/tmtc/PusTmFunnel.h>
|
#include <mission/tmtc/PusTmFunnel.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -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
|
// 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
|
// 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.
|
// 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) {
|
if (pollPapbBusySignal(2) == returnvalue::OK) {
|
||||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
|
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +46,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
|
// nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
|
||||||
if (pollPapbBusySignal(2) == returnvalue::OK) {
|
if (pollPapbBusySignal(2) == returnvalue::OK) {
|
||||||
completePacketTransfer();
|
completePacketTransfer();
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||||
#include <linux/ipcore/VirtualChannelIF.h>
|
#include <linux/ipcore/VirtualChannelIF.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
@ -1,2 +1,11 @@
|
|||||||
target_sources(${LIB_EIVE_MISSION} PRIVATE SyrlinksHandler.cpp
|
target_sources(
|
||||||
CcsdsIpCoreHandler.cpp)
|
${LIB_EIVE_MISSION}
|
||||||
|
PRIVATE SyrlinksHandler.cpp
|
||||||
|
CcsdsIpCoreHandler.cpp
|
||||||
|
LiveTmTask.cpp
|
||||||
|
PersistentLogTmStoreTask.cpp
|
||||||
|
TmStoreTaskBase.cpp
|
||||||
|
VirtualChannel.cpp
|
||||||
|
VirtualChannelWithQueue.cpp
|
||||||
|
PersistentSingleTmStoreTask.cpp
|
||||||
|
LiveTmTask.cpp)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CCSDSHANDLER_H_
|
#define CCSDSHANDLER_H_
|
||||||
|
|
||||||
#include <fsfw/modes/HasModesIF.h>
|
#include <fsfw/modes/HasModesIF.h>
|
||||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
#include <mission/com/VirtualChannelWithQueue.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
101
mission/com/LiveTmTask.cpp
Normal file
101
mission/com/LiveTmTask.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include "LiveTmTask.h"
|
||||||
|
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
|
#include <fsfw/subsystem/helper.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
|
|
||||||
|
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; }
|
55
mission/com/LiveTmTask.h
Normal file
55
mission/com/LiveTmTask.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef MISSION_TMTC_LIVETMTASK_H_
|
||||||
|
#define MISSION_TMTC_LIVETMTASK_H_
|
||||||
|
|
||||||
|
#include <fsfw/modes/HasModesIF.h>
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
||||||
|
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
||||||
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
#include <fsfw/timemanager/Countdown.h>
|
||||||
|
#include <mission/com/VirtualChannelWithQueue.h>
|
||||||
|
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||||
|
#include <mission/tmtc/PusTmFunnel.h>
|
||||||
|
|
||||||
|
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_ */
|
@ -27,6 +27,8 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
while (true) {
|
while (true) {
|
||||||
|
readCommandQueue();
|
||||||
|
|
||||||
if (not cyclicStoreCheck()) {
|
if (not cyclicStoreCheck()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -54,3 +56,17 @@ bool PersistentLogTmStoreTask::initStoresIfPossible() {
|
|||||||
}
|
}
|
||||||
return false;
|
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);
|
||||||
|
}
|
@ -5,11 +5,11 @@
|
|||||||
#include <fsfw/storagemanager/StorageManagerIF.h>
|
#include <fsfw/storagemanager/StorageManagerIF.h>
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||||
|
#include <mission/com/TmStoreTaskBase.h>
|
||||||
|
#include <mission/com/VirtualChannelWithQueue.h>
|
||||||
#include <mission/genericFactory.h>
|
#include <mission/genericFactory.h>
|
||||||
#include <mission/tmtc/PersistentTmStore.h>
|
#include <mission/tmtc/PersistentTmStore.h>
|
||||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
#include <mission/tmtc/TmStoreTaskBase.h>
|
|
||||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
|
||||||
|
|
||||||
struct LogStores {
|
struct LogStores {
|
||||||
LogStores(PersistentTmStores& stores)
|
LogStores(PersistentTmStores& stores)
|
||||||
@ -36,6 +36,7 @@ class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObject
|
|||||||
bool someFileWasSwapped = false;
|
bool someFileWasSwapped = false;
|
||||||
|
|
||||||
bool initStoresIfPossible() override;
|
bool initStoresIfPossible() override;
|
||||||
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */
|
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */
|
@ -1,17 +1,21 @@
|
|||||||
|
#include "PersistentSingleTmStoreTask.h"
|
||||||
|
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
|
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
|
||||||
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
|
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
|
||||||
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan)
|
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan)
|
||||||
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
|
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
|
||||||
|
modeHelper(this),
|
||||||
storeWithQueue(tmStore),
|
storeWithQueue(tmStore),
|
||||||
dumpContext(eventIfDumpDone, eventIfCancelled) {}
|
dumpContext(eventIfDumpDone, eventIfCancelled) {}
|
||||||
|
|
||||||
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
readCommandQueue();
|
||||||
|
|
||||||
// Delay done by the check
|
// Delay done by the check
|
||||||
if (not cyclicStoreCheck()) {
|
if (not cyclicStoreCheck()) {
|
||||||
continue;
|
continue;
|
||||||
@ -33,3 +37,14 @@ bool PersistentSingleTmStoreTask::initStoresIfPossible() {
|
|||||||
}
|
}
|
||||||
return false;
|
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);
|
||||||
|
}
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
#include <mission/com/TmStoreTaskBase.h>
|
||||||
|
#include <mission/com/VirtualChannel.h>
|
||||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
#include <mission/tmtc/TmStoreTaskBase.h>
|
|
||||||
#include <mission/tmtc/VirtualChannel.h>
|
|
||||||
|
|
||||||
class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
@ -17,12 +17,15 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj
|
|||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ModeHelper modeHelper;
|
||||||
PersistentTmStoreWithTmQueue& storeWithQueue;
|
PersistentTmStoreWithTmQueue& storeWithQueue;
|
||||||
DumpContext dumpContext;
|
DumpContext dumpContext;
|
||||||
Countdown tcHandlingCd = Countdown(400);
|
Countdown tcHandlingCd = Countdown(400);
|
||||||
Countdown graceDelayDuringDumping = Countdown(100);
|
Countdown graceDelayDuringDumping = Countdown(100);
|
||||||
|
|
||||||
bool initStoresIfPossible() override;
|
bool initStoresIfPossible() override;
|
||||||
|
|
||||||
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */
|
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */
|
@ -1,6 +1,8 @@
|
|||||||
#include "TmStoreTaskBase.h"
|
#include "TmStoreTaskBase.h"
|
||||||
|
|
||||||
#include <fsfw/ipc/CommandMessageIF.h>
|
#include <fsfw/ipc/CommandMessageIF.h>
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
|
#include <fsfw/subsystem/helper.h>
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
#include <fsfw/tmstorage/TmStoreMessage.h>
|
#include <fsfw/tmstorage/TmStoreMessage.h>
|
||||||
@ -9,7 +11,13 @@
|
|||||||
|
|
||||||
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
|
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
VirtualChannel& channel, SdCardMountedIF& sdcMan)
|
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,
|
bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
|
||||||
DumpContext& dumpContext) {
|
DumpContext& dumpContext) {
|
||||||
@ -26,8 +34,8 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
|
|||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
tmToStoreReceived = true;
|
tmToStoreReceived = true;
|
||||||
}
|
}
|
||||||
// Dump TMs when applicable
|
// Dump TMs when applicable and allowed (mode is on)
|
||||||
if (store.getState() == PersistentTmStore::State::DUMPING) {
|
if (mode == MODE_ON and store.getState() == PersistentTmStore::State::DUMPING) {
|
||||||
if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) {
|
if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -129,3 +137,57 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store
|
|||||||
}
|
}
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,21 @@
|
|||||||
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
|
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
|
||||||
#define MISSION_TMTC_TMSTORETASKBASE_H_
|
#define MISSION_TMTC_TMSTORETASKBASE_H_
|
||||||
|
|
||||||
|
#include <fsfw/modes/HasModesIF.h>
|
||||||
|
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
||||||
|
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
||||||
#include <fsfw/timemanager/Countdown.h>
|
#include <fsfw/timemanager/Countdown.h>
|
||||||
|
#include <mission/com/VirtualChannel.h>
|
||||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
#include <mission/tmtc/VirtualChannel.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping
|
* Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping
|
||||||
* the TM store into the virtual channel directly.
|
* the TM store into the virtual channel directly.
|
||||||
*/
|
*/
|
||||||
class TmStoreTaskBase : public SystemObject {
|
class TmStoreTaskBase : public SystemObject,
|
||||||
|
public HasModesIF,
|
||||||
|
public ModeTreeChildIF,
|
||||||
|
public ModeTreeConnectionIF {
|
||||||
public:
|
public:
|
||||||
struct DumpContext {
|
struct DumpContext {
|
||||||
DumpContext(Event eventIfDone, Event eventIfCancelled)
|
DumpContext(Event eventIfDone, Event eventIfCancelled)
|
||||||
@ -35,8 +41,13 @@ class TmStoreTaskBase : public SystemObject {
|
|||||||
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
|
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
|
||||||
SdCardMountedIF& sdcMan);
|
SdCardMountedIF& sdcMan);
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
MessageQueueIF* requestQueue;
|
||||||
|
ModeHelper modeHelper;
|
||||||
StorageManagerIF& ipcStore;
|
StorageManagerIF& ipcStore;
|
||||||
|
Mode_t mode = HasModesIF::MODE_OFF;
|
||||||
Countdown sdCardCheckCd = Countdown(800);
|
Countdown sdCardCheckCd = Countdown(800);
|
||||||
// 20 minutes are allowed as maximum dump time.
|
// 20 minutes are allowed as maximum dump time.
|
||||||
Countdown cancelDumpCd = Countdown(60 * 20 * 1000);
|
Countdown cancelDumpCd = Countdown(60 * 20 * 1000);
|
||||||
@ -47,6 +58,11 @@ class TmStoreTaskBase : public SystemObject {
|
|||||||
bool fileHasSwapped = false;
|
bool fileHasSwapped = false;
|
||||||
SdCardMountedIF& sdcMan;
|
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);
|
void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn);
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -65,7 +81,18 @@ class TmStoreTaskBase : public SystemObject {
|
|||||||
*/
|
*/
|
||||||
bool cyclicStoreCheck();
|
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_ */
|
#endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */
|
@ -1,4 +1,4 @@
|
|||||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
#include "VirtualChannelWithQueue.h"
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "fsfw/ipc/QueueFactory.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(); }
|
const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); }
|
||||||
|
|
||||||
ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
|
||||||
TmTcMessage message;
|
TmTcMessage message;
|
||||||
ReturnValue_t result = tmQueue->receiveMessage(&message);
|
ReturnValue_t result = tmQueue->receiveMessage(&message);
|
||||||
if (result == MessageQueueIF::EMPTY) {
|
if (result == MessageQueueIF::EMPTY) {
|
||||||
@ -36,7 +36,9 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (performWriteOp) {
|
||||||
result = write(data, size);
|
result = write(data, size);
|
||||||
|
}
|
||||||
// Try delete in any case, ignore failures (which should not happen), it is more important to
|
// Try delete in any case, ignore failures (which should not happen), it is more important to
|
||||||
// propagate write errors.
|
// propagate write errors.
|
||||||
tmStore.deleteData(storeId);
|
tmStore.deleteData(storeId);
|
@ -4,7 +4,7 @@
|
|||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
#include <linux/ipcore/PtmeIF.h>
|
#include <linux/ipcore/PtmeIF.h>
|
||||||
#include <mission/tmtc/VirtualChannel.h>
|
#include <mission/com/VirtualChannel.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ class VirtualChannelWithQueue : public VirtualChannel, public AcceptsTelemetryIF
|
|||||||
|
|
||||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
||||||
[[nodiscard]] const char* getName() const override;
|
[[nodiscard]] const char* getName() const override;
|
||||||
ReturnValue_t sendNextTm();
|
ReturnValue_t handleNextTm(bool performWriteOp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageQueueIF* tmQueue = nullptr;
|
MessageQueueIF* tmQueue = nullptr;
|
@ -3,6 +3,8 @@
|
|||||||
#include <fsfw/ipc/MutexFactory.h>
|
#include <fsfw/ipc/MutexFactory.h>
|
||||||
#include <fsfw/ipc/MutexGuard.h>
|
#include <fsfw/ipc/MutexGuard.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK;
|
com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK;
|
||||||
MutexIF* DATARATE_LOCK = nullptr;
|
MutexIF* DATARATE_LOCK = nullptr;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ auto COM_SEQUENCE_RX_ONLY =
|
|||||||
auto COM_TABLE_RX_ONLY_TGT = std::make_pair(
|
auto COM_TABLE_RX_ONLY_TGT = std::make_pair(
|
||||||
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 1, FixedArrayList<ModeListEntry, 3>());
|
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 1, FixedArrayList<ModeListEntry, 3>());
|
||||||
auto COM_TABLE_RX_ONLY_TRANS_0 = std::make_pair(
|
auto COM_TABLE_RX_ONLY_TRANS_0 = std::make_pair(
|
||||||
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 3>());
|
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 6>());
|
||||||
auto COM_TABLE_RX_ONLY_TRANS_1 = std::make_pair(
|
auto COM_TABLE_RX_ONLY_TRANS_1 = std::make_pair(
|
||||||
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 3, FixedArrayList<ModeListEntry, 3>());
|
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 3, FixedArrayList<ModeListEntry, 3>());
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 =
|
|||||||
FixedArrayList<ModeListEntry, 3>());
|
FixedArrayList<ModeListEntry, 3>());
|
||||||
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 =
|
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 =
|
||||||
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3,
|
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3,
|
||||||
FixedArrayList<ModeListEntry, 3>());
|
FixedArrayList<ModeListEntry, 6>());
|
||||||
|
|
||||||
auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE =
|
auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE =
|
||||||
std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList<ModeListEntry, 3>());
|
std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList<ModeListEntry, 3>());
|
||||||
@ -48,7 +48,7 @@ auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 =
|
|||||||
FixedArrayList<ModeListEntry, 3>());
|
FixedArrayList<ModeListEntry, 3>());
|
||||||
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 =
|
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 =
|
||||||
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3,
|
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3,
|
||||||
FixedArrayList<ModeListEntry, 3>());
|
FixedArrayList<ModeListEntry, 6>());
|
||||||
|
|
||||||
auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE =
|
auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE =
|
||||||
std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList<ModeListEntry, 3>());
|
std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList<ModeListEntry, 3>());
|
||||||
@ -60,7 +60,7 @@ auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 =
|
|||||||
FixedArrayList<ModeListEntry, 3>());
|
FixedArrayList<ModeListEntry, 3>());
|
||||||
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 =
|
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 =
|
||||||
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3,
|
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3,
|
||||||
FixedArrayList<ModeListEntry, 3>());
|
FixedArrayList<ModeListEntry, 6>());
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -110,6 +110,10 @@ void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) {
|
|||||||
|
|
||||||
// Build RX Only transition 0
|
// Build RX Only transition 0
|
||||||
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TRANS_0.second);
|
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)),
|
check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_0.first, &COM_TABLE_RX_ONLY_TRANS_0.second)),
|
||||||
ctxc);
|
ctxc);
|
||||||
|
|
||||||
@ -165,6 +169,10 @@ void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh) {
|
|||||||
// Build TX and RX low transition 1
|
// Build TX and RX low transition 1
|
||||||
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE,
|
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE,
|
||||||
COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
|
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,
|
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first,
|
||||||
&COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)),
|
&COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)),
|
||||||
ctxc);
|
ctxc);
|
||||||
@ -217,6 +225,10 @@ void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh) {
|
|||||||
// Build TX and RX high transition 1
|
// Build TX and RX high transition 1
|
||||||
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE,
|
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE,
|
||||||
COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
|
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,
|
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first,
|
||||||
&COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)),
|
&COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)),
|
||||||
ctxc);
|
ctxc);
|
||||||
@ -271,6 +283,10 @@ void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh) {
|
|||||||
// Build TX and RX default transition 1
|
// Build TX and RX default transition 1
|
||||||
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE,
|
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE,
|
||||||
COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
|
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,
|
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first,
|
||||||
&COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)),
|
&COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)),
|
||||||
ctxc);
|
ctxc);
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
${LIB_EIVE_MISSION}
|
${LIB_EIVE_MISSION}
|
||||||
PRIVATE VirtualChannelWithQueue.cpp
|
PRIVATE PersistentTmStoreWithTmQueue.cpp
|
||||||
PersistentTmStoreWithTmQueue.cpp
|
|
||||||
LiveTmTask.cpp
|
|
||||||
VirtualChannel.cpp
|
|
||||||
TmFunnelHandler.cpp
|
TmFunnelHandler.cpp
|
||||||
TmFunnelBase.cpp
|
TmFunnelBase.cpp
|
||||||
CfdpTmFunnel.cpp
|
CfdpTmFunnel.cpp
|
||||||
tmFilters.cpp
|
tmFilters.cpp
|
||||||
PusLiveDemux.cpp
|
PusLiveDemux.cpp
|
||||||
PersistentSingleTmStoreTask.cpp
|
|
||||||
PersistentLogTmStoreTask.cpp
|
|
||||||
TmStoreTaskBase.cpp
|
|
||||||
PusPacketFilter.cpp
|
PusPacketFilter.cpp
|
||||||
PusTmRouteByFilterHelper.cpp
|
PusTmRouteByFilterHelper.cpp
|
||||||
Service15TmStorage.cpp
|
Service15TmStorage.cpp
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#include "LiveTmTask.h"
|
|
||||||
|
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
#ifndef MISSION_TMTC_LIVETMTASK_H_
|
|
||||||
#define MISSION_TMTC_LIVETMTASK_H_
|
|
||||||
|
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
|
||||||
#include <fsfw/timemanager/Countdown.h>
|
|
||||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
|
||||||
#include <mission/tmtc/PusTmFunnel.h>
|
|
||||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
|
||||||
|
|
||||||
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_ */
|
|
Loading…
Reference in New Issue
Block a user