Merge remote-tracking branch 'upstream/development' into mueller/enhanced-controller

This commit is contained in:
Robin Müller 2020-12-01 15:17:33 +01:00
commit c9adcc742b
4 changed files with 182 additions and 7 deletions

View File

@ -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

View File

@ -1,7 +1,6 @@
#ifndef CONFIG_FSFWCONFIG_H_
#define CONFIG_FSFWCONFIG_H_
#include <FSFWVersion.h>
#include <cstddef>
#include <cstdint>
@ -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

View File

@ -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<HasHealthIF>(*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<uint8_t>(HealthMessage::getHealth(reply));
uint8_t oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
HealthSetReply healthSetReply(health, oldHealth);
return sendTmPacket(Subservice::REPLY_HEALTH_SET, &healthSetReply);
}

View File

@ -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_ */