Refactor IMTQ handling #384

Merged
muellerr merged 30 commits from refactor_imtq_handling into develop 2023-02-21 11:04:29 +01:00
8 changed files with 114 additions and 35 deletions
Showing only changes of commit 56cdd1173e - Show all commits

View File

@ -62,7 +62,7 @@ static constexpr uint32_t SCHED_BLOCK_2_SENSOR_READ_MS = 30;
static constexpr uint32_t SCHED_BLOCK_3_READ_IMTQ_MGM_MS = 42;
meggert marked this conversation as resolved
Review

Is this extra block needed? PERFORM_OPERATION, SEND_WRITE and GET_WRITE are done at 15ms. Why not include the SEND_READ and GET_READ to SCHED_BLOCK_2. Later on during torqueing we also wait only 15ms and not 27ms.

Is this extra block needed? PERFORM_OPERATION, SEND_WRITE and GET_WRITE are done at 15ms. Why not include the SEND_READ and GET_READ to SCHED_BLOCK_2. Later on during torqueing we also wait only 15ms and not 27ms.
Review

Some more buffer time to make sure the IMTQ can really do all the measurements before grabbing the data

Some more buffer time to make sure the IMTQ can really do all the measurements before grabbing the data
Review

Also, more time might be useful in debug build

Also, more time might be useful in debug build
static constexpr uint32_t SCHED_BLOCK_4_ACS_CTRL_MS = 45;
static constexpr uint32_t SCHED_BLOCK_5_ACTUATOR_MS = 50;
static constexpr uint32_t SCHED_BLOCK_6_IMTQ_BLOCK_2_MS = 65;
static constexpr uint32_t SCHED_BLOCK_6_IMTQ_BLOCK_2_MS = 75;
static constexpr uint32_t SCHED_BLOCK_7_RW_READ_MS = 300;
// 15 ms for FM

View File

