refactored throttle handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
This commit is contained in:
parent
031be000d4
commit
9f600a24ff
@ -15,7 +15,8 @@
|
|||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
using namespace cfdp;
|
using namespace cfdp;
|
||||||
|
|
||||||
CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwHandlerParams, const CfdpHandlerCfg& cfdpCfg)
|
CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwHandlerParams, const CfdpHandlerCfg& cfdpCfg,
|
||||||
|
const std::atomic_bool& throttleSignal)
|
||||||
: SystemObject(fsfwHandlerParams.objectId),
|
: SystemObject(fsfwHandlerParams.objectId),
|
||||||
pduQueue(fsfwHandlerParams.tmtcQueue),
|
pduQueue(fsfwHandlerParams.tmtcQueue),
|
||||||
cfdpRequestQueue(fsfwHandlerParams.cfdpQueue),
|
cfdpRequestQueue(fsfwHandlerParams.cfdpQueue),
|
||||||
@ -28,7 +29,8 @@ CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwHandlerParams, const CfdpH
|
|||||||
this->fsfwParams),
|
this->fsfwParams),
|
||||||
srcHandler(SourceHandlerParams(localCfg, cfdpCfg.userHandler, seqCntProvider),
|
srcHandler(SourceHandlerParams(localCfg, cfdpCfg.userHandler, seqCntProvider),
|
||||||
this->fsfwParams),
|
this->fsfwParams),
|
||||||
ipcStore(fsfwHandlerParams.ipcStore) {}
|
ipcStore(fsfwHandlerParams.ipcStore),
|
||||||
|
throttleSignal(throttleSignal) {}
|
||||||
|
|
||||||
[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; }
|
[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; }
|
||||||
|
|
||||||
@ -69,20 +71,11 @@ ReturnValue_t CfdpHandler::initialize() {
|
|||||||
fsmCount++;
|
fsmCount++;
|
||||||
}
|
}
|
||||||
fsmCount = 0;
|
fsmCount = 0;
|
||||||
if (signals::CFDP_CHANNEL_THROTTLE_SIGNAL) {
|
|
||||||
throttlePeriodSourceHandler.resetTimer();
|
if (throttleSignal) {
|
||||||
throttlePeriodOngoing = true;
|
throttlePeriodOngoing = true;
|
||||||
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (throttlePeriodOngoing) {
|
|
||||||
if (throttlePeriodSourceHandler.hasTimedOut()) {
|
|
||||||
throttlePeriodOngoing = false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
shortDelay = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// CFDP can be throttled by the slowest live TM handler to handle back pressure in a sensible
|
// CFDP can be throttled by the slowest live TM handler to handle back pressure in a sensible
|
||||||
// way without requiring huge amounts of memory for large files.
|
// way without requiring huge amounts of memory for large files.
|
||||||
if (!throttlePeriodOngoing) {
|
if (!throttlePeriodOngoing) {
|
||||||
|
@ -62,7 +62,8 @@ struct CfdpHandlerCfg {
|
|||||||
|
|
||||||
class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
|
class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
|
||||||
public:
|
public:
|
||||||
explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg);
|
explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg,
|
||||||
|
const std::atomic_bool& throttleSignal);
|
||||||
|
|
||||||
[[nodiscard]] const char* getName() const override;
|
[[nodiscard]] const char* getName() const override;
|
||||||
[[nodiscard]] uint32_t getIdentifier() const override;
|
[[nodiscard]] uint32_t getIdentifier() const override;
|
||||||
@ -74,7 +75,6 @@ class CfdpHandler : public SystemObject, public ExecutableObjectIF, public Accep
|
|||||||
private:
|
private:
|
||||||
MessageQueueIF& pduQueue;
|
MessageQueueIF& pduQueue;
|
||||||
MessageQueueIF& cfdpRequestQueue;
|
MessageQueueIF& cfdpRequestQueue;
|
||||||
Countdown throttlePeriodSourceHandler = Countdown(80);
|
|
||||||
bool throttlePeriodOngoing = false;
|
bool throttlePeriodOngoing = false;
|
||||||
|
|
||||||
cfdp::LocalEntityCfg localCfg;
|
cfdp::LocalEntityCfg localCfg;
|
||||||
@ -89,6 +89,8 @@ class CfdpHandler : public SystemObject, public ExecutableObjectIF, public Accep
|
|||||||
StorageManagerIF* tcStore = nullptr;
|
StorageManagerIF* tcStore = nullptr;
|
||||||
StorageManagerIF* tmStore = nullptr;
|
StorageManagerIF* tmStore = nullptr;
|
||||||
|
|
||||||
|
const std::atomic_bool& throttleSignal;
|
||||||
|
|
||||||
ReturnValue_t handlePduPacketMessages();
|
ReturnValue_t handlePduPacketMessages();
|
||||||
ReturnValue_t handlePduPacket(TmTcMessage& msg);
|
ReturnValue_t handlePduPacket(TmTcMessage& msg);
|
||||||
ReturnValue_t handleCfdpRequest(CommandMessage& msg);
|
ReturnValue_t handleCfdpRequest(CommandMessage& msg);
|
||||||
|
@ -53,11 +53,14 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channel.isBusy() and not signals::CFDP_CHANNEL_THROTTLE_SIGNAL) {
|
if (channel.isBusy() and !throttlePeriodOngoing) {
|
||||||
// Throttle CFDP packet creator. It is by far the most relevant data creator, so throttling
|
// Throttle CFDP packet creator. It is by far the most relevant data creator, so throttling
|
||||||
// it is the easiest way to handle back pressure for now in a sensible way. It is cleared
|
// it is the easiest way to handle back pressure for now in a sensible way.
|
||||||
// by the data creator.
|
throttleCfdp();
|
||||||
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = true;
|
} else if(!channel.isBusy() and throttlePeriodOngoing) {
|
||||||
|
if(minimumPeriodThrottleCd.hasTimedOut()) {
|
||||||
|
releaseCfdp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!handledTm) {
|
if (!handledTm) {
|
||||||
if (tmFunnelCd.hasTimedOut()) {
|
if (tmFunnelCd.hasTimedOut()) {
|
||||||
@ -164,7 +167,7 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
|
|||||||
result = channel.write(data, size, partiallyWrittenSize);
|
result = channel.write(data, size, partiallyWrittenSize);
|
||||||
if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) {
|
if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) {
|
||||||
// Already throttle CFDP.
|
// Already throttle CFDP.
|
||||||
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = true;
|
throttleCfdp();
|
||||||
result = channel.handleLastWriteSynchronously(data, size, partiallyWrittenSize, 200);
|
result = channel.handleLastWriteSynchronously(data, size, partiallyWrittenSize, 200);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
// TODO: Event? Might lead to dangerous spam though..
|
// TODO: Event? Might lead to dangerous spam though..
|
||||||
@ -180,6 +183,17 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LiveTmTask::throttleCfdp() {
|
||||||
|
throttlePeriodOngoing = true;
|
||||||
|
minimumPeriodThrottleCd.resetTimer();
|
||||||
|
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiveTmTask::releaseCfdp() {
|
||||||
|
throttlePeriodOngoing = false;
|
||||||
|
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = false;
|
||||||
|
}
|
||||||
|
|
||||||
ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; }
|
ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; }
|
||||||
|
|
||||||
ReturnValue_t LiveTmTask::initialize() {
|
ReturnValue_t LiveTmTask::initialize() {
|
||||||
|
@ -39,6 +39,10 @@ class LiveTmTask : public SystemObject,
|
|||||||
CfdpTmFunnel& cfdpFunnel;
|
CfdpTmFunnel& cfdpFunnel;
|
||||||
VirtualChannel& channel;
|
VirtualChannel& channel;
|
||||||
const std::atomic_bool& ptmeLocked;
|
const std::atomic_bool& ptmeLocked;
|
||||||
|
// This countdown ensures that the CFDP is always throttled with a minimum period. Only after
|
||||||
|
// this period, the CFDP can be released if the channel is not busy.
|
||||||
|
Countdown minimumPeriodThrottleCd = Countdown(40);
|
||||||
|
bool throttlePeriodOngoing = false;
|
||||||
|
|
||||||
void readCommandQueue(void);
|
void readCommandQueue(void);
|
||||||
|
|
||||||
@ -56,6 +60,8 @@ class LiveTmTask : public SystemObject,
|
|||||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
|
|
||||||
void announceMode(bool recursive) override;
|
void announceMode(bool recursive) override;
|
||||||
|
void throttleCfdp();
|
||||||
|
void releaseCfdp();
|
||||||
|
|
||||||
object_id_t getObjectId() const override;
|
object_id_t getObjectId() const override;
|
||||||
const HasHealthIF* getOptHealthIF() const override;
|
const HasHealthIF* getOptHealthIF() const override;
|
||||||
|
@ -58,6 +58,7 @@ ReturnValue_t VirtualChannel::handleLastWriteSynchronously(const uint8_t* data,
|
|||||||
delayMs += 10;
|
delayMs += 10;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
sif::debug << "last write after" << delayMs << std::endl;
|
||||||
return finishWrite(data, start, remLen);
|
return finishWrite(data, start, remLen);
|
||||||
}
|
}
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
@ -292,7 +292,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
GROUND_REMOTE_CFG.maxFileSegmentLen = config::CFDP_MAX_FILE_SEGMENT_LEN;
|
GROUND_REMOTE_CFG.maxFileSegmentLen = config::CFDP_MAX_FILE_SEGMENT_LEN;
|
||||||
CfdpHandlerCfg cfdpCfg(localId, indicationCfg, *eiveUserHandler, EIVE_FAULT_HANDLER, PACKET_LIST,
|
CfdpHandlerCfg cfdpCfg(localId, indicationCfg, *eiveUserHandler, EIVE_FAULT_HANDLER, PACKET_LIST,
|
||||||
LOST_SEGMENTS, REMOTE_CFG_PROVIDER);
|
LOST_SEGMENTS, REMOTE_CFG_PROVIDER);
|
||||||
auto* cfdpHandler = new CfdpHandler(params, cfdpCfg);
|
auto* cfdpHandler = new CfdpHandler(params, cfdpCfg, signals::CFDP_CHANNEL_THROTTLE_SIGNAL);
|
||||||
// All CFDP packets arrive wrapped inside CCSDS space packets
|
// All CFDP packets arrive wrapped inside CCSDS space packets
|
||||||
CcsdsDistributorIF::DestInfo info("CFDP Destination", config::EIVE_CFDP_APID,
|
CcsdsDistributorIF::DestInfo info("CFDP Destination", config::EIVE_CFDP_APID,
|
||||||
cfdpHandler->getRequestQueue(), true);
|
cfdpHandler->getRequestQueue(), true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user