Merge remote-tracking branch 'origin/development' into mueller/pus-c-support

This commit is contained in:
Robin Müller 2021-04-29 20:24:37 +02:00
commit 6ede3f9ba2
6 changed files with 79 additions and 24 deletions

View File

@ -24,6 +24,13 @@
* 1. check logic when active-> checkChildrenStateOn * 1. check logic when active-> checkChildrenStateOn
* 2. transition logic to change the mode -> commandChildren * 2. transition logic to change the mode -> commandChildren
* *
* Important:
*
* The implementation must call registerChild(object_id_t child)
* for all commanded children during initialization.
* The implementation must call the initialization function of the base class.
* (This will call the function in SubsystemBase)
*
*/ */
class AssemblyBase: public SubsystemBase { class AssemblyBase: public SubsystemBase {
public: public:
@ -41,9 +48,6 @@ public:
virtual ~AssemblyBase(); virtual ~AssemblyBase();
protected: protected:
// SHOULDDO: Change that OVERWRITE_HEALTH may be returned
// (or return internalState directly?)
/** /**
* Command children to reach [mode,submode] combination * Command children to reach [mode,submode] combination
* Can be done by setting #commandsOutstanding correctly, * Can be done by setting #commandsOutstanding correctly,
@ -68,6 +72,18 @@ protected:
virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
Submode_t wantedSubmode) = 0; Submode_t wantedSubmode) = 0;
/**
* Check whether a combination of mode and submode is valid.
*
* Ground Controller like precise return values from HasModesIF.
* So, please return any of them.
*
* @param mode The targeted mode
* @param submode The targeted submmode
* @return Any information why this combination is invalid from HasModesIF
* like HasModesIF::INVALID_SUBMODE.
* On success return HasReturnvaluesIF::RETURN_OK
*/
virtual ReturnValue_t isModeCombinationValid(Mode_t mode, virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
Submode_t submode) = 0; Submode_t submode) = 0;

View File

@ -308,6 +308,14 @@ void DeviceHandlerBase::doStateMachine() {
uint32_t currentUptime; uint32_t currentUptime;
Clock::getUptime(&currentUptime); Clock::getUptime(&currentUptime);
if (currentUptime - timeoutStart >= childTransitionDelay) { if (currentUptime - timeoutStart >= childTransitionDelay) {
#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0
char printout[60];
sprintf(printout, "Transition timeout (%lu) occured !",
static_cast<unsigned long>(childTransitionDelay));
/* Common configuration error for development, so print it */
printWarningOrError(sif::OutputTypes::OUT_WARNING, "doStateMachine",
RETURN_FAILED, printout);
#endif
triggerEvent(MODE_TRANSITION_FAILED, childTransitionFailure, 0); triggerEvent(MODE_TRANSITION_FAILED, childTransitionFailure, 0);
setMode(transitionSourceMode, transitionSourceSubMode); setMode(transitionSourceMode, transitionSourceSubMode);
break; break;
@ -448,6 +456,15 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm
} }
} }
size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId){
DeviceReplyIter iter = deviceReplyMap.find(commandId);
if(iter != deviceReplyMap.end()) {
return iter->second.replyLen;
}else{
return 0;
}
}
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) {
auto replyIter = deviceReplyMap.find(deviceReply); auto replyIter = deviceReplyMap.find(deviceReply);
@ -638,16 +655,12 @@ void DeviceHandlerBase::doGetWrite() {
void DeviceHandlerBase::doSendRead() { void DeviceHandlerBase::doSendRead() {
ReturnValue_t result; ReturnValue_t result;
size_t requestLen = 0; size_t replyLen = 0;
if(cookieInfo.pendingCommand != deviceCommandMap.end()) { if(cookieInfo.pendingCommand != deviceCommandMap.end()) {
DeviceReplyIter iter = deviceReplyMap.find( replyLen = getNextReplyLength(cookieInfo.pendingCommand->first);
cookieInfo.pendingCommand->first);
if(iter != deviceReplyMap.end()) {
requestLen = iter->second.replyLen;
}
} }
result = communicationInterface->requestReceiveMessage(comCookie, requestLen); result = communicationInterface->requestReceiveMessage(comCookie, replyLen);
if (result == RETURN_OK) { if (result == RETURN_OK) {
cookieInfo.state = COOKIE_READ_SENT; cookieInfo.state = COOKIE_READ_SENT;
@ -1501,10 +1514,9 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
if(errorType == sif::OutputTypes::OUT_WARNING) { if(errorType == sif::OutputTypes::OUT_WARNING) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID " sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID 0x" << std::hex <<
<< std::hex << std::setw(8) << std::setfill('0') std::setw(8) << std::setfill('0') << this->getObjectId() << " | " << errorPrint <<
<< this->getObjectId() << " | " << errorPrint << std::dec std::dec << std::setfill(' ') << std::endl;
<< std::setfill(' ') << std::endl;
#else #else
sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
functionName, this->getObjectId(), errorPrint); functionName, this->getObjectId(), errorPrint);
@ -1512,7 +1524,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
} }
else if(errorType == sif::OutputTypes::OUT_ERROR) { else if(errorType == sif::OutputTypes::OUT_ERROR) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "DeviceHandlerBase::" << functionName << ": Object ID " sif::error << "DeviceHandlerBase::" << functionName << ": Object ID 0x"
<< std::hex << std::setw(8) << std::setfill('0') << std::hex << std::setw(8) << std::setfill('0')
<< this->getObjectId() << " | " << errorPrint << std::dec << this->getObjectId() << " | " << errorPrint << std::dec
<< std::setfill(' ') << std::endl; << std::setfill(' ') << std::endl;

View File

@ -471,13 +471,27 @@ protected:
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand,
uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr,
size_t replyLen = 0, bool periodic = false); size_t replyLen = 0, bool periodic = false);
/** /**
* @brief A simple command to add a command to the commandList. * @brief A simple command to add a command to the commandList.
* @param deviceCommand The command to add * @param deviceCommand The command to add
* @return - @c RETURN_OK when the command was successfully inserted, * @return - @c RETURN_OK when the command was successfully inserted,
* - @c RETURN_FAILED else. * - @c RETURN_FAILED else.
*/ */
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand);
/**
* @brief This function returns the reply length of the next reply to read.
*
* @param deviceCommand The command which triggered the device reply.
*
* @details The default implementation assumes only one reply is triggered by the command. In
* case the command triggers multiple replies (e.g. one acknowledgment, one data,
* and one execution status reply), this function can be overwritten to get the
* reply length of the next reply to read.
*/
virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand);
/** /**
* @brief This is a helper method to facilitate updating entries * @brief This is a helper method to facilitate updating entries
* in the reply map. * in the reply map.
@ -953,7 +967,7 @@ protected:
* - NO_REPLY_EXPECTED if there was no reply found. This is not an * - NO_REPLY_EXPECTED if there was no reply found. This is not an
* error case as many commands do not expect a reply. * error case as many commands do not expect a reply.
*/ */
virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator cmd, virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command,
uint8_t expectedReplies = 1, bool useAlternateId = false, uint8_t expectedReplies = 1, bool useAlternateId = false,
DeviceCommandId_t alternateReplyID = 0); DeviceCommandId_t alternateReplyID = 0);

