diff --git a/CHANGELOG b/CHANGELOG index ed73248d..465f57e4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -## Changes from ASTP 0.0.1 to 0.0.2 +## Changes from ASTP 0.0.1 to 1.0.0 ### FreeRTOS OSAL @@ -6,6 +6,10 @@ - vRequestContextSwitchFromISR is declared extern "C" so it can be defined in a C file without issues +### PUS Services + +- PUS Health Service added, which allows to command and retrieve health via PUS packets + ### EnhancedControllerBase - New base class for a controller which also implements HasActionsIF and HasLocalDataPoolIF diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index be3717b4..1386bf66 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -1,7 +1,6 @@ #ifndef CONFIG_FSFWCONFIG_H_ #define CONFIG_FSFWCONFIG_H_ -#include #include #include @@ -9,12 +8,12 @@ //! Those can lead to code bloat. #define FSFW_CPP_OSTREAM_ENABLED 1 -//! Reduced printout to further decrese code size +//! Reduced printout to further decrease code size //! Be careful, this also turns off most diagnostic prinouts! -#define FSFW_REDUCED_PRINTOUT 0 +#define FSFW_ENHANCED_PRINTOUT 0 -//! Can be used to enable debugging printouts for developing the FSFW -#define FSFW_DEBUGGING 0 +//! Can be used to enable additional debugging printouts for developing the FSFW +#define FSFW_PRINT_VERBOSITY_LEVEL 0 //! Defines the FIFO depth of each commanding service base which //! also determines how many commands a CSB service can handle in one cycle @@ -39,7 +38,10 @@ //! When using the newlib nano library, C99 support for stdio facilities //! will not be provided. This define should be set to 1 if this is the case. -#define FSFW_NO_C99_IO 1 +#define FSFW_NO_C99_IO 1 + +//! Specify whether a special mode store is used for Subsystem components. +#define FSFW_USE_MODESTORE 0 namespace fsfwconfig { //! Default timestamp size. The default timestamp will be an eight byte CDC diff --git a/pus/CService201HealthCommanding.cpp b/pus/CService201HealthCommanding.cpp new file mode 100644 index 00000000..edacd73a --- /dev/null +++ b/pus/CService201HealthCommanding.cpp @@ -0,0 +1,106 @@ +#include "CService201HealthCommanding.h" + +#include "../health/HasHealthIF.h" +#include "../serviceinterface/ServiceInterfaceStream.h" +#include "../health/HealthMessage.h" +#include "servicepackets/Service201Packets.h" + +CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, + uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands, + uint16_t commandTimeoutSeconds): + CommandingServiceBase(objectId, apid, serviceId, + numParallelCommands, commandTimeoutSeconds) { +} + +CService201HealthCommanding::~CService201HealthCommanding() { +} + +ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) { + switch(subservice) { + case(Subservice::COMMAND_SET_HEALTH): + case(Subservice::COMMAND_ANNOUNCE_HEALTH): + case(Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): + return RETURN_OK; + default: + sif::error << "Invalid Subservice" << std::endl; + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + +ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject( + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + MessageQueueId_t *id, object_id_t *objectId) { + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + + return checkInterfaceAndAcquireMessageQueue(id,objectId); +} + +ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { + HasHealthIF * destination = objectManager->get(*objectId); + if(destination == nullptr) { + return CommandingServiceBase::INVALID_OBJECT; + } + + *messageQueueToSet = destination->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CService201HealthCommanding::prepareCommand( + CommandMessage* message, uint8_t subservice, const uint8_t *tcData, + size_t tcDataLen, uint32_t *state, object_id_t objectId) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + switch(subservice) { + case(Subservice::COMMAND_SET_HEALTH): { + HealthSetCommand healthCommand; + result = healthCommand.deSerialize(&tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + break; + } + HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET, + healthCommand.getHealth()); + break; + } + case(Subservice::COMMAND_ANNOUNCE_HEALTH): { + HealthMessage::setHealthMessage(message, + HealthMessage::HEALTH_ANNOUNCE); + break; + } + case(Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): { + HealthMessage::setHealthMessage(message, + HealthMessage::HEALTH_ANNOUNCE_ALL); + break; + } + } + return result; +} + +ReturnValue_t CService201HealthCommanding::handleReply + (const CommandMessage* reply, Command_t previousCommand, + uint32_t *state, CommandMessage* optionalNextCommand, + object_id_t objectId, bool *isStep) { + Command_t replyId = reply->getCommand(); + if (replyId == HealthMessage::REPLY_HEALTH_SET) { + return EXECUTION_COMPLETE; + } + else if(replyId == CommandMessageIF::REPLY_REJECTED) { + return reply->getReplyRejectedReason(); + } + return CommandingServiceBase::INVALID_REPLY; +} + +// Not used for now, health state already reported by event +ReturnValue_t CService201HealthCommanding::prepareHealthSetReply( + const CommandMessage* reply) { + prepareHealthSetReply(reply); + uint8_t health = static_cast(HealthMessage::getHealth(reply)); + uint8_t oldHealth = static_cast(HealthMessage::getOldHealth(reply)); + HealthSetReply healthSetReply(health, oldHealth); + return sendTmPacket(Subservice::REPLY_HEALTH_SET, &healthSetReply); +} + diff --git a/pus/CService201HealthCommanding.h b/pus/CService201HealthCommanding.h new file mode 100644 index 00000000..124e2ac7 --- /dev/null +++ b/pus/CService201HealthCommanding.h @@ -0,0 +1,63 @@ +#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_ +#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_ + +#include "../tmtcservices/CommandingServiceBase.h" + +/** + * @brief Custom PUS service to set health of all objects + * implementing hasHealthIF. + * + * Examples: Device Handlers, Assemblies or Subsystems. + * Full Documentation: ECSS-E-ST-70-41C or ECSS-E-70-41A + * Dissertation Baetz p. 115, 116, 165-167. + * + * This is a gateway service. It relays device commands using the software bus. + * This service is very closely tied to the Commanding Service Base template + * class. There is constant interaction between this Service Base und a + * child class like this service + * + */ +class CService201HealthCommanding: public CommandingServiceBase { +public: + + CService201HealthCommanding(object_id_t objectId, uint16_t apid, + uint8_t serviceId, uint8_t numParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); + virtual~ CService201HealthCommanding(); +protected: + /* CSB abstract function implementations */ + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) override; + /** Prepare health command */ + ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) override; + /** Handle health reply */ + ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) override; + +private: + ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* MessageQueueToSet, object_id_t* objectId); + + ReturnValue_t prepareHealthSetReply(const CommandMessage *reply); + + enum Subservice { + //! [EXPORT] : [TC] Set health of target object + COMMAND_SET_HEALTH = 1, + //! [EXPORT] : [TM] Reply to health set command which also provides old health + REPLY_HEALTH_SET = 2, + //! [EXPORT] : [TC] Commands object to announce their health as an event + COMMAND_ANNOUNCE_HEALTH = 3, + //! [EXPORT] : [TC] Commands all objects in the health map to announce their health + COMMAND_ANNOUNCE_HEALTH_ALL = 4 + }; +}; + +#endif /* FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_ */