Compare commits

..

13 Commits

Author SHA1 Message Date
1da7f7f122 Merge pull request 'Added STOP_DOWNLINK_STORE_CONTENT for Service [15,17]' (#58) from hoffmann/TmStoreMessage into main
Reviewed-on: #58
2025-04-21 19:21:40 +02:00
Philipp Hoffmann
aa443e6aa6 Added STOP_DOWNLINK_STORE_CONTENT for Service [15,17] 2025-04-21 17:05:58 +02:00
7ae58f8125 Merge pull request 'Send HK One Parameter Report back to Sender' (#56) from meier/hk-report-reply-queue into main
Reviewed-on: #56
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2025-04-02 14:04:46 +02:00
7784a26a10 Merge branch 'main' into meier/hk-report-reply-queue 2025-04-02 14:04:37 +02:00
Jakob Meier
3afd0c8d3c updated changelog 2025-04-01 17:25:02 +02:00
Jakob Meier
71623d5314 Merge commit 'f01e58a7' into meier/hk-report-reply-queue 2025-04-01 14:18:07 +02:00
daac5ea727 Merge pull request 'spahr/handleRecoveryEvents' (#54) from spahr/handleRecoveryEvents into main
Reviewed-on: #54
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2025-04-01 14:07:10 +02:00
2c01b83b75 Merge branch 'main' into spahr/handleRecoveryEvents 2025-04-01 14:06:36 +02:00
Jakob Meier
2af6e85f87 send hk report back to sender instead of default destination 2025-03-23 12:35:40 +01:00
spahr@ksat-stuttgart.de
d8ac312e85 remove event because it's no longer needed. 2025-03-22 10:01:01 +01:00
spahr@ksat-stuttgart.de
1e12753533 add device object id to event 2025-03-22 09:49:44 +01:00
spahr@ksat-stuttgart.de
b7699b327b add two new events for the recovery process, to make debug and output more clear. This also makes a recovery process more clear for OPS. 2025-03-22 09:48:30 +01:00
spahr@ksat-stuttgart.de
9945f72eaf improve documentation for event 2025-03-22 09:40:31 +01:00
12 changed files with 28 additions and 57 deletions

View File

@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Changed ## Changed
- send HK one-parameter-report back to sender instead of default hk queue
- Complete overhaul of HK subsystem. Replaced local data pool manager by periodic HK - Complete overhaul of HK subsystem. Replaced local data pool manager by periodic HK
helper. The shared pool and the periodic HK generation are now distinct concepts. helper. The shared pool and the periodic HK generation are now distinct concepts.
- The local HK manager was replaced by a periodic HK helper which has reduced responsibilities. - The local HK manager was replaced by a periodic HK helper which has reduced responsibilities.

View File

@ -235,14 +235,14 @@ bool AssemblyBase::checkAndHandleRecovery() {
if (recoveryOffTimer.isBusy()) { if (recoveryOffTimer.isBusy()) {
return true; return true;
} }
triggerEvent(RECOVERY_STEP, 0); triggerEvent(RECOVERY_WAITING, recoveringDevice->first);
sendHealthCommand(recoveringDevice->second.commandQueue, HEALTHY); sendHealthCommand(recoveringDevice->second.commandQueue, HEALTHY);
internalState = STATE_NONE; internalState = STATE_NONE;
recoveryState = RECOVERY_ONGOING; recoveryState = RECOVERY_ONGOING;
// Don't check state! // Don't check state!
return true; return true;
case RECOVERY_ONGOING: case RECOVERY_ONGOING:
triggerEvent(RECOVERY_STEP, 1); triggerEvent(RECOVERY_RESTARTING, recoveringDevice->first);
recoveryState = RECOVERY_ONGOING_2; recoveryState = RECOVERY_ONGOING_2;
recoveringDevice->second.healthChanged = false; recoveringDevice->second.healthChanged = false;
// Device should be healthy again, so restart a transition. // Device should be healthy again, so restart a transition.
@ -250,7 +250,7 @@ bool AssemblyBase::checkAndHandleRecovery() {
doStartTransition(targetMode, targetSubmode); doStartTransition(targetMode, targetSubmode);
return true; return true;
case RECOVERY_ONGOING_2: case RECOVERY_ONGOING_2:
triggerEvent(RECOVERY_DONE); triggerEvent(RECOVERY_DONE, recoveringDevice->first);
// Now we're through, but not sure if it was successful. // Now we're through, but not sure if it was successful.
recoveryState = RECOVERY_IDLE; recoveryState = RECOVERY_IDLE;
return false; return false;

View File

@ -191,5 +191,3 @@ ReturnValue_t FreshDeviceHandlerBase::getParameter(uint8_t domainId, uint8_t uni
} }
datapool::SharedPool* FreshDeviceHandlerBase::getOptionalSharedPool() { return nullptr; } datapool::SharedPool* FreshDeviceHandlerBase::getOptionalSharedPool() { return nullptr; }
ModeHelper& FreshDeviceHandlerBase::getModeHelper() { return this->modeHelper; }

View File

@ -97,11 +97,6 @@ class FreshDeviceHandlerBase : public SystemObject,
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
ModeTreeChildIF& getModeTreeChildIF() override; ModeTreeChildIF& getModeTreeChildIF() override;
/**
* @brief Return an interface to the ModeHelper.
*/
ModeHelper& getModeHelper();
protected: protected:
ActionHelper actionHelper; ActionHelper actionHelper;
ModeHelper modeHelper; ModeHelper modeHelper;

View File

@ -27,13 +27,19 @@ class HasHealthIF {
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW); static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
//! Assembly overwrites health information of children to keep satellite alive. //! Assembly overwrites health information of children to keep satellite alive.
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW); static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
//! Someone starts a recovery of a component (typically power-cycle). No parameters. //! Someone starts a recovery of a component (typically power-cycle).
//! P1: Object Id of the recovering device.
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM); static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
//! Recovery is ongoing. Comes twice during recovery.
//! P1: 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
//! Recovery was completed. Not necessarily successful. No parameters. //! Recovery was completed. Not necessarily successful. No parameters.
//! P1: Object Id of the recovering device.
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM); static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
//! Recovery is ongoing. The recovering device is currently OFF, waiting for restart.
//! P1: Object Id of the recovering device.
static const Event RECOVERY_WAITING = MAKE_EVENT(13, severity::MEDIUM);
//! Recovery is ongoing. Restarting the recovering device.
//! P1: Object Id of the recovering device.
static const Event RECOVERY_RESTARTING = MAKE_EVENT(14, severity::MEDIUM);
virtual ~HasHealthIF() {} virtual ~HasHealthIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@ -9,7 +9,6 @@
#include "fsfw/housekeeping/HousekeepingSnapshot.h" #include "fsfw/housekeeping/HousekeepingSnapshot.h"
#include "fsfw/ipc/QueueFactory.h" #include "fsfw/ipc/QueueFactory.h"
#include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/timemanager/CCSDSTime.h"
using namespace hk; using namespace hk;
@ -84,6 +83,7 @@ ReturnValue_t PeriodicHelper::performHkOperation() {
ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message) { ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message) {
Command_t command = message->getCommand(); Command_t command = message->getCommand();
MessageQueueId_t sender = message->getSender();
dp::sid_t sid = HousekeepingMessage::getStructureId(message); dp::sid_t sid = HousekeepingMessage::getStructureId(message);
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
switch (command) { switch (command) {
@ -113,7 +113,7 @@ ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message)
} }
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): { case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
return generateHousekeepingPacket(HousekeepingMessage::getStructureId(message)); return generateHousekeepingPacket(HousekeepingMessage::getStructureId(message), sender);
} }
default: default:

