lets see if this works better
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

This commit is contained in:
Robin Müller 2023-10-13 13:21:28 +02:00
parent 5bcd171108
commit c95964ce0f
Signed by: muellerr
GPG Key ID: FCE0B2BD2195142F
5 changed files with 23 additions and 24 deletions

View File

@ -9,6 +9,7 @@
static constexpr bool DEBUG_TM_QUEUE_SPEED = false; static constexpr bool DEBUG_TM_QUEUE_SPEED = false;
std::atomic_bool signals::CFDP_CHANNEL_THROTTLE_SIGNAL = false; std::atomic_bool signals::CFDP_CHANNEL_THROTTLE_SIGNAL = false;
std::atomic_uint32_t signals::CFDP_MSG_COUNTER = 0;
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannel& channel, const std::atomic_bool& ptmeLocked, VirtualChannel& channel, const std::atomic_bool& ptmeLocked,
@ -52,16 +53,14 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
} }
} }
} }
} else {
consecutiveNoBlockWriteCounter = 0;
} }
if (channel.isBusy() and !throttlePeriodOngoing) { 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 the easiest way to handle back pressure for now in a sensible way.
throttleCfdp(); throttleCfdp();
} else if(!channel.isBusy() and throttlePeriodOngoing) { } else if (!channel.isBusy() and throttlePeriodOngoing) {
if(minimumPeriodThrottleCd.hasTimedOut() and consecutiveNoBlockWriteCounter >= 10) { // Half full/empty flow control: Release the CFDP is the queue is empty enough.
sif::debug << "releasing cfdp" << std::endl; if (signals::CFDP_MSG_COUNTER <= config::LIVE_CHANNEL_CFDP_QUEUE_SIZE / 2) {
releaseCfdp(); releaseCfdp();
} }
} }
@ -144,16 +143,21 @@ void LiveTmTask::readCommandQueue(void) {
} }
} }
ReturnValue_t LiveTmTask::handleRegularTmQueue() { return handleGenericTmQueue(*regularTmQueue); } ReturnValue_t LiveTmTask::handleRegularTmQueue() {
return handleGenericTmQueue(*regularTmQueue, false);
}
ReturnValue_t LiveTmTask::handleCfdpTmQueue() { return handleGenericTmQueue(*cfdpTmQueue); } ReturnValue_t LiveTmTask::handleCfdpTmQueue() { return handleGenericTmQueue(*cfdpTmQueue, true); }
ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) { ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue, bool isCfdp) {
TmTcMessage message; TmTcMessage message;
ReturnValue_t result = queue.receiveMessage(&message); ReturnValue_t result = queue.receiveMessage(&message);
if (result == MessageQueueIF::EMPTY) { if (result == MessageQueueIF::EMPTY) {
return result; return result;
} }
if (signals::CFDP_MSG_COUNTER > 0) {
signals::CFDP_MSG_COUNTER--;
}
store_address_t storeId = message.getStorageId(); store_address_t storeId = message.getStorageId();
const uint8_t* data = nullptr; const uint8_t* data = nullptr;
size_t size = 0; size_t size = 0;
@ -165,26 +169,19 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
return result; return result;
} }
if(ptmeLocked) {
consecutiveNoBlockWriteCounter= 0;
}
if (!ptmeLocked) { if (!ptmeLocked) {
size_t partiallyWrittenSize = 0; size_t partiallyWrittenSize = 0;
result = channel.write(data, size, partiallyWrittenSize); result = channel.write(data, size, partiallyWrittenSize);
if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) { if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) {
consecutiveNoBlockWriteCounter = 0;
// Already throttle CFDP. // Already throttle CFDP.
throttleCfdp(); 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..
sif::warning sif::warning << "LiveTmTask: Synchronous write of last segment failed with code 0x"
<< "LiveTmTask: Synchronous write of last segment failed with code 0x"
<< std::setw(4) << std::hex << result << std::dec << std::endl; << std::setw(4) << std::hex << result << std::dec << std::endl;
} }
minimumPeriodThrottleCd.resetTimer(); // minimumPeriodThrottleCd.resetTimer();
} else {
consecutiveNoBlockWriteCounter++;
} }
} }
// 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
@ -195,7 +192,7 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
void LiveTmTask::throttleCfdp() { void LiveTmTask::throttleCfdp() {
throttlePeriodOngoing = true; throttlePeriodOngoing = true;
minimumPeriodThrottleCd.resetTimer(); // minimumPeriodThrottleCd.resetTimer();
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = true; signals::CFDP_CHANNEL_THROTTLE_SIGNAL = true;
} }

View File

@ -10,7 +10,9 @@
#include <mission/com/VirtualChannelWithQueue.h> #include <mission/com/VirtualChannelWithQueue.h>
#include <mission/tmtc/CfdpTmFunnel.h> #include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PusTmFunnel.h> #include <mission/tmtc/PusTmFunnel.h>
#include <cstdint> #include <cstdint>
#include "eive/definitions.h" #include "eive/definitions.h"
class LiveTmTask : public SystemObject, class LiveTmTask : public SystemObject,
@ -37,21 +39,20 @@ class LiveTmTask : public SystemObject,
ModeHelper modeHelper; ModeHelper modeHelper;
Mode_t mode = HasModesIF::MODE_OFF; Mode_t mode = HasModesIF::MODE_OFF;
Countdown tmFunnelCd = Countdown(100); Countdown tmFunnelCd = Countdown(100);
uint32_t consecutiveNoBlockWriteCounter = 0;
PusTmFunnel& pusFunnel; PusTmFunnel& pusFunnel;
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 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. // this period, the CFDP can be released if the channel is not busy.
Countdown minimumPeriodThrottleCd = Countdown(config::CFDP_THROTTLE_PERIOD_MS); // Countdown minimumPeriodThrottleCd = Countdown(config::CFDP_THROTTLE_PERIOD_MS);
bool throttlePeriodOngoing = false; bool throttlePeriodOngoing = false;
void readCommandQueue(void); void readCommandQueue(void);
ReturnValue_t handleRegularTmQueue(); ReturnValue_t handleRegularTmQueue();
ReturnValue_t handleCfdpTmQueue(); ReturnValue_t handleCfdpTmQueue();
ReturnValue_t handleGenericTmQueue(MessageQueueIF& queue); ReturnValue_t handleGenericTmQueue(MessageQueueIF& queue, bool isCfdp);
MessageQueueId_t getCommandQueue() const override; MessageQueueId_t getCommandQueue() const override;

View File

@ -15,6 +15,7 @@ namespace signals {
extern std::atomic_bool CFDP_CHANNEL_THROTTLE_SIGNAL; extern std::atomic_bool CFDP_CHANNEL_THROTTLE_SIGNAL;
extern std::atomic_uint16_t I2C_FATAL_ERRORS; extern std::atomic_uint16_t I2C_FATAL_ERRORS;
extern std::atomic_uint32_t CFDP_MSG_COUNTER;
} // namespace signals } // namespace signals