View File

@ -65,6 +65,9 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) {
ParameterWrapper ownerWrapper; ParameterWrapper ownerWrapper;
result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper,
&streamWrapper, linearIndex); &streamWrapper, linearIndex);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); result = ownerWrapper.copyFrom(&streamWrapper, linearIndex);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -5,8 +5,7 @@
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent,
Mode_t initialMode, uint16_t commandQueueDepth) : Mode_t initialMode, uint16_t commandQueueDepth) :
SystemObject(setObjectId), mode(initialMode), submode(SUBMODE_NONE), SystemObject(setObjectId), mode(initialMode),
childrenChangedMode(false),
commandQueue(QueueFactory::instance()->createMessageQueue( commandQueue(QueueFactory::instance()->createMessageQueue(
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE)), commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE)),
healthHelper(this, setObjectId), modeHelper(this), parentId(parent) { healthHelper(this, setObjectId), modeHelper(this), parentId(parent) {
@ -167,16 +166,16 @@ MessageQueueId_t SubsystemBase::getCommandQueue() const {
} }
ReturnValue_t SubsystemBase::initialize() { ReturnValue_t SubsystemBase::initialize() {
MessageQueueId_t parentQueue = 0; MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE;
ReturnValue_t result = SystemObject::initialize(); ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
if (parentId != 0) { if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId); SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
if (parent == NULL) { if (parent == nullptr) {
return RETURN_FAILED; return RETURN_FAILED;
} }
parentQueue = parent->getCommandQueue(); parentQueue = parent->getCommandQueue();

View File

@ -37,6 +37,17 @@ public:
virtual MessageQueueId_t getCommandQueue() const override; virtual MessageQueueId_t getCommandQueue() const override;
/**
* Function to register the child objects.
* Performs a checks if the child does implement HasHealthIF and/or HasModesIF
*
* Also adds them to the internal childrenMap.
*
* @param objectId
* @return RETURN_OK if successful
* CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
*/
ReturnValue_t registerChild(object_id_t objectId); ReturnValue_t registerChild(object_id_t objectId);
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
@ -56,9 +67,9 @@ protected:
Mode_t mode; Mode_t mode;
Submode_t submode; Submode_t submode = SUBMODE_NONE;
bool childrenChangedMode; bool childrenChangedMode = false;
/** /**
* Always check this against <=0, so you are robust against too many replies * Always check this against <=0, so you are robust against too many replies