View File

@ -35,12 +35,8 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) {
commandedMode = mode; commandedMode = mode;
commandedSubmode = submode; commandedSubmode = submode;
// if (((parentQueueId != MessageQueueIF::NO_QUEUE) && if ((parentQueueId != MessageQueueIF::NO_QUEUE) &&
// (theOneWhoCommandedAMode != parentQueueId))) { (theOneWhoCommandedAMode != parentQueueId)) {
// owner->setToExternalControl();
// }
if(theOneWhoCommandedAMode != parentQueueId and theOneWhoCommandedAMode != powerswitchQueueId) {
owner->setToExternalControl(); owner->setToExternalControl();
} }
@ -110,7 +106,3 @@ bool ModeHelper::isTimedOut() { return countdown.hasTimedOut(); }
bool ModeHelper::isForced() { return forced; } bool ModeHelper::isForced() { return forced; }
void ModeHelper::setForced(bool forced) { this->forced = forced; } void ModeHelper::setForced(bool forced) { this->forced = forced; }
void ModeHelper::setPowerSwitchQueueId(MessageQueueId_t queueId) {
powerswitchQueueId = queueId;
}

View File

@ -21,15 +21,10 @@ class ModeHelper {
/** /**
* @param parentQueue the Queue id of the parent object. * @param parentQueue the Queue id of the parent object.
* Set to MessageQueueIF::NO_QUEUE if no parent present * Set to 0 if no parent present
*/ */
void setParentQueue(MessageQueueId_t parentQueueId); void setParentQueue(MessageQueueId_t parentQueueId);
/**
* Set to MessageQueue::NO_QUEUE if no powerswitch is commanding the obejct.
*/
void setPowerSwitchQueueId(MessageQueueId_t queueId);
ReturnValue_t initialize(MessageQueueId_t parentQueueId); ReturnValue_t initialize(MessageQueueId_t parentQueueId);
ReturnValue_t initialize(void); ReturnValue_t initialize(void);
@ -47,7 +42,6 @@ class ModeHelper {
protected: protected:
HasModesIF *owner; HasModesIF *owner;
MessageQueueId_t parentQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t parentQueueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t powerswitchQueueId = MessageQueueIF::NO_QUEUE;
Countdown countdown; Countdown countdown;

View File

@ -64,11 +64,6 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
for (; tableIter.value != nullptr; ++tableIter) { for (; tableIter.value != nullptr; ++tableIter) {
object_id_t object = tableIter.value->getObject(); object_id_t object = tableIter.value->getObject();
// As default, the objectId in the commandTable is the same as the one in the childrenMap.
// The user has to specify otherwise if required.
object = commandObjectIdToChildrenMapObjectId(object);
if ((iter = childrenMap.find(object)) == childrenMap.end()) { if ((iter = childrenMap.find(object)) == childrenMap.end()) {
// illegal table entry, should only happen due to misconfigured mode table // illegal table entry, should only happen due to misconfigured mode table
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
@ -124,11 +119,7 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
continue; // don't send redundant mode commands (produces event spam), but still command if continue; // don't send redundant mode commands (produces event spam), but still command if
// mode is forced to reach lower levels // mode is forced to reach lower levels
} }
ReturnValue_t result = commandQueue->sendMessage(iter->second.commandQueue, &command);
// Get the messageQueueId if the receiver specified by the commandTable.
// This the same MessageQueueId as stored in the childrenMap if the commanded object is part of the childrenMap.
MessageQueueId_t commandedReceiver = ObjectManager::instance()->get<HasHealthIF>(tableIter->getObject())->getCommandQueue();
ReturnValue_t result = commandQueue->sendMessage(commandedReceiver, &command);
if (result == returnvalue::OK) { if (result == returnvalue::OK) {
++commandsOutstanding; ++commandsOutstanding;
} }
@ -362,7 +353,3 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t childObjectId, MessageQue
} }
return returnvalue::OK; return returnvalue::OK;
} }
object_id_t SubsystemBase::commandObjectIdToChildrenMapObjectId(object_id_t commandId) {
return commandId;
}

