Merge branch 'refactor-fix-ptme' into cfdp-source-handler
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit

This commit is contained in:
2023-10-13 09:45:21 +02:00
34 changed files with 392 additions and 113 deletions

View File

@ -138,8 +138,17 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
return result;
}
dumpedLen = tmReader.getFullPacketLen();
result = channel.write(tmReader.getFullData(), dumpedLen);
if (result == DirectTmSinkIF::IS_BUSY) {
size_t partiallyWrittenSize = 0;
result = channel.write(tmReader.getFullData(), dumpedLen, partiallyWrittenSize);
if (result == VirtualChannelIF::PARTIALLY_WRITTEN) {
result = channel.handleLastWriteSynchronously(tmReader.getFullData(), partiallyWrittenSize,
dumpedLen - partiallyWrittenSize, 200);
if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though..
sif::warning << "PersistentTmStore: Synchronous write of last segment failed with code 0x"
<< std::setw(4) << std::hex << result << std::dec << std::endl;
}
} else 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;

View File

@ -1,25 +1,64 @@
#include "VirtualChannel.h"
#include <fsfw/tasks/TaskFactory.h>
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) {}
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) {
return write(data, size);
ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize) {
return write(data, size, writtenSize);
}
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
return ptme.writeToVc(vcId, data, size);
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size, size_t& writtenSize) {
if (!ptme.containsVc(vcId)) {
return CHANNEL_DOES_NOT_EXIST;
}
return ptme.getVirtChannel(vcId)->write(data, size, writtenSize);
}
uint8_t VirtualChannel::getVcid() const { return vcId; }
ReturnValue_t VirtualChannel::finishWrite(const uint8_t* data, size_t start, size_t remainingSize) {
if (!ptme.containsVc(vcId)) {
return CHANNEL_DOES_NOT_EXIST;
}
return ptme.getVirtChannel(vcId)->finishWrite(data, start, remainingSize);
}
const char* VirtualChannel::getName() const { return vcName.c_str(); }
bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); }
bool VirtualChannel::isBusy() const {
if (!ptme.containsVc(vcId)) {
return CHANNEL_DOES_NOT_EXIST;
}
return ptme.getVirtChannel(vcId)->isBusy();
}
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
void VirtualChannel::cancelTransfer() {
if (!ptme.containsVc(vcId)) {
return;
}
ptme.getVirtChannel(vcId)->cancelTransfer();
}
bool VirtualChannel::isTxOn() const { return txOn; }
ReturnValue_t VirtualChannel::handleLastWriteSynchronously(const uint8_t* data, size_t start,
size_t remLen, unsigned maxDelayMs) {
unsigned delayMs = 0;
while (true) {
if (isBusy()) {
if (delayMs >= maxDelayMs) {
break;
}
TaskFactory::delayTask(10);
delayMs += 10;
continue;
}
return finishWrite(data, start, remLen);
}
return returnvalue::FAILED;
}

View File

@ -15,6 +15,10 @@
*/
class VirtualChannel : public SystemObject, public VirtualChannelIF {
public:
static constexpr uint8_t CLASS_ID = CLASS_ID::VIRTUAL_CHANNEL;
static constexpr ReturnValue_t CHANNEL_DOES_NOT_EXIST = returnvalue::makeCode(CLASS_ID, 0);
/**
* @brief Constructor
*
@ -25,9 +29,12 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
const std::atomic_bool& linkStateProvider);
ReturnValue_t initialize() override;
ReturnValue_t sendNextTm(const uint8_t* data, size_t size);
ReturnValue_t sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize);
bool isBusy() const override;
ReturnValue_t write(const uint8_t* data, size_t size) override;
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
ReturnValue_t handleLastWriteSynchronously(const uint8_t* data, size_t start, size_t remLen,
unsigned maxDelayMs);
void cancelTransfer() override;
uint8_t getVcid() const;
bool isTxOn() const;

View File

@ -36,8 +36,19 @@ ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
return result;
}
// TODO: Hnadle partial write handling
size_t partiallyWrittenSize = 0;
if (performWriteOp) {
result = write(data, size);
result = write(data, size, partiallyWrittenSize);
if (result == PARTIALLY_WRITTEN) {
result = handleLastWriteSynchronously(data, size, partiallyWrittenSize, 200);
if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though..
sif::warning
<< "VirtualChannelWithQueue: Synchronous write of last segment failed with code 0x"
<< std::setw(4) << std::hex << result << std::dec << std::endl;
}
}
}
// Try delete in any case, ignore failures (which should not happen), it is more important to
// propagate write errors.

View File

@ -1,7 +1,7 @@
if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "")
target_sources(${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp
AcsController.cpp
PowerController.cpp)
target_sources(
${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp AcsController.cpp
PowerController.cpp)
endif()
add_subdirectory(acs)

View File

@ -38,9 +38,13 @@ void ScexDeviceHandler::doShutDown() {
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t ScexDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { return OK; }
ReturnValue_t ScexDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
return NOTHING_TO_SEND;
}
ReturnValue_t ScexDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { return OK; }
ReturnValue_t ScexDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
return NOTHING_TO_SEND;
}
ReturnValue_t ScexDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
@ -269,7 +273,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
// Unknown DeviceCommand
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
if (helper.getPacketCounter() == helper.getTotalPacketCounter()) {
if (helper.getPacketCounter() >= helper.getTotalPacketCounter()) {
reader.finish();
commandActive = false;
if (id != PING) {

View File

@ -1 +1,2 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE epsModeTree.cpp EpsSubsystem.cpp GomspacePowerFdir.cpp)
target_sources(${LIB_EIVE_MISSION} PRIVATE epsModeTree.cpp EpsSubsystem.cpp
GomspacePowerFdir.cpp)

View File

@ -13,6 +13,8 @@ class DirectTmSinkIF {
static constexpr uint8_t CLASS_ID = CLASS_ID::TM_SINK;
static constexpr ReturnValue_t IS_BUSY = returnvalue::makeCode(CLASS_ID, 0);
static constexpr ReturnValue_t PARTIALLY_WRITTEN = returnvalue::makeCode(CLASS_ID, 1);
static constexpr ReturnValue_t INCOMPLETE_PARTIAL_WRITE = returnvalue::makeCode(CLASS_ID, 2);
/**
* @brief Implements the functionality to write to a TM sink directly
@ -20,9 +22,12 @@ class DirectTmSinkIF {
* @param data Pointer to buffer holding the data to write
* @param size Number of bytes to write
* @return returnvalue::OK on success, returnvalue::FAILED on failure, IS_BUSY
* if the TM sink is busy.
* if the TM sink is busy, PARTIALLY_WRITTEN if only a portion of the bytes could be
* written.
*/
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
virtual ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) = 0;
virtual ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) = 0;
virtual bool isBusy() const = 0;
};