@ -27,7 +27,7 @@ ReturnValue_t ImtqPollingTask::performOperation(uint8_t operationCode) {
comStatus = returnvalue::OK;
// Stopwatch watch;
switch (currentRequest) {
case imtq::RequestType::MEASURE_WITH_ACTUATION: {
case imtq::RequestType::MEASURE_NO_ACTUATION: {
handleMeasureStep();
break;
}
@ -45,7 +45,7 @@ void ImtqPollingTask::handleMeasureStep() {
uint8_t* replyPtr;
ImtqRepliesDefault replies(replyBuf.data());
// Can be used later to verify correct timing (e.g. all data has been read)
clearReadFlagsDefault(replies);
// clearReadFlagsDefault(replies);
auto i2cCmdExecMeasure = [&](imtq::CC::CC cc) {
ccToReplyPtrMeasure(replies, cc, &replyPtr, replyLen);
return i2cCmdExecDefault(cc, replyPtr, replyLen, imtq::MGM_MEASUREMENT_LOW_LEVEL_ERROR);
@ -134,6 +134,7 @@ void ImtqPollingTask::handleMeasureStep() {
if (i2cCmdExecMeasure(imtq::CC::GET_CAL_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
sif::debug << "measure done" << std::endl;
return;
}
@ -320,7 +321,7 @@ ReturnValue_t ImtqPollingTask::readReceivedMessage(CookieIF* cookie, uint8_t** b
size_t replyLen = 0;
MutexGuard mg(bufLock);
if (currentRequest == imtq::RequestType::MEASURE_WITH_ACTUATION) {
if (currentRequest == imtq::RequestType::MEASURE_NO_ACTUATION) {
replyLen = getExchangeBufLen(specialRequest);
memcpy(exchangeBuf.data(), replyBuf.data(), replyLen);
} else {

View File

@ -22,7 +22,7 @@ class ImtqPollingTask : public SystemObject,
static constexpr ReturnValue_t NO_REPLY_AVAILABLE = returnvalue::makeCode(2, 0);
enum class InternalState { IDLE, BUSY } state = InternalState::IDLE;
imtq::RequestType currentRequest = imtq::RequestType::MEASURE_WITH_ACTUATION;
imtq::RequestType currentRequest = imtq::RequestType::MEASURE_NO_ACTUATION;
SemaphoreIF* semaphore;
ReturnValue_t comStatus = returnvalue::OK;

View File

@ -4,6 +4,7 @@
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <mission/devices/devicedefinitions/imtqHelpers.h>
#include "OBSWConfig.h"
#include "eive/definitions.h"
@ -585,15 +586,15 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
if (cfg.scheduleImtq) {
// This is the MTM measurement cycle
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
DeviceHandlerIF::PERFORM_OPERATION);
imtq::ComStep::DHB_OP);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
DeviceHandlerIF::SEND_WRITE);
imtq::ComStep::START_MEASURE_SEND);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
DeviceHandlerIF::GET_WRITE);
imtq::ComStep::START_MEASURE_GET);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_3_PERIOD,
DeviceHandlerIF::SEND_READ);
imtq::ComStep::READ_MEASURE_SEND);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_3_PERIOD,
DeviceHandlerIF::GET_READ);
imtq::ComStep::READ_MEASURE_GET);
}
thisSequence->addSlot(objects::ACS_CONTROLLER, length * config::acs::SCHED_BLOCK_4_PERIOD, 0);
@ -601,15 +602,13 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
if (cfg.scheduleImtq) {
// This is the torquing cycle.
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_5_PERIOD,
DeviceHandlerIF::PERFORM_OPERATION);
imtq::ComStep::START_ACTUATE_SEND);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_5_PERIOD,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_5_PERIOD,
DeviceHandlerIF::GET_WRITE);
imtq::ComStep::START_ACTUATE_GET);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_6_PERIOD,
DeviceHandlerIF::SEND_READ);
imtq::ComStep::READ_ACTUATE_SEND);
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_6_PERIOD,
DeviceHandlerIF::GET_READ);
imtq::ComStep::READ_ACTUATE_GET);
}
if (cfg.scheduleRws) {

View File

@ -51,6 +51,60 @@ ImtqHandler::ImtqHandler(object_id_t objectId, object_id_t comIF, CookieIF* comC
}
}
ReturnValue_t ImtqHandler::performOperation(uint8_t opCode) {
uint8_t dhbOpCode = DeviceHandlerIF::PERFORM_OPERATION;
switch (static_cast<imtq::ComStep>(opCode)) {
case (imtq::ComStep::DHB_OP): {
break;
}
case (imtq::ComStep::START_MEASURE_SEND): {
requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
dhbOpCode = DeviceHandlerIF::SEND_WRITE;
break;
}
case (imtq::ComStep::START_MEASURE_GET): {
requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
dhbOpCode = DeviceHandlerIF::GET_WRITE;
break;
}
case (imtq::ComStep::READ_MEASURE_SEND): {
requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
dhbOpCode = DeviceHandlerIF::SEND_READ;
break;
}
case (imtq::ComStep::READ_MEASURE_GET): {
requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
dhbOpCode = DeviceHandlerIF::GET_READ;
break;
}
case (imtq::ComStep::START_ACTUATE_SEND): {
requestStep = imtq::RequestType::ACTUATE;
dhbOpCode = DeviceHandlerIF::SEND_WRITE;
break;
}
case (imtq::ComStep::START_ACTUATE_GET): {
requestStep = imtq::RequestType::ACTUATE;
dhbOpCode = DeviceHandlerIF::GET_WRITE;
break;
}
case (imtq::ComStep::READ_ACTUATE_SEND): {
requestStep = imtq::RequestType::ACTUATE;
dhbOpCode = DeviceHandlerIF::SEND_READ;
break;
}
case (imtq::ComStep::READ_ACTUATE_GET): {
requestStep = imtq::RequestType::ACTUATE;
dhbOpCode = DeviceHandlerIF::GET_READ;
break;
}
default: {
sif::error << "ImtqHandler: Unexpected COM step" << std::endl;
break;
}
}
return DeviceHandlerBase::performOperation(dhbOpCode);
}
ImtqHandler::~ImtqHandler() = default;
void ImtqHandler::doStartUp() {
@ -71,7 +125,7 @@ void ImtqHandler::doShutDown() {
ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
switch (requestStep) {
case (imtq::RequestType::MEASURE_WITH_ACTUATION): {
case (imtq::RequestType::MEASURE_NO_ACTUATION): {
*id = imtq::cmdIds::REQUEST;
return buildCommandFromCommand(*id, nullptr, 0);
}
@ -90,7 +144,7 @@ ReturnValue_t ImtqHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
auto genericMeasureRequest = [&](imtq::SpecialRequest specialRequest) {
auto genericSpecialRequest = [&](imtq::SpecialRequest specialRequest, ) {
ImtqRequest request(commandBuffer, sizeof(commandBuffer));
request.setMeasureRequest(specialRequest);
specialRequestActive = true;
@ -99,35 +153,38 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
};
switch (deviceCommand) {
case (imtq::cmdIds::POS_X_SELF_TEST): {
genericMeasureRequest(imtq::SpecialRequest::DO_SELF_TEST_POS_X);
genericSpecialRequest(imtq::SpecialRequest::DO_SELF_TEST_POS_X);
return returnvalue::OK;
}
case (imtq::cmdIds::NEG_X_SELF_TEST): {
genericMeasureRequest(imtq::SpecialRequest::DO_SELF_TEST_NEG_X);
genericSpecialRequest(imtq::SpecialRequest::DO_SELF_TEST_NEG_X);
return returnvalue::OK;
}
case (imtq::cmdIds::POS_Y_SELF_TEST): {
genericMeasureRequest(imtq::SpecialRequest::DO_SELF_TEST_POS_Y);
genericSpecialRequest(imtq::SpecialRequest::DO_SELF_TEST_POS_Y);
return returnvalue::OK;
}
case (imtq::cmdIds::NEG_Y_SELF_TEST): {
genericMeasureRequest(imtq::SpecialRequest::DO_SELF_TEST_NEG_Y);
genericSpecialRequest(imtq::SpecialRequest::DO_SELF_TEST_NEG_Y);
return returnvalue::OK;
}
case (imtq::cmdIds::POS_Z_SELF_TEST): {
genericMeasureRequest(imtq::SpecialRequest::DO_SELF_TEST_POS_Z);
genericSpecialRequest(imtq::SpecialRequest::DO_SELF_TEST_POS_Z);
return returnvalue::OK;
}
case (imtq::cmdIds::NEG_Z_SELF_TEST): {
genericMeasureRequest(imtq::SpecialRequest::DO_SELF_TEST_NEG_Z);
genericSpecialRequest(imtq::SpecialRequest::DO_SELF_TEST_NEG_Z);
return returnvalue::OK;
}
case (imtq::cmdIds::GET_SELF_TEST_RESULT): {
genericMeasureRequest(imtq::SpecialRequest::GET_SELF_TEST_RESULT);
genericSpecialRequest(imtq::SpecialRequest::GET_SELF_TEST_RESULT);
return returnvalue::OK;
}
case (imtq::cmdIds::REQUEST): {
genericMeasureRequest(imtq::SpecialRequest::NONE);
ImtqRequest request(commandBuffer, sizeof(commandBuffer));
request.setMeasureRequest(imtq::SpecialRequest::NONE);
rawPacket = commandBuffer;
rawPacketLen = ImtqRequest::REQUEST_LEN;
return returnvalue::OK;
}
case (imtq::cmdIds::START_ACTUATION_DIPOLE): {
@ -200,8 +257,9 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
ReturnValue_t result;
ReturnValue_t status = returnvalue::OK;
// arrayprinter::print(packet, ImtqReplies::BASE_LEN);
if (requestStep == imtq::RequestType::MEASURE_WITH_ACTUATION) {
if (requestStep == imtq::RequestType::MEASURE_NO_ACTUATION) {
requestStep = imtq::RequestType::ACTUATE;
sif::debug << "handle measure" << std::endl;
ImtqRepliesDefault replies(packet);
if (specialRequestActive) {
if (replies.wasSpecialRequestRead()) {
@ -266,7 +324,7 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
status = result;
}
} else {
requestStep = imtq::RequestType::MEASURE_WITH_ACTUATION;
requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
ImtqRepliesWithTorque replies(packet);
if (replies.wasDipoleActuationRead()) {
parseStatusByte(imtq::CC::START_ACTUATION_DIPOLE, replies.getDipoleActuation());

View File

@ -31,6 +31,7 @@ class ImtqHandler : public DeviceHandlerBase {
void setDebugMode(bool enable);
protected:
ReturnValue_t performOperation(uint8_t opCode);
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
@ -118,7 +119,7 @@ class ImtqHandler : public DeviceHandlerBase {
bool specialRequestActive = false;
bool firstReplyCycle = true;
imtq::RequestType requestStep = imtq::RequestType::MEASURE_WITH_ACTUATION;
imtq::RequestType requestStep = imtq::RequestType::MEASURE_NO_ACTUATION;
/**
* @brief In case of a status reply to a single axis self test command, this function

View File

@ -10,7 +10,19 @@ class ImtqHandler;
namespace imtq {
enum class RequestType : uint8_t { MEASURE_WITH_ACTUATION, ACTUATE };
enum ComStep : uint8_t {
DHB_OP = 0,
START_MEASURE_SEND = 1,
START_MEASURE_GET = 2,
READ_MEASURE_SEND = 3,
READ_MEASURE_GET = 4,
START_ACTUATE_SEND = 5,
START_ACTUATE_GET = 6,
READ_ACTUATE_SEND = 7,
READ_ACTUATE_GET = 8,
};
enum class RequestType : uint8_t { MEASURE_NO_ACTUATION, ACTUATE };
enum class SpecialRequest : uint8_t {
NONE = 0,
@ -1098,7 +1110,7 @@ struct ImtqRequest {
imtq::RequestType getRequestType() const { return static_cast<imtq::RequestType>(rawData[0]); }
void setMeasureRequest(imtq::SpecialRequest specialRequest) {
rawData[0] = static_cast<uint8_t>(imtq::RequestType::MEASURE_WITH_ACTUATION);
rawData[0] = static_cast<uint8_t>(imtq::RequestType::MEASURE_NO_ACTUATION);
rawData[1] = static_cast<uint8_t>(specialRequest);
}
@ -1141,7 +1153,7 @@ struct ImtqRequest {
private:
ImtqRequest(uint8_t* rawData, size_t maxLen) : rawData(rawData) {
if (rawData != nullptr) {
rawData[0] = static_cast<uint8_t>(imtq::RequestType::MEASURE_WITH_ACTUATION);
rawData[0] = static_cast<uint8_t>(imtq::RequestType::MEASURE_NO_ACTUATION);
}
}
uint8_t* rawData;

View File

@ -53,9 +53,10 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) {
#endif
return result;
}
size_t serSize = 0;
result =
spacePacketHeader.serializeBe(&newPacketData, &serSize, spacePacketHeader.getFullPacketLen());
size_t packetLen = 0;
uint8_t* serPtr = newPacketData;
result = spacePacketHeader.serializeBe(&serPtr, &packetLen, spacePacketHeader.getFullPacketLen());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CfdpTmFunnel::handlePacket: Error serializing packet" << std::endl;
@ -79,8 +80,15 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) {
msg.setStorageId(storeId);
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
<<<<<<< Updated upstream
sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy"
<< std::endl;
=======
sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy or store "
"error"
<< std::endl;
break;
>>>>>>> Stashed changes
#endif
}
} else {