View File

@ -153,15 +153,6 @@ class SubsystemBase : public SystemObject,
virtual void announceMode(bool recursive) override; virtual void announceMode(bool recursive) override;
virtual void modeChanged(); virtual void modeChanged();
/**
* @brief This converts the objectId of the object we want to send a mode command to into the
* objectId of the corresponding object in the childrenMap for the current mode command.
* As default implementation, this is the same objectId, and this functions returns it's input value
*
* It is up to the user to specify otherwise.
*/
virtual object_id_t commandObjectIdToChildrenMapObjectId(object_id_t commandId);
}; };
#endif /* FSFW_SUBSYSTEM_SUBSYSTEMBASE_H_ */ #endif /* FSFW_SUBSYSTEM_SUBSYSTEMBASE_H_ */

View File

@ -114,6 +114,11 @@ void TmStoreMessage::setDownlinkContentTimeMessage(CommandMessage* cmd, store_ad
cmd->setParameter2(storeId.raw); cmd->setParameter2(storeId.raw);
} }
void TmStoreMessage::setStopDownlinkContentMessage(CommandMessage* cmd, store_address_t storeId) {
cmd->setCommand(STOP_DOWNLINK_STORE_CONTENT);
cmd->setParameter2(storeId.raw);
}
uint32_t TmStoreMessage::getAddressLow(CommandMessage* cmd) { return cmd->getParameter(); } uint32_t TmStoreMessage::getAddressLow(CommandMessage* cmd) { return cmd->getParameter(); }
uint32_t TmStoreMessage::getAddressHigh(CommandMessage* cmd) { return cmd->getParameter2(); } uint32_t TmStoreMessage::getAddressHigh(CommandMessage* cmd) { return cmd->getParameter2(); }

View File

@ -21,6 +21,7 @@ class TmStoreMessage {
static void setStoreCatalogueReportMessage(CommandMessage* cmd, object_id_t objectId, static void setStoreCatalogueReportMessage(CommandMessage* cmd, object_id_t objectId,
store_address_t storeId); store_address_t storeId);
static void setDownlinkContentTimeMessage(CommandMessage* cmd, store_address_t storeId); static void setDownlinkContentTimeMessage(CommandMessage* cmd, store_address_t storeId);
static void setStopDownlinkContentMessage(CommandMessage* cmd, store_address_t storeId);
static void setIndexReportMessage(CommandMessage* cmd, store_address_t storeId); static void setIndexReportMessage(CommandMessage* cmd, store_address_t storeId);
static ReturnValue_t setDeleteBlocksMessage(CommandMessage* cmd, uint32_t addressLow, static ReturnValue_t setDeleteBlocksMessage(CommandMessage* cmd, uint32_t addressLow,
uint32_t addressHigh); uint32_t addressHigh);
@ -54,6 +55,7 @@ class TmStoreMessage {
static const Command_t DOWNLINK_STORE_CONTENT_BLOCKS = MAKE_COMMAND_ID(12); static const Command_t DOWNLINK_STORE_CONTENT_BLOCKS = MAKE_COMMAND_ID(12);
static const Command_t REPORT_INDEX_REQUEST = MAKE_COMMAND_ID(13); static const Command_t REPORT_INDEX_REQUEST = MAKE_COMMAND_ID(13);
static const Command_t INDEX_REPORT = MAKE_COMMAND_ID(14); static const Command_t INDEX_REPORT = MAKE_COMMAND_ID(14);
static const Command_t STOP_DOWNLINK_STORE_CONTENT = MAKE_COMMAND_ID(15);
private: private:
TmStoreMessage(); TmStoreMessage();