Merge branch 'mueller/master' into mueller/DHB_separating_steps
This commit is contained in:
commit
d22c6a5fe9
@ -1,9 +1,11 @@
|
|||||||
#include "ActionHelper.h"
|
#include "ActionHelper.h"
|
||||||
#include "HasActionsIF.h"
|
#include "HasActionsIF.h"
|
||||||
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
|
|
||||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) :
|
ActionHelper::ActionHelper(HasActionsIF* setOwner,
|
||||||
owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) {
|
MessageQueueIF* useThisQueue) :
|
||||||
|
owner(setOwner), queueToUse(useThisQueue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionHelper::~ActionHelper() {
|
ActionHelper::~ActionHelper() {
|
||||||
@ -32,13 +34,15 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
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;
|
CommandMessage reply;
|
||||||
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result);
|
||||||
queueToUse->sendMessage(reportTo, &reply);
|
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;
|
CommandMessage reply;
|
||||||
ActionMessage::setCompletionReply(&reply, commandId, result);
|
ActionMessage::setCompletionReply(&reply, commandId, result);
|
||||||
queueToUse->sendMessage(reportTo, &reply);
|
queueToUse->sendMessage(reportTo, &reply);
|
||||||
@ -48,8 +52,8 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
|||||||
queueToUse = queue;
|
queueToUse = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
||||||
store_address_t dataAddress) {
|
ActionId_t actionId, store_address_t dataAddress) {
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
@ -85,21 +89,27 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
|||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
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) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
ipcStore->deleteData(storeAddress);
|
ipcStore->deleteData(storeAddress);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
//We don't need to report the objectId, as we receive REQUESTED data before the completion success message.
|
// We don't need to report the objectId, as we receive REQUESTED data
|
||||||
//True aperiodic replies need to be reported with another dedicated message.
|
// before the completion success message.
|
||||||
|
// True aperiodic replies need to be reported with
|
||||||
|
// another dedicated message.
|
||||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||||
|
|
||||||
//TODO Service Implementation sucks at the moment
|
// TODO: Service Implementation sucks at the moment
|
||||||
|
// TODO: why does it suck and why would someone need to hide the sender?
|
||||||
if (hideSender) {
|
if (hideSender) {
|
||||||
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
result = queueToUse->sendMessage(reportTo, &reply);
|
result = queueToUse->sendMessage(reportTo, &reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK){
|
if (result != HasReturnvaluesIF::RETURN_OK){
|
||||||
ipcStore->deleteData(storeAddress);
|
ipcStore->deleteData(storeAddress);
|
||||||
}
|
}
|
||||||
@ -108,3 +118,39 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
|||||||
|
|
||||||
void ActionHelper::resetHelper() {
|
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);
|
||||||
|
|
||||||
|
// TODO: Service Implementation sucks at the moment
|
||||||
|
// TODO: why does it suck and why would someone need to hide the sender?
|
||||||
|
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_
|
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||||
#define ACTIONHELPER_H_
|
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||||
|
|
||||||
#include "ActionMessage.h"
|
#include "ActionMessage.h"
|
||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
#include "../ipc/MessageQueueIF.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.
|
* Components which use the HasActionIF this helper can be used to handle
|
||||||
* It does handle step messages as well as other answers to action calls. It uses the executeAction function
|
* the action messages.
|
||||||
* of its owner as callback. The call of the initialize function is mandatory and it needs a valid messageQueueIF pointer!
|
* 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;
|
class HasActionsIF;
|
||||||
|
|
||||||
@ -18,7 +21,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Constructor of the action helper
|
* Constructor of the action helper
|
||||||
* @param setOwner Pointer to the owner of the interface
|
* @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);
|
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||||
|
|
||||||
@ -26,28 +30,35 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Function to be called from the owner with a new command message
|
* 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 a valid action message the helper will use the
|
||||||
* If the message is invalid or the callback fails a message reply will be send to the sender of the message automatically.
|
* 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
|
* @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);
|
ReturnValue_t handleActionMessage(CommandMessage* command);
|
||||||
/**
|
/**
|
||||||
* Helper initialize function. Must be called before use of any other helper function
|
* Helper initialize function. Must be called before use of any other
|
||||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional if queue was set in constructor
|
* helper function
|
||||||
|
* @param queueToUse_ Pointer to the messageQueue to be used, optional
|
||||||
|
* if queue was set in constructor
|
||||||
* @return Returns RETURN_OK if successful
|
* @return Returns RETURN_OK if successful
|
||||||
*/
|
*/
|
||||||
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
|
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 step Number of steps already done
|
||||||
* @param reportTo The messageQueueId to report the step message to
|
* @param reportTo The messageQueueId to report the step message to
|
||||||
* @param commandId ID of the executed command
|
* @param commandId ID of the executed command
|
||||||
* @param result Result of the execution
|
* @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
|
* Function to be called by the owner to send a action completion message
|
||||||
*
|
*
|
||||||
@ -55,39 +66,59 @@ public:
|
|||||||
* @param commandId ID of the executed command
|
* @param commandId ID of the executed command
|
||||||
* @param result Result of the execution
|
* @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
|
* 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 reportTo MessageQueueId_t to report the action completion
|
||||||
|
* message to
|
||||||
* @param replyId ID of the executed command
|
* @param replyId ID of the executed command
|
||||||
* @param data Pointer to the data
|
* @param data Pointer to the data
|
||||||
* @return Returns RETURN_OK if successful, otherwise failure code
|
* @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 setup the MessageQueueIF* of the helper. Can be used to set the messageQueueIF* if
|
* Function to be called by the owner if an action does report data.
|
||||||
* message queue is unavailable at construction and initialize but must be setup before first call of other functions.
|
* 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.
|
||||||
* @param queue Queue to be used by the helper
|
* @param queue Queue to be used by the helper
|
||||||
*/
|
*/
|
||||||
void setQueueToUse(MessageQueueIF *queue);
|
void setQueueToUse(MessageQueueIF *queue);
|
||||||
protected:
|
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
|
HasActionsIF* owner;//!< Pointer to the owner
|
||||||
MessageQueueIF* queueToUse;//!< Queue to be used as response sender, has to be set with
|
//! Queue to be used as response sender, has to be set in ctor or with
|
||||||
StorageManagerIF* ipcStore;//!< Pointer to an IPC Store, initialized during construction or initialize(MessageQueueIF* queueToUse_) or with setQueueToUse(MessageQueueIF *queue)
|
//! 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 commandedBy MessageQueueID of Commander
|
||||||
* @param actionId ID of action to be done
|
* @param actionId ID of action to be done
|
||||||
* @param dataAddress Address of additional data in IPC Store
|
* @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();
|
virtual void resetHelper();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ACTIONHELPER_H_ */
|
#endif /* FSFW_ACTION_ACTIONHELPER_H_ */
|
||||||
|
@ -47,10 +47,9 @@ public:
|
|||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
/**
|
/**
|
||||||
* Execute or initialize the execution of a certain function.
|
* Execute or initialize the execution of a certain function.
|
||||||
* Returning #EXECUTION_FINISHED or a failure code, nothing else needs to
|
* When used in conjunction with the ActionHelper class, returning
|
||||||
* be done. When needing more steps, return RETURN_OK and issue steps and
|
* a return code which is not equal to RETURN_OK will trigger a step reply
|
||||||
* completion manually.
|
* with step 0.
|
||||||
* One "step failed" or completion report must be issued!
|
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t executeAction(ActionId_t actionId,
|
virtual ReturnValue_t executeAction(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_
|
#ifndef FSFW_CONTAINER_ARRAYLIST_H_
|
||||||
#define FRAMEWORK_CONTAINER_ARRAYLIST_H_
|
#define FSFW_CONTAINER_ARRAYLIST_H_
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
@ -20,6 +20,30 @@ public:
|
|||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the allocating constructor.
|
||||||
|
* It allocates an array of the specified size.
|
||||||
|
* @param maxSize
|
||||||
|
*/
|
||||||
|
ArrayList(count_t maxSize) :
|
||||||
|
size(0), maxSize_(maxSize), allocated(true) {
|
||||||
|
entries = new T[maxSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the non-allocating constructor
|
||||||
|
*
|
||||||
|
* It expects a pointer to an array of a certain size and initializes
|
||||||
|
* itself to it.
|
||||||
|
*
|
||||||
|
* @param storage the array to use as backend
|
||||||
|
* @param maxSize size of storage
|
||||||
|
* @param size size of data already present in storage
|
||||||
|
*/
|
||||||
|
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
|
||||||
|
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
||||||
* It is too ambigous in this case.
|
* It is too ambigous in this case.
|
||||||
@ -33,30 +57,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
count_t size;
|
count_t size;
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the allocating constructor;
|
|
||||||
*
|
|
||||||
* It allocates an array of the specified size.
|
|
||||||
*
|
|
||||||
* @param maxSize
|
|
||||||
*/
|
|
||||||
ArrayList(count_t maxSize) :
|
|
||||||
size(0), maxSize_(maxSize), allocated(true) {
|
|
||||||
entries = new T[maxSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the non-allocating constructor
|
|
||||||
*
|
|
||||||
* It expects a pointer to an array of a certain size and initializes itself to it.
|
|
||||||
*
|
|
||||||
* @param storage the array to use as backend
|
|
||||||
* @param maxSize size of storage
|
|
||||||
* @param size size of data already present in storage
|
|
||||||
*/
|
|
||||||
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
|
|
||||||
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor, if the allocating constructor was used, it deletes the array.
|
* Destructor, if the allocating constructor was used, it deletes the array.
|
||||||
@ -116,7 +116,11 @@ public:
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator*() {
|
T& operator*() {
|
||||||
|
return *value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const {
|
||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,18 +131,18 @@ public:
|
|||||||
const T *operator->() const {
|
const T *operator->() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//SHOULDDO this should be implemented as non-member
|
|
||||||
bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{
|
|
||||||
return (value == other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//SHOULDDO this should be implemented as non-member
|
|
||||||
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
friend bool operator==(const ArrayList::Iterator& lhs,
|
||||||
|
const ArrayList::Iterator& rhs) {
|
||||||
|
return (lhs.value == rhs.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const ArrayList::Iterator& lhs,
|
||||||
|
const ArrayList::Iterator& rhs) {
|
||||||
|
return not (lhs.value == rhs.value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator pointing to the first stored elmement
|
* Iterator pointing to the first stored elmement
|
||||||
*
|
*
|
||||||
@ -192,7 +196,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return maximum number of elements
|
* @return maximum number of elements
|
||||||
*/
|
*/
|
||||||
uint32_t maxSize() const {
|
size_t maxSize() const {
|
||||||
return this->maxSize_;
|
return this->maxSize_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +240,7 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* remembering the maximum size
|
* remembering the maximum size
|
||||||
*/
|
*/
|
||||||
uint32_t maxSize_;
|
size_t maxSize_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if the array was allocated and needs to be deleted in the destructor.
|
* true if the array was allocated and needs to be deleted in the destructor.
|
||||||
@ -244,4 +248,6 @@ protected:
|
|||||||
bool allocated;
|
bool allocated;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ARRAYLIST_H_ */
|
|
||||||
|
|
||||||
|
#endif /* FSFW_CONTAINER_ARRAYLIST_H_ */
|
||||||
|
@ -27,14 +27,27 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom copy constructor which prevents setting the
|
* @brief Custom copy constructor which prevents setting the
|
||||||
* underlying pointer wrong.
|
* underlying pointer wrong. This function allocates memory!
|
||||||
|
* @details This is a very heavy operation so try to avoid this!
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
|
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
|
||||||
fifoVector(other.maxCapacity) {
|
fifoVector(other.maxCapacity) {
|
||||||
|
this->fifoVector = other.fifoVector;
|
||||||
this->setContainer(fifoVector.data());
|
this->setContainer(fifoVector.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom assignment operator
|
||||||
|
* @details This is a very heavy operation so try to avoid this!
|
||||||
|
* @param other DyamicFIFO to copy from
|
||||||
|
*/
|
||||||
|
DynamicFIFO& operator=(const DynamicFIFO& other){
|
||||||
|
FIFOBase<T>::operator=(other);
|
||||||
|
this->fifoVector = other.fifoVector;
|
||||||
|
this->setContainer(fifoVector.data());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::vector<T> fifoVector;
|
std::vector<T> fifoVector;
|
||||||
};
|
};
|
||||||
|
@ -25,9 +25,21 @@ public:
|
|||||||
* @param other
|
* @param other
|
||||||
*/
|
*/
|
||||||
FIFO(const FIFO& other): FIFOBase<T>(other) {
|
FIFO(const FIFO& other): FIFOBase<T>(other) {
|
||||||
|
this->fifoArray = other.fifoArray;
|
||||||
this->setContainer(fifoArray.data());
|
this->setContainer(fifoArray.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom assignment operator
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
FIFO& operator=(const FIFO& other){
|
||||||
|
FIFOBase<T>::operator=(other);
|
||||||
|
this->fifoArray = other.fifoArray;
|
||||||
|
this->setContainer(fifoArray.data());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<T, capacity> fifoArray;
|
std::array<T, capacity> fifoArray;
|
||||||
};
|
};
|
||||||
|
@ -19,32 +19,46 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Insert value into FIFO
|
* Insert value into FIFO
|
||||||
* @param value
|
* @param value
|
||||||
* @return
|
* @return RETURN_OK on success, FULL if full
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(T value);
|
ReturnValue_t insert(T value);
|
||||||
/**
|
/**
|
||||||
* Retrieve item from FIFO. This removes the item from the FIFO.
|
* Retrieve item from FIFO. This removes the item from the FIFO.
|
||||||
* @param value
|
* @param value Must point to a valid T
|
||||||
* @return
|
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||||
*/
|
*/
|
||||||
ReturnValue_t retrieve(T *value);
|
ReturnValue_t retrieve(T *value);
|
||||||
/**
|
/**
|
||||||
* Retrieve item from FIFO without removing it from FIFO.
|
* Retrieve item from FIFO without removing it from FIFO.
|
||||||
* @param value
|
* @param value Must point to a valid T
|
||||||
* @return
|
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
|
||||||
*/
|
*/
|
||||||
ReturnValue_t peek(T * value);
|
ReturnValue_t peek(T * value);
|
||||||
/**
|
/**
|
||||||
* Remove item from FIFO.
|
* Remove item from FIFO.
|
||||||
* @return
|
* @return RETURN_OK on success, EMPTY if empty
|
||||||
*/
|
*/
|
||||||
ReturnValue_t pop();
|
ReturnValue_t pop();
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Check if FIFO is empty
|
||||||
|
* @return True if empty, False if not
|
||||||
|
*/
|
||||||
bool empty();
|
bool empty();
|
||||||
|
/***
|
||||||
|
* Check if FIFO is Full
|
||||||
|
* @return True if full, False if not
|
||||||
|
*/
|
||||||
bool full();
|
bool full();
|
||||||
|
/***
|
||||||
|
* Current used size (elements) used
|
||||||
|
* @return size_t in elements
|
||||||
|
*/
|
||||||
size_t size();
|
size_t size();
|
||||||
|
/***
|
||||||
|
* Get maximal capacity of fifo
|
||||||
|
* @return size_t with max capacity of this fifo
|
||||||
|
*/
|
||||||
size_t getMaxCapacity() const;
|
size_t getMaxCapacity() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -26,6 +26,9 @@ inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
|
|||||||
if (empty()) {
|
if (empty()) {
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
} else {
|
} else {
|
||||||
|
if (value == nullptr){
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
*value = values[readIndex];
|
*value = values[readIndex];
|
||||||
readIndex = next(readIndex);
|
readIndex = next(readIndex);
|
||||||
--currentSize;
|
--currentSize;
|
||||||
@ -38,6 +41,9 @@ inline ReturnValue_t FIFOBase<T>::peek(T* value) {
|
|||||||
if(empty()) {
|
if(empty()) {
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
} else {
|
} else {
|
||||||
|
if (value == nullptr){
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
*value = values[readIndex];
|
*value = values[readIndex];
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,51 +1,32 @@
|
|||||||
#ifndef FIXEDARRAYLIST_H_
|
#ifndef FIXEDARRAYLIST_H_
|
||||||
#define FIXEDARRAYLIST_H_
|
#define FIXEDARRAYLIST_H_
|
||||||
|
|
||||||
#include "../container/ArrayList.h"
|
#include "ArrayList.h"
|
||||||
|
#include <cmath>
|
||||||
/**
|
/**
|
||||||
* @brief Array List with a fixed maximum size
|
* \ingroup container
|
||||||
* @ingroup container
|
|
||||||
*/
|
*/
|
||||||
template<typename T, uint32_t MAX_SIZE, typename count_t = uint8_t>
|
template<typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
||||||
class FixedArrayList: public ArrayList<T, count_t> {
|
class FixedArrayList: public ArrayList<T, count_t> {
|
||||||
|
static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
|
||||||
private:
|
private:
|
||||||
T data[MAX_SIZE];
|
T data[MAX_SIZE];
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* (Robin) Maybe we should also implement move assignment and move ctor.
|
|
||||||
* Or at least delete them.
|
|
||||||
*/
|
|
||||||
FixedArrayList() :
|
FixedArrayList() :
|
||||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Robin): We could create a constructor to initialize the fixed array list
|
|
||||||
// with data and the known size field
|
|
||||||
// so it can be used for serialization too (with SerialFixedArrrayListAdapter)
|
|
||||||
// is this feasible?
|
|
||||||
/**
|
|
||||||
* Initialize a fixed array list with data and number of data fields.
|
|
||||||
* Endianness of entries can be swapped optionally.
|
|
||||||
* @param data_
|
|
||||||
* @param count
|
|
||||||
* @param swapArrayListEndianess
|
|
||||||
*/
|
|
||||||
FixedArrayList(T * data_, count_t count):
|
|
||||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
|
||||||
memcpy(this->data, data_, count * sizeof(T));
|
|
||||||
this->size = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
FixedArrayList(const FixedArrayList& other) :
|
FixedArrayList(const FixedArrayList& other) :
|
||||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
memcpy(this->data, other.data, sizeof(this->data));
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
|
this->size = other.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedArrayList& operator=(FixedArrayList other) {
|
FixedArrayList& operator=(FixedArrayList other) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
memcpy(this->data, other.data, sizeof(this->data));
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
|
this->size = other.size;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
#ifndef FIXEDMAP_H_
|
#ifndef FSFW_CONTAINER_FIXEDMAP_H_
|
||||||
#define FIXEDMAP_H_
|
#define FSFW_CONTAINER_FIXEDMAP_H_
|
||||||
|
|
||||||
#include "../container/ArrayList.h"
|
#include "ArrayList.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map implementation for maps with a pre-defined size.
|
* @brief Map implementation for maps with a pre-defined size.
|
||||||
* @details Can be initialized with desired maximum size.
|
* @details
|
||||||
* Iterator is used to access <key,value> pair and
|
* Can be initialized with desired maximum size.
|
||||||
* iterate through map entries. Complexity O(n).
|
* Iterator is used to access <key,value> pair and iterate through map entries.
|
||||||
|
* Complexity O(n).
|
||||||
|
* @warning Iterators return a non-const key_t in the pair.
|
||||||
|
* @warning A User is not allowed to change the key, otherwise the map is corrupted.
|
||||||
* @ingroup container
|
* @ingroup container
|
||||||
*/
|
*/
|
||||||
template<typename key_t, typename T>
|
template<typename key_t, typename T>
|
||||||
class FixedMap: public SerializeIF {
|
class FixedMap: public SerializeIF {
|
||||||
|
static_assert (std::is_trivially_copyable<T>::value or
|
||||||
|
std::is_base_of<SerializeIF, T>::value,
|
||||||
|
"Types used in FixedMap must either be trivial copy-able or a "
|
||||||
|
"derived class from SerializeIF to be serialize-able");
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
||||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
||||||
@ -51,28 +59,17 @@ public:
|
|||||||
Iterator(std::pair<key_t, T> *pair) :
|
Iterator(std::pair<key_t, T> *pair) :
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
|
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator*() {
|
|
||||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -> operator overloaded, can be used to access value
|
|
||||||
T *operator->() {
|
|
||||||
return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can be used to access the key of the iterator
|
|
||||||
key_t first() {
|
|
||||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternative to access value, similar to std::map implementation
|
|
||||||
T second() {
|
|
||||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
friend bool operator==(const typename FixedMap::Iterator& lhs,
|
||||||
|
const typename FixedMap::Iterator& rhs) {
|
||||||
|
return (lhs.value == rhs.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const typename FixedMap::Iterator& lhs,
|
||||||
|
const typename FixedMap::Iterator& rhs) {
|
||||||
|
return not (lhs.value == rhs.value);
|
||||||
|
}
|
||||||
|
|
||||||
Iterator begin() const {
|
Iterator begin() const {
|
||||||
return Iterator(&theMap[0]);
|
return Iterator(&theMap[0]);
|
||||||
@ -86,16 +83,16 @@ public:
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) {
|
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) {
|
||||||
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
||||||
return FixedMap::KEY_ALREADY_EXISTS;
|
return KEY_ALREADY_EXISTS;
|
||||||
}
|
}
|
||||||
if (_size == theMap.maxSize()) {
|
if (_size == theMap.maxSize()) {
|
||||||
return FixedMap::MAP_FULL;
|
return MAP_FULL;
|
||||||
}
|
}
|
||||||
theMap[_size].first = key;
|
theMap[_size].first = key;
|
||||||
theMap[_size].second = value;
|
theMap[_size].second = value;
|
||||||
if (storedValue != NULL) {
|
if (storedValue != nullptr) {
|
||||||
*storedValue = Iterator(&theMap[_size]);
|
*storedValue = Iterator(&theMap[_size]);
|
||||||
}
|
}
|
||||||
++_size;
|
++_size;
|
||||||
@ -156,6 +153,24 @@ public:
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool empty() {
|
||||||
|
if(_size == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool full() {
|
||||||
|
if(_size >= theMap.maxSize()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_size = 0;
|
_size = 0;
|
||||||
}
|
}
|
||||||
@ -164,16 +179,6 @@ public:
|
|||||||
return theMap.maxSize();
|
return theMap.maxSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool full() {
|
|
||||||
if(_size == theMap.maxSize()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||||
size_t maxSize, Endianness streamEndianness) const {
|
size_t maxSize, Endianness streamEndianness) const {
|
||||||
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
|
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
|
||||||
@ -222,4 +227,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FIXEDMAP_H_ */
|
#endif /* FSFW_CONTAINER_FIXEDMAP_H_ */
|
||||||
|
@ -1,171 +1,206 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
#ifndef FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||||
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
#define FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||||
|
|
||||||
#include "../container/ArrayList.h"
|
#include "ArrayList.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <set>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map implementation which allows entries with identical keys
|
* @brief An associative container which allows multiple entries of the same key.
|
||||||
* @details
|
* @details
|
||||||
* Performs no dynamic memory allocation except on initialization.
|
* Same keys are ordered by KEY_COMPARE function which is std::less<key_t> > by default.
|
||||||
* Uses an ArrayList as the underlying container and thus has a linear
|
*
|
||||||
|
* It uses the ArrayList, so technically this is not a real map, it is an array of pairs
|
||||||
|
* of type key_t, T. It is ordered by key_t as FixedMap but allows same keys. Thus it has a linear
|
||||||
* complexity O(n). As long as the number of entries remains low, this
|
* complexity O(n). As long as the number of entries remains low, this
|
||||||
* should not be an issue.
|
* should not be an issue.
|
||||||
* The number of insertion and deletion operation should be minimized
|
* The number of insertion and deletion operation should be minimized
|
||||||
* as those incur exensive memory move operations (the underlying container
|
* as those incur extensive memory move operations (the underlying container
|
||||||
* is not node based).
|
* is not node based).
|
||||||
* @ingroup container
|
*
|
||||||
|
* Its of fixed size so no allocations are performed after the construction.
|
||||||
|
*
|
||||||
|
* The maximum size is given as first parameter of the constructor.
|
||||||
|
*
|
||||||
|
* It provides an iterator to do list iterations.
|
||||||
|
*
|
||||||
|
* The type T must have a copy constructor if it is not trivial copy-able.
|
||||||
|
*
|
||||||
|
* @warning Iterators return a non-const key_t in the pair.
|
||||||
|
* @warning A User is not allowed to change the key, otherwise the map is corrupted.
|
||||||
|
*
|
||||||
|
* \ingroup container
|
||||||
*/
|
*/
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
||||||
class FixedOrderedMultimap {
|
class FixedOrderedMultimap {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
||||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01);
|
||||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02);
|
||||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
|
||||||
|
|
||||||
/**
|
/***
|
||||||
* Initializes the ordered multimap with a fixed maximum size.
|
* Constructor which needs a size_t for the maximum allowed size
|
||||||
* @param maxSize
|
*
|
||||||
|
* Can not be resized during runtime
|
||||||
|
*
|
||||||
|
* Allocates memory at construction
|
||||||
|
* @param maxSize size_t of Maximum allowed size
|
||||||
*/
|
*/
|
||||||
FixedOrderedMultimap(size_t maxSize);
|
FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~FixedOrderedMultimap() {}
|
/***
|
||||||
|
* Virtual destructor frees Memory by deleting its member
|
||||||
|
*/
|
||||||
|
virtual ~FixedOrderedMultimap() {
|
||||||
|
}
|
||||||
|
|
||||||
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
|
/***
|
||||||
|
* Special iterator for FixedOrderedMultimap
|
||||||
|
*/
|
||||||
|
class Iterator: public ArrayList<std::pair<key_t, T>, size_t>::Iterator {
|
||||||
public:
|
public:
|
||||||
/** Returns an iterator to nullptr */
|
Iterator() :
|
||||||
Iterator();
|
ArrayList<std::pair<key_t, T>, size_t>::Iterator() {
|
||||||
/** Initializes iterator to given entry */
|
}
|
||||||
Iterator(std::pair<key_t, T> *pair);
|
|
||||||
/** Dereference operator can be used to get value */
|
Iterator(std::pair<key_t, T> *pair) :
|
||||||
T operator*();
|
ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) {
|
||||||
/** Arrow operator can be used to get pointer to value */
|
}
|
||||||
T *operator->();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Iterator to start of map */
|
/***
|
||||||
Iterator begin() const;
|
* Returns an iterator pointing to the first element
|
||||||
/** Iterator to end of map */
|
* @return Iterator pointing to first element
|
||||||
Iterator end() const;
|
*/
|
||||||
/** Current (variable) size of the map */
|
Iterator begin() const {
|
||||||
size_t size() const;
|
return Iterator(&theMap[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a key/value pair inside the map. An iterator to the stored
|
* Returns an iterator pointing to one element past the end
|
||||||
* value might be returned optionally.
|
* @return Iterator pointing to one element past the end
|
||||||
* @param key
|
*/
|
||||||
* @param value
|
Iterator end() const {
|
||||||
* @param storedValue
|
return Iterator(&theMap[_size]);
|
||||||
* @return
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Returns the current size of the map (not maximum size!)
|
||||||
|
* @return Current size
|
||||||
|
*/
|
||||||
|
size_t size() const{
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the map, does not deallocate any memory
|
||||||
|
*/
|
||||||
|
void clear(){
|
||||||
|
_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum size of the map
|
||||||
|
* @return Maximum size of the map
|
||||||
|
*/
|
||||||
|
size_t maxSize() const{
|
||||||
|
return theMap.maxSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Used to insert a key and value separately.
|
||||||
|
*
|
||||||
|
* @param[in] key Key of the new element
|
||||||
|
* @param[in] value Value of the new element
|
||||||
|
* @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr
|
||||||
|
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
|
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
|
||||||
/**
|
|
||||||
* Insert a given std::pair<key, value>
|
/***
|
||||||
* @param pair
|
* Used to insert new pair instead of single values
|
||||||
* @return
|
*
|
||||||
|
* @param pair Pair to be inserted
|
||||||
|
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insert(std::pair<key_t, T> pair);
|
ReturnValue_t insert(std::pair<key_t, T> pair);
|
||||||
/**
|
|
||||||
* Checks existence of key in map.
|
/***
|
||||||
* @param key
|
* Can be used to check if a certain key is in the map
|
||||||
* @return
|
* @param key Key to be checked
|
||||||
* - @c KEY_DOES_NOT_EXIST if key does not exists.
|
* @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise
|
||||||
* - @c RETURN_OK otherwise.
|
|
||||||
*/
|
*/
|
||||||
ReturnValue_t exists(key_t key) const;
|
ReturnValue_t exists(key_t key) const;
|
||||||
|
|
||||||
ReturnValue_t erase(Iterator *iter) {
|
/***
|
||||||
uint32_t i;
|
* Used to delete the element in the iterator
|
||||||
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
|
*
|
||||||
return KEY_DOES_NOT_EXIST;
|
* The iterator will point to the element before or begin(),
|
||||||
}
|
* but never to one element in front of the map.
|
||||||
removeFromPosition(i);
|
*
|
||||||
if (*iter != begin()) {
|
* @warning The iterator needs to be valid and dereferenceable
|
||||||
(*iter)--;
|
* @param[in/out] iter Pointer to iterator to the element that needs to be ereased
|
||||||
} else {
|
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||||
*iter = begin();
|
*/
|
||||||
}
|
ReturnValue_t erase(Iterator *iter);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t erase(key_t key) {
|
/***
|
||||||
uint32_t i;
|
* Used to erase by key
|
||||||
if ((i = findFirstIndex(key)) >= _size) {
|
* @param key Key to be erased
|
||||||
return KEY_DOES_NOT_EXIST;
|
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
|
||||||
}
|
*/
|
||||||
do {
|
ReturnValue_t erase(key_t key);
|
||||||
removeFromPosition(i);
|
|
||||||
i = findFirstIndex(key, i);
|
|
||||||
} while (i < _size);
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Find returns the first appearance of the key
|
||||||
|
*
|
||||||
|
* If the key does not exist, it points to end()
|
||||||
|
*
|
||||||
|
* @param key Key to search for
|
||||||
|
* @return Iterator pointing to the first entry of key
|
||||||
|
*/
|
||||||
Iterator find(key_t key) const{
|
Iterator find(key_t key) const{
|
||||||
ReturnValue_t result = exists(key);
|
ReturnValue_t result = exists(key);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
return Iterator(&theMap[findFirstIndex(key)]);
|
return Iterator(&theMap[findFirstIndex(key)]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Finds first entry of the given key and returns a
|
||||||
|
* pointer to the value
|
||||||
|
*
|
||||||
|
* @param key Key to search for
|
||||||
|
* @param value Found value
|
||||||
|
* @return RETURN_OK if it points to the value,
|
||||||
|
* KEY_DOES_NOT_EXIST if the key is not in the map
|
||||||
|
*/
|
||||||
|
ReturnValue_t find(key_t key, T **value) const;
|
||||||
|
|
||||||
|
friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||||
|
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||||
|
return (lhs.value == rhs.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t find(key_t key, T **value) const {
|
friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs,
|
||||||
ReturnValue_t result = exists(key);
|
const typename FixedOrderedMultimap::Iterator& rhs) {
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
return not (lhs.value == rhs.value);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
*value = &theMap[findFirstIndex(key)].second;
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t maxSize() const {
|
|
||||||
return theMap.maxSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef KEY_COMPARE compare;
|
typedef KEY_COMPARE compare;
|
||||||
compare myComp;
|
compare myComp;
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
ArrayList<std::pair<key_t, T>, size_t> theMap;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
|
|
||||||
uint32_t findFirstIndex(key_t key, uint32_t startAt = 0) const {
|
size_t findFirstIndex(key_t key, size_t startAt = 0) const;
|
||||||
if (startAt >= _size) {
|
|
||||||
return startAt + 1;
|
|
||||||
}
|
|
||||||
uint32_t i = startAt;
|
|
||||||
for (i = startAt; i < _size; ++i) {
|
|
||||||
if (theMap[i].first == key) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t findNicePlace(key_t key) const {
|
size_t findNicePlace(key_t key) const;
|
||||||
uint32_t i = 0;
|
|
||||||
for (i = 0; i < _size; ++i) {
|
|
||||||
if (myComp(key, theMap[i].first)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeFromPosition(uint32_t position) {
|
void removeFromPosition(size_t position);
|
||||||
if (_size <= position) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memmove(&theMap[position], &theMap[position + 1],
|
|
||||||
(_size - position - 1) * sizeof(std::pair<key_t,T>));
|
|
||||||
--_size;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "FixedOrderedMultimap.tpp"
|
#include "FixedOrderedMultimap.tpp"
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */
|
#endif /* FSFW_CONTAINER_FIXEDORDEREDMULTIMAP_H_ */
|
||||||
|
@ -1,59 +1,14 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
|
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
|
||||||
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
|
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::Iterator():
|
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(){}
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::Iterator(
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) {
|
||||||
std::pair<key_t, T> *pair):
|
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair){}
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline T FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::operator*() {
|
|
||||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline typename FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator
|
|
||||||
FixedOrderedMultimap<key_t, T, KEY_COMPARE>::begin() const {
|
|
||||||
return Iterator(&theMap[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline typename FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator
|
|
||||||
FixedOrderedMultimap<key_t, T, KEY_COMPARE>::end() const {
|
|
||||||
return Iterator(&theMap[_size]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::size() const {
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline T* FixedOrderedMultimap<key_t, T, KEY_COMPARE>::Iterator::operator->() {
|
|
||||||
return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline FixedOrderedMultimap<key_t, T, KEY_COMPARE>::FixedOrderedMultimap(
|
|
||||||
size_t maxSize): theMap(maxSize), _size(0) {}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(
|
|
||||||
key_t key, T value, Iterator *storedValue) {
|
|
||||||
if (_size == theMap.maxSize()) {
|
if (_size == theMap.maxSize()) {
|
||||||
return MAP_FULL;
|
return MAP_FULL;
|
||||||
}
|
}
|
||||||
uint32_t position = findNicePlace(key);
|
size_t position = findNicePlace(key);
|
||||||
// Compiler might emitt warning because std::pair is not a POD type (yet..)
|
memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]),
|
||||||
// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm#std::pair-example
|
|
||||||
// Should still work without issues.
|
|
||||||
std::memmove(&theMap[position + 1], &theMap[position],
|
|
||||||
(_size - position) * sizeof(std::pair<key_t,T>));
|
(_size - position) * sizeof(std::pair<key_t,T>));
|
||||||
theMap[position].first = key;
|
theMap[position].first = key;
|
||||||
theMap[position].second = value;
|
theMap[position].second = value;
|
||||||
@ -63,16 +18,13 @@ inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(
|
|||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) {
|
||||||
std::pair<key_t, T> pair) {
|
return insert(pair.first, pair.second);
|
||||||
return insert(pair.fist, pair.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename key_t, typename T, typename KEY_COMPARE>
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const {
|
||||||
key_t key) const {
|
|
||||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
||||||
if (findFirstIndex(key) < _size) {
|
if (findFirstIndex(key) < _size) {
|
||||||
result = HasReturnvaluesIF::RETURN_OK;
|
result = HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -80,4 +32,78 @@ inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) {
|
||||||
|
size_t i;
|
||||||
|
if ((i = findFirstIndex((*iter).value->first)) >= _size) {
|
||||||
|
return KEY_DOES_NOT_EXIST;
|
||||||
|
}
|
||||||
|
removeFromPosition(i);
|
||||||
|
if (*iter != begin()) {
|
||||||
|
(*iter)--;
|
||||||
|
} else {
|
||||||
|
*iter = begin();
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) {
|
||||||
|
size_t i;
|
||||||
|
if ((i = findFirstIndex(key)) >= _size) {
|
||||||
|
return KEY_DOES_NOT_EXIST;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
removeFromPosition(i);
|
||||||
|
i = findFirstIndex(key, i);
|
||||||
|
} while (i < _size);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
|
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const {
|
||||||
|
ReturnValue_t result = exists(key);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
*value = &theMap[findFirstIndex(key)].second;
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
|
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const {
|
||||||
|
if (startAt >= _size) {
|
||||||
|
return startAt + 1;
|
||||||
|
}
|
||||||
|
size_t i = startAt;
|
||||||
|
for (i = startAt; i < _size; ++i) {
|
||||||
|
if (theMap[i].first == key) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
|
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const {
|
||||||
|
size_t i = 0;
|
||||||
|
for (i = 0; i < _size; ++i) {
|
||||||
|
if (myComp(key, theMap[i].first)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename key_t, typename T, typename KEY_COMPARE>
|
||||||
|
inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) {
|
||||||
|
if (_size <= position) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]),
|
||||||
|
(_size - position - 1) * sizeof(std::pair<key_t,T>));
|
||||||
|
--_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */
|
#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
|
#ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
|
||||||
#define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
|
#define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
|
||||||
|
|
||||||
#include "../container/ArrayList.h"
|
#include "ArrayList.h"
|
||||||
#include "../container/SinglyLinkedList.h"
|
#include "SinglyLinkedList.h"
|
||||||
|
|
||||||
template<typename T, typename count_t = uint8_t>
|
template<typename T, typename count_t = uint8_t>
|
||||||
class HybridIterator: public LinkedElement<T>::Iterator,
|
class HybridIterator: public LinkedElement<T>::Iterator,
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
#ifndef ISDERIVEDFROM_H_
|
|
||||||
#define ISDERIVEDFROM_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* These template type checks are based on SFINAE
|
|
||||||
* (https://en.cppreference.com/w/cpp/language/sfinae)
|
|
||||||
*
|
|
||||||
* @tparam D Derived Type
|
|
||||||
* @tparam B Base Type
|
|
||||||
*/
|
|
||||||
template<typename D, typename B>
|
|
||||||
class IsDerivedFrom {
|
|
||||||
class No {
|
|
||||||
};
|
|
||||||
class Yes {
|
|
||||||
No no[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
// This will be chosen if B is the base type
|
|
||||||
static Yes Test(B*); // declared, but not defined
|
|
||||||
// This will be chosen for anything else
|
|
||||||
static No Test(... ); // declared, but not defined
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename, typename>
|
|
||||||
struct is_same {
|
|
||||||
static bool const value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename A>
|
|
||||||
struct is_same<A, A> {
|
|
||||||
static bool const value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<bool C, typename T = void>
|
|
||||||
struct enable_if {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct enable_if<false, T> { };
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ISDERIVEDFROM_H_ */
|
|
@ -3,26 +3,62 @@
|
|||||||
|
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "../storagemanager/StorageManagerIF.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
/**
|
||||||
|
* The Placement Factory is used to create objects at runtime in a specific pool.
|
||||||
|
* In general, this should be avoided and it should only be used if you know what you are doing.
|
||||||
|
* You are not allowed to use this container with a type that allocates memory internally like ArrayList.
|
||||||
|
*
|
||||||
|
* Also, you have to check the returned pointer in generate against nullptr!
|
||||||
|
*
|
||||||
|
* A backend of Type StorageManagerIF must be given as a place to store the new objects.
|
||||||
|
* Therefore ThreadSafety is only provided by your StorageManager Implementation.
|
||||||
|
*
|
||||||
|
* Objects must be destroyed by the user with "destroy"! Otherwise the pool will not be cleared.
|
||||||
|
*
|
||||||
|
* The concept is based on the placement new operator.
|
||||||
|
*
|
||||||
|
* @warning Do not use with any Type that allocates memory internally!
|
||||||
|
* @ingroup container
|
||||||
|
*/
|
||||||
class PlacementFactory {
|
class PlacementFactory {
|
||||||
public:
|
public:
|
||||||
PlacementFactory(StorageManagerIF* backend) :
|
PlacementFactory(StorageManagerIF* backend) :
|
||||||
dataBackend(backend) {
|
dataBackend(backend) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Generates an object of type T in the backend storage.
|
||||||
|
*
|
||||||
|
* @warning Do not use with any Type that allocates memory internally!
|
||||||
|
*
|
||||||
|
* @tparam T Type of Object
|
||||||
|
* @param args Constructor Arguments to be passed
|
||||||
|
* @return A pointer to the new object or a nullptr in case of failure
|
||||||
|
*/
|
||||||
template<typename T, typename ... Args>
|
template<typename T, typename ... Args>
|
||||||
T* generate(Args&&... args) {
|
T* generate(Args&&... args) {
|
||||||
store_address_t tempId;
|
store_address_t tempId;
|
||||||
uint8_t* pData = NULL;
|
uint8_t* pData = nullptr;
|
||||||
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
|
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
|
||||||
&pData);
|
&pData);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
T* temp = new (pData) T(std::forward<Args>(args)...);
|
T* temp = new (pData) T(std::forward<Args>(args)...);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
/***
|
||||||
|
* Function to destroy the object allocated with generate and free space in backend.
|
||||||
|
* This must be called by the user.
|
||||||
|
*
|
||||||
|
* @param thisElement Element to be destroyed
|
||||||
|
* @return RETURN_OK if the element was destroyed, different errors on failure
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReturnValue_t destroy(T* thisElement) {
|
ReturnValue_t destroy(T* thisElement) {
|
||||||
|
if (thisElement == nullptr){
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
|
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
|
||||||
thisElement->~T();
|
thisElement->~T();
|
||||||
uint8_t* pointer = (uint8_t*) (thisElement);
|
uint8_t* pointer = (uint8_t*) (thisElement);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_
|
#ifndef FSFW_CONTAINER_RINGBUFFERBASE_H_
|
||||||
#define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_
|
#define FSFW_CONTAINER_RINGBUFFERBASE_H_
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -65,6 +65,7 @@ protected:
|
|||||||
size_t read[N_READ_PTRS];
|
size_t read[N_READ_PTRS];
|
||||||
const size_t size;
|
const size_t size;
|
||||||
const bool overwriteOld;
|
const bool overwriteOld;
|
||||||
|
|
||||||
void incrementWrite(uint32_t amount) {
|
void incrementWrite(uint32_t amount) {
|
||||||
write = ((write + amount - start) % size) + start;
|
write = ((write + amount - start) % size) + start;
|
||||||
}
|
}
|
||||||
@ -90,7 +91,6 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t getRead(uint8_t n = 0) const {
|
size_t getRead(uint8_t n = 0) const {
|
||||||
return read[n];
|
return read[n];
|
||||||
}
|
}
|
||||||
@ -110,4 +110,4 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */
|
#endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "SimpleRingBuffer.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
using namespace std;
|
|
||||||
SimpleRingBuffer buffer(64, false);
|
|
||||||
uint8_t data[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
|
|
||||||
ReturnValue_t result = buffer.writeData(data, 8);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
}
|
|
||||||
result = buffer.writeData(data, 8);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
}
|
|
||||||
uint8_t buffer2[47] = {0};
|
|
||||||
for (uint8_t count = 0; count<sizeof(buffer2); count++) {
|
|
||||||
buffer2[count] = count;
|
|
||||||
}
|
|
||||||
result = buffer.writeData(buffer2, sizeof(buffer2));
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
}
|
|
||||||
result = buffer.writeData(buffer2, sizeof(buffer2));
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
}
|
|
||||||
uint8_t readBuffer[64] = {0};
|
|
||||||
uint32_t writtenData = 0;
|
|
||||||
result = buffer.readData(readBuffer, 12, true, &writtenData);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "readData failed." << endl;
|
|
||||||
} else {
|
|
||||||
cout << "Read data: " << writtenData << endl;
|
|
||||||
for (uint32_t count = 0; count < writtenData; count++) {
|
|
||||||
cout << hex << (uint16_t)readBuffer[count] << " ";
|
|
||||||
}
|
|
||||||
cout << dec << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = buffer.readData(readBuffer, 60, true, &writtenData);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "readData failed." << endl;
|
|
||||||
} else {
|
|
||||||
cout << "Read data: " << writtenData << endl;
|
|
||||||
for (uint32_t count = 0; count < writtenData; count++) {
|
|
||||||
cout << hex << (uint16_t)readBuffer[count] << " ";
|
|
||||||
}
|
|
||||||
cout << dec << endl;
|
|
||||||
}
|
|
||||||
result = buffer.writeData(data, sizeof(data));
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
}
|
|
||||||
result = buffer.readData(readBuffer, 60, true, &writtenData);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "readData failed." << endl;
|
|
||||||
} else {
|
|
||||||
cout << "Read data: " << writtenData << endl;
|
|
||||||
for (uint32_t count = 0; count < writtenData; count++) {
|
|
||||||
cout << hex << (uint16_t)readBuffer[count] << " ";
|
|
||||||
}
|
|
||||||
cout << dec << endl;
|
|
||||||
}
|
|
||||||
result = buffer.writeData(readBuffer, sizeof(readBuffer));
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
}
|
|
||||||
result = buffer.writeData(readBuffer, sizeof(readBuffer)-1);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
cout << "writeData failed." << endl;
|
|
||||||
} else {
|
|
||||||
cout << "write done." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
#include "../container/SharedRingBuffer.h"
|
#include "SharedRingBuffer.h"
|
||||||
#include "../ipc/MutexFactory.h"
|
#include "../ipc/MutexFactory.h"
|
||||||
#include "../ipc/MutexHelper.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
|
|||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
||||||
const size_t size, bool overwriteOld, size_t maxExcessBytes):
|
const size_t size, bool overwriteOld, size_t maxExcessBytes):
|
||||||
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
|
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
|
||||||
@ -16,6 +17,11 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
|||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SharedRingBuffer::setToUseReceiveSizeFIFO(uint32_t fifoDepth) {
|
||||||
|
this->fifoDepth = fifoDepth;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
|
ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
|
||||||
MutexIF::TimeoutType timeoutType, dur_millis_t timeout) {
|
MutexIF::TimeoutType timeoutType, dur_millis_t timeout) {
|
||||||
return mutex->lockMutex(timeoutType, timeout);
|
return mutex->lockMutex(timeoutType, timeout);
|
||||||
@ -25,6 +31,25 @@ ReturnValue_t SharedRingBuffer::unlockRingBufferMutex() {
|
|||||||
return mutex->unlockMutex();
|
return mutex->unlockMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MutexIF* SharedRingBuffer::getMutexHandle() const {
|
MutexIF* SharedRingBuffer::getMutexHandle() const {
|
||||||
return mutex;
|
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;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
|
#ifndef FSFW_CONTAINER_SHAREDRINGBUFFER_H_
|
||||||
#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
|
#define FSFW_CONTAINER_SHAREDRINGBUFFER_H_
|
||||||
|
|
||||||
#include "../container/SimpleRingBuffer.h"
|
#include "SimpleRingBuffer.h"
|
||||||
|
#include "DynamicFIFO.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../timemanager/Clock.h"
|
#include "../timemanager/Clock.h"
|
||||||
@ -26,6 +27,8 @@ public:
|
|||||||
SharedRingBuffer(object_id_t objectId, const size_t size,
|
SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||||
bool overwriteOld, size_t maxExcessBytes);
|
bool overwriteOld, size_t maxExcessBytes);
|
||||||
|
|
||||||
|
void setToUseReceiveSizeFIFO(uint32_t fifoDepth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor takes an external buffer with the specified size.
|
* This constructor takes an external buffer with the specified size.
|
||||||
* @param buffer
|
* @param buffer
|
||||||
@ -59,10 +62,23 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
MutexIF* getMutexHandle() const;
|
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:
|
private:
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
|
|
||||||
|
size_t fifoDepth = 0;
|
||||||
|
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */
|
#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../container/SimpleRingBuffer.h"
|
#include "SimpleRingBuffer.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
|
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
|
||||||
@ -25,12 +25,10 @@ SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SimpleRingBuffer::~SimpleRingBuffer() {
|
SimpleRingBuffer::~SimpleRingBuffer() {
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
|
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
|
||||||
size_t amount) {
|
size_t amount) {
|
||||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||||
@ -131,5 +129,3 @@ ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
|
|||||||
incrementRead(amount, READ_PTR);
|
incrementRead(amount, READ_PTR);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_
|
#ifndef FSFW_CONTAINER_SIMPLERINGBUFFER_H_
|
||||||
#define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_
|
#define FSFW_CONTAINER_SIMPLERINGBUFFER_H_
|
||||||
|
|
||||||
#include "../container/RingBufferBase.h"
|
#include "RingBufferBase.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,6 +117,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
|
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
|
||||||
size_t* trueAmount = nullptr);
|
size_t* trueAmount = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t READ_PTR = 0;
|
static const uint8_t READ_PTR = 0;
|
||||||
uint8_t* buffer = nullptr;
|
uint8_t* buffer = nullptr;
|
||||||
@ -124,5 +125,5 @@ private:
|
|||||||
size_t excessBytes = 0;
|
size_t excessBytes = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */
|
#endif /* FSFW_CONTAINER_SIMPLERINGBUFFER_H_ */
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ElementIterator back() const {
|
ElementIterator back() const {
|
||||||
LinkedElement<T> *element = start;
|
LinkedElement<T> *element = start;
|
||||||
while (element != nullptr) {
|
while (element->getNext() != nullptr) {
|
||||||
element = element->getNext();
|
element = element->getNext();
|
||||||
}
|
}
|
||||||
return ElementIterator::Iterator(element);
|
return ElementIterator::Iterator(element);
|
||||||
|
@ -1,365 +0,0 @@
|
|||||||
#include "FixedArrayList.h"
|
|
||||||
#include "SinglyLinkedList.h"
|
|
||||||
#include "HybridIterator.h"
|
|
||||||
|
|
||||||
#include "FixedMap.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
class Packet: public SinglyLinkedList {
|
|
||||||
public:
|
|
||||||
SinglyLinkedList::Element<uint32_t> element1;
|
|
||||||
SinglyLinkedList::Element<uint32_t> element2;
|
|
||||||
|
|
||||||
Packet() {
|
|
||||||
this->start = &element1;
|
|
||||||
element1.next = &element2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Packet2: public SinglyLinkedList {
|
|
||||||
public:
|
|
||||||
SinglyLinkedList::Element<uint32_t> element1;
|
|
||||||
SinglyLinkedList::Element<FixedArrayList<FixedArrayList<uint8_t, 5>, 2>> element2;
|
|
||||||
SinglyLinkedList::Element<uint32_t> element3;
|
|
||||||
|
|
||||||
Packet2() {
|
|
||||||
this->start = &element1;
|
|
||||||
element1.next = &element2;
|
|
||||||
element2.next = &element3;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Packet3: public SinglyLinkedList {
|
|
||||||
public:
|
|
||||||
SinglyLinkedList::TypedElement<uint32_t> element1;
|
|
||||||
SinglyLinkedList::TypedElement<uint32_t> element2;
|
|
||||||
|
|
||||||
Packet3() {
|
|
||||||
this->start = &element1;
|
|
||||||
element1.next = &element2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void arrayList() {
|
|
||||||
puts("** Array List **");
|
|
||||||
FixedArrayList<uint32_t, 10, uint32_t> list;
|
|
||||||
FixedArrayList<uint32_t, 10, uint32_t> list2;
|
|
||||||
|
|
||||||
list.size = 2;
|
|
||||||
|
|
||||||
list[0] = 0xcafecafe;
|
|
||||||
|
|
||||||
list[1] = 0x12345678;
|
|
||||||
|
|
||||||
uint8_t buffer[100];
|
|
||||||
uint8_t *pointer = buffer;
|
|
||||||
uint32_t size = 0;
|
|
||||||
uint32_t maxSize = 100;
|
|
||||||
uint32_t i;
|
|
||||||
int32_t size2;
|
|
||||||
|
|
||||||
printf("printsize: %i\n", list.getPrintSize());
|
|
||||||
|
|
||||||
list.print(&pointer, &size, 100, true);
|
|
||||||
|
|
||||||
printf("buffer(%i):", size);
|
|
||||||
for (i = 0; i < size; ++i) {
|
|
||||||
printf("%02x", buffer[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
pointer = buffer;
|
|
||||||
|
|
||||||
size2 = size;
|
|
||||||
|
|
||||||
printf("list2 read: %x\n", list2.read(&pointer, &size2, true));
|
|
||||||
|
|
||||||
printf("list2(%i):", list2.size);
|
|
||||||
for (ArrayList<uint32_t, uint32_t>::Iterator iter = list2.begin();
|
|
||||||
iter != list2.end(); iter++) {
|
|
||||||
printf("0x%04x ", *iter);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
HybridIterator<uint32_t, uint32_t> hiter(list.begin(),list.end());
|
|
||||||
|
|
||||||
printf("hybrid1: 0x%04x\n", *(hiter++));
|
|
||||||
printf("hybrid2: 0x%04x\n", *hiter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void allocatingList() {
|
|
||||||
puts("** Allocating List **");
|
|
||||||
ArrayList<uint8_t> myList(3), myList2(2);
|
|
||||||
myList[0] = 0xab;
|
|
||||||
myList[1] = 0xcd;
|
|
||||||
myList.size = 2;
|
|
||||||
|
|
||||||
uint8_t buffer[100];
|
|
||||||
uint8_t *pointer = buffer;
|
|
||||||
uint32_t size = 0;
|
|
||||||
uint32_t maxSize = 100;
|
|
||||||
uint32_t i;
|
|
||||||
int32_t size2;
|
|
||||||
|
|
||||||
myList.print(&pointer, &size, 100, true);
|
|
||||||
|
|
||||||
pointer = buffer;
|
|
||||||
size2 = size;
|
|
||||||
|
|
||||||
printf("Read %x\n", myList2.read(&pointer, &size2, true));
|
|
||||||
|
|
||||||
printf("%x,%x\n", myList2[0], myList2[1]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void linkedList() {
|
|
||||||
puts("** Linked List **");
|
|
||||||
uint8_t buffer[100];
|
|
||||||
uint8_t *pointer = buffer;
|
|
||||||
uint32_t size = 0;
|
|
||||||
uint32_t maxSize = 100;
|
|
||||||
uint32_t i;
|
|
||||||
int32_t size2;
|
|
||||||
|
|
||||||
Packet myPacket;
|
|
||||||
myPacket.element1.entry = 0x12345678;
|
|
||||||
myPacket.element2.entry = 0x9abcdef0;
|
|
||||||
|
|
||||||
pointer = buffer;
|
|
||||||
size = 0;
|
|
||||||
ReturnValue_t result = myPacket.print(&pointer, &size, 100, true);
|
|
||||||
|
|
||||||
printf("result %02x\n", result);
|
|
||||||
|
|
||||||
printf("printsize: %i\n", myPacket.getPrintSize());
|
|
||||||
|
|
||||||
printf("buffer(%i):", size);
|
|
||||||
for (i = 0; i < size; ++i) {
|
|
||||||
printf("%02x", buffer[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
Packet3 myPacket3;
|
|
||||||
|
|
||||||
myPacket3.element1.entry = 0x12345678;
|
|
||||||
myPacket3.element2.entry = 0xabcdeff;
|
|
||||||
|
|
||||||
SinglyLinkedList::TypedIterator<uint32_t> titer(&myPacket3.element1);
|
|
||||||
|
|
||||||
printf("0x%04x\n", *titer);
|
|
||||||
|
|
||||||
HybridIterator<uint32_t, uint32_t> hiter(&myPacket3.element1);
|
|
||||||
|
|
||||||
printf("hybrid1: 0x%04x\n", *hiter);
|
|
||||||
hiter++;
|
|
||||||
printf("hybrid2: 0x%04x\n", *hiter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void complex() {
|
|
||||||
puts("** complex **");
|
|
||||||
uint8_t buffer[100];
|
|
||||||
uint8_t *pointer = buffer;
|
|
||||||
uint32_t size = 0;
|
|
||||||
uint32_t maxSize = 100;
|
|
||||||
uint32_t i;
|
|
||||||
int32_t size2 = size;
|
|
||||||
|
|
||||||
Packet myPacket2;
|
|
||||||
|
|
||||||
size2 = size;
|
|
||||||
pointer = buffer;
|
|
||||||
|
|
||||||
myPacket2.read(&pointer, &size2, true);
|
|
||||||
|
|
||||||
printf("packet: 0x%04x, 0x%04x\n", myPacket2.element1.entry,
|
|
||||||
myPacket2.element2.entry);
|
|
||||||
|
|
||||||
buffer[0] = 0x12;
|
|
||||||
buffer[1] = 0x34;
|
|
||||||
buffer[2] = 0x56;
|
|
||||||
buffer[3] = 0x78;
|
|
||||||
buffer[4] = 0x2;
|
|
||||||
buffer[5] = 0x3;
|
|
||||||
buffer[6] = 0xab;
|
|
||||||
buffer[7] = 0xcd;
|
|
||||||
buffer[8] = 0xef;
|
|
||||||
buffer[9] = 0x2;
|
|
||||||
buffer[10] = 0x11;
|
|
||||||
buffer[11] = 0x22;
|
|
||||||
buffer[12] = 0xca;
|
|
||||||
buffer[13] = 0xfe;
|
|
||||||
buffer[14] = 0x5a;
|
|
||||||
buffer[15] = 0xfe;
|
|
||||||
|
|
||||||
pointer = buffer;
|
|
||||||
size2 = 23;
|
|
||||||
|
|
||||||
Packet2 p2;
|
|
||||||
|
|
||||||
ReturnValue_t result = p2.read(&pointer, &size2, true);
|
|
||||||
printf("result is %02x\n", result);
|
|
||||||
|
|
||||||
printf("%04x; %i: %i: %x %x %x; %i: %x %x;; %04x\n", p2.element1.entry,
|
|
||||||
p2.element2.entry.size, p2.element2.entry[0].size,
|
|
||||||
p2.element2.entry[0][0], p2.element2.entry[0][1],
|
|
||||||
p2.element2.entry[0][2], p2.element2.entry[1].size,
|
|
||||||
p2.element2.entry[1][0], p2.element2.entry[1][1],
|
|
||||||
p2.element3.entry);
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
struct Test {
|
|
||||||
uint32_t a;
|
|
||||||
uint32_t b;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename key_t, typename T>
|
|
||||||
void printMap(FixedMap<key_t, T> *map) {
|
|
||||||
typename FixedMap<key_t, T>::Iterator iter;
|
|
||||||
printf("Map (%i): ", map->getSize());
|
|
||||||
for (iter = map->begin(); iter != map->end(); ++iter) {
|
|
||||||
printf("%x:%08x,%08x ", iter.value->first, (*iter).a, (*iter).b);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void map() {
|
|
||||||
puts("** Map **");
|
|
||||||
typename FixedMap<T, Test>::Iterator iter;
|
|
||||||
ReturnValue_t result;
|
|
||||||
FixedMap<T, Test> myMap(5);
|
|
||||||
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
Test a;
|
|
||||||
a.a = 0x01234567;
|
|
||||||
a.b = 0xabcdef89;
|
|
||||||
|
|
||||||
myMap.insert(1, a);
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
a.a = 0;
|
|
||||||
|
|
||||||
myMap.insert(2, a);
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
printf("2 exists: %x\n", myMap.exists(0x02));
|
|
||||||
|
|
||||||
printf("ff exists: %x\n", myMap.exists(0xff));
|
|
||||||
|
|
||||||
a.a = 1;
|
|
||||||
printf("insert 0x2: %x\n", myMap.insert(2, a));
|
|
||||||
|
|
||||||
result = myMap.insert(0xff, a);
|
|
||||||
a.a = 0x44;
|
|
||||||
result = myMap.insert(0xab, a);
|
|
||||||
result = myMap.insert(0xa, a);
|
|
||||||
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
printf("insert 0x5: %x\n", myMap.insert(5, a));
|
|
||||||
|
|
||||||
printf("erase 0xfe: %x\n", myMap.erase(0xfe));
|
|
||||||
|
|
||||||
printf("erase 0x2: %x\n", myMap.erase(0x2));
|
|
||||||
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
printf("erase 0xab: %x\n", myMap.erase(0xab));
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
printf("insert 0x5: %x\n", myMap.insert(5, a));
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
iter = myMap.begin();
|
|
||||||
++iter;
|
|
||||||
++iter;
|
|
||||||
++iter;
|
|
||||||
|
|
||||||
printf("iter: %i: %x,%x\n",iter.value->first, iter->a, iter->b);
|
|
||||||
|
|
||||||
myMap.erase(&iter);
|
|
||||||
|
|
||||||
printf("iter: %i: %x,%x\n",iter.value->first, iter->a, iter->b);
|
|
||||||
printMap<T, Test>(&myMap);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void mapPrint() {
|
|
||||||
puts("** Map Print **");
|
|
||||||
FixedMap<uint16_t, Packet2> myMap(5);
|
|
||||||
Packet2 myPacket;
|
|
||||||
myPacket.element1.entry = 0x12345678;
|
|
||||||
|
|
||||||
myPacket.element2.entry[0][0] = 0xab;
|
|
||||||
myPacket.element2.entry[0][1] = 0xcd;
|
|
||||||
myPacket.element2.entry[0].size = 2;
|
|
||||||
myPacket.element2.entry.size = 1;
|
|
||||||
|
|
||||||
myPacket.element3.entry = 0xabcdef90;
|
|
||||||
|
|
||||||
myMap.insert(0x1234, myPacket);
|
|
||||||
|
|
||||||
uint8_t buffer[100];
|
|
||||||
uint32_t size = 0, i;
|
|
||||||
uint8_t *pointer = buffer;
|
|
||||||
|
|
||||||
printf("printsize: %i\n", myMap.getPrintSize());
|
|
||||||
|
|
||||||
SerializeAdapter<FixedMap<uint16_t, Packet2>>::print(&myMap, &pointer,
|
|
||||||
&size, 100, false);
|
|
||||||
|
|
||||||
printf("buffer(%i):", size);
|
|
||||||
for (i = 0; i < size; ++i) {
|
|
||||||
printf("%02x", buffer[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
int32_t size2 = size;
|
|
||||||
pointer = buffer;
|
|
||||||
|
|
||||||
FixedMap<uint16_t, Packet2> myMap2(5);
|
|
||||||
|
|
||||||
ReturnValue_t result = SerializeAdapter<FixedMap<uint16_t, Packet2>>::read(
|
|
||||||
&myMap2, &pointer, &size2, false);
|
|
||||||
|
|
||||||
Packet2 *myPacket2 = myMap2.find(0x1234);
|
|
||||||
|
|
||||||
printf("Map (%i): Packet2: %x, Array (%i): Array (%i): %x, %x; %x\n",
|
|
||||||
myMap2.getSize(), myPacket2->element1.entry,
|
|
||||||
myPacket2->element2.entry.size, myPacket2->element2.entry[0].size,
|
|
||||||
myPacket2->element2.entry[0][0], myPacket2->element2.entry[0][1],
|
|
||||||
myPacket2->element3.entry);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void empty() {
|
|
||||||
puts("** Empty **");
|
|
||||||
ArrayList<uint32_t> list(0);
|
|
||||||
printf("%p %p\n", list.front(), list.back());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
|
|
||||||
// arrayList();
|
|
||||||
// linkedList();
|
|
||||||
// allocatingList();
|
|
||||||
// complex();
|
|
||||||
|
|
||||||
map<uint32_t>();
|
|
||||||
//
|
|
||||||
// mapPrint();
|
|
||||||
|
|
||||||
// empty();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
#include "../subsystem/SubsystemBase.h"
|
#include "ControllerBase.h"
|
||||||
#include "../controller/ControllerBase.h"
|
|
||||||
#include "../subsystem/SubsystemBase.h"
|
#include "../subsystem/SubsystemBase.h"
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
@ -9,7 +9,8 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
|||||||
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
|
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
|
||||||
submode(SUBMODE_NONE), modeHelper(this),
|
submode(SUBMODE_NONE), modeHelper(this),
|
||||||
healthHelper(this, setObjectId), hkSwitcher(this) {
|
healthHelper(this, setObjectId), hkSwitcher(this) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
|
commandQueueDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase::~ControllerBase() {
|
ControllerBase::~ControllerBase() {
|
||||||
@ -25,7 +26,7 @@ ReturnValue_t ControllerBase::initialize() {
|
|||||||
MessageQueueId_t parentQueue = 0;
|
MessageQueueId_t parentQueue = 0;
|
||||||
if (parentId != objects::NO_OBJECT) {
|
if (parentId != objects::NO_OBJECT) {
|
||||||
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
||||||
if (parent == NULL) {
|
if (parent == nullptr) {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
parentQueue = parent->getCommandQueue();
|
parentQueue = parent->getCommandQueue();
|
||||||
@ -56,8 +57,9 @@ MessageQueueId_t ControllerBase::getCommandQueue() const {
|
|||||||
|
|
||||||
void ControllerBase::handleQueue() {
|
void ControllerBase::handleQueue() {
|
||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
for (result = commandQueue->receiveMessage(&command);
|
||||||
|
result == RETURN_OK;
|
||||||
result = commandQueue->receiveMessage(&command)) {
|
result = commandQueue->receiveMessage(&command)) {
|
||||||
|
|
||||||
result = modeHelper.handleModeCommand(&command);
|
result = modeHelper.handleModeCommand(&command);
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
#include "../modes/ModeHelper.h"
|
#include "../modes/ModeHelper.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../tasks/ExecutableObjectIF.h"
|
#include "../tasks/ExecutableObjectIF.h"
|
||||||
|
#include "../tasks/PeriodicTaskIF.h"
|
||||||
#include "../datapool/HkSwitchHelper.h"
|
#include "../datapool/HkSwitchHelper.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic base class for controller classes
|
* @brief Generic base class for controller classes
|
||||||
* @details
|
* @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,
|
class ControllerBase: public HasModesIF,
|
||||||
public HasHealthIF,
|
public HasHealthIF,
|
||||||
@ -26,24 +28,18 @@ public:
|
|||||||
size_t commandQueueDepth = 3);
|
size_t commandQueueDepth = 3);
|
||||||
virtual ~ControllerBase();
|
virtual ~ControllerBase();
|
||||||
|
|
||||||
|
/** SystemObject override */
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const 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 ReturnValue_t setHealth(HealthState health) override;
|
||||||
|
|
||||||
virtual HasHealthIF::HealthState getHealth() override;
|
virtual HasHealthIF::HealthState getHealth() override;
|
||||||
|
|
||||||
/**
|
/** ExecutableObjectIF overrides */
|
||||||
* Implementation of ExecutableObjectIF function
|
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
*
|
virtual void setTaskIF(PeriodicTaskIF* task) override;
|
||||||
* 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;
|
|
||||||
|
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -56,6 +52,9 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
|
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Periodic helper, implemented by child class.
|
||||||
|
*/
|
||||||
virtual void performControlOperation() = 0;
|
virtual void performControlOperation() = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
@ -73,6 +72,7 @@ protected:
|
|||||||
|
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
|
|
||||||
|
// Is this still needed?
|
||||||
HkSwitchHelper hkSwitcher;
|
HkSwitchHelper hkSwitcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,13 +81,16 @@ protected:
|
|||||||
*/
|
*/
|
||||||
PeriodicTaskIF* executingTask = nullptr;
|
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 modeChanged(Mode_t mode, Submode_t submode);
|
||||||
virtual void startTransition(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 getMode(Mode_t *mode, Submode_t *submode);
|
||||||
virtual void setToExternalControl();
|
virtual void setToExternalControl();
|
||||||
virtual void announceMode(bool recursive);
|
virtual void announceMode(bool recursive);
|
||||||
|
/** HK helpers */
|
||||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
114
controller/ExtendedControllerBase.cpp
Normal file
114
controller/ExtendedControllerBase.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t ExtendedControllerBase::getCommandQueue() const {
|
||||||
|
return commandQueue->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) {
|
||||||
|
sif::warning << "ExtendedControllerBase::getDataSetHandle: No child "
|
||||||
|
<< " implementation provided, returning nullptr!" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
72
controller/ExtendedControllerBase.h
Normal file
72
controller/ExtendedControllerBase.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
virtual MessageQueueId_t getCommandQueue() const 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_ */
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef DATASETIF_H_
|
#ifndef FSFW_DATAPOOL_DATASETIF_H_
|
||||||
#define DATASETIF_H_
|
#define FSFW_DATAPOOL_DATASETIF_H_
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../timemanager/Clock.h"
|
#include "../timemanager/Clock.h"
|
||||||
@ -34,7 +34,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual ~DataSetIF() {}
|
virtual ~DataSetIF() {}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This operation provides a method to register local data pool
|
* @brief This operation provides a method to register local data pool
|
||||||
* variables to register in a data set by passing itself
|
* variables to register in a data set by passing itself
|
||||||
@ -45,4 +44,4 @@ public:
|
|||||||
virtual uint16_t getFillCount() const = 0;
|
virtual uint16_t getFillCount() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOL_DATASETIF_H_ */
|
#endif /* FSFW_DATAPOOL_DATASETIF_H_ */
|
||||||
|
@ -59,6 +59,11 @@ uint16_t PoolDataSetBase::getFillCount() const {
|
|||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
if(registeredVariables[count] == nullptr) {
|
||||||
|
// configuration error.
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
// These checks are often performed by the respective
|
// These checks are often performed by the respective
|
||||||
// variable implementation too, but I guess a double check does not hurt.
|
// variable implementation too, but I guess a double check does not hurt.
|
||||||
if (registeredVariables[count]->getReadWriteMode() !=
|
if (registeredVariables[count]->getReadWriteMode() !=
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_
|
#ifndef FSFW_DATAPOOL_POOLDATASETBASE_H_
|
||||||
#define FRAMEWORK_DATAPOOL_DATASETBASE_H_
|
#define FSFW_DATAPOOL_POOLDATASETBASE_H_
|
||||||
#include "../datapool/PoolDataSetIF.h"
|
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "PoolDataSetIF.h"
|
||||||
|
#include "PoolVariableIF.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,4 +149,4 @@ private:
|
|||||||
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);
|
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOL_POOLPOOLDATASETBASE_H_ */
|
#endif /* FSFW_DATAPOOL_POOLDATASETBASE_H_ */
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
|
#ifndef FSFW_DATAPOOL_POOLDATASETIF_H_
|
||||||
#define FRAMEWORK_DATAPOOL_POOLDATASETIF_H_
|
#define FSFW_DATAPOOL_POOLDATASETIF_H_
|
||||||
|
|
||||||
#include "DataSetIF.h"
|
#include "DataSetIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extendes the DataSetIF by adding abstract functions to lock
|
||||||
|
* and unlock a data pool and read/commit semantics.
|
||||||
|
*/
|
||||||
class PoolDataSetIF: public DataSetIF {
|
class PoolDataSetIF: public DataSetIF {
|
||||||
public:
|
public:
|
||||||
virtual~ PoolDataSetIF() {};
|
virtual~ PoolDataSetIF() {};
|
||||||
@ -25,4 +30,4 @@ public:
|
|||||||
virtual bool isValid() const = 0;
|
virtual bool isValid() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOL_POOLDATASETIF_H_ */
|
#endif /* FSFW_DATAPOOL_POOLDATASETIF_H_ */
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "../datapool/PoolEntry.h"
|
#include "PoolEntry.h"
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||||
#include "../globalfunctions/arrayprinter.h"
|
#include "../globalfunctions/arrayprinter.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_
|
#ifndef FSFW_DATAPOOL_POOLENTRY_H_
|
||||||
#define FRAMEWORK_DATAPOOL_POOLENTRY_H_
|
#define FSFW_DATAPOOL_POOLENTRY_H_
|
||||||
|
|
||||||
#include "../datapool/PoolEntryIF.h"
|
#include "PoolEntryIF.h"
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -127,4 +127,4 @@ public:
|
|||||||
Type getType();
|
Type getType();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* POOLENTRY_H_ */
|
#endif /* FSFW_DATAPOOL_POOLENTRY_H_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
|
#ifndef FSFW_DATAPOOL_POOLENTRYIF_H_
|
||||||
#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
|
#define FSFW_DATAPOOL_POOLENTRYIF_H_
|
||||||
|
|
||||||
#include "../globalfunctions/Type.h"
|
#include "../globalfunctions/Type.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -60,4 +60,4 @@ public:
|
|||||||
virtual Type getType() = 0;
|
virtual Type getType() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* POOLENTRYIF_H_ */
|
#endif /* FSFW_DATAPOOL_POOLENTRYIF_H_ */
|
||||||
|
@ -1,188 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file PoolRawAccessHelper.cpp
|
|
||||||
*
|
|
||||||
* @date 22.12.2019
|
|
||||||
* @author R. Mueller
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../datapool/PoolRawAccessHelper.h"
|
|
||||||
#include "../datapoolglob/GlobalDataSet.h"
|
|
||||||
#include "../serialize/SerializeAdapter.h"
|
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
PoolRawAccessHelper::PoolRawAccessHelper(uint32_t * poolIdBuffer_,
|
|
||||||
uint8_t numberOfParameters_):
|
|
||||||
poolIdBuffer(reinterpret_cast<uint8_t * >(poolIdBuffer_)),
|
|
||||||
numberOfParameters(numberOfParameters_), validBufferIndex(0),
|
|
||||||
validBufferIndexBit(1) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PoolRawAccessHelper::~PoolRawAccessHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PoolRawAccessHelper::serialize(uint8_t **buffer, size_t *size,
|
|
||||||
const size_t max_size, SerializeIF::Endianness streamEndianness) {
|
|
||||||
SerializationArgs serializationArgs = {buffer, size, max_size,
|
|
||||||
streamEndianness};
|
|
||||||
ReturnValue_t result = RETURN_OK;
|
|
||||||
size_t remainingParametersSize = numberOfParameters * 4;
|
|
||||||
for(uint8_t count=0; count < numberOfParameters; count++) {
|
|
||||||
result = serializeCurrentPoolEntryIntoBuffer(serializationArgs,
|
|
||||||
&remainingParametersSize, false);
|
|
||||||
if(result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(remainingParametersSize != 0) {
|
|
||||||
sif::debug << "PoolRawAccessHelper: "
|
|
||||||
"Remaining parameters size not 0 !" << std::endl;
|
|
||||||
result = RETURN_FAILED;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PoolRawAccessHelper::serializeWithValidityMask(uint8_t ** buffer,
|
|
||||||
size_t * size, const size_t max_size,
|
|
||||||
SerializeIF::Endianness streamEndianness) {
|
|
||||||
ReturnValue_t result = RETURN_OK;
|
|
||||||
SerializationArgs argStruct = {buffer, size, max_size, streamEndianness};
|
|
||||||
size_t remainingParametersSize = numberOfParameters * 4;
|
|
||||||
uint8_t validityMaskSize = ceil((float)numberOfParameters/8.0);
|
|
||||||
uint8_t validityMask[validityMaskSize];
|
|
||||||
memset(validityMask,0, validityMaskSize);
|
|
||||||
for(uint8_t count = 0; count < numberOfParameters; count++) {
|
|
||||||
result = serializeCurrentPoolEntryIntoBuffer(argStruct,
|
|
||||||
&remainingParametersSize,true,validityMask);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(remainingParametersSize != 0) {
|
|
||||||
sif::debug << "PoolRawAccessHelper: Remaining "
|
|
||||||
"parameters size not 0 !" << std::endl;
|
|
||||||
result = RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(*argStruct.buffer, validityMask, validityMaskSize);
|
|
||||||
*size += validityMaskSize;
|
|
||||||
validBufferIndex = 1;
|
|
||||||
validBufferIndexBit = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PoolRawAccessHelper::serializeCurrentPoolEntryIntoBuffer(
|
|
||||||
SerializationArgs argStruct, size_t * remainingParameters,
|
|
||||||
bool withValidMask, uint8_t * validityMask) {
|
|
||||||
uint32_t currentPoolId;
|
|
||||||
// Deserialize current pool ID from pool ID buffer
|
|
||||||
ReturnValue_t result = SerializeAdapter::deSerialize(¤tPoolId,
|
|
||||||
&poolIdBuffer,remainingParameters, SerializeIF::Endianness::MACHINE);
|
|
||||||
if(result != RETURN_OK) {
|
|
||||||
sif::debug << std::hex << "PoolRawAccessHelper: Error deSeralizing "
|
|
||||||
"pool IDs" << std::dec << std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = handlePoolEntrySerialization(currentPoolId, argStruct,
|
|
||||||
withValidMask, validityMask);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization(
|
|
||||||
uint32_t currentPoolId,SerializationArgs argStruct, bool withValidMask,
|
|
||||||
uint8_t * validityMask) {
|
|
||||||
ReturnValue_t result = RETURN_FAILED;
|
|
||||||
uint8_t arrayPosition = 0;
|
|
||||||
uint8_t counter = 0;
|
|
||||||
bool poolEntrySerialized = false;
|
|
||||||
//debug << "Pool Raw Access Helper: Handling Pool ID: "
|
|
||||||
// << std::hex << currentPoolId << std::endl;
|
|
||||||
while(not poolEntrySerialized) {
|
|
||||||
|
|
||||||
if(counter > GlobDataSet::DATA_SET_MAX_SIZE) {
|
|
||||||
sif::error << "PoolRawAccessHelper: Config error, "
|
|
||||||
"max. number of possible data set variables exceeded"
|
|
||||||
<< std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
counter ++;
|
|
||||||
|
|
||||||
GlobDataSet currentDataSet;
|
|
||||||
//debug << "Current array position: " << (int)arrayPosition << std::endl;
|
|
||||||
PoolRawAccess currentPoolRawAccess(currentPoolId, arrayPosition,
|
|
||||||
¤tDataSet, PoolVariableIF::VAR_READ);
|
|
||||||
|
|
||||||
result = currentDataSet.read();
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
sif::debug << std::hex << "PoolRawAccessHelper: Error reading raw "
|
|
||||||
"dataset with returncode 0x" << result << std::dec << std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = checkRemainingSize(¤tPoolRawAccess, &poolEntrySerialized,
|
|
||||||
&arrayPosition);
|
|
||||||
if(result != RETURN_OK) {
|
|
||||||
sif::error << "Pool Raw Access Helper: Configuration Error at pool ID "
|
|
||||||
<< std::hex << currentPoolId
|
|
||||||
<< ". Size till end smaller than 0" << std::dec << std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set valid mask bit if necessary
|
|
||||||
if(withValidMask) {
|
|
||||||
if(currentPoolRawAccess.isValid()) {
|
|
||||||
handleMaskModification(validityMask);
|
|
||||||
}
|
|
||||||
validBufferIndexBit ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = currentDataSet.serialize(argStruct.buffer, argStruct.size,
|
|
||||||
argStruct.max_size, argStruct.streamEndianness);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
sif::debug << "Pool Raw Access Helper: Error serializing pool data with "
|
|
||||||
"ID 0x" << std::hex << currentPoolId << " into send buffer "
|
|
||||||
"with return code " << result << std::dec << std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PoolRawAccessHelper::checkRemainingSize(PoolRawAccess*
|
|
||||||
currentPoolRawAccess, bool * isSerialized, uint8_t * arrayPosition) {
|
|
||||||
int8_t remainingSize = currentPoolRawAccess->getSizeTillEnd() -
|
|
||||||
currentPoolRawAccess->getSizeOfType();
|
|
||||||
if(remainingSize == 0) {
|
|
||||||
*isSerialized = true;
|
|
||||||
}
|
|
||||||
else if(remainingSize > 0) {
|
|
||||||
*arrayPosition += 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PoolRawAccessHelper::handleMaskModification(uint8_t * validityMask) {
|
|
||||||
validityMask[validBufferIndex] =
|
|
||||||
bitSetter(validityMask[validBufferIndex], validBufferIndexBit, true);
|
|
||||||
if(validBufferIndexBit == 8) {
|
|
||||||
validBufferIndex ++;
|
|
||||||
validBufferIndexBit = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t PoolRawAccessHelper::bitSetter(uint8_t byte, uint8_t position,
|
|
||||||
bool value) {
|
|
||||||
if(position < 1 or position > 8) {
|
|
||||||
sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl;
|
|
||||||
return byte;
|
|
||||||
}
|
|
||||||
uint8_t shiftNumber = position + (6 - 2 * (position - 1));
|
|
||||||
byte |= 1UL << shiftNumber;
|
|
||||||
return byte;
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file PoolRawAccessHelper.h
|
|
||||||
*
|
|
||||||
* @date 22.12.2019
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
|
|
||||||
#define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
|
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "../datapoolglob/GlobalDataSet.h"
|
|
||||||
#include "../datapoolglob/PoolRawAccess.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This helper function simplifies accessing data pool entries
|
|
||||||
* via PoolRawAccess
|
|
||||||
* @details Can be used for a Housekeeping Service
|
|
||||||
* like ECSS PUS Service 3 if the type of the datapool entries is unknown.
|
|
||||||
* The provided dataset can be serialized into a provided buffer automatically by
|
|
||||||
* providing a buffer of pool IDs
|
|
||||||
* @ingroup data_pool
|
|
||||||
*/
|
|
||||||
class PoolRawAccessHelper: public HasReturnvaluesIF {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Call this constructor if a dataset needs to be serialized via
|
|
||||||
* Pool Raw Access
|
|
||||||
* @param dataSet_ This dataset will be used to perform thread-safe reading
|
|
||||||
* @param poolIdBuffer_ A buffer of uint32_t pool IDs
|
|
||||||
* @param numberOfParameters_ The number of parameters / pool IDs
|
|
||||||
*/
|
|
||||||
PoolRawAccessHelper(uint32_t * poolIdBuffer_, uint8_t numberOfParameters_);
|
|
||||||
virtual ~PoolRawAccessHelper();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize the datapool entries derived from the pool ID buffer
|
|
||||||
* directly into a provided buffer
|
|
||||||
* @param [out] buffer
|
|
||||||
* @param [out] size Size of the serialized buffer
|
|
||||||
* @param max_size
|
|
||||||
* @param bigEndian
|
|
||||||
* @return @c RETURN_OK On success
|
|
||||||
* @c RETURN_FAILED on failure
|
|
||||||
*/
|
|
||||||
ReturnValue_t serialize(uint8_t ** buffer, size_t * size,
|
|
||||||
const size_t max_size, SerializeIF::Endianness streamEndianness);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serializes data pool entries into provided buffer with the validity mask buffer
|
|
||||||
* at the end of the buffer. Every bit of the validity mask denotes
|
|
||||||
* the validity of a corresponding data pool entry from left to right.
|
|
||||||
* @param [out] buffer
|
|
||||||
* @param [out] size Size of the serialized buffer plus size
|
|
||||||
* of the validity mask
|
|
||||||
* @return @c RETURN_OK On success
|
|
||||||
* @c RETURN_FAILED on failure
|
|
||||||
*/
|
|
||||||
ReturnValue_t serializeWithValidityMask(uint8_t ** buffer, size_t * size,
|
|
||||||
const size_t max_size, SerializeIF::Endianness streamEndianness);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
// DataSet * dataSet;
|
|
||||||
const uint8_t * poolIdBuffer;
|
|
||||||
uint8_t numberOfParameters;
|
|
||||||
|
|
||||||
uint8_t validBufferIndex;
|
|
||||||
uint8_t validBufferIndexBit;
|
|
||||||
|
|
||||||
struct SerializationArgs {
|
|
||||||
uint8_t ** buffer;
|
|
||||||
size_t * size;
|
|
||||||
const size_t max_size;
|
|
||||||
SerializeIF::Endianness streamEndianness;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Helper function to serialize single pool entries
|
|
||||||
* @param pPoolIdBuffer
|
|
||||||
* @param buffer
|
|
||||||
* @param remainingParameters
|
|
||||||
* @param hkDataSize
|
|
||||||
* @param max_size
|
|
||||||
* @param bigEndian
|
|
||||||
* @param withValidMask Can be set optionally to set a
|
|
||||||
* provided validity mask
|
|
||||||
* @param validityMask Can be supplied and will be set if
|
|
||||||
* @c withValidMask is set to true
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t serializeCurrentPoolEntryIntoBuffer(
|
|
||||||
SerializationArgs argStruct, size_t * remainingParameters,
|
|
||||||
bool withValidMask = false, uint8_t * validityMask = nullptr);
|
|
||||||
|
|
||||||
ReturnValue_t handlePoolEntrySerialization(uint32_t currentPoolId,
|
|
||||||
SerializationArgs argStruct, bool withValidMask = false,
|
|
||||||
uint8_t * validityMask = nullptr);
|
|
||||||
|
|
||||||
ReturnValue_t checkRemainingSize(PoolRawAccess * currentPoolRawAccess,
|
|
||||||
bool * isSerialized, uint8_t * arrayPosition);
|
|
||||||
void handleMaskModification(uint8_t * validityMask);
|
|
||||||
/**
|
|
||||||
* Sets specific bit of a byte
|
|
||||||
* @param byte
|
|
||||||
* @param position Position of byte to set from 1 to 8
|
|
||||||
* @param value Binary value to set
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
uint8_t bitSetter(uint8_t byte, uint8_t position, bool value);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ */
|
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef POOLVARLIST_H_
|
#ifndef FSFW_DATAPOOL_POOLVARLIST_H_
|
||||||
#define POOLVARLIST_H_
|
#define FSFW_DATAPOOL_POOLVARLIST_H_
|
||||||
|
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../datapoolglob/GlobalPoolVariable.h"
|
#include "../datapoolglob/GlobalPoolVariable.h"
|
||||||
@ -8,7 +8,8 @@ class PoolVarList {
|
|||||||
private:
|
private:
|
||||||
GlobPoolVar<T> variables[n_var];
|
GlobPoolVar<T> variables[n_var];
|
||||||
public:
|
public:
|
||||||
PoolVarList( const uint32_t set_id[n_var], DataSetIF* dataSet, PoolVariableIF::ReadWriteMode_t setReadWriteMode ) {
|
PoolVarList( const uint32_t set_id[n_var], DataSetIF* dataSet,
|
||||||
|
PoolVariableIF::ReadWriteMode_t setReadWriteMode ) {
|
||||||
//I really should have a look at the new init list c++ syntax.
|
//I really should have a look at the new init list c++ syntax.
|
||||||
if (dataSet == NULL) {
|
if (dataSet == NULL) {
|
||||||
return;
|
return;
|
||||||
@ -25,4 +26,4 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* POOLVARLIST_H_ */
|
#endif /* FSFW_DATAPOOL_POOLVARLIST_H_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
|
#ifndef FSFW_DATAPOOL_POOLVARIABLEIF_H_
|
||||||
#define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
|
#define FSFW_DATAPOOL_POOLVARIABLEIF_H_
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
@ -96,4 +96,4 @@ protected:
|
|||||||
|
|
||||||
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
||||||
|
|
||||||
#endif /* POOLVARIABLEIF_H_ */
|
#endif /* FSFW_DATAPOOL_POOLVARIABLEIF_H_ */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../datapool/ControllerSet.h"
|
#include <fsfw/datapoolglob/ControllerSet.h>
|
||||||
|
|
||||||
ControllerSet::ControllerSet() {
|
ControllerSet::ControllerSet() {
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef CONTROLLERSET_H_
|
#ifndef FSFW_DATAPOOLGLOB_CONTROLLERSET_H_
|
||||||
#define CONTROLLERSET_H_
|
#define FSFW_DATAPOOLGLOB_CONTROLLERSET_H_
|
||||||
|
|
||||||
#include "../datapoolglob/GlobalDataSet.h"
|
#include "../datapoolglob/GlobalDataSet.h"
|
||||||
|
|
||||||
@ -12,4 +12,4 @@ public:
|
|||||||
void setInvalid();
|
void setInvalid();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONTROLLERSET_H_ */
|
#endif /* FSFW_DATAPOOLGLOB_CONTROLLERSET_H_ */
|
@ -1,7 +1,8 @@
|
|||||||
#include "../datapoolglob/DataPoolAdmin.h"
|
#include "DataPoolAdmin.h"
|
||||||
#include "../datapoolglob/GlobalDataSet.h"
|
#include "GlobalDataSet.h"
|
||||||
#include "../datapoolglob/GlobalDataPool.h"
|
#include "GlobalDataPool.h"
|
||||||
#include "../datapoolglob/PoolRawAccess.h"
|
#include "PoolRawAccess.h"
|
||||||
|
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
#include "../parameters/ParameterMessage.h"
|
#include "../parameters/ParameterMessage.h"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#ifndef DATAPOOLADMIN_H_
|
#ifndef FSFW_DATAPOOLGLOB_DATAPOOLADMIN_H_
|
||||||
#define DATAPOOLADMIN_H_
|
#define FSFW_DATAPOOLGLOB_DATAPOOLADMIN_H_
|
||||||
|
|
||||||
|
#include "DataPoolParameterWrapper.h"
|
||||||
|
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
@ -7,10 +9,9 @@
|
|||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../parameters/ReceivesParameterMessagesIF.h"
|
#include "../parameters/ReceivesParameterMessagesIF.h"
|
||||||
|
|
||||||
#include "../memory/MemoryHelper.h"
|
|
||||||
#include "../action/SimpleActionHelper.h"
|
#include "../action/SimpleActionHelper.h"
|
||||||
#include "../datapoolglob/DataPoolParameterWrapper.h"
|
#include "../memory/MemoryHelper.h"
|
||||||
|
|
||||||
|
|
||||||
class DataPoolAdmin: public HasActionsIF,
|
class DataPoolAdmin: public HasActionsIF,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
@ -56,4 +57,4 @@ private:
|
|||||||
Command_t initialCommand);
|
Command_t initialCommand);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DATAPOOLADMIN_H_ */
|
#endif /* FSFW_DATAPOOLGLOB_DATAPOOLADMIN_H_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef GLOBALPOOLVECTOR_H_
|
#ifndef FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_H_
|
||||||
#define GLOBALPOOLVECTOR_H_
|
#define FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_H_
|
||||||
|
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
#include "../datapool/PoolEntry.h"
|
#include "../datapool/PoolEntry.h"
|
||||||
@ -182,4 +182,4 @@ private:
|
|||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
using gp_vec_t = GlobPoolVector<T, vectorSize>;
|
using gp_vec_t = GlobPoolVector<T, vectorSize>;
|
||||||
|
|
||||||
#endif /* POOLVECTOR_H_ */
|
#endif /* FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_H_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef GLOBALPOOLVECTOR_TPP_
|
#ifndef FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_TPP_
|
||||||
#define GLOBALPOOLVECTOR_TPP_
|
#define FSFW_DATAPOOLGLOB_GLOBALPOOLVECTOR_TPP_
|
||||||
|
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_
|
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
||||||
#define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_
|
#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
||||||
|
|
||||||
#include "../datapool/PoolEntryIF.h"
|
#include "../datapool/PoolEntryIF.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
#include "../housekeeping/HousekeepingMessage.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class LocalDataPoolManager;
|
class LocalDataPoolManager;
|
||||||
class DataSetIF;
|
class LocalPoolDataSetBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definition for local pool entries.
|
* @brief Type definition for local pool entries.
|
||||||
*/
|
*/
|
||||||
@ -61,11 +64,11 @@ public:
|
|||||||
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
|
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the minimum sampling frequency, which will usually be the
|
* Returns the minimum sampling frequency in milliseconds, which will
|
||||||
* period the pool owner performs its periodic operation-
|
* usually be the period the pool owner performs its periodic operation.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
|
virtual uint32_t getPeriodicOperationFrequency() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is used by the pool manager to get a valid dataset
|
* This function is used by the pool manager to get a valid dataset
|
||||||
@ -73,7 +76,7 @@ public:
|
|||||||
* @param sid Corresponding structure ID
|
* @param sid Corresponding structure ID
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual DataSetIF* getDataSetHandle(sid_t sid) = 0;
|
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0;
|
||||||
|
|
||||||
/* These function can be implemented by pool owner, as they are required
|
/* These function can be implemented by pool owner, as they are required
|
||||||
* by the housekeeping message interface */
|
* by the housekeeping message interface */
|
||||||
@ -84,9 +87,9 @@ public:
|
|||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
};
|
};
|
||||||
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
|
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
|
||||||
dur_seconds_t newInterval) {
|
float newIntervalSeconds) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ */
|
||||||
|
@ -1,63 +1,75 @@
|
|||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "LocalDataPoolManager.h"
|
||||||
#include "../datapoollocal/LocalDataSet.h"
|
#include "LocalPoolDataSetBase.h"
|
||||||
|
|
||||||
|
#include "../housekeeping/HousekeepingSetPacket.h"
|
||||||
#include "../housekeeping/AcceptsHkPacketsIF.h"
|
#include "../housekeeping/AcceptsHkPacketsIF.h"
|
||||||
#include "../ipc/MutexFactory.h"
|
#include "../ipc/MutexFactory.h"
|
||||||
#include "../ipc/MutexHelper.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
|
#include "../objectmanager/frameworkObjects.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
object_id_t LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT;
|
object_id_t LocalDataPoolManager::defaultHkDestination =
|
||||||
|
objects::PUS_SERVICE_3_HOUSEKEEPING;
|
||||||
|
|
||||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
|
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
|
||||||
MessageQueueIF* queueToUse, bool appendValidityBuffer):
|
MessageQueueIF* queueToUse, bool appendValidityBuffer):
|
||||||
appendValidityBuffer(appendValidityBuffer) {
|
appendValidityBuffer(appendValidityBuffer) {
|
||||||
if(owner == nullptr) {
|
if(owner == nullptr) {
|
||||||
sif::error << "HkManager: Invalid supplied owner!" << std::endl;
|
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||||
|
<< "Invalid supplied owner!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->owner = owner;
|
this->owner = owner;
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
if(mutex == nullptr) {
|
if(mutex == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||||
"Could not create mutex." << std::endl;
|
<< "Could not create mutex." << std::endl;
|
||||||
}
|
|
||||||
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
|
||||||
if(ipcStore == nullptr) {
|
|
||||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
|
||||||
"Could not set IPC store." << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hkQueue = queueToUse;
|
hkQueue = queueToUse;
|
||||||
|
|
||||||
if(defaultHkDestination != objects::NO_OBJECT) {
|
|
||||||
AcceptsHkPacketsIF* hkPacketReceiver =
|
|
||||||
objectManager->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
|
||||||
if(hkPacketReceiver != nullptr) {
|
|
||||||
defaultHkDestinationId = hkPacketReceiver->getHkQueue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager::~LocalDataPoolManager() {}
|
LocalDataPoolManager::~LocalDataPoolManager() {}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||||
if(queueToUse == nullptr) {
|
if(queueToUse == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::initialize: Supplied queue "
|
sif::error << "LocalDataPoolManager::initialize: "
|
||||||
"invalid!" << std::endl;
|
<< std::hex << "0x" << owner->getObjectId() << ". Supplied "
|
||||||
|
<< "queue invalid!" << std::dec << std::endl;
|
||||||
}
|
}
|
||||||
hkQueue = queueToUse;
|
hkQueue = queueToUse;
|
||||||
|
|
||||||
|
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
|
if(ipcStore == nullptr) {
|
||||||
|
sif::error << "LocalDataPoolManager::initialize: "
|
||||||
|
<< std::hex << "0x" << owner->getObjectId() << ": Could not "
|
||||||
|
<< "set IPC store." <<std::dec << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(defaultHkDestination != objects::NO_OBJECT) {
|
||||||
|
AcceptsHkPacketsIF* hkPacketReceiver =
|
||||||
|
objectManager->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
||||||
|
if(hkPacketReceiver != nullptr) {
|
||||||
|
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||||
|
<< "Default HK destination object is invalid!" << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation(
|
ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation(
|
||||||
uint8_t nonDiagInvlFactor) {
|
uint8_t nonDiagInvlFactor) {
|
||||||
setNonDiagnosticIntervalFactor(nonDiagInvlFactor);
|
setNonDiagnosticIntervalFactor(nonDiagInvlFactor);
|
||||||
diagnosticMinimumInterval = owner->getPeriodicOperationFrequency();
|
|
||||||
regularMinimumInterval = diagnosticMinimumInterval *
|
|
||||||
nonDiagnosticIntervalFactor;
|
|
||||||
return initializeHousekeepingPoolEntriesOnce();
|
return initializeHousekeepingPoolEntriesOnce();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,20 +83,17 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
sif::warning << "HousekeepingManager: The map should only be initialized "
|
sif::warning << "HousekeepingManager: The map should only be initialized "
|
||||||
"once!" << std::endl;
|
<< "once!" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::performHkOperation() {
|
ReturnValue_t LocalDataPoolManager::performHkOperation() {
|
||||||
for(auto& hkReceiversIter: hkReceiversMap) {
|
for(auto& receiver: hkReceiversMap) {
|
||||||
HkReceiver* receiver = &hkReceiversIter.second;
|
//HkReceiver* receiver = &hkReceiversIter.second;
|
||||||
if(not receiver->reportingEnabled) {
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(receiver->reportingType) {
|
switch(receiver.reportingType) {
|
||||||
case(ReportingType::PERIODIC): {
|
case(ReportingType::PERIODIC): {
|
||||||
if(receiver->dataId.dataSetSid.notSet()) {
|
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
||||||
// Periodic packets shall only be generated from datasets.
|
// Periodic packets shall only be generated from datasets.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -110,50 +119,100 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
|
|||||||
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
||||||
if(hkReceiverObject == nullptr) {
|
if(hkReceiverObject == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:"
|
sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:"
|
||||||
" Invalid receiver!"<< std::endl;
|
<< " Invalid receiver!"<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HkReceiver hkReceiver;
|
struct HkReceiver hkReceiver;
|
||||||
hkReceiver.dataId.dataSetSid = sid;
|
hkReceiver.dataId.sid = sid;
|
||||||
hkReceiver.reportingType = ReportingType::PERIODIC;
|
hkReceiver.reportingType = ReportingType::PERIODIC;
|
||||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
||||||
hkReceiver.reportingEnabled = enableReporting;
|
|
||||||
if(not isDiagnostics) {
|
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
hkReceiver.hkParameter.collectionIntervalTicks =
|
if(dataSet != nullptr) {
|
||||||
intervalSecondsToInterval(isDiagnostics, collectionInterval *
|
dataSet->setReportingEnabled(enableReporting);
|
||||||
nonDiagnosticIntervalFactor);
|
dataSet->setDiagnostic(isDiagnostics);
|
||||||
}
|
dataSet->initializePeriodicHelper(collectionInterval,
|
||||||
else {
|
owner->getPeriodicOperationFrequency(), isDiagnostics);
|
||||||
hkReceiver.hkParameter.collectionIntervalTicks =
|
|
||||||
intervalSecondsToInterval(isDiagnostics, collectionInterval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hkReceiver.isDiagnostics = isDiagnostics;
|
hkReceiversMap.push_back(hkReceiver);
|
||||||
hkReceiver.intervalCounter = 1;
|
|
||||||
|
|
||||||
hkReceiversMap.emplace(packetDestination, hkReceiver);
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
|
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
|
||||||
CommandMessage* message) {
|
CommandMessage* message) {
|
||||||
Command_t command = message->getCommand();
|
Command_t command = message->getCommand();
|
||||||
|
sid_t sid = HousekeepingMessage::getSid(message);
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
switch(command) {
|
switch(command) {
|
||||||
// I think those are the only commands which can be handled here..
|
case(HousekeepingMessage::ENABLE_PERIODIC_DIAGNOSTICS_GENERATION): {
|
||||||
case(HousekeepingMessage::ADD_HK_REPORT_STRUCT):
|
result = togglePeriodicGeneration(sid, true, true);
|
||||||
case(HousekeepingMessage::ADD_DIAGNOSTICS_REPORT_STRUCT):
|
break;
|
||||||
// We should use OwnsLocalPoolDataIF to specify those functions..
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
|
case(HousekeepingMessage::DISABLE_PERIODIC_DIAGNOSTICS_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, false, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case(HousekeepingMessage::ENABLE_PERIODIC_HK_REPORT_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, true, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case(HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, false, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES):
|
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES):
|
||||||
|
return generateSetStructurePacket(sid, true);
|
||||||
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES):
|
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES):
|
||||||
//return generateSetStructurePacket(message->getSid());
|
return generateSetStructurePacket(sid, false);
|
||||||
|
case(HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL):
|
||||||
|
case(HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
||||||
|
float newCollIntvl = 0;
|
||||||
|
HousekeepingMessage::getCollectionIntervalModificationCommand(message,
|
||||||
|
&newCollIntvl);
|
||||||
|
if(command == HousekeepingMessage::
|
||||||
|
MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL) {
|
||||||
|
result = changeCollectionInterval(sid, newCollIntvl, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = changeCollectionInterval(sid, newCollIntvl, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
|
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
|
||||||
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT):
|
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
|
||||||
//return generateHousekeepingPacket(message->getSid());
|
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
|
if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT
|
||||||
|
and dataSet->isDiagnostics()) {
|
||||||
|
return WRONG_HK_PACKET_TYPE;
|
||||||
|
}
|
||||||
|
else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT
|
||||||
|
and not dataSet->isDiagnostics()) {
|
||||||
|
return WRONG_HK_PACKET_TYPE;
|
||||||
|
}
|
||||||
|
return generateHousekeepingPacket(HousekeepingMessage::getSid(message),
|
||||||
|
dataSet, true);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CommandMessageIF::UNKNOWN_COMMAND;
|
return CommandMessageIF::UNKNOWN_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandMessage reply;
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||||
|
}
|
||||||
|
hkQueue->sendMessage(hkDestinationId, &reply);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
||||||
@ -161,7 +220,7 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
|||||||
auto poolIter = localPoolMap.find(localPoolId);
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
if (poolIter == localPoolMap.end()) {
|
if (poolIter == localPoolMap.end()) {
|
||||||
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
||||||
" Pool entry not found." << std::endl;
|
<< " Pool entry not found." << std::endl;
|
||||||
return POOL_ENTRY_NOT_FOUND;
|
return POOL_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
poolIter->second->print();
|
poolIter->second->print();
|
||||||
@ -172,40 +231,47 @@ MutexIF* LocalDataPoolManager::getMutexHandle() {
|
|||||||
return mutex;
|
return mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
|
HasLocalDataPoolIF* LocalDataPoolManager::getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
||||||
float collectionInterval, MessageQueueId_t destination) {
|
LocalPoolDataSetBase* dataSet, bool forDownlink,
|
||||||
LocalPoolDataSetBase* dataSetToSerialize =
|
MessageQueueId_t destination) {
|
||||||
dynamic_cast<LocalPoolDataSetBase*>(owner->getDataSetHandle(sid));
|
if(dataSet == nullptr) {
|
||||||
if(dataSetToSerialize == nullptr) {
|
// Configuration error.
|
||||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
||||||
" Set ID not found or dataset not assigned!" << std::endl;
|
<< " Set ID not found or dataset not assigned!" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
sif::info << "hk gen called" << std::endl;
|
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
HousekeepingPacketDownlink hkPacket(sid, collectionInterval,
|
HousekeepingPacketDownlink hkPacket(sid, dataSet);
|
||||||
dataSetToSerialize->getFillCount(), dataSetToSerialize);
|
size_t serializedSize = 0;
|
||||||
ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId);
|
ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, storeId,
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
forDownlink, &serializedSize);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK or serializedSize == 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and now we set a HK message and send it the HK packet destination.
|
// and now we set a HK message and send it the HK packet destination.
|
||||||
CommandMessage hkMessage;
|
CommandMessage hkMessage;
|
||||||
HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId);
|
if(dataSet->isDiagnostics()) {
|
||||||
|
HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
HousekeepingMessage::setHkReportReply(&hkMessage, sid, storeId);
|
||||||
|
}
|
||||||
|
|
||||||
if(hkQueue == nullptr) {
|
if(hkQueue == nullptr) {
|
||||||
return QUEUE_OR_DESTINATION_NOT_SET;
|
return QUEUE_OR_DESTINATION_NOT_SET;
|
||||||
}
|
}
|
||||||
if(destination == MessageQueueIF::NO_QUEUE) {
|
if(destination == MessageQueueIF::NO_QUEUE) {
|
||||||
if(defaultHkDestinationId == MessageQueueIF::NO_QUEUE) {
|
if(hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
||||||
// error, all destinations invalid
|
// error, all destinations invalid
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
destination = defaultHkDestinationId;
|
destination = hkDestinationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hkQueue->sendMessage(destination, &hkMessage);
|
return hkQueue->sendMessage(destination, &hkMessage);
|
||||||
@ -213,46 +279,22 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
|
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
|
||||||
HousekeepingPacketDownlink& hkPacket,
|
HousekeepingPacketDownlink& hkPacket,
|
||||||
store_address_t *storeId) {
|
store_address_t& storeId, bool forDownlink,
|
||||||
|
size_t* serializedSize) {
|
||||||
uint8_t* dataPtr = nullptr;
|
uint8_t* dataPtr = nullptr;
|
||||||
size_t serializedSize = 0;
|
|
||||||
const size_t maxSize = hkPacket.getSerializedSize();
|
const size_t maxSize = hkPacket.getSerializedSize();
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(storeId,
|
|
||||||
serializedSize, &dataPtr);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hkPacket.serialize(&dataPtr, &serializedSize, maxSize,
|
|
||||||
SerializeIF::Endianness::MACHINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
|
|
||||||
LocalPoolDataSetBase* dataSet = dynamic_cast<LocalPoolDataSetBase*>(
|
|
||||||
owner->getDataSetHandle(sid));
|
|
||||||
if(dataSet == nullptr) {
|
|
||||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
|
||||||
" Set ID not found" << std::endl;
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
size_t expectedSize = dataSet->getFillCount() * sizeof(lp_id_t);
|
|
||||||
uint8_t* storePtr = nullptr;
|
|
||||||
store_address_t storeId;
|
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
||||||
expectedSize,&storePtr);
|
maxSize, &dataPtr);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
|
|
||||||
"Could not get free element from IPC store." << std::endl;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
size_t size = 0;
|
|
||||||
result = dataSet->serializeLocalPoolIds(&storePtr, &size,
|
if(forDownlink) {
|
||||||
expectedSize, SerializeIF::Endianness::BIG);
|
return hkPacket.serialize(&dataPtr, serializedSize, maxSize,
|
||||||
if(expectedSize != size) {
|
SerializeIF::Endianness::BIG);
|
||||||
sif::error << "HousekeepingManager::generateSetStructurePacket: "
|
|
||||||
"Expected size is not equal to serialized size" << std::endl;
|
|
||||||
}
|
}
|
||||||
return result;
|
return hkPacket.serialize(&dataPtr, serializedSize, maxSize,
|
||||||
|
SerializeIF::Endianness::MACHINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
|
void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
|
||||||
@ -260,46 +302,126 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
|
|||||||
this->nonDiagnosticIntervalFactor = nonDiagInvlFactor;
|
this->nonDiagnosticIntervalFactor = nonDiagInvlFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||||
|
sid_t sid = receiver.dataId.sid;
|
||||||
|
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
|
if(not dataSet->getReportingEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dataSet->periodicHelper == nullptr) {
|
||||||
|
// Configuration error.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(not dataSet->periodicHelper->checkOpNecessary()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) {
|
|
||||||
if(receiver->intervalCounter >=
|
|
||||||
receiver->hkParameter.collectionIntervalTicks) {
|
|
||||||
ReturnValue_t result = generateHousekeepingPacket(
|
ReturnValue_t result = generateHousekeepingPacket(
|
||||||
receiver->dataId.dataSetSid);
|
sid, dataSet, true);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
// configuration error
|
// configuration error
|
||||||
sif::debug << "LocalDataPoolManager::performHkOperation:"
|
sif::debug << "LocalDataPoolManager::performHkOperation:"
|
||||||
<< "0x" << std::setfill('0') << std::setw(8)
|
<< "0x" << std::hex << std::setfill('0') << std::setw(8)
|
||||||
<< owner->getObjectId() << " Error generating "
|
<< owner->getObjectId() << " Error generating "
|
||||||
<< "HK packet" << std::setfill(' ') << std::endl;
|
<< "HK packet" << std::setfill(' ') << std::dec << std::endl;
|
||||||
}
|
|
||||||
receiver->intervalCounter = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
receiver->intervalCounter++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics,
|
|
||||||
float collectionIntervalSeconds) {
|
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
|
||||||
if(isDiagnostics) {
|
bool enable, bool isDiagnostics) {
|
||||||
return std::ceil(collectionIntervalSeconds * 1000
|
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
/diagnosticMinimumInterval);
|
if((dataSet->isDiagnostics() and not isDiagnostics) or
|
||||||
}
|
(not dataSet->isDiagnostics() and isDiagnostics)) {
|
||||||
else {
|
return WRONG_HK_PACKET_TYPE;
|
||||||
return std::ceil(collectionIntervalSeconds * 1000
|
|
||||||
/regularMinimumInterval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics,
|
if((dataSet->getReportingEnabled() and enable) or
|
||||||
uint32_t collectionInterval) {
|
(not dataSet->getReportingEnabled() and not enable)) {
|
||||||
|
return REPORTING_STATUS_UNCHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSet->setReportingEnabled(enable);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
|
||||||
|
float newCollectionInterval, bool isDiagnostics) {
|
||||||
|
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
|
bool targetIsDiagnostics = dataSet->isDiagnostics();
|
||||||
|
if((targetIsDiagnostics and not isDiagnostics) or
|
||||||
|
(not targetIsDiagnostics and isDiagnostics)) {
|
||||||
|
return WRONG_HK_PACKET_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dataSet->periodicHelper == nullptr) {
|
||||||
|
// config error
|
||||||
|
return PERIODIC_HELPER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSet->periodicHelper->changeCollectionInterval(newCollectionInterval);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
||||||
|
bool isDiagnostics) {
|
||||||
|
// Get and check dataset first.
|
||||||
|
LocalPoolDataSetBase* dataSet = dynamic_cast<LocalPoolDataSetBase*>(
|
||||||
|
owner->getDataSetHandle(sid));
|
||||||
|
if(dataSet == nullptr) {
|
||||||
|
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
||||||
|
<< " Set ID not found" << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool targetIsDiagnostics = dataSet->isDiagnostics();
|
||||||
|
if((targetIsDiagnostics and not isDiagnostics) or
|
||||||
|
(not targetIsDiagnostics and isDiagnostics)) {
|
||||||
|
return WRONG_HK_PACKET_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid = dataSet->isValid();
|
||||||
|
bool reportingEnabled = dataSet->getReportingEnabled();
|
||||||
|
float collectionInterval =
|
||||||
|
dataSet->periodicHelper->getCollectionIntervalInSeconds();
|
||||||
|
|
||||||
|
// Generate set packet which can be serialized.
|
||||||
|
HousekeepingSetPacket setPacket(sid,
|
||||||
|
reportingEnabled, valid, collectionInterval, dataSet);
|
||||||
|
size_t expectedSize = setPacket.getSerializedSize();
|
||||||
|
uint8_t* storePtr = nullptr;
|
||||||
|
store_address_t storeId;
|
||||||
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
||||||
|
expectedSize,&storePtr);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
|
||||||
|
<< "Could not get free element from IPC store." << std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize set packet into store.
|
||||||
|
size_t size = 0;
|
||||||
|
result = setPacket.serialize(&storePtr, &size, expectedSize,
|
||||||
|
SerializeIF::Endianness::BIG);
|
||||||
|
if(expectedSize != size) {
|
||||||
|
sif::error << "HousekeepingManager::generateSetStructurePacket: "
|
||||||
|
<< "Expected size is not equal to serialized size" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send structure reporting reply.
|
||||||
|
CommandMessage reply;
|
||||||
if(isDiagnostics) {
|
if(isDiagnostics) {
|
||||||
return static_cast<float>(collectionInterval *
|
HousekeepingMessage::setDiagnosticsStuctureReportReply(&reply,
|
||||||
diagnosticMinimumInterval);
|
sid, storeId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return static_cast<float>(collectionInterval *
|
HousekeepingMessage::setHkStuctureReportReply(&reply,
|
||||||
regularMinimumInterval);
|
sid, storeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hkQueue->reply(&reply);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||||
|
|
||||||
|
#include "HasLocalDataPoolIF.h"
|
||||||
|
|
||||||
#include "../housekeeping/HousekeepingPacketDownlink.h"
|
#include "../housekeeping/HousekeepingPacketDownlink.h"
|
||||||
|
#include "../housekeeping/HousekeepingMessage.h"
|
||||||
|
#include "../housekeeping/PeriodicHousekeepingHelper.h"
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
|
#include "../datapool/PoolEntry.h"
|
||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
|
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
|
||||||
#include "../datapool/PoolEntry.h"
|
|
||||||
#include "../datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../ipc/MutexHelper.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
@ -23,7 +24,7 @@ class LocalDataSetBase;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class is the managing instance for local data pool.
|
* @brief This class is the managing instance for the local data pool.
|
||||||
* @details
|
* @details
|
||||||
* The actual data pool structure is a member of this class. Any class which
|
* The actual data pool structure is a member of this class. Any class which
|
||||||
* has a local data pool shall have this class as a member and implement
|
* has a local data pool shall have this class as a member and implement
|
||||||
@ -49,10 +50,14 @@ class LocalDataPoolManager {
|
|||||||
public:
|
public:
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
||||||
|
|
||||||
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x0);
|
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
||||||
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x1);
|
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
|
||||||
|
|
||||||
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x2);
|
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x02);
|
||||||
|
|
||||||
|
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x03);
|
||||||
|
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x04);
|
||||||
|
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x05);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor is used by a class which wants to implement
|
* This constructor is used by a class which wants to implement
|
||||||
@ -69,16 +74,30 @@ public:
|
|||||||
virtual~ LocalDataPoolManager();
|
virtual~ LocalDataPoolManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the map by calling the map initialization function of the
|
* Assigns the queue to use.
|
||||||
* owner and assigns the queue to use.
|
|
||||||
* @param queueToUse
|
* @param queueToUse
|
||||||
* @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc
|
* @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t initialize(MessageQueueIF* queueToUse);
|
ReturnValue_t initialize(MessageQueueIF* queueToUse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the map by calling the map initialization function and
|
||||||
|
* setting the periodic factor for non-diagnostic packets.
|
||||||
|
* Don't forget to call this, otherwise the map will be invalid!
|
||||||
|
* @param nonDiagInvlFactor
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
ReturnValue_t initializeAfterTaskCreation(uint8_t nonDiagInvlFactor = 5);
|
ReturnValue_t initializeAfterTaskCreation(uint8_t nonDiagInvlFactor = 5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should be called in the periodic handler of the owner.
|
||||||
|
* It performs all the periodic functionalities of the data pool manager,
|
||||||
|
* for example generating periodic HK packets.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t performHkOperation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ -97,12 +116,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setNonDiagnosticIntervalFactor(uint8_t nonDiagInvlFactor);
|
void setNonDiagnosticIntervalFactor(uint8_t nonDiagInvlFactor);
|
||||||
|
|
||||||
/**
|
|
||||||
* This should be called in the periodic handler of the owner.
|
|
||||||
* It performs all the periodic functionalities of the data pool manager.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t performHkOperation();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a housekeeping packet with a given SID.
|
* Generate a housekeeping packet with a given SID.
|
||||||
@ -110,9 +123,8 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t generateHousekeepingPacket(sid_t sid,
|
ReturnValue_t generateHousekeepingPacket(sid_t sid,
|
||||||
float collectionInterval = 0,
|
LocalPoolDataSetBase* dataSet, bool forDownlink,
|
||||||
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
||||||
ReturnValue_t generateSetStructurePacket(sid_t sid);
|
|
||||||
|
|
||||||
ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
|
ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
|
||||||
|
|
||||||
@ -124,26 +136,27 @@ public:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
|
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
|
||||||
|
|
||||||
const HasLocalDataPoolIF* getOwner() const;
|
HasLocalDataPoolIF* getOwner();
|
||||||
|
|
||||||
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
|
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Different types of housekeeping reporting are possible.
|
* Different types of housekeeping reporting are possible.
|
||||||
* 1. PERIODIC: HK packets are generated in fixed intervals and sent to
|
* 1. PERIODIC:
|
||||||
|
* HK packets are generated in fixed intervals and sent to
|
||||||
* destination. Fromat will be raw.
|
* destination. Fromat will be raw.
|
||||||
* 2. UPDATED: Notification will be sent out if HK data has changed.
|
* 2. UPDATE_NOTIFICATION:
|
||||||
* Question: Send Raw data directly or just the message?
|
* Notification will be sent out if HK data has changed.
|
||||||
* 3. REQUESTED: HK packets are only generated if explicitely requested.
|
* 3. UPDATE_SNAPSHOT:
|
||||||
|
* HK packets are only generated if explicitely requested.
|
||||||
* Propably not necessary, just use multiple local data sets or
|
* Propably not necessary, just use multiple local data sets or
|
||||||
* shared datasets.
|
* shared datasets.
|
||||||
*
|
|
||||||
* Notifications should also be possible for single variables instead of
|
|
||||||
* full dataset updates.
|
|
||||||
*/
|
*/
|
||||||
enum class ReportingType: uint8_t {
|
enum class ReportingType: uint8_t {
|
||||||
//! Periodic generation of HK packets.
|
//! Periodic generation of HK packets.
|
||||||
PERIODIC,
|
PERIODIC,
|
||||||
|
//! Housekeeping packet will be generated if values have changed.
|
||||||
|
UPDATE_HK,
|
||||||
//! Update notification will be sent out as message.
|
//! Update notification will be sent out as message.
|
||||||
UPDATE_NOTIFICATION,
|
UPDATE_NOTIFICATION,
|
||||||
//! Notification will be sent out as message and a snapshot of the
|
//! Notification will be sent out as message and a snapshot of the
|
||||||
@ -151,6 +164,17 @@ public:
|
|||||||
UPDATE_SNAPSHOT,
|
UPDATE_SNAPSHOT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Different data types are possible in the HK receiver map.
|
||||||
|
* For example, updates can be requested for full datasets or
|
||||||
|
* for single pool variables. Periodic reporting is only possible for
|
||||||
|
* data sets.
|
||||||
|
*/
|
||||||
|
enum class DataType: uint8_t {
|
||||||
|
LOCAL_POOL_VARIABLE,
|
||||||
|
DATA_SET
|
||||||
|
};
|
||||||
|
|
||||||
/* Copying forbidden */
|
/* Copying forbidden */
|
||||||
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
||||||
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
||||||
@ -160,51 +184,37 @@ private:
|
|||||||
//! Every housekeeping data manager has a mutex to protect access
|
//! Every housekeeping data manager has a mutex to protect access
|
||||||
//! to it's data pool.
|
//! to it's data pool.
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
|
|
||||||
/** The class which actually owns the manager (and its datapool). */
|
/** The class which actually owns the manager (and its datapool). */
|
||||||
HasLocalDataPoolIF* owner = nullptr;
|
HasLocalDataPoolIF* owner = nullptr;
|
||||||
|
|
||||||
uint8_t nonDiagnosticIntervalFactor = 0;
|
uint8_t nonDiagnosticIntervalFactor = 0;
|
||||||
dur_millis_t regularMinimumInterval = 0;
|
|
||||||
dur_millis_t diagnosticMinimumInterval = 0;
|
|
||||||
|
|
||||||
/** Default receiver for periodic HK packets */
|
/** Default receiver for periodic HK packets */
|
||||||
static object_id_t defaultHkDestination;
|
static object_id_t defaultHkDestination;
|
||||||
MessageQueueId_t defaultHkDestinationId = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t hkDestinationId = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
/** The data pool manager will keep an internal map of HK receivers. */
|
/** The data pool manager will keep an internal map of HK receivers. */
|
||||||
struct HkReceiver {
|
struct HkReceiver {
|
||||||
/** Different member of this union will be used depending on the
|
/** Object ID of receiver */
|
||||||
type of data the receiver is interested in (full datasets or
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
single data variables. */
|
|
||||||
|
DataType dataType = DataType::DATA_SET;
|
||||||
union DataId {
|
union DataId {
|
||||||
DataId(): dataSetSid() {}
|
DataId(): sid() {};
|
||||||
/** Will be initialized to INVALID_ADDRESS */
|
sid_t sid;
|
||||||
sid_t dataSetSid;
|
lp_id_t localPoolId;
|
||||||
lp_id_t localPoolId = HasLocalDataPoolIF::NO_POOL_ID;
|
|
||||||
};
|
};
|
||||||
DataId dataId;
|
DataId dataId;
|
||||||
|
|
||||||
ReportingType reportingType = ReportingType::PERIODIC;
|
ReportingType reportingType = ReportingType::PERIODIC;
|
||||||
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
||||||
bool reportingEnabled = true;
|
|
||||||
/** Different members of this union will be used depending on reporting
|
|
||||||
type */
|
|
||||||
union HkParameter {
|
|
||||||
/** This parameter will be used for the PERIODIC type */
|
|
||||||
uint32_t collectionIntervalTicks = 0;
|
|
||||||
/** This parameter will be used for the ON_UPDATE type */
|
|
||||||
bool hkDataChanged;
|
|
||||||
};
|
|
||||||
HkParameter hkParameter;
|
|
||||||
bool isDiagnostics;
|
|
||||||
/** General purpose counter which is used for periodic generation. */
|
|
||||||
uint32_t intervalCounter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Using a multimap as the same object might request multiple datasets */
|
/** This vector will contain the list of HK receivers. */
|
||||||
using HkReceiversMap = std::multimap<object_id_t, struct HkReceiver>;
|
using HkReceivers = std::vector<struct HkReceiver>;
|
||||||
|
|
||||||
HkReceiversMap hkReceiversMap;
|
HkReceivers hkReceiversMap;
|
||||||
|
|
||||||
/** This is the map holding the actual data. Should only be initialized
|
/** This is the map holding the actual data. Should only be initialized
|
||||||
* once ! */
|
* once ! */
|
||||||
@ -245,17 +255,16 @@ private:
|
|||||||
template <class T> ReturnValue_t fetchPoolEntry(lp_id_t localPoolId,
|
template <class T> ReturnValue_t fetchPoolEntry(lp_id_t localPoolId,
|
||||||
PoolEntry<T> **poolEntry);
|
PoolEntry<T> **poolEntry);
|
||||||
|
|
||||||
void setMinimalSamplingFrequency(float frequencySeconds);
|
|
||||||
ReturnValue_t serializeHkPacketIntoStore(
|
ReturnValue_t serializeHkPacketIntoStore(
|
||||||
HousekeepingPacketDownlink& hkPacket,
|
HousekeepingPacketDownlink& hkPacket,
|
||||||
store_address_t *storeId);
|
store_address_t& storeId, bool forDownlink, size_t* serializedSize);
|
||||||
|
|
||||||
uint32_t intervalSecondsToInterval(bool isDiagnostics,
|
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
|
||||||
float collectionIntervalSeconds);
|
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable,
|
||||||
float intervalToIntervalSeconds(bool isDiagnostics,
|
bool isDiagnostics);
|
||||||
uint32_t collectionInterval);
|
ReturnValue_t changeCollectionInterval(sid_t sid,
|
||||||
|
float newCollectionInterval, bool isDiagnostics);
|
||||||
void performPeriodicHkGeneration(HkReceiver* hkReceiver);
|
ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -279,4 +288,4 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATASET_H_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALDATASET_H_
|
||||||
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
|
||||||
|
#include "LocalPoolDataSetBase.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class LocalDataSet: public LocalPoolDataSetBase {
|
class LocalDataSet: public LocalPoolDataSetBase {
|
||||||
@ -17,4 +18,4 @@ private:
|
|||||||
std::vector<PoolVariableIF*> poolVarList;
|
std::vector<PoolVariableIF*> poolVarList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALDATASET_H_ */
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "LocalPoolDataSetBase.h"
|
#include "LocalPoolDataSetBase.h"
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "../datapoollocal/LocalDataPoolManager.h"
|
||||||
|
#include "../housekeeping/PeriodicHousekeepingHelper.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -7,16 +8,22 @@
|
|||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||||
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxNumberOfVariables):
|
const size_t maxNumberOfVariables, bool noPeriodicHandling):
|
||||||
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
|
// Configuration error.
|
||||||
<< std::endl;
|
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||||
|
<< "invalid!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
hkManager = hkOwner->getHkManagerHandle();
|
||||||
this->sid.objectId = hkOwner->getObjectId();
|
this->sid.objectId = hkOwner->getObjectId();
|
||||||
this->sid.ownerSetId = setId;
|
this->sid.ownerSetId = setId;
|
||||||
|
|
||||||
|
// Data creators get a periodic helper for periodic HK data generation.
|
||||||
|
if(not noPeriodicHandling) {
|
||||||
|
periodicHelper = new PeriodicHousekeepingHelper(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
|
LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
|
||||||
@ -26,8 +33,9 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
|
|||||||
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
||||||
sid.objectId);
|
sid.objectId);
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
|
// Configuration error.
|
||||||
<< std::endl;
|
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||||
|
<< "invalid!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
hkManager = hkOwner->getHkManagerHandle();
|
||||||
@ -111,8 +119,14 @@ ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
||||||
size_t* size, size_t maxSize,
|
size_t* size, size_t maxSize,SerializeIF::Endianness streamEndianness,
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
bool serializeFillCount) const {
|
||||||
|
// Serialize as uint8_t
|
||||||
|
uint8_t fillCount = this->fillCount;
|
||||||
|
if(serializeFillCount) {
|
||||||
|
SerializeAdapter::serialize(&fillCount, buffer, size, maxSize,
|
||||||
|
streamEndianness);
|
||||||
|
}
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
|
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
|
||||||
auto result = SerializeAdapter::serialize(¤tPoolId, buffer,
|
auto result = SerializeAdapter::serialize(¤tPoolId, buffer,
|
||||||
@ -127,6 +141,16 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t LocalPoolDataSetBase::getLocalPoolIdsSerializedSize(
|
||||||
|
bool serializeFillCount) const {
|
||||||
|
if(serializeFillCount) {
|
||||||
|
return fillCount * sizeof(lp_id_t) + sizeof(uint8_t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return fillCount * sizeof(lp_id_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t LocalPoolDataSetBase::getSerializedSize() const {
|
size_t LocalPoolDataSetBase::getSerializedSize() const {
|
||||||
if(withValidityBuffer) {
|
if(withValidityBuffer) {
|
||||||
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
|
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
|
||||||
@ -175,6 +199,41 @@ void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const {
|
|||||||
*byte |= 1 << shiftNumber;
|
*byte |= 1 << shiftNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::setDiagnostic(bool isDiagnostics) {
|
||||||
|
this->diagnostic = isDiagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalPoolDataSetBase::isDiagnostics() const {
|
||||||
|
return diagnostic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
|
||||||
|
this->reportingEnabled = reportingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalPoolDataSetBase::getReportingEnabled() const {
|
||||||
|
return reportingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::initializePeriodicHelper(
|
||||||
|
float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||||
|
bool isDiagnostics, uint8_t nonDiagIntervalFactor) {
|
||||||
|
periodicHelper->initialize(collectionInterval, minimumPeriodicInterval,
|
||||||
|
isDiagnostics, nonDiagIntervalFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::setChanged(bool changed) {
|
||||||
|
this->changed = changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalPoolDataSetBase::isChanged() const {
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
sid_t LocalPoolDataSetBase::getSid() const {
|
||||||
|
return sid;
|
||||||
|
}
|
||||||
|
|
||||||
bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
|
bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
|
||||||
uint8_t position) const {
|
uint8_t position) const {
|
||||||
if(position > 7) {
|
if(position > 7) {
|
||||||
@ -190,4 +249,11 @@ bool LocalPoolDataSetBase::isValid() const {
|
|||||||
return this->valid;
|
return this->valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
|
||||||
|
if(setEntriesRecursively) {
|
||||||
|
for(size_t idx = 0; idx < this->getFillCount(); idx++) {
|
||||||
|
registeredVariables[idx] -> setValid(valid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->valid = valid;
|
||||||
|
}
|
||||||
|
@ -1,27 +1,36 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
||||||
|
|
||||||
|
#include "HasLocalDataPoolIF.h"
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
#include "../datapool/PoolDataSetBase.h"
|
#include "../datapool/PoolDataSetBase.h"
|
||||||
#include "../datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class LocalDataPoolManager;
|
class LocalDataPoolManager;
|
||||||
|
class PeriodicHousekeepingHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The LocalDataSet class manages a set of locally checked out
|
* @brief The LocalDataSet class manages a set of locally checked out
|
||||||
* variables for local data pools
|
* variables for local data pools
|
||||||
* @details
|
* @details
|
||||||
|
* Extends the PoolDataSetBase class for local data pools by introducing
|
||||||
|
* a validity state, a flag to mark the set as changed, and various other
|
||||||
|
* functions to make it usable by the LocalDataPoolManager class.
|
||||||
|
*
|
||||||
* This class manages a list, where a set of local variables (or pool variables)
|
* This class manages a list, where a set of local variables (or pool variables)
|
||||||
* are registered. They are checked-out (i.e. their values are looked
|
* are registered. They are checked-out (i.e. their values are looked
|
||||||
* up and copied) with the read call. After the user finishes working with the
|
* up and copied) with the read call. After the user finishes working with the
|
||||||
* pool variables, he can write back all variable values to the pool with
|
* pool variables, he can write back all variable values to the pool with
|
||||||
* the commit call. The data set manages locking and freeing the local data pools,
|
* the commit call. The data set manages locking and freeing the local data
|
||||||
* to ensure thread-safety.
|
* pools, to ensure thread-safety.
|
||||||
|
*
|
||||||
|
* Pool variables can be added to the dataset by using the constructor
|
||||||
|
* argument of the pool variable or using the #registerVariable member function.
|
||||||
*
|
*
|
||||||
* An internal state manages usage of this class. Variables may only be
|
* An internal state manages usage of this class. Variables may only be
|
||||||
* registered before the read call is made, and the commit call only
|
* registered before any read call is made, and the commit call can only happen
|
||||||
* after the read call.
|
* after the read call.
|
||||||
*
|
*
|
||||||
* If pool variables are writable and not committed until destruction
|
* If pool variables are writable and not committed until destruction
|
||||||
@ -31,17 +40,21 @@ class LocalDataPoolManager;
|
|||||||
* @ingroup data_pool
|
* @ingroup data_pool
|
||||||
*/
|
*/
|
||||||
class LocalPoolDataSetBase: public PoolDataSetBase {
|
class LocalPoolDataSetBase: public PoolDataSetBase {
|
||||||
|
friend class LocalDataPoolManager;
|
||||||
|
friend class PeriodicHousekeepingHelper;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for the creator of local pool data.
|
* @brief Constructor for the creator of local pool data.
|
||||||
|
* @details
|
||||||
|
* This constructor also initializes the components required for
|
||||||
|
* periodic handling.
|
||||||
*/
|
*/
|
||||||
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||||
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxNumberOfVariables);
|
const size_t maxNumberOfVariables, bool noPeriodicHandling = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for users of local pool data. The passed pool
|
* @brief Constructor for users of local pool data.
|
||||||
* owner should implement the HasHkPoolParametersIF.
|
|
||||||
* @details
|
* @details
|
||||||
* @param sid Unique identifier of dataset consisting of object ID and
|
* @param sid Unique identifier of dataset consisting of object ID and
|
||||||
* set ID.
|
* set ID.
|
||||||
@ -63,6 +76,9 @@ public:
|
|||||||
|
|
||||||
void setValidityBufferGeneration(bool withValidityBuffer);
|
void setValidityBufferGeneration(bool withValidityBuffer);
|
||||||
|
|
||||||
|
sid_t getSid() const;
|
||||||
|
|
||||||
|
/** SerializeIF overrides */
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const override;
|
SerializeIF::Endianness streamEndianness) const override;
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t *size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t *size,
|
||||||
@ -73,7 +89,7 @@ public:
|
|||||||
* Special version of the serilization function which appends a
|
* Special version of the serilization function which appends a
|
||||||
* validity buffer at the end. Each bit of this validity buffer
|
* validity buffer at the end. Each bit of this validity buffer
|
||||||
* denotes whether the container data set entries are valid from left
|
* denotes whether the container data set entries are valid from left
|
||||||
* to right, MSB first.
|
* to right, MSB first. (length = ceil(N/8), N = number of pool variables)
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* @param size
|
* @param size
|
||||||
* @param maxSize
|
* @param maxSize
|
||||||
@ -88,18 +104,58 @@ public:
|
|||||||
size_t *size, SerializeIF::Endianness streamEndianness);
|
size_t *size, SerializeIF::Endianness streamEndianness);
|
||||||
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer,
|
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer,
|
||||||
size_t* size, size_t maxSize,
|
size_t* size, size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const;
|
SerializeIF::Endianness streamEndianness,
|
||||||
|
bool serializeFillCount = true) const;
|
||||||
|
uint8_t getLocalPoolIdsSerializedSize(bool serializeFillCount = true) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the dataset valid or invalid
|
||||||
|
* @param setEntriesRecursively
|
||||||
|
* If this is true, all contained datasets will also be set recursively.
|
||||||
|
*/
|
||||||
|
void setValidity(bool valid, bool setEntriesRecursively);
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
|
|
||||||
|
void setChanged(bool changed);
|
||||||
|
bool isChanged() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
|
|
||||||
|
bool diagnostic = false;
|
||||||
|
void setDiagnostic(bool diagnostics);
|
||||||
|
bool isDiagnostics() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for periodic generation.
|
||||||
|
*/
|
||||||
|
bool reportingEnabled = false;
|
||||||
|
void setReportingEnabled(bool enabled);
|
||||||
|
bool getReportingEnabled() const;
|
||||||
|
|
||||||
|
void initializePeriodicHelper(float collectionInterval,
|
||||||
|
dur_millis_t minimumPeriodicInterval,
|
||||||
|
bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the valid state of a dataset is always relevant to the whole
|
* If the valid state of a dataset is always relevant to the whole
|
||||||
* data set we can use this flag.
|
* data set we can use this flag.
|
||||||
*/
|
*/
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to mark the dataset as changed, which is used
|
||||||
|
* by the LocalDataPoolManager to send out update messages.
|
||||||
|
*/
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify whether the validity buffer is serialized too when serializing
|
||||||
|
* or deserializing the packet. Each bit of the validity buffer will
|
||||||
|
* contain the validity state of the pool variables from left to right.
|
||||||
|
* The size of validity buffer thus will be ceil(N / 8) with N = number of
|
||||||
|
* pool variables.
|
||||||
|
*/
|
||||||
bool withValidityBuffer = true;
|
bool withValidityBuffer = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,9 +181,10 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void bitSetter(uint8_t* byte, uint8_t position) const;
|
void bitSetter(uint8_t* byte, uint8_t position) const;
|
||||||
bool bitGetter(const uint8_t* byte, uint8_t position) const;
|
bool bitGetter(const uint8_t* byte, uint8_t position) const;
|
||||||
private:
|
|
||||||
|
|
||||||
|
PeriodicHousekeepingHelper* periodicHelper = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
||||||
|
|
||||||
|
#include "HasLocalDataPoolIF.h"
|
||||||
|
#include "LocalDataPoolManager.h"
|
||||||
|
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
#include "../datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
|
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,13 +38,13 @@ public:
|
|||||||
* @param poolId ID of the local pool entry.
|
* @param poolId ID of the local pool entry.
|
||||||
* @param hkOwner Pointer of the owner. This will generally be the calling
|
* @param hkOwner Pointer of the owner. This will generally be the calling
|
||||||
* class itself which passes "this".
|
* class itself which passes "this".
|
||||||
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
|
||||||
* @param dataSet The data set in which the variable shall register itself.
|
* @param dataSet The data set in which the variable shall register itself.
|
||||||
* If nullptr, the variable is not registered.
|
* If nullptr, the variable is not registered.
|
||||||
|
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
||||||
*/
|
*/
|
||||||
LocalPoolVar(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
LocalPoolVar(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
|
DataSetIF* dataSet = nullptr,
|
||||||
DataSetIF* dataSet = nullptr);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor is used by data users like controllers to have
|
* This constructor is used by data users like controllers to have
|
||||||
@ -58,13 +58,14 @@ public:
|
|||||||
* the pool variable in that dataset directly.
|
* the pool variable in that dataset directly.
|
||||||
* @param poolId ID of the local pool entry.
|
* @param poolId ID of the local pool entry.
|
||||||
* @param hkOwner object ID of the pool owner.
|
* @param hkOwner object ID of the pool owner.
|
||||||
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
|
||||||
* @param dataSet The data set in which the variable shall register itself.
|
* @param dataSet The data set in which the variable shall register itself.
|
||||||
* If nullptr, the variable is not registered.
|
* If nullptr, the variable is not registered.
|
||||||
|
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
LocalPoolVar(lp_id_t poolId, object_id_t poolOwner,
|
LocalPoolVar(lp_id_t poolId, object_id_t poolOwner,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
|
DataSetIF* dataSet = nullptr,
|
||||||
DataSetIF* dataSet = nullptr);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
|
||||||
virtual~ LocalPoolVar() {};
|
virtual~ LocalPoolVar() {};
|
||||||
|
|
||||||
@ -173,4 +174,4 @@ using lp_float_t = LocalPoolVar<float>;
|
|||||||
using lp_double_t = LocalPoolVar<double>;
|
using lp_double_t = LocalPoolVar<double>;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_
|
||||||
|
|
||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
||||||
#error Include LocalPoolVariable.h before LocalPoolVariable.tpp!
|
#error Include LocalPoolVariable.h before LocalPoolVariable.tpp!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId,
|
inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId,
|
||||||
HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode,
|
HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
|
||||||
DataSetIF* dataSet):
|
pool_rwm_t setReadWriteMode):
|
||||||
localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the "
|
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
||||||
"NO_PARAMETER value!" << std::endl;
|
<< "which is the NO_PARAMETER value!" << std::endl;
|
||||||
}
|
}
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner is a nullptr!"
|
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
||||||
<< std::endl;
|
<< "owner is a invalid!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
hkManager = hkOwner->getHkManagerHandle();
|
||||||
@ -27,17 +27,18 @@ inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId,
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner,
|
inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner,
|
||||||
pool_rwm_t setReadWriteMode, DataSetIF *dataSet):
|
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||||
readWriteMode(setReadWriteMode) {
|
localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the "
|
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
||||||
"NO_PARAMETER value!" << std::endl;
|
<< "which is the NO_PARAMETER value!" << std::endl;
|
||||||
}
|
}
|
||||||
HasLocalDataPoolIF* hkOwner =
|
HasLocalDataPoolIF* hkOwner =
|
||||||
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner did not implement"
|
sif::error << "LocalPoolVariable: The supplied pool owner did not "
|
||||||
"the correct interface HasHkPoolParametersIF!" << std::endl;
|
<< "implement the correct interface "
|
||||||
|
<< "HasLocalDataPoolIF!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
hkManager = hkOwner->getHkManagerHandle();
|
||||||
|
@ -47,8 +47,9 @@ public:
|
|||||||
* If nullptr, the variable is not registered.
|
* If nullptr, the variable is not registered.
|
||||||
*/
|
*/
|
||||||
LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
|
DataSetIF* dataSet = nullptr,
|
||||||
DataSetIF* dataSet = nullptr);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor is used by data users like controllers to have
|
* This constructor is used by data users like controllers to have
|
||||||
@ -65,8 +66,9 @@ public:
|
|||||||
* If nullptr, the variable is not registered.
|
* If nullptr, the variable is not registered.
|
||||||
*/
|
*/
|
||||||
LocalPoolVector(lp_id_t poolId, object_id_t poolOwner,
|
LocalPoolVector(lp_id_t poolId, object_id_t poolOwner,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
|
DataSetIF* dataSet = nullptr,
|
||||||
DataSetIF* dataSet = nullptr);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the local copy of the data pool entry.
|
* @brief This is the local copy of the data pool entry.
|
||||||
@ -192,7 +194,7 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolVector.tpp"
|
#include "LocalPoolVector.tpp"
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
using lp_vec_t = LocalPoolVector<T, vectorSize>;
|
using lp_vec_t = LocalPoolVector<T, vectorSize>;
|
||||||
|
@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
||||||
HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode,
|
HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
|
||||||
DataSetIF* dataSet) :
|
pool_rwm_t setReadWriteMode):
|
||||||
localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) {
|
localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) {
|
||||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the "
|
sif::warning << "LocalPoolVector: PoolVariableIF::NO_PARAMETER passed "
|
||||||
"NO_PARAMETER value!" << std::endl;
|
<< "as pool ID, which is the NO_PARAMETER value!" << std::endl;
|
||||||
}
|
}
|
||||||
memset(this->value, 0, vectorSize * sizeof(T));
|
std::memset(this->value, 0, vectorSize * sizeof(T));
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
hkManager = hkOwner->getHkManagerHandle();
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
dataSet->registerVariable(this);
|
dataSet->registerVariable(this);
|
||||||
@ -23,17 +23,18 @@ inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
|||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
||||||
object_id_t poolOwner, pool_rwm_t setReadWriteMode, DataSetIF *dataSet):
|
object_id_t poolOwner, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||||
readWriteMode(readWriteMode) {
|
readWriteMode(setReadWriteMode) {
|
||||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the "
|
sif::warning << "LocalPoolVector: PoolVariableIF::NO_PARAMETER passed "
|
||||||
"NO_PARAMETER value!" << std::endl;
|
<< "as pool ID, which is the NO_PARAMETER value!" << std::endl;
|
||||||
}
|
}
|
||||||
HasLocalDataPoolIF* hkOwner =
|
HasLocalDataPoolIF* hkOwner =
|
||||||
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner did not implement"
|
sif::error << "LocalPoolVariable: The supplied pool owner did not "
|
||||||
"the correct interface HasHkPoolParametersIF!" << std::endl;
|
<< "implement the correct interface HasHkPoolParametersIF!"
|
||||||
|
<< std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
hkManager = hkOwner->getHkManagerHandle();
|
||||||
@ -67,7 +68,7 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
|||||||
std::dec << " failed." << std::endl;
|
std::dec << " failed." << std::endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
memcpy(this->value, poolEntry->address, poolEntry->getByteSize());
|
std::memcpy(this->value, poolEntry->address, poolEntry->getByteSize());
|
||||||
this->valid = poolEntry->valid;
|
this->valid = poolEntry->valid;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -96,7 +97,7 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
|||||||
std::dec << " failed.\n" << std::flush;
|
std::dec << " failed.\n" << std::flush;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
memcpy(poolEntry->address, this->value, poolEntry->getByteSize());
|
std::memcpy(poolEntry->address, this->value, poolEntry->getByteSize());
|
||||||
poolEntry->valid = this->valid;
|
poolEntry->valid = this->valid;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
|
#ifndef FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
|
#define FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
|
||||||
|
|
||||||
|
#include "LocalPoolDataSetBase.h"
|
||||||
#include "../datapool/SharedDataSetIF.h"
|
#include "../datapool/SharedDataSetIF.h"
|
||||||
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
|
||||||
* Baseline question: If this dataset is shared, is there once instance
|
|
||||||
* shared among many objects or multiple instances? Maybe be flexible
|
|
||||||
* and provide both ways? Sharing one instance requires a mutex lock.
|
|
||||||
* If there are multiple instances, it is not shared anymore, to be fair..
|
|
||||||
* Then a regular local data set is sufficient.
|
|
||||||
*/
|
|
||||||
class SharedLocalDataSet: public SystemObject,
|
class SharedLocalDataSet: public SystemObject,
|
||||||
public LocalPoolDataSetBase,
|
public LocalPoolDataSetBase,
|
||||||
public SharedDataSetIF {
|
public SharedDataSetIF {
|
||||||
@ -27,5 +21,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */
|
||||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_
|
#ifndef FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_
|
||||||
#define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_
|
#define FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_
|
||||||
|
|
||||||
#include "LocalPoolDataSetBase.h"
|
#include "LocalPoolDataSetBase.h"
|
||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -7,21 +8,43 @@
|
|||||||
/**
|
/**
|
||||||
* @brief This local dataset type is created on the stack.
|
* @brief This local dataset type is created on the stack.
|
||||||
* @details
|
* @details
|
||||||
* Size of data set specified as a constructor argument. It is recommended
|
* This will is the primary data structure to organize pool variables into
|
||||||
* to use the default LocalDataSet of the dataset is constructed on the heap
|
* sets which can be accessed via the housekeeping service interface or
|
||||||
* and the SharedLocalDataSet if it created on the heap and used by multiple
|
* which can be sent to other software objects.
|
||||||
* other software objects.
|
*
|
||||||
* @tparam capacity
|
* It is recommended to read the documentation of the LocalPoolDataSetBase
|
||||||
|
* class for more information on how this class works and how to use it.
|
||||||
|
* @tparam capacity Capacity of the static dataset, which is usually known
|
||||||
|
* beforehand.
|
||||||
*/
|
*/
|
||||||
template <uint8_t NUM_VARIABLES>
|
template <uint8_t NUM_VARIABLES>
|
||||||
class StaticLocalDataSet: public LocalPoolDataSetBase {
|
class StaticLocalDataSet: public LocalPoolDataSetBase {
|
||||||
public:
|
public:
|
||||||
StaticLocalDataSet(sid_t sid):
|
/**
|
||||||
LocalPoolDataSetBase(sid, poolVarList.data(), NUM_VARIABLES) {
|
* Constructor used by data owner and creator like device handlers.
|
||||||
|
* This constructor also initialized the components required for
|
||||||
|
* periodic handling.
|
||||||
|
* @param hkOwner
|
||||||
|
* @param setId
|
||||||
|
*/
|
||||||
|
StaticLocalDataSet(HasLocalDataPoolIF* hkOwner,
|
||||||
|
uint32_t setId): LocalPoolDataSetBase(hkOwner, setId, nullptr,
|
||||||
|
NUM_VARIABLES) {
|
||||||
|
this->setContainer(poolVarList.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used by data users like controllers.
|
||||||
|
* @param hkOwner
|
||||||
|
* @param setId
|
||||||
|
*/
|
||||||
|
StaticLocalDataSet(sid_t sid): LocalPoolDataSetBase(sid, nullptr,
|
||||||
|
NUM_VARIABLES) {
|
||||||
|
this->setContainer(poolVarList.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList;
|
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */
|
||||||
|
@ -122,7 +122,7 @@ uint32_t CommunicationMessage::getUint32Data() const{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CommunicationMessage::setDataByte(uint8_t byte, uint8_t position) {
|
void CommunicationMessage::setDataByte(uint8_t byte, uint8_t position) {
|
||||||
if(0 <= position && position <= 3) {
|
if(position <= 3) {
|
||||||
memcpy(getData() + 3 * sizeof(uint32_t) + position * sizeof(uint8_t), &byte, sizeof(byte));
|
memcpy(getData() + 3 * sizeof(uint32_t) + position * sizeof(uint8_t), &byte, sizeof(byte));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -131,7 +131,7 @@ void CommunicationMessage::setDataByte(uint8_t byte, uint8_t position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t CommunicationMessage::getDataByte(uint8_t position) const {
|
uint8_t CommunicationMessage::getDataByte(uint8_t position) const {
|
||||||
if(0 <= position && position <= 3) {
|
if(position <= 3) {
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
memcpy(&byte, getData() + 3 * sizeof(uint32_t) + position * sizeof(uint8_t), sizeof(byte));
|
memcpy(&byte, getData() + 3 * sizeof(uint32_t) + position * sizeof(uint8_t), sizeof(byte));
|
||||||
return byte;
|
return byte;
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
#include "../devicehandlers/DeviceHandlerBase.h"
|
#include "DeviceHandlerBase.h"
|
||||||
|
#include "AcceptsDeviceResponsesIF.h"
|
||||||
|
#include "DeviceTmReportingWrapper.h"
|
||||||
|
|
||||||
|
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||||
|
#include "../datapoolglob/GlobalDataSet.h"
|
||||||
|
#include "../datapoolglob/GlobalPoolVariable.h"
|
||||||
#include "../objectmanager/ObjectManager.h"
|
#include "../objectmanager/ObjectManager.h"
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "../storagemanager/StorageManagerIF.h"
|
||||||
#include "../thermal/ThermalComponentIF.h"
|
#include "../thermal/ThermalComponentIF.h"
|
||||||
#include "../devicehandlers/AcceptsDeviceResponsesIF.h"
|
|
||||||
|
|
||||||
#include "../datapoolglob/GlobalDataSet.h"
|
|
||||||
#include "../datapoolglob/GlobalPoolVariable.h"
|
|
||||||
#include "../devicehandlers/DeviceTmReportingWrapper.h"
|
|
||||||
#include "../globalfunctions/CRC.h"
|
#include "../globalfunctions/CRC.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
#include "../housekeeping/HousekeepingMessage.h"
|
||||||
#include "../ipc/MessageQueueMessage.h"
|
#include "../ipc/MessageQueueMessage.h"
|
||||||
#include "../subsystem/SubsystemBase.h"
|
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../subsystem/SubsystemBase.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
|
|||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
||||||
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
||||||
PoolDataSetIF* replyDataSet, size_t replyLen, bool periodic,
|
LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic,
|
||||||
bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
||||||
//No need to check, as we may try to insert multiple times.
|
//No need to check, as we may try to insert multiple times.
|
||||||
insertInCommandMap(deviceCommand);
|
insertInCommandMap(deviceCommand);
|
||||||
@ -413,7 +413,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
||||||
uint16_t maxDelayCycles, PoolDataSetIF* dataSet,
|
uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet,
|
||||||
size_t replyLen, bool periodic) {
|
size_t replyLen, bool periodic) {
|
||||||
DeviceReplyInfo info;
|
DeviceReplyInfo info;
|
||||||
info.maxDelayCycles = maxDelayCycles;
|
info.maxDelayCycles = maxDelayCycles;
|
||||||
@ -463,7 +463,7 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep
|
|||||||
|
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId,
|
ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId,
|
||||||
PoolDataSetIF *dataSet) {
|
LocalPoolDataSetBase *dataSet) {
|
||||||
auto replyIter = deviceReplyMap.find(replyId);
|
auto replyIter = deviceReplyMap.find(replyId);
|
||||||
if(replyIter == deviceReplyMap.end()) {
|
if(replyIter == deviceReplyMap.end()) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
@ -1286,10 +1286,14 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
if (iter == deviceCommandMap.end()) {
|
if (iter == deviceCommandMap.end()) {
|
||||||
result = COMMAND_NOT_SUPPORTED;
|
result = COMMAND_NOT_SUPPORTED;
|
||||||
} else if (iter->second.isExecuting) {
|
} else if (iter->second.isExecuting) {
|
||||||
|
//so we can track misconfigurations
|
||||||
sif::debug << std::hex << getObjectId()
|
sif::debug << std::hex << getObjectId()
|
||||||
<< ": DHB::buildInternalCommand: Command "
|
<< ": DHB::buildInternalCommand: Command "
|
||||||
<< deviceCommandId << " isExecuting" << std::endl; //so we can track misconfigurations
|
<< deviceCommandId << " isExecuting" << std::dec
|
||||||
return; //this is an internal command, no need to report a failure here, missed reply will track if a reply is too late, otherwise, it's ok
|
<< std::endl;
|
||||||
|
// this is an internal command, no need to report a failure here,
|
||||||
|
// missed reply will track if a reply is too late, otherwise, it's ok
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
iter->second.sendReplyTo = NO_COMMANDER;
|
iter->second.sendReplyTo = NO_COMMANDER;
|
||||||
iter->second.isExecuting = true;
|
iter->second.isExecuting = true;
|
||||||
@ -1396,10 +1400,14 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
pstIntervalMs = executingTask->getPeriodMs();
|
pstIntervalMs = executingTask->getPeriodMs();
|
||||||
}
|
}
|
||||||
this->hkManager.initializeAfterTaskCreation();
|
this->hkManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
|
if(setStartupImmediately) {
|
||||||
|
startTransition(MODE_ON, SUBMODE_NONE);
|
||||||
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) {
|
LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) {
|
||||||
auto iter = deviceReplyMap.find(sid.ownerSetId);
|
auto iter = deviceReplyMap.find(sid.ownerSetId);
|
||||||
if(iter != deviceReplyMap.end()) {
|
if(iter != deviceReplyMap.end()) {
|
||||||
return iter->second.dataSet;
|
return iter->second.dataSet;
|
||||||
@ -1413,6 +1421,10 @@ object_id_t DeviceHandlerBase::getObjectId() const {
|
|||||||
return SystemObject::getObjectId();
|
return SystemObject::getObjectId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceHandlerBase::setStartUpImmediately() {
|
||||||
|
this->setStartupImmediately = true;
|
||||||
|
}
|
||||||
|
|
||||||
dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
|
dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
|
||||||
return pstIntervalMs;
|
return pstIntervalMs;
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
||||||
#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
||||||
|
|
||||||
|
#include "DeviceHandlerIF.h"
|
||||||
|
#include "DeviceCommunicationIF.h"
|
||||||
|
#include "DeviceHandlerFailureIsolation.h"
|
||||||
|
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../tasks/ExecutableObjectIF.h"
|
#include "../tasks/ExecutableObjectIF.h"
|
||||||
#include "../devicehandlers/DeviceHandlerIF.h"
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../devicehandlers/DeviceCommunicationIF.h"
|
|
||||||
#include "../modes/HasModesIF.h"
|
#include "../modes/HasModesIF.h"
|
||||||
#include "../power/PowerSwitchIF.h"
|
#include "../power/PowerSwitchIF.h"
|
||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../tasks/PeriodicTaskIF.h"
|
#include "../tasks/PeriodicTaskIF.h"
|
||||||
|
|
||||||
#include "../action/ActionHelper.h"
|
#include "../action/ActionHelper.h"
|
||||||
#include "../health/HealthHelper.h"
|
#include "../health/HealthHelper.h"
|
||||||
#include "../parameters/ParameterHelper.h"
|
#include "../parameters/ParameterHelper.h"
|
||||||
#include "../datapool/HkSwitchHelper.h"
|
#include "../datapool/HkSwitchHelper.h"
|
||||||
#include "../datapoollocal/HasLocalDataPoolIF.h"
|
#include "../datapoollocal/HasLocalDataPoolIF.h"
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "../datapoollocal/LocalDataPoolManager.h"
|
||||||
#include "../devicehandlers/DeviceHandlerFailureIsolation.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace Factory{
|
namespace Factory{
|
||||||
@ -104,6 +105,18 @@ public:
|
|||||||
void setHkDestination(object_id_t hkDestination);
|
void setHkDestination(object_id_t hkDestination);
|
||||||
void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId,
|
void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId,
|
||||||
uint32_t thermalRequestPoolId);
|
uint32_t thermalRequestPoolId);
|
||||||
|
/**
|
||||||
|
* @brief Helper function to ease device handler development.
|
||||||
|
* This will instruct the transition to MODE_ON immediately
|
||||||
|
* (leading to doStartUp() being called for the transition to the ON mode),
|
||||||
|
* so external mode commanding is not necessary anymore.
|
||||||
|
*
|
||||||
|
* This has to be called before the task is started!
|
||||||
|
* (e.g. in the task factory). This is only a helper function for
|
||||||
|
* development. Regular mode commanding should be performed by commanding
|
||||||
|
* the AssemblyBase or Subsystem objects resposible for the device handler.
|
||||||
|
*/
|
||||||
|
void setStartUpImmediately();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is the device handler base core component and is
|
* @brief This function is the device handler base core component and is
|
||||||
@ -149,6 +162,14 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initialize();
|
virtual ReturnValue_t initialize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Intialization steps performed after all tasks have been created.
|
||||||
|
* This function will be called by the executing task.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
virtual ~DeviceHandlerBase();
|
virtual ~DeviceHandlerBase();
|
||||||
|
|
||||||
@ -370,7 +391,8 @@ protected:
|
|||||||
* - @c RETURN_FAILED else.
|
* - @c RETURN_FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand,
|
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand,
|
||||||
uint16_t maxDelayCycles, PoolDataSetIF* replyDataSet = nullptr,
|
uint16_t maxDelayCycles,
|
||||||
|
LocalPoolDataSetBase* replyDataSet = nullptr,
|
||||||
size_t replyLen = 0, bool periodic = false,
|
size_t replyLen = 0, bool periodic = false,
|
||||||
bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0);
|
bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0);
|
||||||
|
|
||||||
@ -385,7 +407,7 @@ protected:
|
|||||||
* - @c RETURN_FAILED else.
|
* - @c RETURN_FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand,
|
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand,
|
||||||
uint16_t maxDelayCycles, PoolDataSetIF* dataSet = nullptr,
|
uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr,
|
||||||
size_t replyLen = 0, bool periodic = false);
|
size_t replyLen = 0, bool periodic = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -415,7 +437,7 @@ protected:
|
|||||||
bool periodic = false);
|
bool periodic = false);
|
||||||
|
|
||||||
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId,
|
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId,
|
||||||
PoolDataSetIF* dataset);
|
LocalPoolDataSetBase* dataset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Can be implemented by child handler to
|
* @brief Can be implemented by child handler to
|
||||||
@ -645,7 +667,7 @@ protected:
|
|||||||
//! The dataset used to access housekeeping data related to the
|
//! The dataset used to access housekeeping data related to the
|
||||||
//! respective device reply. Will point to a dataset held by
|
//! respective device reply. Will point to a dataset held by
|
||||||
//! the child handler (if one is specified)
|
//! the child handler (if one is specified)
|
||||||
PoolDataSetIF* dataSet = nullptr;
|
LocalPoolDataSetBase* dataSet;
|
||||||
//! The command that expects this reply.
|
//! The command that expects this reply.
|
||||||
DeviceCommandMap::iterator command;
|
DeviceCommandMap::iterator command;
|
||||||
};
|
};
|
||||||
@ -946,14 +968,17 @@ protected:
|
|||||||
|
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode);
|
uint32_t *msToReachTheMode);
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
|
||||||
virtual void setToExternalControl();
|
/* HasModesIF overrides */
|
||||||
virtual void announceMode(bool recursive);
|
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
|
virtual void setToExternalControl() override;
|
||||||
|
virtual void announceMode(bool recursive) override;
|
||||||
|
|
||||||
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
|
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overwrites SystemObject::triggerEvent in order to inform FDIR"Helper" faster about executed events.
|
* Overwrites SystemObject::triggerEvent in order to inform FDIR"Helper"
|
||||||
|
* faster about executed events.
|
||||||
* This is a bit sneaky, but improves responsiveness of the device FDIR.
|
* This is a bit sneaky, but improves responsiveness of the device FDIR.
|
||||||
* @param event The event to be thrown
|
* @param event The event to be thrown
|
||||||
* @param parameter1 Optional parameter 1
|
* @param parameter1 Optional parameter 1
|
||||||
@ -1045,6 +1070,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
uint32_t timeoutStart = 0;
|
uint32_t timeoutStart = 0;
|
||||||
|
|
||||||
|
bool setStartupImmediately = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delay for the current mode transition, used for time out
|
* Delay for the current mode transition, used for time out
|
||||||
*/
|
*/
|
||||||
@ -1163,7 +1190,6 @@ private:
|
|||||||
ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data,
|
ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data,
|
||||||
uint32_t *len);
|
uint32_t *len);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!!
|
* @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!!
|
||||||
*/
|
*/
|
||||||
@ -1174,28 +1200,14 @@ private:
|
|||||||
*/
|
*/
|
||||||
void callChildStatemachine();
|
void callChildStatemachine();
|
||||||
|
|
||||||
/**
|
|
||||||
* Switches the channel of the cookie used for the communication
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param newChannel the object Id of the channel to switch to
|
|
||||||
* @return
|
|
||||||
* - @c RETURN_OK when cookie was changed
|
|
||||||
* - @c RETURN_FAILED when cookies could not be changed,
|
|
||||||
* e.g. because the newChannel is not enabled
|
|
||||||
* - @c returnvalues of RMAPChannelIF::isActive()
|
|
||||||
*/
|
|
||||||
ReturnValue_t switchCookieChannel(object_id_t newChannelId);
|
|
||||||
|
|
||||||
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
|
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
|
||||||
|
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
virtual DataSetIF* getDataSetHandle(sid_t sid) override;
|
|
||||||
|
virtual dur_millis_t getPeriodicOperationFrequency() const override;
|
||||||
|
|
||||||
void parseReply(const uint8_t* receivedData,
|
void parseReply(const uint8_t* receivedData,
|
||||||
size_t receivedDataLen);
|
size_t receivedDataLen);
|
||||||
|
|
||||||
virtual dur_millis_t getPeriodicOperationFrequency() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||||
|
@ -247,6 +247,14 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (owner == nullptr) {
|
||||||
|
// Configuration error.
|
||||||
|
sif::error << "DeviceHandlerFailureIsolation::"
|
||||||
|
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (owner->getHealth() == HasHealthIF::FAULTY
|
if (owner->getHealth() == HasHealthIF::FAULTY
|
||||||
|| owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) {
|
|| owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) {
|
||||||
//Ignore all events in case device is already faulty.
|
//Ignore all events in case device is already faulty.
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
#ifndef DEVICEHANDLERIF_H_
|
#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_
|
||||||
#define DEVICEHANDLERIF_H_
|
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_
|
||||||
|
|
||||||
|
#include "DeviceHandlerMessage.h"
|
||||||
|
|
||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
#include "../devicehandlers/DeviceHandlerMessage.h"
|
|
||||||
#include "../events/Event.h"
|
#include "../events/Event.h"
|
||||||
#include "../modes/HasModesIF.h"
|
#include "../modes/HasModesIF.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used to uniquely identify commands that are sent to a device
|
||||||
|
* The values are defined in the device-specific implementations
|
||||||
|
*/
|
||||||
|
using DeviceCommandId_t = uint32_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the Interface used to communicate with a device handler.
|
* @brief This is the Interface used to communicate with a device handler.
|
||||||
* @details Includes all expected return values, events and modes.
|
* @details Includes all expected return values, events and modes.
|
||||||
@ -15,6 +22,7 @@
|
|||||||
class DeviceHandlerIF {
|
class DeviceHandlerIF {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
static const uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
static const uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
||||||
static const uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
static const uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
||||||
|
|
||||||
@ -153,4 +161,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DEVICEHANDLERIF_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ */
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
|
#include "DeviceHandlerMessage.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../devicehandlers/DeviceHandlerMessage.h"
|
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
|
||||||
|
|
||||||
DeviceHandlerMessage::DeviceHandlerMessage() {
|
|
||||||
}
|
|
||||||
|
|
||||||
store_address_t DeviceHandlerMessage::getStoreAddress(
|
store_address_t DeviceHandlerMessage::getStoreAddress(
|
||||||
const CommandMessage* message) {
|
const CommandMessage* message) {
|
||||||
@ -25,14 +21,6 @@ uint8_t DeviceHandlerMessage::getWiretappingMode(
|
|||||||
return message->getParameter();
|
return message->getParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
//void DeviceHandlerMessage::setDeviceHandlerDirectCommandMessage(
|
|
||||||
// CommandMessage* message, DeviceCommandId_t deviceCommand,
|
|
||||||
// store_address_t commandParametersStoreId) {
|
|
||||||
// message->setCommand(CMD_DIRECT);
|
|
||||||
// message->setParameter(deviceCommand);
|
|
||||||
// message->setParameter2(commandParametersStoreId.raw);
|
|
||||||
//}
|
|
||||||
|
|
||||||
void DeviceHandlerMessage::setDeviceHandlerRawCommandMessage(
|
void DeviceHandlerMessage::setDeviceHandlerRawCommandMessage(
|
||||||
CommandMessage* message, store_address_t rawPacketStoreId) {
|
CommandMessage* message, store_address_t rawPacketStoreId) {
|
||||||
message->setCommand(CMD_RAW);
|
message->setCommand(CMD_RAW);
|
||||||
@ -79,13 +67,12 @@ void DeviceHandlerMessage::setDeviceHandlerDirectCommandReply(
|
|||||||
void DeviceHandlerMessage::clear(CommandMessage* message) {
|
void DeviceHandlerMessage::clear(CommandMessage* message) {
|
||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
case CMD_RAW:
|
case CMD_RAW:
|
||||||
// case CMD_DIRECT:
|
|
||||||
case REPLY_RAW_COMMAND:
|
case REPLY_RAW_COMMAND:
|
||||||
case REPLY_RAW_REPLY:
|
case REPLY_RAW_REPLY:
|
||||||
case REPLY_DIRECT_COMMAND_DATA: {
|
case REPLY_DIRECT_COMMAND_DATA: {
|
||||||
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
|
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
|
||||||
objects::IPC_STORE);
|
objects::IPC_STORE);
|
||||||
if (ipcStore != NULL) {
|
if (ipcStore != nullptr) {
|
||||||
ipcStore->deleteData(getStoreAddress(message));
|
ipcStore->deleteData(getStoreAddress(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,69 +1,56 @@
|
|||||||
#ifndef DEVICEHANDLERMESSAGE_H_
|
#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_
|
||||||
#define DEVICEHANDLERMESSAGE_H_
|
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_
|
||||||
|
|
||||||
#include "../action/ActionMessage.h"
|
#include "../action/ActionMessage.h"
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "../storagemanager/StorageManagerIF.h"
|
||||||
//SHOULDDO: rework the static constructors to name the type of command they are building, maybe even hide setting the commandID.
|
// SHOULDDO: rework the static constructors to name the type of command
|
||||||
|
// they are building, maybe even hide setting the commandID.
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used to uniquely identify commands that are sent to a device
|
* @brief The DeviceHandlerMessage is used to send commands to classes
|
||||||
*
|
* implementing DeviceHandlerIF
|
||||||
* The values are defined in the device-specific implementations
|
|
||||||
*/
|
|
||||||
typedef uint32_t DeviceCommandId_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The DeviceHandlerMessage is used to send Commands to a DeviceHandlerIF
|
|
||||||
*/
|
*/
|
||||||
class DeviceHandlerMessage {
|
class DeviceHandlerMessage {
|
||||||
private:
|
|
||||||
DeviceHandlerMessage();
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Instantiation forbidden. Instead, use static functions to operate
|
||||||
|
* on messages.
|
||||||
|
*/
|
||||||
|
DeviceHandlerMessage() = delete;
|
||||||
|
virtual ~DeviceHandlerMessage() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are the commands that can be sent to a DeviceHandlerBase
|
* These are the commands that can be sent to a DeviceHandlerBase
|
||||||
*/
|
*/
|
||||||
static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND;
|
static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND;
|
||||||
static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send
|
//! Sends a raw command, setParameter is a storeId containing the
|
||||||
// static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command
|
//! raw packet to send
|
||||||
static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier
|
static const Command_t CMD_RAW = MAKE_COMMAND_ID(1);
|
||||||
static const Command_t CMD_WIRETAPPING = MAKE_COMMAND_ID( 4 ); //!< (De)Activates the monitoring of all raw traffic in DeviceHandlers, setParameter is 0 to deactivate, 1 to activate
|
//! Requests a IO-Board switch, setParameter() is the IO-Board identifier
|
||||||
|
static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID(3);
|
||||||
|
//! (De)Activates the monitoring of all raw traffic in DeviceHandlers,
|
||||||
|
//! setParameter is 0 to deactivate, 1 to activate
|
||||||
|
static const Command_t CMD_WIRETAPPING = MAKE_COMMAND_ID(4);
|
||||||
|
|
||||||
/*static const Command_t REPLY_SWITCHED_IOBOARD = MAKE_COMMAND_ID(1 );//!< Reply to a @c CMD_SWITCH_IOBOARD, indicates switch was successful, getParameter() contains the board switched to (0: nominal, 1: redundant)
|
//! Signals that a direct command was sent
|
||||||
static const Command_t REPLY_CANT_SWITCH_IOBOARD = MAKE_COMMAND_ID( 2); //!< Reply to a @c CMD_SWITCH_IOBOARD, indicating the switch could not be performed, getParameter() contains the error message
|
static const Command_t REPLY_DIRECT_COMMAND_SENT = ActionMessage::STEP_SUCCESS;
|
||||||
static const Command_t REPLY_WIRETAPPING = MAKE_COMMAND_ID( 3); //!< Reply to a @c CMD_WIRETAPPING, getParameter() is the current state, 1 enabled, 0 disabled
|
//! Contains a raw command sent to the Device
|
||||||
|
static const Command_t REPLY_RAW_COMMAND = MAKE_COMMAND_ID(0x11);
|
||||||
static const Command_t REPLY_COMMAND_WAS_SENT = MAKE_COMMAND_ID(4 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates the command was successfully sent to the device, getParameter() contains the ::DeviceCommandId_t
|
//! Contains a raw reply from the Device, getParameter() is the ObjcetId
|
||||||
static const Command_t REPLY_COMMAND_NOT_SUPPORTED = MAKE_COMMAND_ID(5 );//!< Reply to a @c CMD_DIRECT, the requested ::DeviceCommand_t is not supported, getParameter() contains the requested ::DeviceCommand_t, getParameter2() contains the ::DeviceCommandId_t
|
//! of the sender, getParameter2() is a ::store_id_t containing the
|
||||||
static const Command_t REPLY_COMMAND_WAS_NOT_SENT = MAKE_COMMAND_ID(6 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates the command was not sent, getParameter contains the RMAP Return code (@see rmap.h), getParameter2() contains the ::DeviceCommandId_t
|
//! raw packet received
|
||||||
|
static const Command_t REPLY_RAW_REPLY = MAKE_COMMAND_ID(0x12);
|
||||||
static const Command_t REPLY_COMMAND_ALREADY_SENT = MAKE_COMMAND_ID(7 );//!< Reply to a @c CMD_DIRECT, the requested ::DeviceCommand_t has already been sent to the device and not ye been answered
|
|
||||||
static const Command_t REPLY_WRONG_MODE_FOR_CMD = MAKE_COMMAND_ID(8 );//!< Reply to a @c CMD_RAW or @c CMD_DIRECT, indicates that the requested command can not be sent in the curent mode, getParameter() contains the DeviceHandlerCommand_t
|
|
||||||
static const Command_t REPLY_NO_DATA = MAKE_COMMAND_ID(9 ); //!< Reply to a CMD_RAW or @c CMD_DIRECT, indicates that the ::store_id_t was invalid, getParameter() contains the ::DeviceCommandId_t, getPrameter2() contains the error code
|
|
||||||
*/
|
|
||||||
static const Command_t REPLY_DIRECT_COMMAND_SENT = ActionMessage::STEP_SUCCESS; //!< Signals that a direct command was sent
|
|
||||||
static const Command_t REPLY_RAW_COMMAND = MAKE_COMMAND_ID(0x11 ); //!< Contains a raw command sent to the Device
|
|
||||||
static const Command_t REPLY_RAW_REPLY = MAKE_COMMAND_ID( 0x12); //!< Contains a raw reply from the Device, getParameter() is the ObjcetId of the sender, getParameter2() is a ::store_id_t containing the raw packet received
|
|
||||||
static const Command_t REPLY_DIRECT_COMMAND_DATA = ActionMessage::DATA_REPLY;
|
static const Command_t REPLY_DIRECT_COMMAND_DATA = ActionMessage::DATA_REPLY;
|
||||||
|
|
||||||
/**
|
|
||||||
* Default Destructor
|
|
||||||
*/
|
|
||||||
virtual ~DeviceHandlerMessage() {
|
|
||||||
}
|
|
||||||
|
|
||||||
static store_address_t getStoreAddress(const CommandMessage* message);
|
static store_address_t getStoreAddress(const CommandMessage* message);
|
||||||
static uint32_t getDeviceCommandId(const CommandMessage* message);
|
static uint32_t getDeviceCommandId(const CommandMessage* message);
|
||||||
static object_id_t getDeviceObjectId(const CommandMessage *message);
|
static object_id_t getDeviceObjectId(const CommandMessage *message);
|
||||||
static object_id_t getIoBoardObjectId(const CommandMessage* message);
|
static object_id_t getIoBoardObjectId(const CommandMessage* message);
|
||||||
static uint8_t getWiretappingMode(const CommandMessage* message);
|
static uint8_t getWiretappingMode(const CommandMessage* message);
|
||||||
|
|
||||||
// static void setDeviceHandlerDirectCommandMessage(CommandMessage* message,
|
|
||||||
// DeviceCommandId_t deviceCommand,
|
|
||||||
// store_address_t commandParametersStoreId);
|
|
||||||
|
|
||||||
static void setDeviceHandlerDirectCommandReply(CommandMessage* message,
|
static void setDeviceHandlerDirectCommandReply(CommandMessage* message,
|
||||||
object_id_t deviceObjectid,
|
object_id_t deviceObjectid,
|
||||||
store_address_t commandParametersStoreId);
|
store_address_t commandParametersStoreId);
|
||||||
@ -75,11 +62,6 @@ public:
|
|||||||
object_id_t deviceObjectid, store_address_t rawPacketStoreId,
|
object_id_t deviceObjectid, store_address_t rawPacketStoreId,
|
||||||
bool isCommand);
|
bool isCommand);
|
||||||
|
|
||||||
// static void setDeviceHandlerMessage(CommandMessage* message,
|
|
||||||
// Command_t command, DeviceCommandId_t deviceCommand,
|
|
||||||
// store_address_t commandParametersStoreId);
|
|
||||||
// static void setDeviceHandlerMessage(CommandMessage* message,
|
|
||||||
// Command_t command, store_address_t rawPacketStoreId);
|
|
||||||
static void setDeviceHandlerWiretappingMessage(CommandMessage* message,
|
static void setDeviceHandlerWiretappingMessage(CommandMessage* message,
|
||||||
uint8_t wiretappingMode);
|
uint8_t wiretappingMode);
|
||||||
static void setDeviceHandlerSwitchIoBoardMessage(CommandMessage* message,
|
static void setDeviceHandlerSwitchIoBoardMessage(CommandMessage* message,
|
||||||
@ -88,4 +70,4 @@ public:
|
|||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DEVICEHANDLERMESSAGE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERMESSAGE_H_ */
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
|
||||||
namespace EVENT {
|
namespace EVENT {
|
||||||
EventId_t getEventId(Event event) {
|
EventId_t getEventId(Event event) {
|
||||||
return (event & 0xFFFF);
|
return (event & 0xFFFF);
|
||||||
@ -8,7 +9,8 @@ EventSeverity_t getSeverity(Event event) {
|
|||||||
return ((event >> 16) & 0xFF);
|
return ((event >> 16) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event makeEvent(EventId_t eventId, EventSeverity_t eventSeverity) {
|
Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
|
||||||
return (eventSeverity << 16) + (eventId & 0xFFFF);
|
EventSeverity_t eventSeverity) {
|
||||||
|
return (eventSeverity << 16) + (subsystemId * 100) + uniqueEventId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "fwSubsystemIdRanges.h"
|
#include "fwSubsystemIdRanges.h"
|
||||||
//could be move to more suitable location
|
//could be move to more suitable location
|
||||||
#include <config/tmtc/subsystemIdRanges.h>
|
#include <subsystemIdRanges.h>
|
||||||
|
|
||||||
typedef uint16_t EventId_t;
|
typedef uint16_t EventId_t;
|
||||||
typedef uint8_t EventSeverity_t;
|
typedef uint8_t EventSeverity_t;
|
||||||
@ -18,9 +18,10 @@ EventId_t getEventId(Event event);
|
|||||||
|
|
||||||
EventSeverity_t getSeverity(Event event);
|
EventSeverity_t getSeverity(Event event);
|
||||||
|
|
||||||
Event makeEvent(EventId_t eventId, EventSeverity_t eventSeverity);
|
Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
|
||||||
|
EventSeverity_t eventSeverity);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace SEVERITY {
|
namespace SEVERITY {
|
||||||
static const EventSeverity_t INFO = 1;
|
static const EventSeverity_t INFO = 1;
|
||||||
static const EventSeverity_t LOW = 2;
|
static const EventSeverity_t LOW = 2;
|
||||||
|
@ -109,13 +109,13 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if FSFW_DEBUG_OUTPUT == 1
|
||||||
|
|
||||||
void EventManager::printEvent(EventMessage* message) {
|
void EventManager::printEvent(EventMessage* message) {
|
||||||
const char *string = 0;
|
const char *string = 0;
|
||||||
switch (message->getSeverity()) {
|
switch (message->getSeverity()) {
|
||||||
case SEVERITY::INFO:
|
case SEVERITY::INFO:
|
||||||
#ifdef DEBUG_INFO_EVENT
|
#if DEBUG_INFO_EVENT == 1
|
||||||
string = translateObject(message->getReporter());
|
string = translateObject(message->getReporter());
|
||||||
sif::info << "EVENT: ";
|
sif::info << "EVENT: ";
|
||||||
if (string != 0) {
|
if (string != 0) {
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
#include "../tasks/ExecutableObjectIF.h"
|
#include "../tasks/ExecutableObjectIF.h"
|
||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
|
#include <FSFWConfig.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if FSFW_DEBUG_OUTPUT == 1
|
||||||
// forward declaration, should be implemented by mission
|
// forward declaration, should be implemented by mission
|
||||||
extern const char* translateObject(object_id_t object);
|
extern const char* translateObject(object_id_t object);
|
||||||
extern const char* translateEvents(Event event);
|
extern const char* translateEvents(Event event);
|
||||||
@ -55,7 +57,7 @@ protected:
|
|||||||
|
|
||||||
void notifyListeners(EventMessage *message);
|
void notifyListeners(EventMessage *message);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if FSFW_DEBUG_OUTPUT == 1
|
||||||
void printEvent(EventMessage *message);
|
void printEvent(EventMessage *message);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#ifndef EVENTMANAGERIF_H_
|
#ifndef EVENTMANAGERIF_H_
|
||||||
#define EVENTMANAGERIF_H_
|
#define EVENTMANAGERIF_H_
|
||||||
|
|
||||||
#include "eventmatching/eventmatching.h"
|
|
||||||
#include "EventMessage.h"
|
#include "EventMessage.h"
|
||||||
|
#include "eventmatching/eventmatching.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
|
#include "../ipc/MessageQueueIF.h"
|
||||||
|
|
||||||
class EventManagerIF {
|
class EventManagerIF {
|
||||||
public:
|
public:
|
||||||
@ -16,7 +17,8 @@ public:
|
|||||||
|
|
||||||
virtual MessageQueueId_t getEventReportQueue() = 0;
|
virtual MessageQueueId_t getEventReportQueue() = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false) = 0;
|
virtual ReturnValue_t registerListener(MessageQueueId_t listener,
|
||||||
|
bool forwardAllButSelected = false) = 0;
|
||||||
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener,
|
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener,
|
||||||
EventId_t event) = 0;
|
EventId_t event) = 0;
|
||||||
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener,
|
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener,
|
||||||
@ -31,18 +33,22 @@ public:
|
|||||||
bool reporterInverted = false) = 0;
|
bool reporterInverted = false) = 0;
|
||||||
|
|
||||||
static void triggerEvent(object_id_t reportingObject, Event event,
|
static void triggerEvent(object_id_t reportingObject, Event event,
|
||||||
uint32_t parameter1 = 0, uint32_t parameter2 = 0, MessageQueueId_t sentFrom = 0) {
|
uint32_t parameter1 = 0, uint32_t parameter2 = 0,
|
||||||
|
MessageQueueId_t sentFrom = 0) {
|
||||||
EventMessage message(event, reportingObject, parameter1, parameter2);
|
EventMessage message(event, reportingObject, parameter1, parameter2);
|
||||||
triggerEvent(&message, sentFrom);
|
triggerEvent(&message, sentFrom);
|
||||||
}
|
}
|
||||||
static void triggerEvent(EventMessage* message, MessageQueueId_t sentFrom = 0) {
|
|
||||||
static MessageQueueId_t eventmanagerQueue = 0;
|
static void triggerEvent(EventMessage* message,
|
||||||
if (eventmanagerQueue == 0) {
|
MessageQueueId_t sentFrom = 0) {
|
||||||
|
static MessageQueueId_t eventmanagerQueue = MessageQueueIF::NO_QUEUE;
|
||||||
|
if (eventmanagerQueue == MessageQueueIF::NO_QUEUE) {
|
||||||
EventManagerIF *eventmanager = objectManager->get<EventManagerIF>(
|
EventManagerIF *eventmanager = objectManager->get<EventManagerIF>(
|
||||||
objects::EVENT_MANAGER);
|
objects::EVENT_MANAGER);
|
||||||
if (eventmanager != NULL) {
|
if (eventmanager == nullptr) {
|
||||||
eventmanagerQueue = eventmanager->getEventReportQueue();
|
return;
|
||||||
}
|
}
|
||||||
|
eventmanagerQueue = eventmanager->getEventReportQueue();
|
||||||
}
|
}
|
||||||
MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, sentFrom);
|
MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, sentFrom);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ enum {
|
|||||||
SYSTEM_MANAGER_1 = 75,
|
SYSTEM_MANAGER_1 = 75,
|
||||||
SYSTEM_1 = 79,
|
SYSTEM_1 = 79,
|
||||||
PUS_SERVICE_1 = 80,
|
PUS_SERVICE_1 = 80,
|
||||||
|
PUS_SERVICE_9 = 89,
|
||||||
|
PUS_SERVICE_17 = 97,
|
||||||
FW_SUBSYSTEM_ID_RANGE
|
FW_SUBSYSTEM_ID_RANGE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
|
|
||||||
// TODO: Documentation.
|
|
||||||
class ConfirmsFailuresIF {
|
class ConfirmsFailuresIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::HANDLES_FAILURES_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::HANDLES_FAILURES_IF;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../fdir/EventCorrelation.h"
|
#include "EventCorrelation.h"
|
||||||
|
|
||||||
EventCorrelation::EventCorrelation(uint32_t timeout) :
|
EventCorrelation::EventCorrelation(uint32_t timeout) :
|
||||||
eventPending(false) {
|
eventPending(false) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "../events/EventManagerIF.h"
|
#include "../events/EventManagerIF.h"
|
||||||
#include "../fdir/FailureIsolationBase.h"
|
#include "FailureIsolationBase.h"
|
||||||
#include "../health/HasHealthIF.h"
|
#include "../health/HasHealthIF.h"
|
||||||
#include "../health/HealthMessage.h"
|
#include "../health/HealthMessage.h"
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#define FRAMEWORK_FDIR_FAILUREISOLATIONBASE_H_
|
#define FRAMEWORK_FDIR_FAILUREISOLATIONBASE_H_
|
||||||
|
|
||||||
#include "../events/EventMessage.h"
|
#include "../events/EventMessage.h"
|
||||||
#include "../fdir/ConfirmsFailuresIF.h"
|
#include "ConfirmsFailuresIF.h"
|
||||||
#include "../fdir/FaultCounter.h"
|
#include "FaultCounter.h"
|
||||||
#include "../health/HealthMessage.h"
|
#include "../health/HealthMessage.h"
|
||||||
#include "../parameters/HasParametersIF.h"
|
#include "../parameters/HasParametersIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../fdir/FaultCounter.h"
|
#include "FaultCounter.h"
|
||||||
|
|
||||||
FaultCounter::FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs,
|
FaultCounter::FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs,
|
||||||
uint8_t setParameterDomain) :
|
uint8_t setParameterDomain) :
|
||||||
|
13
fsfw.mk
13
fsfw.mk
@ -31,12 +31,25 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/*.cpp)
|
|||||||
# select the OS
|
# select the OS
|
||||||
ifeq ($(OS_FSFW),rtems)
|
ifeq ($(OS_FSFW),rtems)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/rtems/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/rtems/*.cpp)
|
||||||
|
|
||||||
else ifeq ($(OS_FSFW),linux)
|
else ifeq ($(OS_FSFW),linux)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/linux/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/linux/*.cpp)
|
||||||
|
|
||||||
else ifeq ($(OS_FSFW),freeRTOS)
|
else ifeq ($(OS_FSFW),freeRTOS)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/FreeRTOS/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/FreeRTOS/*.cpp)
|
||||||
|
|
||||||
else ifeq ($(OS_FSFW),host)
|
else ifeq ($(OS_FSFW),host)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/host/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/host/*.cpp)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/windows/*.cpp)
|
||||||
|
else
|
||||||
|
# For now, the linux UDP bridge sources needs to be included manually by upper makefile
|
||||||
|
# for host OS because we can't be sure the OS is linux.
|
||||||
|
# Following lines can be used to do this:
|
||||||
|
# CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TcUnixUdpPollingTask.cpp
|
||||||
|
# CXXSRC += $(FRAMEWORK_PATH)/osal/linux/TmTcUnixUdpBridge.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
else
|
else
|
||||||
$(error invalid OS_FSFW specified, valid OS_FSFW are rtems, linux, freeRTOS, host)
|
$(error invalid OS_FSFW specified, valid OS_FSFW are rtems, linux, freeRTOS, host)
|
||||||
endif
|
endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../globalfunctions/AsciiConverter.h"
|
#include "AsciiConverter.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../globalfunctions/CRC.h"
|
#include "CRC.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
const uint16_t CRC::crc16ccitt_table[256] = {
|
const uint16_t CRC::crc16ccitt_table[256] = {
|
||||||
|
@ -92,7 +92,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream,
|
|||||||
else {
|
else {
|
||||||
/* The next byte is a STX, DTX or 0x0D character which
|
/* The next byte is a STX, DTX or 0x0D character which
|
||||||
* was escaped by a DLE character. The actual byte was
|
* was escaped by a DLE character. The actual byte was
|
||||||
* also encoded by adding + 0x40 to preven having control chars,
|
* also encoded by adding + 0x40 to prevent having control chars,
|
||||||
* in the stream at all, so we convert it back. */
|
* in the stream at all, so we convert it back. */
|
||||||
if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) {
|
if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) {
|
||||||
destStream[decodedIndex] = nextByte - 0x40;
|
destStream[decodedIndex] = nextByte - 0x40;
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
* char based transmission systems.
|
* char based transmission systems.
|
||||||
* The passed source strean is converted into a encoded stream by adding
|
* The passed source strean is converted into a encoded stream by adding
|
||||||
* a STX marker at the start of the stream and an ETX marker at the end of
|
* a STX marker at the start of the stream and an ETX marker at the end of
|
||||||
* the stream. Any STX, ETX, DLE and CR occurences in the source stream are
|
* the stream. Any STX, ETX, DLE and CR occurrences in the source stream are
|
||||||
* escaped by a DLE character. The encoder also replaces escaped control chars
|
* escaped by a DLE character. The encoder also replaces escaped control chars
|
||||||
* by another char, so STX, ETX and CR should not appear anywhere in the actual
|
* by another char, so STX, ETX and CR should not appear anywhere in the actual
|
||||||
* encoded data stream.
|
* encoded data stream.
|
||||||
*
|
*
|
||||||
* When using a strictly char based reception of packets enoded with DLE,
|
* When using a strictly char based reception of packets encoded with DLE,
|
||||||
* STX can be used to notify a reader that actual data will start to arrive
|
* STX can be used to notify a reader that actual data will start to arrive
|
||||||
* while ETX can be used to notify the reader that the data has ended.
|
* while ETX can be used to notify the reader that the data has ended.
|
||||||
*/
|
*/
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
static constexpr uint8_t STX_CHAR = 0x02;
|
static constexpr uint8_t STX_CHAR = 0x02;
|
||||||
//! End Of Text character. Last character in encoded stream
|
//! End Of Text character. Last character in encoded stream
|
||||||
static constexpr uint8_t ETX_CHAR = 0x03;
|
static constexpr uint8_t ETX_CHAR = 0x03;
|
||||||
//! Data Link Escape character. Used to escape STX, ETX and DLE occurences
|
//! Data Link Escape character. Used to escape STX, ETX and DLE occurrences
|
||||||
//! in the source stream.
|
//! in the source stream.
|
||||||
static constexpr uint8_t DLE_CHAR = 0x10;
|
static constexpr uint8_t DLE_CHAR = 0x10;
|
||||||
static constexpr uint8_t CARRIAGE_RETURN = 0x0D;
|
static constexpr uint8_t CARRIAGE_RETURN = 0x0D;
|
||||||
@ -47,7 +47,7 @@ public:
|
|||||||
* Encodes the give data stream by preceding it with the STX marker
|
* Encodes the give data stream by preceding it with the STX marker
|
||||||
* and ending it with an ETX marker. STX, ETX and DLE characters inside
|
* and ending it with an ETX marker. STX, ETX and DLE characters inside
|
||||||
* the stream are escaped by DLE characters and also replaced by adding
|
* the stream are escaped by DLE characters and also replaced by adding
|
||||||
* 0x40 (which is reverted in the decoing process).
|
* 0x40 (which is reverted in the decoding process).
|
||||||
* @param sourceStream
|
* @param sourceStream
|
||||||
* @param sourceLen
|
* @param sourceLen
|
||||||
* @param destStream
|
* @param destStream
|
||||||
|
44
globalfunctions/PeriodicOperationDivider.cpp
Normal file
44
globalfunctions/PeriodicOperationDivider.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "PeriodicOperationDivider.h"
|
||||||
|
|
||||||
|
|
||||||
|
PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider,
|
||||||
|
bool resetAutomatically): resetAutomatically(resetAutomatically),
|
||||||
|
counter(divider), divider(divider) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PeriodicOperationDivider::checkAndIncrement() {
|
||||||
|
bool opNecessary = check();
|
||||||
|
if(opNecessary) {
|
||||||
|
if(resetAutomatically) {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
return opNecessary;
|
||||||
|
}
|
||||||
|
counter ++;
|
||||||
|
return opNecessary;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PeriodicOperationDivider::check() {
|
||||||
|
if(counter >= divider) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void PeriodicOperationDivider::resetCounter() {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeriodicOperationDivider::setDivider(uint32_t newDivider) {
|
||||||
|
divider = newDivider;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PeriodicOperationDivider::getCounter() const {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PeriodicOperationDivider::getDivider() const {
|
||||||
|
return divider;
|
||||||
|
}
|
65
globalfunctions/PeriodicOperationDivider.h
Normal file
65
globalfunctions/PeriodicOperationDivider.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#ifndef FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_
|
||||||
|
#define FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lightweight helper class to facilitate periodic operation with
|
||||||
|
* decreased frequencies.
|
||||||
|
* @details
|
||||||
|
* This class is useful to perform operations which have to be performed
|
||||||
|
* with a reduced frequency, like debugging printouts in high periodic tasks
|
||||||
|
* or low priority operations.
|
||||||
|
*/
|
||||||
|
class PeriodicOperationDivider {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initialize with the desired divider and specify whether the internal
|
||||||
|
* counter will be reset automatically.
|
||||||
|
* @param divider
|
||||||
|
* @param resetAutomatically
|
||||||
|
*/
|
||||||
|
PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether operation is necessary.
|
||||||
|
* If an operation is necessary and the class has been
|
||||||
|
* configured to be reset automatically, the counter will be reset.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* -@c true if the counter is larger or equal to the divider
|
||||||
|
* -@c false otherwise
|
||||||
|
*/
|
||||||
|
bool checkAndIncrement();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether an operation is necessary.
|
||||||
|
* This function will not increment the counter!
|
||||||
|
* @return
|
||||||
|
* -@c true if the counter is larger or equal to the divider
|
||||||
|
* -@c false otherwise
|
||||||
|
*/
|
||||||
|
bool check();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to reset the counter to 0 manually.
|
||||||
|
*/
|
||||||
|
void resetCounter();
|
||||||
|
uint32_t getCounter() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to set a new divider value.
|
||||||
|
* @param newDivider
|
||||||
|
*/
|
||||||
|
void setDivider(uint32_t newDivider);
|
||||||
|
uint32_t getDivider() const;
|
||||||
|
private:
|
||||||
|
bool resetAutomatically = true;
|
||||||
|
uint32_t counter = 0;
|
||||||
|
uint32_t divider = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_ */
|
@ -1,4 +1,4 @@
|
|||||||
#include "../globalfunctions/arrayprinter.h"
|
#include "arrayprinter.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size,
|
|||||||
if(i < size - 1){
|
if(i < size - 1){
|
||||||
sif::info << " , ";
|
sif::info << " , ";
|
||||||
if(i > 0 and i % maxCharPerLine == 0) {
|
if(i > 0 and i % maxCharPerLine == 0) {
|
||||||
sif::info << "\r\n" << std::flush;
|
sif::info << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef BINARYMATCHER_H_
|
#ifndef BINARYMATCHER_H_
|
||||||
#define BINARYMATCHER_H_
|
#define BINARYMATCHER_H_
|
||||||
|
|
||||||
#include "../../globalfunctions/matching/MatcherIF.h"
|
#include "MatcherIF.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class BinaryMatcher: public MatcherIF<T> {
|
class BinaryMatcher: public MatcherIF<T> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef DECIMALMATCHER_H_
|
#ifndef DECIMALMATCHER_H_
|
||||||
#define DECIMALMATCHER_H_
|
#define DECIMALMATCHER_H_
|
||||||
|
|
||||||
#include "../../globalfunctions/matching/MatcherIF.h"
|
#include "MatcherIF.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class DecimalMatcher: public MatcherIF<T> {
|
class DecimalMatcher: public MatcherIF<T> {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_
|
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_MATCHTREE_H_
|
||||||
|
|
||||||
#include "../../container/BinaryTree.h"
|
#include "../../container/BinaryTree.h"
|
||||||
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
|
#include "SerializeableMatcherIF.h"
|
||||||
#include "../../serialize/SerializeAdapter.h"
|
#include "../../serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef RANGEMATCHER_H_
|
#ifndef RANGEMATCHER_H_
|
||||||
#define RANGEMATCHER_H_
|
#define RANGEMATCHER_H_
|
||||||
|
|
||||||
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
|
#include "SerializeableMatcherIF.h"
|
||||||
#include "../../serialize/SerializeAdapter.h"
|
#include "../../serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
|
#ifndef FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
|
||||||
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
|
#define FRAMEWORK_GLOBALFUNCTIONS_MATCHING_SERIALIZEABLEMATCHERIF_H_
|
||||||
|
|
||||||
#include "../../globalfunctions/matching/MatcherIF.h"
|
#include "MatcherIF.h"
|
||||||
#include "../../serialize/SerializeIF.h"
|
#include "../../serialize/SerializeIF.h"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "QuaternionOperations.h"
|
#include "QuaternionOperations.h"
|
||||||
#include "../../globalfunctions/math/VectorOperations.h"
|
#include "VectorOperations.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef HASHEALTHIF_H_
|
#ifndef FSFW_HEALTH_HASHEALTHIF_H_
|
||||||
#define HASHEALTHIF_H_
|
#define FSFW_HEALTH_HASHEALTHIF_H_
|
||||||
|
|
||||||
#include "../events/Event.h"
|
#include "../events/Event.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
@ -8,9 +8,13 @@
|
|||||||
class HasHealthIF {
|
class HasHealthIF {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef enum {
|
enum HealthState: uint8_t {
|
||||||
HEALTHY = 1, FAULTY = 0, EXTERNAL_CONTROL = 2, NEEDS_RECOVERY = 3, PERMANENT_FAULTY = 4
|
HEALTHY = 1,
|
||||||
} HealthState;
|
FAULTY = 0,
|
||||||
|
EXTERNAL_CONTROL = 2,
|
||||||
|
NEEDS_RECOVERY = 3,
|
||||||
|
PERMANENT_FAULTY = 4
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||||
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||||
@ -31,20 +35,17 @@ public:
|
|||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the Health State
|
* @brief Set the Health State
|
||||||
*
|
|
||||||
* The parent will be informed, if the Health changes
|
* The parent will be informed, if the Health changes
|
||||||
*
|
|
||||||
* @param health
|
* @param health
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t setHealth(HealthState health) = 0;
|
virtual ReturnValue_t setHealth(HealthState health) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get Health State
|
* @brief Get Health State
|
||||||
*
|
|
||||||
* @return Health State of the object
|
* @return Health State of the object
|
||||||
*/
|
*/
|
||||||
virtual HasHealthIF::HealthState getHealth() = 0;
|
virtual HasHealthIF::HealthState getHealth() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HASHEALTHIF_H_ */
|
#endif /* FSFW_HEALTH_HASHEALTHIF_H_ */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../health/HealthHelper.h"
|
#include "HealthHelper.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||||
|
|
||||||
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) :
|
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) :
|
||||||
@ -71,7 +71,7 @@ void HealthHelper::setHealth(HasHealthIF::HealthState health) {
|
|||||||
|
|
||||||
void HealthHelper::informParent(HasHealthIF::HealthState health,
|
void HealthHelper::informParent(HasHealthIF::HealthState health,
|
||||||
HasHealthIF::HealthState oldHealth) {
|
HasHealthIF::HealthState oldHealth) {
|
||||||
if (parentQueue == MessageQueueMessageIF::NO_QUEUE) {
|
if (parentQueue == MessageQueueIF::NO_QUEUE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CommandMessage information;
|
CommandMessage information;
|
||||||
@ -86,7 +86,7 @@ void HealthHelper::informParent(HasHealthIF::HealthState health,
|
|||||||
|
|
||||||
void HealthHelper::handleSetHealthCommand(CommandMessage* command) {
|
void HealthHelper::handleSetHealthCommand(CommandMessage* command) {
|
||||||
ReturnValue_t result = owner->setHealth(HealthMessage::getHealth(command));
|
ReturnValue_t result = owner->setHealth(HealthMessage::getHealth(command));
|
||||||
if (command->getSender() == MessageQueueMessageIF::NO_QUEUE) {
|
if (command->getSender() == MessageQueueIF::NO_QUEUE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
#ifndef FRAMEWORK_HEALTH_HEALTHHELPER_H_
|
#ifndef FSFW_HEALTH_HEALTHHELPER_H_
|
||||||
#define FRAMEWORK_HEALTH_HEALTHHELPER_H_
|
#define FSFW_HEALTH_HEALTHHELPER_H_
|
||||||
|
|
||||||
|
#include "HasHealthIF.h"
|
||||||
|
#include "HealthMessage.h"
|
||||||
|
#include "HealthTableIF.h"
|
||||||
|
|
||||||
#include "../events/EventManagerIF.h"
|
#include "../events/EventManagerIF.h"
|
||||||
#include "../events/EventReportingProxyIF.h"
|
#include "../events/EventReportingProxyIF.h"
|
||||||
#include "../health/HasHealthIF.h"
|
|
||||||
#include "../health/HealthMessage.h"
|
|
||||||
#include "../health/HealthTableIF.h"
|
|
||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#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
|
* If a parent is set in the ctor, the parent will be informed with a
|
||||||
* (including replying to the sender) and updating the Health Table.
|
* @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.
|
* changes, not for all @c HEALTH_SET commands received.
|
||||||
*
|
*
|
||||||
* It does NOT handle @c HEALTH_INFO messages
|
* It does NOT handle @c HEALTH_INFO messages
|
||||||
@ -26,10 +29,9 @@ class HealthHelper {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ctor
|
|
||||||
*
|
|
||||||
* @param owner
|
* @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);
|
HealthHelper(HasHealthIF* owner, object_id_t objectId);
|
||||||
|
|
||||||
@ -56,7 +58,8 @@ public:
|
|||||||
* @param message
|
* @param message
|
||||||
* @return
|
* @return
|
||||||
* -@c RETURN_OK if the message was handled
|
* -@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_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);
|
ReturnValue_t handleHealthCommand(CommandMessage *message);
|
||||||
|
|
||||||
@ -77,15 +80,18 @@ public:
|
|||||||
HasHealthIF::HealthState getHealth();
|
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);
|
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
|
* @return
|
||||||
* -@c RETURN_OK if the Health Table was found and the object could be registered
|
* -@c RETURN_OK if the Health Table was found and the object
|
||||||
|
* could be registered
|
||||||
* -@c RETURN_FAILED else
|
* -@c RETURN_FAILED else
|
||||||
*/
|
*/
|
||||||
ReturnValue_t initialize(MessageQueueId_t parentQueue );
|
ReturnValue_t initialize(MessageQueueId_t parentQueue );
|
||||||
@ -109,13 +115,17 @@ private:
|
|||||||
HasHealthIF* owner;
|
HasHealthIF* owner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if the #parentQueue is not NULL, a @c HEALTH_INFO message will be sent to this queue
|
* if the #parentQueue is not NULL, a @c HEALTH_INFO message
|
||||||
* @param health the health is passed as parameter so that the number of calls to the health table can be minimized
|
* 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.
|
* @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);
|
void handleSetHealthCommand(CommandMessage *message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HEALTHHELPER_H_ */
|
#endif /* FSFW_HEALTH_HEALTHHELPER_H_ */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../health/HealthMessage.h"
|
#include "HealthMessage.h"
|
||||||
|
|
||||||
void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command,
|
void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command,
|
||||||
HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth) {
|
HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth) {
|
||||||
@ -7,11 +7,13 @@ void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command,
|
|||||||
message->setParameter2(oldHealth);
|
message->setParameter2(oldHealth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command) {
|
void HealthMessage::setHealthMessage(CommandMessage* message,
|
||||||
|
Command_t command) {
|
||||||
message->setCommand(command);
|
message->setCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
HasHealthIF::HealthState HealthMessage::getHealth(const CommandMessage* message) {
|
HasHealthIF::HealthState HealthMessage::getHealth(
|
||||||
|
const CommandMessage* message) {
|
||||||
return (HasHealthIF::HealthState) message->getParameter();
|
return (HasHealthIF::HealthState) message->getParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,26 @@
|
|||||||
#ifndef HEALTHMESSAGE_H_
|
#ifndef FSFW_HEALTH_HEALTHMESSAGE_H_
|
||||||
#define HEALTHMESSAGE_H_
|
#define FSFW_HEALTH_HEALTHMESSAGE_H_
|
||||||
|
|
||||||
#include "../health/HasHealthIF.h"
|
#include "HasHealthIF.h"
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
|
|
||||||
class HealthMessage {
|
class HealthMessage {
|
||||||
public:
|
public:
|
||||||
static const uint8_t MESSAGE_ID = messagetypes::HEALTH_COMMAND;
|
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 HEALTH_INFO = MAKE_COMMAND_ID(5);
|
||||||
static const Command_t REPLY_HEALTH_SET = MAKE_COMMAND_ID(6);
|
static const Command_t REPLY_HEALTH_SET = MAKE_COMMAND_ID(6);
|
||||||
|
|
||||||
static void setHealthMessage(CommandMessage *message, Command_t command,
|
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 void setHealthMessage(CommandMessage *message, Command_t command);
|
||||||
|
|
||||||
static HasHealthIF::HealthState getHealth(const CommandMessage *message);
|
static HasHealthIF::HealthState getHealth(const CommandMessage *message);
|
||||||
@ -27,4 +33,4 @@ private:
|
|||||||
HealthMessage();
|
HealthMessage();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HEALTHMESSAGE_H_ */
|
#endif /* FSFW_HEALTH_HEALTHMESSAGE_H_ */
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "../health/HealthTable.h"
|
#include "HealthTable.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
#include "../ipc/MutexFactory.h"
|
#include "../ipc/MutexFactory.h"
|
||||||
|
#include "../serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
HealthTable::HealthTable(object_id_t objectid) :
|
HealthTable::HealthTable(object_id_t objectid) :
|
||||||
SystemObject(objectid) {
|
SystemObject(objectid) {
|
||||||
@ -18,74 +19,64 @@ ReturnValue_t HealthTable::registerObject(object_id_t object,
|
|||||||
if (healthMap.count(object) != 0) {
|
if (healthMap.count(object) != 0) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
healthMap.insert(
|
healthMap.emplace(object, initilialState);
|
||||||
std::pair<object_id_t, HasHealthIF::HealthState>(object,
|
|
||||||
initilialState));
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HealthTable::setHealth(object_id_t object,
|
void HealthTable::setHealth(object_id_t object,
|
||||||
HasHealthIF::HealthState newState) {
|
HasHealthIF::HealthState newState) {
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||||
HealthMap::iterator iter = healthMap.find(object);
|
HealthMap::iterator iter = healthMap.find(object);
|
||||||
if (iter != healthMap.end()) {
|
if (iter != healthMap.end()) {
|
||||||
iter->second = newState;
|
iter->second = newState;
|
||||||
}
|
}
|
||||||
mutex->unlockMutex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) {
|
HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) {
|
||||||
HasHealthIF::HealthState state = HasHealthIF::HEALTHY;
|
HasHealthIF::HealthState state = HasHealthIF::HEALTHY;
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||||
HealthMap::iterator iter = healthMap.find(object);
|
HealthMap::iterator iter = healthMap.find(object);
|
||||||
if (iter != healthMap.end()) {
|
if (iter != healthMap.end()) {
|
||||||
state = iter->second;
|
state = iter->second;
|
||||||
}
|
}
|
||||||
mutex->unlockMutex();
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HealthTable::getPrintSize() {
|
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
bool HealthTable::hasHealth(object_id_t object) {
|
||||||
uint32_t size = healthMap.size() * 5 + 2;
|
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||||
mutex->unlockMutex();
|
HealthMap::iterator iter = healthMap.find(object);
|
||||||
|
if (iter != healthMap.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HealthTable::getPrintSize() {
|
||||||
|
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||||
|
uint32_t size = healthMap.size() * sizeof(object_id_t) +
|
||||||
|
sizeof(HasHealthIF::HealthState) + sizeof(uint16_t);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HealthTable::hasHealth(object_id_t object) {
|
|
||||||
bool exits = false;
|
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
|
||||||
HealthMap::iterator iter = healthMap.find(object);
|
|
||||||
if (iter != healthMap.end()) {
|
|
||||||
exits = true;
|
|
||||||
}
|
|
||||||
mutex->unlockMutex();
|
|
||||||
return exits;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HealthTable::printAll(uint8_t* pointer, size_t maxSize) {
|
void HealthTable::printAll(uint8_t* pointer, size_t maxSize) {
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
uint16_t count = healthMap.size();
|
uint16_t count = healthMap.size();
|
||||||
ReturnValue_t result = SerializeAdapter::serialize(&count,
|
SerializeAdapter::serialize(&count,
|
||||||
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||||
HealthMap::iterator iter;
|
for (const auto& health: healthMap) {
|
||||||
for (iter = healthMap.begin();
|
SerializeAdapter::serialize(&health.first,
|
||||||
iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK;
|
|
||||||
++iter) {
|
|
||||||
result = SerializeAdapter::serialize(&iter->first,
|
|
||||||
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||||
uint8_t health = iter->second;
|
uint8_t healthValue = health.second;
|
||||||
result = SerializeAdapter::serialize(&health, &pointer, &size,
|
SerializeAdapter::serialize(&healthValue, &pointer, &size,
|
||||||
maxSize, SerializeIF::Endianness::BIG);
|
maxSize, SerializeIF::Endianness::BIG);
|
||||||
}
|
}
|
||||||
mutex->unlockMutex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HealthTable::iterate(
|
ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) {
|
||||||
std::pair<object_id_t, HasHealthIF::HealthState> *value, bool reset) {
|
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||||
if (reset) {
|
if (reset) {
|
||||||
mapIterator = healthMap.begin();
|
mapIterator = healthMap.begin();
|
||||||
}
|
}
|
||||||
@ -94,7 +85,5 @@ ReturnValue_t HealthTable::iterate(
|
|||||||
}
|
}
|
||||||
*value = *mapIterator;
|
*value = *mapIterator;
|
||||||
mapIterator++;
|
mapIterator++;
|
||||||
mutex->unlockMutex();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,42 @@
|
|||||||
#ifndef FRAMEWORK_HEALTH_HEALTHTABLE_H_
|
#ifndef FSFW_HEALTH_HEALTHTABLE_H_
|
||||||
#define FRAMEWORK_HEALTH_HEALTHTABLE_H_
|
#define FSFW_HEALTH_HEALTHTABLE_H_
|
||||||
|
|
||||||
#include "../health/HealthTableIF.h"
|
#include "HealthTableIF.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
typedef std::map<object_id_t, HasHealthIF::HealthState> HealthMap;
|
|
||||||
|
|
||||||
class HealthTable: public HealthTableIF, public SystemObject {
|
class HealthTable: public HealthTableIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
HealthTable(object_id_t objectid);
|
HealthTable(object_id_t objectid);
|
||||||
virtual ~HealthTable();
|
virtual ~HealthTable();
|
||||||
|
|
||||||
|
/** HealthTableIF overrides */
|
||||||
virtual ReturnValue_t registerObject(object_id_t object,
|
virtual ReturnValue_t registerObject(object_id_t object,
|
||||||
HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY);
|
HasHealthIF::HealthState initilialState =
|
||||||
|
HasHealthIF::HEALTHY) override;
|
||||||
|
virtual size_t getPrintSize() override;
|
||||||
|
virtual void printAll(uint8_t *pointer, size_t maxSize) override;
|
||||||
|
|
||||||
virtual bool hasHealth(object_id_t object);
|
/** ManagesHealthIF overrides */
|
||||||
virtual void setHealth(object_id_t object, HasHealthIF::HealthState newState);
|
virtual bool hasHealth(object_id_t object) override;
|
||||||
virtual HasHealthIF::HealthState getHealth(object_id_t);
|
virtual void setHealth(object_id_t object,
|
||||||
|
HasHealthIF::HealthState newState) override;
|
||||||
virtual uint32_t getPrintSize();
|
virtual HasHealthIF::HealthState getHealth(object_id_t) override;
|
||||||
virtual void printAll(uint8_t *pointer, size_t maxSize);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
using HealthMap = std::map<object_id_t, HasHealthIF::HealthState>;
|
||||||
|
using HealthEntry = std::pair<object_id_t, HasHealthIF::HealthState>;
|
||||||
|
|
||||||
MutexIF* mutex;
|
MutexIF* mutex;
|
||||||
HealthMap healthMap;
|
HealthMap healthMap;
|
||||||
|
|
||||||
HealthMap::iterator mapIterator;
|
HealthMap::iterator mapIterator;
|
||||||
|
|
||||||
virtual ReturnValue_t iterate(std::pair<object_id_t,HasHealthIF::HealthState> *value, bool reset = false);
|
virtual ReturnValue_t iterate(
|
||||||
|
HealthEntry* value,
|
||||||
|
bool reset = false) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HEALTHTABLE_H_ */
|
#endif /* FSFW_HEALTH_HEALTHTABLE_H_ */
|
||||||
|
@ -1,28 +1,24 @@
|
|||||||
#ifndef FRAMEWORK_HEALTH_HEALTHTABLEIF_H_
|
#ifndef FSFW_HEALTH_HEALTHTABLEIF_H_
|
||||||
#define FRAMEWORK_HEALTH_HEALTHTABLEIF_H_
|
#define FSFW_HEALTH_HEALTHTABLEIF_H_
|
||||||
|
|
||||||
#include "../health/ManagesHealthIF.h"
|
#include "ManagesHealthIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
class HealthTableIF: public ManagesHealthIF {
|
class HealthTableIF: public ManagesHealthIF {
|
||||||
// TODO: This is in the mission folder and not in the framework folder.
|
|
||||||
// delete it?
|
|
||||||
friend class HealthCommandingService;
|
|
||||||
public:
|
public:
|
||||||
virtual ~HealthTableIF() {
|
virtual ~HealthTableIF() {}
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReturnValue_t registerObject(object_id_t object,
|
virtual ReturnValue_t registerObject(object_id_t object,
|
||||||
HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0;
|
HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0;
|
||||||
|
|
||||||
virtual uint32_t getPrintSize() = 0;
|
virtual size_t getPrintSize() = 0;
|
||||||
virtual void printAll(uint8_t *pointer, size_t maxSize) = 0;
|
virtual void printAll(uint8_t *pointer, size_t maxSize) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ReturnValue_t iterate(std::pair<object_id_t,HasHealthIF::HealthState> *value, bool reset = false) = 0;
|
virtual ReturnValue_t iterate(
|
||||||
|
std::pair<object_id_t,HasHealthIF::HealthState> *value,
|
||||||
|
bool reset = false) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ */
|
#endif /* FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ */
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#ifndef FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_
|
#ifndef FSFW_HEALTH_MANAGESHEALTHIF_H_
|
||||||
#define FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_
|
#define FSFW_HEALTH_MANAGESHEALTHIF_H_
|
||||||
|
|
||||||
#include "../health/HasHealthIF.h"
|
#include "HasHealthIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
|
|
||||||
class ManagesHealthIF {
|
class ManagesHealthIF {
|
||||||
public:
|
public:
|
||||||
virtual ~ManagesHealthIF() {
|
virtual ~ManagesHealthIF() {
|
||||||
@ -49,4 +50,4 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ */
|
#endif /* FSFW_HEALTH_MANAGESHEALTHIF_H_ */
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||||
#include "HousekeepingMessage.h"
|
#include "HousekeepingMessage.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
HousekeepingMessage::~HousekeepingMessage() {}
|
HousekeepingMessage::~HousekeepingMessage() {}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkReportMessage(CommandMessage* message, sid_t sid,
|
void HousekeepingMessage::setHkReportReply(CommandMessage* message, sid_t sid,
|
||||||
store_address_t storeId) {
|
store_address_t storeId) {
|
||||||
message->setCommand(HK_REPORT);
|
message->setCommand(HK_REPORT);
|
||||||
message->setMessageSize(HK_MESSAGE_SIZE);
|
message->setMessageSize(HK_MESSAGE_SIZE);
|
||||||
@ -11,7 +12,7 @@ void HousekeepingMessage::setHkReportMessage(CommandMessage* message, sid_t sid,
|
|||||||
message->setParameter3(storeId.raw);
|
message->setParameter3(storeId.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkDiagnosticsMessage(CommandMessage* message,
|
void HousekeepingMessage::setHkDiagnosticsReply(CommandMessage* message,
|
||||||
sid_t sid, store_address_t storeId) {
|
sid_t sid, store_address_t storeId) {
|
||||||
message->setCommand(DIAGNOSTICS_REPORT);
|
message->setCommand(DIAGNOSTICS_REPORT);
|
||||||
message->setMessageSize(HK_MESSAGE_SIZE);
|
message->setMessageSize(HK_MESSAGE_SIZE);
|
||||||
@ -19,7 +20,7 @@ void HousekeepingMessage::setHkDiagnosticsMessage(CommandMessage* message,
|
|||||||
message->setParameter3(storeId.raw);
|
message->setParameter3(storeId.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message,
|
sid_t HousekeepingMessage::getHkDataReply(const CommandMessage *message,
|
||||||
store_address_t *storeIdToSet) {
|
store_address_t *storeIdToSet) {
|
||||||
if(storeIdToSet != nullptr) {
|
if(storeIdToSet != nullptr) {
|
||||||
*storeIdToSet = message->getParameter3();
|
*storeIdToSet = message->getParameter3();
|
||||||
@ -27,6 +28,96 @@ sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message,
|
|||||||
return getSid(message);
|
return getSid(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message,
|
||||||
|
sid_t sid, bool enableReporting, bool isDiagnostics) {
|
||||||
|
if(isDiagnostics) {
|
||||||
|
if(enableReporting) {
|
||||||
|
message->setCommand(ENABLE_PERIODIC_DIAGNOSTICS_GENERATION);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message->setCommand(DISABLE_PERIODIC_DIAGNOSTICS_GENERATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(enableReporting) {
|
||||||
|
message->setCommand(ENABLE_PERIODIC_HK_REPORT_GENERATION);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message->setCommand(DISABLE_PERIODIC_HK_REPORT_GENERATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setSid(message, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setStructureReportingCommand(CommandMessage *command,
|
||||||
|
sid_t sid, bool isDiagnostics) {
|
||||||
|
if(isDiagnostics) {
|
||||||
|
command->setCommand(REPORT_DIAGNOSTICS_REPORT_STRUCTURES);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command->setCommand(REPORT_HK_REPORT_STRUCTURES);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSid(command, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command,
|
||||||
|
sid_t sid, bool isDiagnostics) {
|
||||||
|
if(isDiagnostics) {
|
||||||
|
command->setCommand(GENERATE_ONE_DIAGNOSTICS_REPORT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command->setCommand(GENERATE_ONE_PARAMETER_REPORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSid(command, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setCollectionIntervalModificationCommand(
|
||||||
|
CommandMessage *command, sid_t sid, float collectionInterval,
|
||||||
|
bool isDiagnostics) {
|
||||||
|
if(isDiagnostics) {
|
||||||
|
command->setCommand(MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
||||||
|
}
|
||||||
|
command->setParameter3(collectionInterval);
|
||||||
|
|
||||||
|
setSid(command, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
sid_t HousekeepingMessage::getCollectionIntervalModificationCommand(
|
||||||
|
const CommandMessage* command, float* newCollectionInterval) {
|
||||||
|
if(newCollectionInterval != nullptr) {
|
||||||
|
*newCollectionInterval = command->getParameter3();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSid(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setHkRequestSuccessReply(CommandMessage *reply,
|
||||||
|
sid_t sid) {
|
||||||
|
setSid(reply, sid);
|
||||||
|
reply->setCommand(HK_REQUEST_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setHkRequestFailureReply(CommandMessage *reply,
|
||||||
|
sid_t sid, ReturnValue_t error) {
|
||||||
|
setSid(reply, sid);
|
||||||
|
reply->setCommand(HK_REQUEST_FAILURE);
|
||||||
|
reply->setParameter3(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
sid_t HousekeepingMessage::getHkRequestFailureReply(const CommandMessage *reply,
|
||||||
|
ReturnValue_t *error) {
|
||||||
|
if(error != nullptr) {
|
||||||
|
*error = reply->getParameter3();
|
||||||
|
}
|
||||||
|
return getSid(reply);
|
||||||
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getSid(const CommandMessage* message) {
|
sid_t HousekeepingMessage::getSid(const CommandMessage* message) {
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw));
|
std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw));
|
||||||
@ -37,3 +128,35 @@ void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) {
|
|||||||
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw));
|
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply,
|
||||||
|
sid_t sid, store_address_t storeId) {
|
||||||
|
reply->setCommand(HK_DEFINITIONS_REPORT);
|
||||||
|
setSid(reply, sid);
|
||||||
|
reply->setParameter3(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::setDiagnosticsStuctureReportReply(
|
||||||
|
CommandMessage *reply, sid_t sid, store_address_t storeId) {
|
||||||
|
reply->setCommand(DIAGNOSTICS_DEFINITION_REPORT);
|
||||||
|
setSid(reply, sid);
|
||||||
|
reply->setParameter3(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HousekeepingMessage::clear(CommandMessage* message) {
|
||||||
|
switch(message->getCommand()) {
|
||||||
|
case(HK_REPORT):
|
||||||
|
case(DIAGNOSTICS_REPORT):
|
||||||
|
case(HK_DEFINITIONS_REPORT):
|
||||||
|
case(DIAGNOSTICS_DEFINITION_REPORT):
|
||||||
|
case(UPDATE_SNAPSHOT): {
|
||||||
|
store_address_t storeId;
|
||||||
|
getHkDataReply(message, &storeId);
|
||||||
|
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
|
||||||
|
objects::IPC_STORE);
|
||||||
|
if (ipcStore != nullptr) {
|
||||||
|
ipcStore->deleteData(storeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message->setCommand(CommandMessage::CMD_NONE);
|
||||||
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
#ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_
|
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
||||||
#define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_
|
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
||||||
|
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
#include "../ipc/FwMessageTypes.h"
|
#include "../ipc/FwMessageTypes.h"
|
||||||
|
#include "../objectmanager/frameworkObjects.h"
|
||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "../storagemanager/StorageManagerIF.h"
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
union sid_t {
|
union sid_t {
|
||||||
static constexpr uint64_t INVALID_ADDRESS =
|
static constexpr uint64_t INVALID_SID = -1;
|
||||||
std::numeric_limits<uint64_t>::max();
|
static constexpr uint32_t INVALID_SET_ID = -1;
|
||||||
sid_t(): raw(INVALID_ADDRESS) {}
|
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
|
||||||
|
sid_t(): raw(INVALID_SID) {}
|
||||||
|
|
||||||
sid_t(object_id_t objectId, uint32_t setId):
|
sid_t(object_id_t objectId, uint32_t setId):
|
||||||
objectId(objectId),
|
objectId(objectId),
|
||||||
@ -31,7 +32,15 @@ union sid_t {
|
|||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
|
|
||||||
bool notSet() const {
|
bool notSet() const {
|
||||||
return raw == INVALID_ADDRESS;
|
return raw == INVALID_SID;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const sid_t& other) const {
|
||||||
|
return raw == other.raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const sid_t& other) const {
|
||||||
|
return not (raw == other.raw);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,25 +58,15 @@ public:
|
|||||||
sizeof(sid_t) + sizeof(uint32_t);
|
sizeof(sid_t) + sizeof(uint32_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The HK message is initialized with a pointer to a message which holds
|
* Concrete instance is not used, instead this class operates on
|
||||||
* the message data, see CommandMessageIF and getInternalMessage().
|
* command message instances.
|
||||||
* @param message
|
|
||||||
*/
|
*/
|
||||||
HousekeepingMessage() = delete;
|
HousekeepingMessage() = delete;
|
||||||
virtual ~HousekeepingMessage();
|
virtual ~HousekeepingMessage();
|
||||||
|
|
||||||
static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING;
|
static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING;
|
||||||
|
|
||||||
static constexpr Command_t ADD_HK_REPORT_STRUCT =
|
static constexpr Command_t ENABLE_PERIODIC_HK_REPORT_GENERATION =
|
||||||
MAKE_COMMAND_ID(1);
|
|
||||||
static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT =
|
|
||||||
MAKE_COMMAND_ID(2);
|
|
||||||
|
|
||||||
static constexpr Command_t DELETE_HK_REPORT_STRUCT = MAKE_COMMAND_ID(3);
|
|
||||||
static constexpr Command_t DELETE_DIAGNOSTICS_REPORT_STRUCT =
|
|
||||||
MAKE_COMMAND_ID(4);
|
|
||||||
|
|
||||||
static constexpr Command_t ENABLE_PERIODIC_HK_GENERATION =
|
|
||||||
MAKE_COMMAND_ID(5);
|
MAKE_COMMAND_ID(5);
|
||||||
static constexpr Command_t DISABLE_PERIODIC_HK_REPORT_GENERATION =
|
static constexpr Command_t DISABLE_PERIODIC_HK_REPORT_GENERATION =
|
||||||
MAKE_COMMAND_ID(6);
|
MAKE_COMMAND_ID(6);
|
||||||
@ -92,31 +91,67 @@ public:
|
|||||||
static constexpr Command_t GENERATE_ONE_DIAGNOSTICS_REPORT =
|
static constexpr Command_t GENERATE_ONE_DIAGNOSTICS_REPORT =
|
||||||
MAKE_COMMAND_ID(28);
|
MAKE_COMMAND_ID(28);
|
||||||
|
|
||||||
static constexpr Command_t APPEND_PARAMETERS_TO_PARAMETER_REPORT_STRUCTURE =
|
|
||||||
MAKE_COMMAND_ID(29);
|
|
||||||
static constexpr Command_t APPEND_PARAMETERS_TO_DIAGNOSTICS_REPORT_STRUCTURE =
|
|
||||||
MAKE_COMMAND_ID(30);
|
|
||||||
|
|
||||||
static constexpr Command_t MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL =
|
static constexpr Command_t MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL =
|
||||||
MAKE_COMMAND_ID(31);
|
MAKE_COMMAND_ID(31);
|
||||||
static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL =
|
static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL =
|
||||||
MAKE_COMMAND_ID(32);
|
MAKE_COMMAND_ID(32);
|
||||||
|
|
||||||
|
static constexpr Command_t HK_REQUEST_SUCCESS =
|
||||||
|
MAKE_COMMAND_ID(128);
|
||||||
|
static constexpr Command_t HK_REQUEST_FAILURE =
|
||||||
|
MAKE_COMMAND_ID(129);
|
||||||
|
|
||||||
|
static constexpr Command_t UPDATE_NOTIFICATION = MAKE_COMMAND_ID(130);
|
||||||
|
static constexpr Command_t UPDATE_SNAPSHOT = MAKE_COMMAND_ID(131);
|
||||||
|
|
||||||
|
static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(132);
|
||||||
|
|
||||||
static sid_t getSid(const CommandMessage* message);
|
static sid_t getSid(const CommandMessage* message);
|
||||||
|
|
||||||
static void setHkReportMessage(CommandMessage* message, sid_t sid,
|
/** Setter functions */
|
||||||
|
static void setToggleReportingCommand(CommandMessage* command, sid_t sid,
|
||||||
|
bool enableReporting, bool isDiagnostics);
|
||||||
|
static void setStructureReportingCommand(CommandMessage* command, sid_t sid,
|
||||||
|
bool isDiagnostics);
|
||||||
|
static void setOneShotReportCommand(CommandMessage* command, sid_t sid,
|
||||||
|
bool isDiagnostics);
|
||||||
|
static void setCollectionIntervalModificationCommand(
|
||||||
|
CommandMessage* command, sid_t sid, float collectionInterval,
|
||||||
|
bool isDiagnostics);
|
||||||
|
|
||||||
|
static void setHkReportReply(CommandMessage* reply, sid_t sid,
|
||||||
store_address_t storeId);
|
store_address_t storeId);
|
||||||
static void setHkDiagnosticsMessage(CommandMessage* message, sid_t sid,
|
static void setHkDiagnosticsReply(CommandMessage* reply, sid_t sid,
|
||||||
store_address_t storeId);
|
store_address_t storeId);
|
||||||
|
|
||||||
//! Get the respective SID and store ID. Command ID can be used beforehand
|
static void setHkRequestSuccessReply(CommandMessage* reply, sid_t sid);
|
||||||
//! to distinguish between diagnostics and regular HK packets
|
static void setHkRequestFailureReply(CommandMessage* reply, sid_t sid,
|
||||||
static sid_t getHkReportMessage(const CommandMessage* message,
|
ReturnValue_t error);
|
||||||
|
|
||||||
|
static void setHkStuctureReportReply(CommandMessage* reply,
|
||||||
|
sid_t sid, store_address_t storeId);
|
||||||
|
static void setDiagnosticsStuctureReportReply(CommandMessage* reply,
|
||||||
|
sid_t sid, store_address_t storeId);
|
||||||
|
|
||||||
|
static sid_t getHkRequestFailureReply(const CommandMessage* reply,
|
||||||
|
ReturnValue_t* error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generic getter function for housekeeping data replies
|
||||||
|
* @details
|
||||||
|
* Command ID can be used beforehand to distinguish between diagnostics and
|
||||||
|
* regular HK packets. This getter function should be used for the
|
||||||
|
* command IDs 10, 12, 25 and 26.
|
||||||
|
*/
|
||||||
|
static sid_t getHkDataReply(const CommandMessage* message,
|
||||||
store_address_t * storeIdToSet);
|
store_address_t * storeIdToSet);
|
||||||
|
static sid_t getCollectionIntervalModificationCommand(
|
||||||
|
const CommandMessage* command, float* newCollectionInterval);
|
||||||
|
|
||||||
|
static void clear(CommandMessage* message);
|
||||||
private:
|
private:
|
||||||
static void setSid(CommandMessage* message, sid_t sid);
|
static void setSid(CommandMessage* message, sid_t sid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ */
|
#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_ */
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#ifndef FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
|
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
|
||||||
#define FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
|
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
|
||||||
#include "../serialize/SerialLinkedListAdapter.h"
|
#include "../serialize/SerialLinkedListAdapter.h"
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "../storagemanager/StorageManagerIF.h"
|
||||||
|
|
||||||
@ -15,67 +14,21 @@
|
|||||||
*/
|
*/
|
||||||
class HousekeepingPacketDownlink: public SerialLinkedListAdapter<SerializeIF> {
|
class HousekeepingPacketDownlink: public SerialLinkedListAdapter<SerializeIF> {
|
||||||
public:
|
public:
|
||||||
HousekeepingPacketDownlink(sid_t sid, float collectionInterval, uint8_t
|
HousekeepingPacketDownlink(sid_t sid, LocalPoolDataSetBase* dataSetPtr):
|
||||||
numberOfParameters, LocalPoolDataSetBase* dataSetPtr):
|
sourceId(sid.objectId), setId(sid.ownerSetId), hkData(dataSetPtr) {
|
||||||
sourceId(sid.objectId), setId(sid.ownerSetId),
|
|
||||||
collectionInterval(collectionInterval),
|
|
||||||
numberOfParameters(numberOfParameters), hkData(dataSetPtr) {
|
|
||||||
setLinks();
|
setLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper functions which can be used to move HK data from the IPC store
|
|
||||||
* to the telemetry store. TODO: maybe not needed.
|
|
||||||
* @param formerStore
|
|
||||||
* @param storeId
|
|
||||||
* @param newStore
|
|
||||||
* @param newStoreId [out]
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t moveToOtherStore(StorageManagerIF* formerStore,
|
|
||||||
store_address_t storeId, StorageManagerIF* newStore,
|
|
||||||
store_address_t* newStoreId) {
|
|
||||||
const uint8_t* dataPtr = nullptr;
|
|
||||||
size_t hkDataSize = 0;
|
|
||||||
ReturnValue_t result = formerStore->getData(storeId, &dataPtr,
|
|
||||||
&hkDataSize);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newStore->addData(newStoreId, dataPtr, hkDataSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setLinks() {
|
void setLinks() {
|
||||||
setStart(&sourceId);
|
setStart(&sourceId);
|
||||||
sourceId.setNext(&setId);
|
sourceId.setNext(&setId);
|
||||||
setId.setNext(&collectionInterval);
|
setId.setNext(&hkData);
|
||||||
collectionInterval.setNext(&numberOfParameters);
|
|
||||||
numberOfParameters.setNext(&hkData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializeElement<object_id_t> sourceId;
|
SerializeElement<object_id_t> sourceId;
|
||||||
SerializeElement<uint32_t> setId;
|
SerializeElement<uint32_t> setId;
|
||||||
SerializeElement<float> collectionInterval;
|
|
||||||
SerializeElement<uint8_t> numberOfParameters;
|
|
||||||
LinkedElement<SerializeIF> hkData;
|
LinkedElement<SerializeIF> hkData;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ */
|
#endif /* FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
|
||||||
// size_t maxSize, Endianness streamEndianness) const override {
|
|
||||||
// ReturnValue_t result = SerialLinkedListAdapter::serialize(buffer, size,
|
|
||||||
// maxSize, streamEndianness);
|
|
||||||
// if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
// return dataSetPtr->serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// virtual size_t getSerializedSize() const override {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user