From 3e79d2e73ad239b5f1c4838178f35348ac5ca6b8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 10 Oct 2020 20:04:01 +0200 Subject: [PATCH] added extended controller base --- controller/ControllerBase.cpp | 8 +- controller/ControllerBase.h | 30 +++---- controller/ExtendedControllerBase.cpp | 110 ++++++++++++++++++++++++++ controller/ExtendedControllerBase.h | 70 ++++++++++++++++ 4 files changed, 201 insertions(+), 17 deletions(-) create mode 100644 controller/ExtendedControllerBase.cpp create mode 100644 controller/ExtendedControllerBase.h diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index 4f50fe1f..45e678eb 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -9,7 +9,8 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId, SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode(SUBMODE_NONE), modeHelper(this), healthHelper(this, setObjectId), hkSwitcher(this) { - commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); + commandQueue = QueueFactory::instance()->createMessageQueue( + commandQueueDepth); } ControllerBase::~ControllerBase() { @@ -56,8 +57,9 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { void ControllerBase::handleQueue() { CommandMessage command; - ReturnValue_t result; - for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + for (result = commandQueue->receiveMessage(&command); + result == RETURN_OK; result = commandQueue->receiveMessage(&command)) { result = modeHelper.handleModeCommand(&command); diff --git a/controller/ControllerBase.h b/controller/ControllerBase.h index 6c2ec1d6..25d3ab1f 100644 --- a/controller/ControllerBase.h +++ b/controller/ControllerBase.h @@ -11,9 +11,10 @@ #include "../datapool/HkSwitchHelper.h" /** - * @brief Generic base class for controller classes + * @brief Generic base class for controller classes * @details - * Implements common interfaces for controllers. + * Implements common interfaces for controllers, which generally have + * a mode and a health state. This avoids boilerplate code. */ class ControllerBase: public HasModesIF, public HasHealthIF, @@ -27,24 +28,18 @@ public: size_t commandQueueDepth = 3); virtual ~ControllerBase(); + /** SystemObject override */ virtual ReturnValue_t initialize() override; virtual MessageQueueId_t getCommandQueue() const override; - virtual ReturnValue_t performOperation(uint8_t opCode) override; - + /** HasHealthIF overrides */ virtual ReturnValue_t setHealth(HealthState health) override; - virtual HasHealthIF::HealthState getHealth() override; - /** - * Implementation of ExecutableObjectIF function - * - * Used to setup the reference of the task, that executes this component - * @param task_ Pointer to the taskIF of this task - */ - virtual void setTaskIF(PeriodicTaskIF* task_) override; - + /** ExecutableObjectIF overrides */ + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual void setTaskIF(PeriodicTaskIF* task) override; virtual ReturnValue_t initializeAfterTaskCreation() override; protected: @@ -57,6 +52,9 @@ protected: */ virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; + /** + * Periodic helper, implemented by child class. + */ virtual void performControlOperation() = 0; virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, @@ -74,6 +72,7 @@ protected: HealthHelper healthHelper; + // Is this still needed? HkSwitchHelper hkSwitcher; /** @@ -82,13 +81,16 @@ protected: */ PeriodicTaskIF* executingTask = nullptr; - void handleQueue(); + /** Handle mode and health messages */ + virtual void handleQueue(); + /** Mode helpers */ virtual void modeChanged(Mode_t mode, Submode_t submode); virtual void startTransition(Mode_t mode, Submode_t submode); virtual void getMode(Mode_t *mode, Submode_t *submode); virtual void setToExternalControl(); virtual void announceMode(bool recursive); + /** HK helpers */ virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); }; diff --git a/controller/ExtendedControllerBase.cpp b/controller/ExtendedControllerBase.cpp new file mode 100644 index 00000000..f3336e43 --- /dev/null +++ b/controller/ExtendedControllerBase.cpp @@ -0,0 +1,110 @@ +#include "ExtendedControllerBase.h" + + +ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, + object_id_t parentId, size_t commandQueueDepth): + ControllerBase(objectId, parentId, commandQueueDepth), + localPoolManager(this, commandQueue), + actionHelper(this, commandQueue) { +} + +ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { + // needs to be overriden and implemented by child class. + return HasReturnvaluesIF::RETURN_OK; +} + + + +ReturnValue_t ExtendedControllerBase::initializeLocalDataPool( + LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + // needs to be overriden and implemented by child class. + return HasReturnvaluesIF::RETURN_OK; +} + +object_id_t ExtendedControllerBase::getObjectId() const { + return SystemObject::getObjectId(); +} + +LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() { + return &localPoolManager; +} + +uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const { + return this->executingTask->getPeriodMs(); +} + +ReturnValue_t ExtendedControllerBase::handleCommandMessage( + CommandMessage *message) { + ReturnValue_t result = actionHelper.handleActionMessage(message); + if(result == HasReturnvaluesIF::RETURN_OK) { + return result; + } + return localPoolManager.handleHousekeepingMessage(message); +} + +void ExtendedControllerBase::handleQueue() { + CommandMessage command; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + for (result = commandQueue->receiveMessage(&command); + result == RETURN_OK; + result = commandQueue->receiveMessage(&command)) { + result = actionHelper.handleActionMessage(&command); + if (result == RETURN_OK) { + continue; + } + + result = modeHelper.handleModeCommand(&command); + if (result == RETURN_OK) { + continue; + } + + result = healthHelper.handleHealthCommand(&command); + if (result == RETURN_OK) { + continue; + } + + result = localPoolManager.handleHousekeepingMessage(&command); + if (result == RETURN_OK) { + continue; + } + + result = handleCommandMessage(&command); + if (result == RETURN_OK) { + continue; + } + command.setToUnknownCommand(); + commandQueue->reply(&command); + } +} + +ReturnValue_t ExtendedControllerBase::initialize() { + ReturnValue_t result = ControllerBase::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + return localPoolManager.initialize(commandQueue); +} + +ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() { + return localPoolManager.initializeAfterTaskCreation(); +} + +ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) { + handleQueue(); + hkSwitcher.performOperation(); + localPoolManager.performHkOperation(); + performControlOperation(); + return RETURN_OK; +} + +LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) { + sif::warning << "ExtendedControllerBase::getDataSetHandle: No child " + << " implementation provided, returning nullptr!" << std::endl; + return nullptr; +} diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h new file mode 100644 index 00000000..fa47950a --- /dev/null +++ b/controller/ExtendedControllerBase.h @@ -0,0 +1,70 @@ +#ifndef FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ +#define FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ + +#include "ControllerBase.h" + +#include "../action/HasActionsIF.h" +#include "../datapoollocal/HasLocalDataPoolIF.h" +#include "../action/ActionHelper.h" +#include "../datapoollocal/LocalDataPoolManager.h" + +/** + * @brief Extendes the basic ControllerBase with the common components + * HasActionsIF for commandability and HasLocalDataPoolIF to keep + * a pool of local data pool variables. + * @details + * Default implementations required for the interfaces will be empty and have + * to be implemented by child class. + */ +class ExtendedControllerBase: public ControllerBase, + public HasActionsIF, + public HasLocalDataPoolIF { +public: + ExtendedControllerBase(object_id_t objectId, object_id_t parentId, + size_t commandQueueDepth = 3); + + /** SystemObjectIF overrides */ + virtual ReturnValue_t initialize() override; + + /** ExecutableObjectIF overrides */ + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual ReturnValue_t initializeAfterTaskCreation() override; + +protected: + LocalDataPoolManager localPoolManager; + ActionHelper actionHelper; + + /** + * Implemented by child class. Handle all command messages which are + * not health, mode, action or housekeeping messages. + * @param message + * @return + */ + virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; + + /** + * Periodic helper from ControllerBase, implemented by child class. + */ + virtual void performControlOperation() = 0; + + /** Handle the four messages mentioned above */ + void handleQueue() override; + + /** HasActionsIF overrides */ + virtual ReturnValue_t executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, + size_t size) override; + + /** HasLocalDatapoolIF overrides */ + virtual object_id_t getObjectId() const override; + virtual ReturnValue_t initializeLocalDataPool( + LocalDataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + virtual LocalDataPoolManager* getHkManagerHandle() override; + virtual uint32_t getPeriodicOperationFrequency() const override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; +}; + + + +#endif /* FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ */