Merge branch 'master' into mueller/feature/windowsUdpBridge
This commit is contained in:
commit
652dc00cc9
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
11
FSFWVersion.h
Normal file
11
FSFWVersion.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef FSFW_DEFAULTCFG_VERSION_H_
|
||||
#define FSFW_DEFAULTCFG_VERSION_H_
|
||||
|
||||
const char* const FSFW_VERSION_NAME = "fsfw";
|
||||
|
||||
#define FSFW_VERSION 0
|
||||
#define FSFW_SUBVERSION 0
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_DEFAULTCFG_VERSION_H_ */
|
4
README.md
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
||||
Flight Software Framework (FSFW)
|
||||
======
|
||||
|
||||
I want to be written!
|
@ -3,8 +3,9 @@
|
||||
#include "../ipc/MessageQueueSenderIF.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) :
|
||||
owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) {
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner,
|
||||
MessageQueueIF* useThisQueue) :
|
||||
owner(setOwner), queueToUse(useThisQueue) {
|
||||
}
|
||||
|
||||
ActionHelper::~ActionHelper() {
|
||||
@ -33,13 +34,15 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) {
|
||||
void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo,
|
||||
ActionId_t commandId, ReturnValue_t result) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) {
|
||||
void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
ReturnValue_t result) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setCompletionReply(&reply, commandId, result);
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
@ -49,8 +52,8 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
||||
queueToUse = queue;
|
||||
}
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
||||
ActionId_t actionId, store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = NULL;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
@ -62,6 +65,11 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
|
||||
}
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
if(result == HasActionsIF::EXECUTION_FINISHED) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setCompletionReply(&reply, actionId, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
@ -86,22 +94,28 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
result = data->serialize(&dataPtr, &size, maxSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeAddress);
|
||||
return result;
|
||||
}
|
||||
//We don't need to report the objectId, as we receive REQUESTED data before the completion success message.
|
||||
//True aperiodic replies need to be reported with another dedicated message.
|
||||
// We don't need to report the objectId, as we receive REQUESTED data
|
||||
// before the completion success message.
|
||||
// True aperiodic replies need to be reported with
|
||||
// another dedicated message.
|
||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||
|
||||
//TODO Service Implementation sucks at the moment
|
||||
if (hideSender){
|
||||
// If the sender needs to be hidden, for example to handle packet
|
||||
// as unrequested reply, this will be done here.
|
||||
if (hideSender) {
|
||||
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
result = queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
if ( result != HasReturnvaluesIF::RETURN_OK){
|
||||
|
||||
if (result != HasReturnvaluesIF::RETURN_OK){
|
||||
ipcStore->deleteData(storeAddress);
|
||||
}
|
||||
return result;
|
||||
@ -109,3 +123,39 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
||||
|
||||
void ActionHelper::resetHelper() {
|
||||
}
|
||||
|
||||
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
||||
ActionId_t replyId, const uint8_t *data, size_t dataSize,
|
||||
bool hideSender) {
|
||||
CommandMessage reply;
|
||||
store_address_t storeAddress;
|
||||
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeAddress);
|
||||
return result;
|
||||
}
|
||||
|
||||
// We don't need to report the objectId, as we receive REQUESTED data
|
||||
// before the completion success message.
|
||||
// True aperiodic replies need to be reported with
|
||||
// another dedicated message.
|
||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||
|
||||
// If the sender needs to be hidden, for example to handle packet
|
||||
// as unrequested reply, this will be done here.
|
||||
if (hideSender) {
|
||||
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
||||
}
|
||||
else {
|
||||
result = queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
if (result != HasReturnvaluesIF::RETURN_OK){
|
||||
ipcStore->deleteData(storeAddress);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,15 +1,18 @@
|
||||
#ifndef ACTIONHELPER_H_
|
||||
#define ACTIONHELPER_H_
|
||||
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||
|
||||
#include "ActionMessage.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
/**
|
||||
* \brief Action Helper is a helper class which handles action messages
|
||||
* @brief Action Helper is a helper class which handles action messages
|
||||
*
|
||||
* Components which use the HasActionIF this helper can be used to handle the action messages.
|
||||
* It does handle step messages as well as other answers to action calls. It uses the executeAction function
|
||||
* of its owner as callback. The call of the initialize function is mandatory and it needs a valid messageQueueIF pointer!
|
||||
* Components which use the HasActionIF this helper can be used to handle
|
||||
* the action messages.
|
||||
* It does handle step messages as well as other answers to action calls.
|
||||
* It uses the executeAction function of its owner as callback.
|
||||
* The call of the initialize function is mandatory and needs a
|
||||
* valid MessageQueueIF pointer!
|
||||
*/
|
||||
class HasActionsIF;
|
||||
|
||||
@ -18,7 +21,8 @@ public:
|
||||
/**
|
||||
* Constructor of the action helper
|
||||
* @param setOwner Pointer to the owner of the interface
|
||||
* @param useThisQueue messageQueue to be used, can be set during initialize function as well.
|
||||
* @param useThisQueue messageQueue to be used, can be set during
|
||||
* initialize function as well.
|
||||
*/
|
||||
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
|
||||
@ -26,28 +30,36 @@ public:
|
||||
/**
|
||||
* Function to be called from the owner with a new command message
|
||||
*
|
||||
* If the message is a valid action message the helper will use the executeAction function from HasActionsIF.
|
||||
* If the message is invalid or the callback fails a message reply will be send to the sender of the message automatically.
|
||||
* If the message is a valid action message the helper will use the
|
||||
* executeAction function from HasActionsIF.
|
||||
* If the message is invalid or the callback fails a message reply will be
|
||||
* send to the sender of the message automatically.
|
||||
*
|
||||
* @param command Pointer to a command message received by the owner
|
||||
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message, CommandMessage::UNKNOW_COMMAND if this message ID is unkown
|
||||
* @return HasReturnvaluesIF::RETURN_OK if the message is a action message,
|
||||
* CommandMessage::UNKNOW_COMMAND if this message ID is unkown
|
||||
*/
|
||||
ReturnValue_t handleActionMessage(CommandMessage* command);
|
||||
/**
|
||||
* Helper initialize function. Must be called before use of any other helper function
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional if queue was set in constructor
|
||||
* Helper initialize function. Must be called before use of any other
|
||||
* helper function
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
||||
* if queue was set in constructor
|
||||
* @return Returns RETURN_OK if successful
|
||||
*/
|
||||
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
|
||||
/**
|
||||
* Function to be called from the owner to send a step message. Success or failure will be determined by the result value.
|
||||
* Function to be called from the owner to send a step message.
|
||||
* Success or failure will be determined by the result value.
|
||||
*
|
||||
* @param step Number of steps already done
|
||||
* @param reportTo The messageQueueId to report the step message to
|
||||
* @param commandId ID of the executed command
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void step(uint8_t step, MessageQueueId_t reportTo,
|
||||
ActionId_t commandId,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
/**
|
||||
* Function to be called by the owner to send a action completion message
|
||||
*
|
||||
@ -55,39 +67,59 @@ public:
|
||||
* @param commandId ID of the executed command
|
||||
* @param result Result of the execution
|
||||
*/
|
||||
void finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(MessageQueueId_t reportTo, ActionId_t commandId,
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
/**
|
||||
* Function to be called by the owner if an action does report data
|
||||
*
|
||||
* @param reportTo MessageQueueId_t to report the action completion message to
|
||||
* Function to be called by the owner if an action does report data.
|
||||
* Takes a SerializeIF* pointer and serializes it into the IPC store.
|
||||
* @param reportTo MessageQueueId_t to report the action completion
|
||||
* message to
|
||||
* @param replyId ID of the executed command
|
||||
* @param data Pointer to the data
|
||||
* @return Returns RETURN_OK if successful, otherwise failure code
|
||||
*/
|
||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender = false);
|
||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
||||
SerializeIF* data, bool hideSender = false);
|
||||
/**
|
||||
* Function to be called by the owner if an action does report data.
|
||||
* Takes the raw data and writes it into the IPC store.
|
||||
* @param reportTo MessageQueueId_t to report the action completion
|
||||
* message to
|
||||
* @param replyId ID of the executed command
|
||||
* @param data Pointer to the data
|
||||
* @return Returns RETURN_OK if successful, otherwise failure code
|
||||
*/
|
||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId,
|
||||
const uint8_t* data, size_t dataSize, bool hideSender = false);
|
||||
/**
|
||||
* Function to setup the MessageQueueIF* of the helper. Can be used to set the messageQueueIF* if
|
||||
* message queue is unavailable at construction and initialize but must be setup before first call of other functions.
|
||||
* Function to setup the MessageQueueIF* of the helper. Can be used to
|
||||
* set the MessageQueueIF* if message queue is unavailable at construction
|
||||
* and initialize but must be setup before first call of other functions.
|
||||
* @param queue Queue to be used by the helper
|
||||
*/
|
||||
void setQueueToUse(MessageQueueIF *queue);
|
||||
protected:
|
||||
static const uint8_t STEP_OFFSET = 1;//!< Increase of value of this per step
|
||||
//!< Increase of value of this per step
|
||||
static const uint8_t STEP_OFFSET = 1;
|
||||
HasActionsIF* owner;//!< Pointer to the owner
|
||||
MessageQueueIF* queueToUse;//!< Queue to be used as response sender, has to be set with
|
||||
StorageManagerIF* ipcStore;//!< Pointer to an IPC Store, initialized during construction or initialize(MessageQueueIF* queueToUse_) or with setQueueToUse(MessageQueueIF *queue)
|
||||
//! Queue to be used as response sender, has to be set in ctor or with
|
||||
//! setQueueToUse
|
||||
MessageQueueIF* queueToUse;
|
||||
//! Pointer to an IPC Store, initialized during construction or
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
|
||||
/**
|
||||
*Internal function called by handleActionMessage(CommandMessage* command)
|
||||
*
|
||||
* Internal function called by handleActionMessage
|
||||
* @param commandedBy MessageQueueID of Commander
|
||||
* @param actionId ID of action to be done
|
||||
* @param dataAddress Address of additional data in IPC Store
|
||||
*/
|
||||
virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress);
|
||||
virtual void prepareExecution(MessageQueueId_t commandedBy,
|
||||
ActionId_t actionId, store_address_t dataAddress);
|
||||
/**
|
||||
*
|
||||
* @brief Default implementation is empty.
|
||||
*/
|
||||
virtual void resetHelper();
|
||||
};
|
||||
|
||||
#endif /* ACTIONHELPER_H_ */
|
||||
#endif /* FSFW_ACTION_ACTIONHELPER_H_ */
|
||||
|
@ -1,11 +1,12 @@
|
||||
#ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_
|
||||
#define FRAMEWORK_ACTION_HASACTIONSIF_H_
|
||||
#ifndef FSFW_ACTION_HASACTIONSIF_H_
|
||||
#define FSFW_ACTION_HASACTIONSIF_H_
|
||||
|
||||
#include "ActionHelper.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Interface for component which uses actions
|
||||
@ -47,14 +48,16 @@ public:
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
/**
|
||||
* Execute or initialize the execution of a certain function.
|
||||
* Returning #EXECUTION_FINISHED or a failure code, nothing else needs to
|
||||
* be done. When needing more steps, return RETURN_OK and issue steps and
|
||||
* completion manually.
|
||||
* One "step failed" or completion report must be issued!
|
||||
* The ActionHelpers will execute this function and behave differently
|
||||
* depending on the returnvalue.
|
||||
*
|
||||
* @return
|
||||
* -@c EXECUTION_FINISHED Finish reply will be generated
|
||||
* -@c Not RETURN_OK Step failure reply will be generated
|
||||
*/
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */
|
||||
#endif /* FSFW_ACTION_HASACTIONSIF_H_ */
|
||||
|
@ -1,16 +1,17 @@
|
||||
#include "HasActionsIF.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
|
||||
MessageQueueIF* useThisQueue) :
|
||||
ActionHelper(setOwner, useThisQueue), isExecuting(false), lastCommander(
|
||||
0), lastAction(0), stepCount(0) {
|
||||
ActionHelper(setOwner, useThisQueue), isExecuting(false) {
|
||||
}
|
||||
|
||||
SimpleActionHelper::~SimpleActionHelper() {
|
||||
}
|
||||
|
||||
void SimpleActionHelper::step(ReturnValue_t result) {
|
||||
//STEP_OFFESET is subtracted to compensate for adding offset in base method, which is not necessary here.
|
||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||
// method, which is not necessary here.
|
||||
ActionHelper::step(stepCount - STEP_OFFSET, lastCommander, lastAction,
|
||||
result);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@ -1,8 +1,13 @@
|
||||
#ifndef SIMPLEACTIONHELPER_H_
|
||||
#define SIMPLEACTIONHELPER_H_
|
||||
#ifndef FSFW_ACTION_SIMPLEACTIONHELPER_H_
|
||||
#define FSFW_ACTION_SIMPLEACTIONHELPER_H_
|
||||
|
||||
#include "ActionHelper.h"
|
||||
|
||||
/**
|
||||
* @brief This is an action helper which is only able to service one action
|
||||
* at a time but remembers last commander and last action which
|
||||
* simplifies usage
|
||||
*/
|
||||
class SimpleActionHelper: public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
@ -12,13 +17,14 @@ public:
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
|
||||
protected:
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress);
|
||||
virtual void resetHelper();
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress);
|
||||
virtual void resetHelper();
|
||||
private:
|
||||
bool isExecuting;
|
||||
MessageQueueId_t lastCommander;
|
||||
ActionId_t lastAction;
|
||||
uint8_t stepCount;
|
||||
MessageQueueId_t lastCommander = MessageQueueIF::NO_QUEUE;
|
||||
ActionId_t lastAction = 0;
|
||||
uint8_t stepCount = 0;
|
||||
};
|
||||
|
||||
#endif /* SIMPLEACTIONHELPER_H_ */
|
||||
|
@ -9,6 +9,7 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
|
||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
||||
const size_t size, bool overwriteOld, size_t maxExcessBytes):
|
||||
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
|
||||
@ -16,6 +17,11 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
|
||||
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
|
||||
this->fifoDepth = fifoDepth;
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
|
||||
MutexIF::TimeoutType timeoutType, dur_millis_t timeout) {
|
||||
return mutex->lockMutex(timeoutType, timeout);
|
||||
@ -25,6 +31,25 @@ ReturnValue_t SharedRingBuffer::unlockRingBufferMutex() {
|
||||
return mutex->unlockMutex();
|
||||
}
|
||||
|
||||
|
||||
|
||||
MutexIF* SharedRingBuffer::getMutexHandle() const {
|
||||
return mutex;
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::initialize() {
|
||||
if(fifoDepth > 0) {
|
||||
receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth);
|
||||
}
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
||||
if(receiveSizesFIFO == nullptr) {
|
||||
// Configuration error.
|
||||
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
||||
<< " was not configured to have sizes FIFO, returning nullptr!"
|
||||
<< std::endl;
|
||||
}
|
||||
return receiveSizesFIFO;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_CONTAINER_SHAREDRINGBUFFER_H_
|
||||
|
||||
#include "SimpleRingBuffer.h"
|
||||
#include "DynamicFIFO.h"
|
||||
#include "../ipc/MutexIF.h"
|
||||
#include "../objectmanager/SystemObject.h"
|
||||
#include "../timemanager/Clock.h"
|
||||
@ -26,6 +27,16 @@ public:
|
||||
SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||
bool overwriteOld, size_t maxExcessBytes);
|
||||
|
||||
/**
|
||||
* @brief This function can be used to add an optional FIFO to the class
|
||||
* @details
|
||||
* This FIFO will be allocated in the initialize function (and will
|
||||
* have a fixed maximum size after that). It can be used to store
|
||||
* values like packet sizes, for example for a shared ring buffer
|
||||
* used by producer/consumer tasks.
|
||||
*/
|
||||
void setToUseReceiveSizeFIFO(size_t fifoDepth);
|
||||
|
||||
/**
|
||||
* This constructor takes an external buffer with the specified size.
|
||||
* @param buffer
|
||||
@ -59,8 +70,21 @@ public:
|
||||
* @return
|
||||
*/
|
||||
MutexIF* getMutexHandle() const;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
/**
|
||||
* If the shared ring buffer was configured to have a sizes FIFO, a handle
|
||||
* to that FIFO can be retrieved with this function.
|
||||
* Do not forget to protect access with a lock if required!
|
||||
* @return
|
||||
*/
|
||||
DynamicFIFO<size_t>* getReceiveSizesFIFO();
|
||||
private:
|
||||
MutexIF* mutex = nullptr;
|
||||
|
||||
size_t fifoDepth = 0;
|
||||
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
6
defaultcfg/README.md
Normal file
6
defaultcfg/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# How to setup configuration folder for FSFW
|
||||
|
||||
It is recommended to copy the content of the defaultcfg folder
|
||||
into a config folder which is in the same directory as the Flight
|
||||
Software Framework submodule. After that, the config.mk folder should be
|
||||
included by the primary Makefile with CURRENTPATH set correctly.
|
54
defaultcfg/config/FSFWConfig.h
Normal file
54
defaultcfg/config/FSFWConfig.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef CONFIG_FSFWCONFIG_H_
|
||||
#define CONFIG_FSFWCONFIG_H_
|
||||
|
||||
#include <FSFWVersion.h>
|
||||
#include <cstddef>
|
||||
|
||||
//! Used to determine whether C++ ostreams are used
|
||||
//! Those can lead to code bloat.
|
||||
#define FSFW_CPP_OSTREAM_ENABLED 1
|
||||
|
||||
//! Reduced printout to further decrese code size
|
||||
//! Be careful, this also turns off most diagnostic prinouts!
|
||||
#define FSFW_REDUCED_PRINTOUT 0
|
||||
|
||||
//! Can be used to enable debugging printouts for developing the FSFW
|
||||
#define FSFW_DEBUGGING 0
|
||||
|
||||
//! Defines the FIFO depth of each commanding service base which
|
||||
//! also determines how many commands a CSB service can handle in one cycle
|
||||
//! simulataneously. This will increase the required RAM for
|
||||
//! each CSB service !
|
||||
#define FSFW_CSB_FIFO_DEPTH 6
|
||||
|
||||
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
|
||||
//! additional output which requires the translation files translateObjects
|
||||
//! and translateEvents (and their compiled source files)
|
||||
#define FSFW_OBJ_EVENT_TRANSLATION 0
|
||||
|
||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||
#define FSFW_DEBUG_OUTPUT 1
|
||||
//! Specify whether info events are printed too.
|
||||
#define FSFW_DEBUG_INFO 1
|
||||
#include <translateObjects.h>
|
||||
#include <translateEvents.h>
|
||||
#else
|
||||
#define FSFW_DEBUG_OUTPUT 0
|
||||
#endif
|
||||
|
||||
//! 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
|
||||
|
||||
namespace fsfwconfig {
|
||||
//! Default timestamp size. The default timestamp will be an eight byte CDC
|
||||
//! short timestamp.
|
||||
static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 8;
|
||||
|
||||
//! Configure the allocated pool sizes for the event manager.
|
||||
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
|
||||
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
|
||||
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
16
defaultcfg/config/OBSWConfig.h
Normal file
16
defaultcfg/config/OBSWConfig.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef CONFIG_OBSWCONFIG_H_
|
||||
#define CONFIG_OBSWCONFIG_H_
|
||||
|
||||
#include "OBSWVersion.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace config {
|
||||
#endif
|
||||
|
||||
/* Add mission configuration flags here */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_OBSWCONFIG_H_ */
|
9
defaultcfg/config/OBSWVersion.h
Normal file
9
defaultcfg/config/OBSWVersion.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef CONFIG_VERSION_H_
|
||||
#define CONFIG_VERSION_H_
|
||||
|
||||
/* OBSW versioning can be specified in this file */
|
||||
|
||||
#define OBSW_VERSION 0
|
||||
#define OBSW_SUBVERSION 0
|
||||
|
||||
#endif /* CONFIG_VERSION_H_ */
|
15
defaultcfg/config/config.mk
Normal file
15
defaultcfg/config/config.mk
Normal file
@ -0,0 +1,15 @@
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/tmtc/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/devices/*.cpp)
|
||||
|
||||
INCLUDES += $(CURRENTPATH)
|
||||
INCLUDES += $(CURRENTPATH)/objects
|
||||
INCLUDES += $(CURRENTPATH)/returnvalues
|
||||
INCLUDES += $(CURRENTPATH)/tmtc
|
||||
INCLUDES += $(CURRENTPATH)/events
|
||||
INCLUDES += $(CURRENTPATH)/devices
|
||||
INCLUDES += $(CURRENTPATH)/pollingsequence
|
||||
INCLUDES += $(CURRENTPATH)/ipc
|
5
defaultcfg/config/devices/logicalAddresses.cpp
Normal file
5
defaultcfg/config/devices/logicalAddresses.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "logicalAddresses.h"
|
||||
|
||||
|
||||
|
||||
|
18
defaultcfg/config/devices/logicalAddresses.h
Normal file
18
defaultcfg/config/devices/logicalAddresses.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef CONFIG_DEVICES_LOGICALADDRESSES_H_
|
||||
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
|
||||
|
||||
#include <config/objects/systemObjectList.h>
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* Can be used for addresses for physical devices like I2C adresses.
|
||||
*/
|
||||
namespace addresses {
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses: address_t {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */
|
4
defaultcfg/config/devices/powerSwitcherList.cpp
Normal file
4
defaultcfg/config/devices/powerSwitcherList.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "powerSwitcherList.h"
|
||||
|
||||
|
||||
|
12
defaultcfg/config/devices/powerSwitcherList.h
Normal file
12
defaultcfg/config/devices/powerSwitcherList.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef CONFIG_DEVICES_POWERSWITCHERLIST_H_
|
||||
#define CONFIG_DEVICES_POWERSWITCHERLIST_H_
|
||||
|
||||
namespace switches {
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum switcherList {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
18
defaultcfg/config/events/subsystemIdRanges.h
Normal file
18
defaultcfg/config/events/subsystemIdRanges.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <fsfw/events/fwSubsystemIdRanges.h>
|
||||
|
||||
/**
|
||||
* @brief Custom subsystem IDs can be added here
|
||||
* @details
|
||||
* Subsystem IDs are used to create unique events.
|
||||
*/
|
||||
namespace SUBSYSTEM_ID {
|
||||
enum: uint8_t {
|
||||
SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE,
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */
|
11
defaultcfg/config/ipc/missionMessageTypes.cpp
Normal file
11
defaultcfg/config/ipc/missionMessageTypes.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include <config/ipc/MissionMessageTypes.h>
|
||||
#include <fsfw/ipc/CommandMessageIF.h>
|
||||
|
||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
||||
switch(message->getMessageType()) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
21
defaultcfg/config/ipc/missionMessageTypes.h
Normal file
21
defaultcfg/config/ipc/missionMessageTypes.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef CONFIG_IPC_MISSIONMESSAGETYPES_H_
|
||||
#define CONFIG_IPC_MISSIONMESSAGETYPES_H_
|
||||
|
||||
#include <fsfw/ipc/CommandMessage.h>
|
||||
#include <fsfw/ipc/FwMessageTypes.h>
|
||||
|
||||
/**
|
||||
* Custom command messages are specified here.
|
||||
* Most messages needed to use FSFW are already located in
|
||||
* <fsfw/ipc/FwMessageTypes.h>
|
||||
* @param message Generic Command Message
|
||||
*/
|
||||
namespace messagetypes {
|
||||
enum CustomMessageTypes {
|
||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT
|
||||
};
|
||||
|
||||
void clearMissionMessage(CommandMessage* message);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */
|
54
defaultcfg/config/objects/Factory.cpp
Normal file
54
defaultcfg/config/objects/Factory.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "Factory.h"
|
||||
#include "../tmtc/apid.h"
|
||||
#include "../tmtc/pusIds.h"
|
||||
#include "../objects/systemObjectList.h"
|
||||
#include "../devices/logicalAddresses.h"
|
||||
#include "../devices/powerSwitcherList.h"
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/events/EventManager.h>
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* This class should be used to create all system objects required for
|
||||
* the on-board software, using the object ID list from the configuration
|
||||
* folder.
|
||||
*
|
||||
* The objects are registered in the internal object manager automatically.
|
||||
* This is used later to add objects to tasks.
|
||||
*
|
||||
* This file also sets static framework IDs.
|
||||
*
|
||||
* Framework objects are created first.
|
||||
* @ingroup init
|
||||
*/
|
||||
void Factory::produce(void) {
|
||||
setStaticFrameworkObjectIds();
|
||||
new EventManager(objects::EVENT_MANAGER);
|
||||
new HealthTable(objects::HEALTH_TABLE);
|
||||
//new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
||||
}
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||
|
||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||
|
||||
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||
DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2_DEVICE_ACCESS;
|
||||
|
||||
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||
|
||||
TmPacketStored::timeStamperId = objects::PUS_TIME;
|
||||
//TmFunnel::downlinkDestination = objects::NO_OBJECT;
|
||||
}
|
||||
|
17
defaultcfg/config/objects/Factory.h
Normal file
17
defaultcfg/config/objects/Factory.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef FACTORY_H_
|
||||
#define FACTORY_H_
|
||||
|
||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace Factory {
|
||||
/**
|
||||
* @brief Creates all SystemObject elements which are persistent
|
||||
* during execution.
|
||||
*/
|
||||
void produce();
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
|
||||
#endif /* FACTORY_H_ */
|
16
defaultcfg/config/objects/systemObjectList.h
Normal file
16
defaultcfg/config/objects/systemObjectList.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||
#define CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||
|
||||
// The objects will be instantiated in the ID order
|
||||
namespace objects {
|
||||
enum sourceObjects: uint32_t {
|
||||
/* All addresses between start and end are reserved for the FSFW */
|
||||
FSFW_CONFIG_RESERVED_START = PUS_SERVICE_1_VERIFICATION,
|
||||
FSFW_CONFIG_RESERVED_END = TM_STORE
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
23
defaultcfg/config/pollingsequence/PollingSequenceFactory.cpp
Normal file
23
defaultcfg/config/pollingsequence/PollingSequenceFactory.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "PollingSequenceFactory.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
|
||||
ReturnValue_t pst::pollingSequenceInitDefault(
|
||||
FixedTimeslotTaskIF *thisSequence) {
|
||||
/* Length of a communication cycle */
|
||||
uint32_t length = thisSequence->getPeriodMs();
|
||||
|
||||
/* Add polling sequence table here */
|
||||
|
||||
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else {
|
||||
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
32
defaultcfg/config/pollingsequence/PollingSequenceFactory.h
Normal file
32
defaultcfg/config/pollingsequence/PollingSequenceFactory.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef POLLINGSEQUENCEFACTORY_H_
|
||||
#define POLLINGSEQUENCEFACTORY_H_
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
class FixedTimeslotTaskIF;
|
||||
|
||||
/**
|
||||
* All device handlers are scheduled by adding them into Polling Sequence Tables (PST)
|
||||
* to satisfy stricter timing requirements of device communication,
|
||||
* A device handler has four different communication steps:
|
||||
* 1. DeviceHandlerIF::SEND_WRITE -> Send write via interface
|
||||
* 2. DeviceHandlerIF::GET_WRITE -> Get confirmation for write
|
||||
* 3. DeviceHandlerIF::SEND_READ -> Send read request
|
||||
* 4. DeviceHandlerIF::GET_READ -> Read from interface
|
||||
* The PST specifies precisely when the respective ComIF functions are called
|
||||
* during the communication cycle time.
|
||||
* The task is created using the FixedTimeslotTaskIF,
|
||||
* which utilises the underlying Operating System Abstraction Layer (OSAL)
|
||||
*
|
||||
* @param thisSequence FixedTimeslotTaskIF * object is passed inside the Factory class when creating the PST
|
||||
* @return
|
||||
*/
|
||||
namespace pst {
|
||||
|
||||
/* Default PST */
|
||||
ReturnValue_t pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* POLLINGSEQUENCEINIT_H_ */
|
16
defaultcfg/config/returnvalues/classIds.h
Normal file
16
defaultcfg/config/returnvalues/classIds.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef CONFIG_RETURNVALUES_CLASSIDS_H_
|
||||
#define CONFIG_RETURNVALUES_CLASSIDS_H_
|
||||
|
||||
#include <fsfw/returnvalues/FwClassIds.h>
|
||||
|
||||
/**
|
||||
* @brief CLASS_ID defintions which are required for custom returnvalues.
|
||||
*/
|
||||
namespace CLASS_ID {
|
||||
enum {
|
||||
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */
|
18
defaultcfg/config/tmtc/apid.h
Normal file
18
defaultcfg/config/tmtc/apid.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef CONFIG_TMTC_APID_H_
|
||||
#define CONFIG_TMTC_APID_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* Application Process Definition: entity, uniquely identified by an
|
||||
* application process ID (APID), capable of generating telemetry source
|
||||
* packets and receiving telecommand packets.
|
||||
*
|
||||
* Chose APID(s) for mission and define it here.
|
||||
*/
|
||||
namespace apid {
|
||||
static const uint16_t DEFAULT_APID = 0x00;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_TMTC_APID_H_ */
|
23
defaultcfg/config/tmtc/pusIds.h
Normal file
23
defaultcfg/config/tmtc/pusIds.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef CONFIG_TMTC_PUSIDS_HPP_
|
||||
#define CONFIG_TMTC_PUSIDS_HPP_
|
||||
|
||||
namespace pus {
|
||||
enum Ids: uint8_t {
|
||||
PUS_SERVICE_1 = 1,
|
||||
PUS_SERVICE_2 = 2,
|
||||
PUS_SERVICE_3 = 3,
|
||||
PUS_SERVICE_5 = 5,
|
||||
PUS_SERVICE_6 = 6,
|
||||
PUS_SERVICE_8 = 8,
|
||||
PUS_SERVICE_9 = 9,
|
||||
PUS_SERVICE_11 = 11,
|
||||
PUS_SERVICE_17 = 17,
|
||||
PUS_SERVICE_19 = 19,
|
||||
PUS_SERVICE_20 = 20,
|
||||
PUS_SERVICE_23 = 23,
|
||||
PUS_SERVICE_200 = 200,
|
||||
PUS_SERVICE_201 = 201,
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* CONFIG_TMTC_PUSIDS_HPP_ */
|
@ -1224,7 +1224,7 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
||||
if (result == BUSY) {
|
||||
//so we can track misconfigurations
|
||||
sif::debug << std::hex << getObjectId()
|
||||
<< ": DHB::buildInternalCommand: Busy" << std::endl;
|
||||
<< ": DHB::buildInternalCommand: Busy" << std::dec << std::endl;
|
||||
result = NOTHING_TO_SEND; //no need to report this
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include "fwSubsystemIdRanges.h"
|
||||
//could be move to more suitable location
|
||||
#include <config/tmtc/subsystemIdRanges.h>
|
||||
#include <subsystemIdRanges.h>
|
||||
|
||||
typedef uint16_t EventId_t;
|
||||
typedef uint8_t EventSeverity_t;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "EventManager.h"
|
||||
#include "EventMessage.h"
|
||||
#include <FSFWConfig.h>
|
||||
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../ipc/QueueFactory.h"
|
||||
#include "../ipc/MutexFactory.h"
|
||||
@ -12,8 +14,10 @@ const uint16_t EventManager::POOL_SIZES[N_POOLS] = {
|
||||
// objects registering for certain events.
|
||||
// Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher.
|
||||
// So a good guess is 75 to a max of 100 pools required for each, which fits well.
|
||||
// SHOULDDO: Shouldn't this be in the config folder and passed via ctor?
|
||||
const uint16_t EventManager::N_ELEMENTS[N_POOLS] = { 240, 120, 120 };
|
||||
const uint16_t EventManager::N_ELEMENTS[N_POOLS] = {
|
||||
fsfwconfig::FSFW_EVENTMGMR_MATCHTREE_NODES ,
|
||||
fsfwconfig::FSFW_EVENTMGMT_EVENTIDMATCHERS,
|
||||
fsfwconfig::FSFW_EVENTMGMR_RANGEMATCHERS };
|
||||
|
||||
EventManager::EventManager(object_id_t setObjectId) :
|
||||
SystemObject(setObjectId),
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef HASHEALTHIF_H_
|
||||
#define HASHEALTHIF_H_
|
||||
#ifndef FSFW_HEALTH_HASHEALTHIF_H_
|
||||
#define FSFW_HEALTH_HASHEALTHIF_H_
|
||||
|
||||
#include "../events/Event.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
@ -8,9 +8,13 @@
|
||||
class HasHealthIF {
|
||||
public:
|
||||
|
||||
typedef enum {
|
||||
HEALTHY = 1, FAULTY = 0, EXTERNAL_CONTROL = 2, NEEDS_RECOVERY = 3, PERMANENT_FAULTY = 4
|
||||
} HealthState;
|
||||
enum HealthState: uint8_t {
|
||||
HEALTHY = 1,
|
||||
FAULTY = 0,
|
||||
EXTERNAL_CONTROL = 2,
|
||||
NEEDS_RECOVERY = 3,
|
||||
PERMANENT_FAULTY = 4
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||
@ -31,20 +35,17 @@ public:
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
/**
|
||||
* set the Health State
|
||||
*
|
||||
* @brief Set the Health State
|
||||
* The parent will be informed, if the Health changes
|
||||
*
|
||||
* @param health
|
||||
*/
|
||||
virtual ReturnValue_t setHealth(HealthState health) = 0;
|
||||
|
||||
/**
|
||||
* get Health State
|
||||
*
|
||||
* @return Health State of the object
|
||||
* @brief Get Health State
|
||||
* @return Health State of the object
|
||||
*/
|
||||
virtual HasHealthIF::HealthState getHealth() = 0;
|
||||
};
|
||||
|
||||
#endif /* HASHEALTHIF_H_ */
|
||||
#endif /* FSFW_HEALTH_HASHEALTHIF_H_ */
|
||||
|
@ -12,13 +12,15 @@
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* Helper class for Objects that implement HasHealthIF
|
||||
* @brief Helper class for Objects that implement HasHealthIF
|
||||
* @details
|
||||
* It takes care of registering with the Health Table as well as handling
|
||||
* health commands (including replying to the sender) and updating
|
||||
* the Health Table.
|
||||
*
|
||||
* It takes care of registering with the Health Table as well as handling health commands
|
||||
* (including replying to the sender) and updating the Health Table.
|
||||
*
|
||||
* If a parent is set in the ctor, the parent will be informed with a @c HEALTH_INFO message
|
||||
* about changes in the health state. Note that a @c HEALTH_INFO is only generated if the Health
|
||||
* If a parent is set in the ctor, the parent will be informed with a
|
||||
* @c HEALTH_INFO message about changes in the health state.
|
||||
* Note that a @c HEALTH_INFO is only generated if the Health
|
||||
* changes, not for all @c HEALTH_SET commands received.
|
||||
*
|
||||
* It does NOT handle @c HEALTH_INFO messages
|
||||
@ -27,10 +29,9 @@ class HealthHelper {
|
||||
public:
|
||||
|
||||
/**
|
||||
* ctor
|
||||
*
|
||||
* @param owner
|
||||
* @param objectId the object Id to use when communication with the HealthTable
|
||||
* @param objectId The object Id to use when communication with
|
||||
* the HealthTable
|
||||
*/
|
||||
HealthHelper(HasHealthIF* owner, object_id_t objectId);
|
||||
|
||||
@ -56,8 +57,9 @@ public:
|
||||
*
|
||||
* @param message
|
||||
* @return
|
||||
* -@c RETURN_OK if the message was handled
|
||||
* -@c RETURN_FAILED if the message could not be handled (ie it was not a @c HEALTH_SET or @c HEALTH_READ message)
|
||||
* -@c RETURN_OK if the message was handled
|
||||
* -@c RETURN_FAILED if the message could not be handled
|
||||
* (ie it was not a @c HEALTH_SET or @c HEALTH_READ message)
|
||||
*/
|
||||
ReturnValue_t handleHealthCommand(CommandMessage *message);
|
||||
|
||||
@ -78,16 +80,19 @@ public:
|
||||
HasHealthIF::HealthState getHealth();
|
||||
|
||||
/**
|
||||
* @param parentQueue the Queue id of the parent object. Set to 0 if no parent present
|
||||
* @param parentQueue The queue ID of the parent object.
|
||||
* Set to 0 if no parent present
|
||||
*/
|
||||
void setParentQueue(MessageQueueId_t parentQueue);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param parentQueue the Queue id of the parent object. Set to 0 if no parent present
|
||||
* @param parentQueue The queue ID of the parent object.
|
||||
* Set to 0 if no parent present
|
||||
* @return
|
||||
* -@c RETURN_OK if the Health Table was found and the object could be registered
|
||||
* -@c RETURN_FAILED else
|
||||
* -@c RETURN_OK if the Health Table was found and the object
|
||||
* could be registered
|
||||
* -@c RETURN_FAILED else
|
||||
*/
|
||||
ReturnValue_t initialize(MessageQueueId_t parentQueue );
|
||||
|
||||
@ -110,11 +115,15 @@ private:
|
||||
HasHealthIF* owner;
|
||||
|
||||
/**
|
||||
* if the #parentQueue is not NULL, a @c HEALTH_INFO message will be sent to this queue
|
||||
* @param health the health is passed as parameter so that the number of calls to the health table can be minimized
|
||||
* if the #parentQueue is not NULL, a @c HEALTH_INFO message
|
||||
* will be sent to this queue
|
||||
* @param health
|
||||
* The health is passed as parameter so that the number of
|
||||
* calls to the health table can be minimized
|
||||
* @param oldHealth information of the previous health state.
|
||||
*/
|
||||
void informParent(HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth);
|
||||
void informParent(HasHealthIF::HealthState health,
|
||||
HasHealthIF::HealthState oldHealth);
|
||||
|
||||
void handleSetHealthCommand(CommandMessage *message);
|
||||
};
|
||||
|
@ -7,11 +7,13 @@ void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command,
|
||||
message->setParameter2(oldHealth);
|
||||
}
|
||||
|
||||
void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command) {
|
||||
void HealthMessage::setHealthMessage(CommandMessage* message,
|
||||
Command_t command) {
|
||||
message->setCommand(command);
|
||||
}
|
||||
|
||||
HasHealthIF::HealthState HealthMessage::getHealth(const CommandMessage* message) {
|
||||
HasHealthIF::HealthState HealthMessage::getHealth(
|
||||
const CommandMessage* message) {
|
||||
return (HasHealthIF::HealthState) message->getParameter();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef HEALTHMESSAGE_H_
|
||||
#define HEALTHMESSAGE_H_
|
||||
#ifndef FSFW_HEALTH_HEALTHMESSAGE_H_
|
||||
#define FSFW_HEALTH_HEALTHMESSAGE_H_
|
||||
|
||||
#include "HasHealthIF.h"
|
||||
#include "../ipc/CommandMessage.h"
|
||||
@ -7,14 +7,20 @@
|
||||
class HealthMessage {
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::HEALTH_COMMAND;
|
||||
static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1);//REPLY_COMMAND_OK/REPLY_REJECTED
|
||||
static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(3); //NO REPLY!
|
||||
|
||||
static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1);
|
||||
// No reply expected, health will be announced as event!
|
||||
static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(2);
|
||||
// Same as before, but all objects in health table will
|
||||
// announce their health as events.
|
||||
static const Command_t HEALTH_ANNOUNCE_ALL = MAKE_COMMAND_ID(3);
|
||||
|
||||
static const Command_t HEALTH_INFO = MAKE_COMMAND_ID(5);
|
||||
static const Command_t REPLY_HEALTH_SET = MAKE_COMMAND_ID(6);
|
||||
|
||||
static void setHealthMessage(CommandMessage *message, Command_t command,
|
||||
HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth = HasHealthIF::FAULTY);
|
||||
|
||||
HasHealthIF::HealthState health,
|
||||
HasHealthIF::HealthState oldHealth = HasHealthIF::FAULTY);
|
||||
static void setHealthMessage(CommandMessage *message, Command_t command);
|
||||
|
||||
static HasHealthIF::HealthState getHealth(const CommandMessage *message);
|
||||
@ -27,4 +33,4 @@ private:
|
||||
HealthMessage();
|
||||
};
|
||||
|
||||
#endif /* HEALTHMESSAGE_H_ */
|
||||
#endif /* FSFW_HEALTH_HEALTHMESSAGE_H_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "HealthTable.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
#include "../ipc/MutexHelper.h"
|
||||
#include "../ipc/MutexFactory.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
|
||||
HealthTable::HealthTable(object_id_t objectid) :
|
||||
SystemObject(objectid) {
|
||||
@ -9,6 +10,12 @@ HealthTable::HealthTable(object_id_t objectid) :
|
||||
mapIterator = healthMap.begin();
|
||||
}
|
||||
|
||||
void HealthTable::setMutexTimeout(MutexIF::TimeoutType timeoutType,
|
||||
uint32_t timeoutMs) {
|
||||
this->timeoutType = timeoutType;
|
||||
this->mutexTimeoutMs = timeoutMs;
|
||||
}
|
||||
|
||||
HealthTable::~HealthTable() {
|
||||
MutexFactory::instance()->deleteMutex(mutex);
|
||||
}
|
||||
@ -18,74 +25,63 @@ ReturnValue_t HealthTable::registerObject(object_id_t object,
|
||||
if (healthMap.count(object) != 0) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
healthMap.insert(
|
||||
std::pair<object_id_t, HasHealthIF::HealthState>(object,
|
||||
initilialState));
|
||||
healthMap.emplace(object, initilialState);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void HealthTable::setHealth(object_id_t object,
|
||||
HasHealthIF::HealthState newState) {
|
||||
mutex->lockMutex(MutexIF::BLOCKING);
|
||||
MutexHelper(mutex, timeoutType, mutexTimeoutMs);
|
||||
HealthMap::iterator iter = healthMap.find(object);
|
||||
if (iter != healthMap.end()) {
|
||||
iter->second = newState;
|
||||
}
|
||||
mutex->unlockMutex();
|
||||
}
|
||||
|
||||
HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) {
|
||||
HasHealthIF::HealthState state = HasHealthIF::HEALTHY;
|
||||
mutex->lockMutex(MutexIF::BLOCKING);
|
||||
MutexHelper(mutex, timeoutType, mutexTimeoutMs);
|
||||
HealthMap::iterator iter = healthMap.find(object);
|
||||
if (iter != healthMap.end()) {
|
||||
state = iter->second;
|
||||
}
|
||||
mutex->unlockMutex();
|
||||
return state;
|
||||
}
|
||||
|
||||
uint32_t HealthTable::getPrintSize() {
|
||||
mutex->lockMutex(MutexIF::BLOCKING);
|
||||
uint32_t size = healthMap.size() * 5 + 2;
|
||||
mutex->unlockMutex();
|
||||
return size;
|
||||
}
|
||||
|
||||
bool HealthTable::hasHealth(object_id_t object) {
|
||||
bool exits = false;
|
||||
mutex->lockMutex(MutexIF::BLOCKING);
|
||||
MutexHelper(mutex, timeoutType, mutexTimeoutMs);
|
||||
HealthMap::iterator iter = healthMap.find(object);
|
||||
if (iter != healthMap.end()) {
|
||||
exits = true;
|
||||
return true;
|
||||
}
|
||||
mutex->unlockMutex();
|
||||
return exits;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t HealthTable::getPrintSize() {
|
||||
MutexHelper(mutex, timeoutType, mutexTimeoutMs);
|
||||
uint32_t size = healthMap.size() * sizeof(object_id_t) +
|
||||
sizeof(HasHealthIF::HealthState) + sizeof(uint16_t);
|
||||
return size;
|
||||
}
|
||||
|
||||
void HealthTable::printAll(uint8_t* pointer, size_t maxSize) {
|
||||
mutex->lockMutex(MutexIF::BLOCKING);
|
||||
MutexHelper(mutex, timeoutType, mutexTimeoutMs);
|
||||
size_t size = 0;
|
||||
uint16_t count = healthMap.size();
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&count,
|
||||
SerializeAdapter::serialize(&count,
|
||||
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
HealthMap::iterator iter;
|
||||
for (iter = healthMap.begin();
|
||||
iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK;
|
||||
++iter) {
|
||||
result = SerializeAdapter::serialize(&iter->first,
|
||||
for (const auto& health: healthMap) {
|
||||
SerializeAdapter::serialize(&health.first,
|
||||
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
uint8_t health = iter->second;
|
||||
result = SerializeAdapter::serialize(&health, &pointer, &size,
|
||||
uint8_t healthValue = health.second;
|
||||
SerializeAdapter::serialize(&healthValue, &pointer, &size,
|
||||
maxSize, SerializeIF::Endianness::BIG);
|
||||
}
|
||||
mutex->unlockMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t HealthTable::iterate(
|
||||
std::pair<object_id_t, HasHealthIF::HealthState> *value, bool reset) {
|
||||
ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
mutex->lockMutex(MutexIF::BLOCKING);
|
||||
MutexHelper(mutex, timeoutType, mutexTimeoutMs);
|
||||
if (reset) {
|
||||
mapIterator = healthMap.begin();
|
||||
}
|
||||
@ -94,7 +90,5 @@ ReturnValue_t HealthTable::iterate(
|
||||
}
|
||||
*value = *mapIterator;
|
||||
mapIterator++;
|
||||
mutex->unlockMutex |