1
0
forked from fsfw/fsfw

Merge remote-tracking branch 'upstream/mueller/master' into mueller/master

This commit is contained in:
2021-01-14 11:25:14 +01:00
89 changed files with 3119 additions and 1989 deletions

View File

@ -0,0 +1,27 @@
#ifndef FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
#define FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
class LocalDataPoolManager;
class MutexIF;
/**
* @brief Accessor class which can be used by classes which like to use the pool manager.
*/
class AccessPoolManagerIF {
public:
virtual ~AccessPoolManagerIF() {};
virtual MutexIF* getLocalPoolMutex() = 0;
/**
* Can be used to get a handle to the local data pool manager.
* This function is protected because it should only be used by the
* class imlementing the interface.
*/
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
protected:
};
#endif /* FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_ */

View File

@ -5,4 +5,6 @@ target_sources(${LIB_FSFW_NAME}
LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp
SharedLocalDataSet.cpp
)
)
add_subdirectory(internal)

View File

@ -1,105 +1,66 @@
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
#include "locPoolDefinitions.h"
#include "localPoolDefinitions.h"
#include "../datapool/PoolEntryIF.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../ipc/MessageQueueSenderIF.h"
#include "../housekeeping/HousekeepingMessage.h"
#include <map>
class LocalDataPoolManager;
class AccessPoolManagerIF;
class ProvidesDataPoolSubscriptionIF;
class LocalPoolDataSetBase;
class LocalPoolObjectBase;
using LocalDataPool = std::map<lp_id_t, PoolEntryIF*>;
using LocalDataPoolMapIter = LocalDataPool::iterator;
class LocalDataPoolManager;
/**
* @brief This interface is implemented by classes which posses a local
* data pool (not the managing class). It defines the relationship
* between the local data pool owner and the LocalDataPoolManager.
* @brief This interface is implemented by classes which posses a local data pool (not the
* managing class). It defines the relationship between the local data pool owner
* and the LocalDataPoolManager.
* @details
* Any class implementing this interface shall also have a LocalDataPoolManager
* member class which contains the actual pool data structure
* and exposes the public interface for it.
* This is required because the pool entries are templates, which makes
* specifying an interface rather difficult. The local data pool can be
* accessed by using the LocalPoolVariable, LocalPoolVector or LocalDataSet
* classes.
* Any class implementing this interface shall also have a LocalDataPoolManager member class which
* contains the actual pool data structure and exposes the public interface for it.
* The local data pool can be accessed using helper classes by using the
* LocalPoolVariable, LocalPoolVector or LocalDataSet classes. Every local pool variable can
* be uniquely identified by a global pool ID (gp_id_t) and every dataset tied
* to a pool manager can be uniqely identified by a global structure ID (sid_t).
*
* Architectural Note:
* This could be circumvented by using a wrapper/accessor function or
* implementing the templated function in this interface..
* The first solution sounds better than the second but
* the LocalPoolVariable classes are templates as well, so this just shifts
* the problem somewhere else. Interfaces are nice, but the most
* pragmatic solution I found was to offer the client the full interface
* of the LocalDataPoolManager.
*/
class HasLocalDataPoolIF {
friend class HasLocalDpIFManagerAttorney;
friend class HasLocalDpIFUserAttorney;
public:
virtual~ HasLocalDataPoolIF() {};
virtual~ HasLocalDataPoolIF() {};
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
virtual object_id_t getObjectId() const = 0;
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
/** Command queue for housekeeping messages. */
virtual MessageQueueId_t getCommandQueue() const = 0;
virtual object_id_t getObjectId() const = 0;
/**
* Is used by pool owner to initialize the pool map once
* The manager instance shall also be passed to this function.
* It can be used to subscribe for periodic packets for for updates.
*/
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) = 0;
/** Command queue for housekeeping messages. */
virtual MessageQueueId_t getCommandQueue() const = 0;
/**
* Is used by pool owner to initialize the pool map once
* The manager instance shall also be passed to this function.
* It can be used to subscribe for periodic packets for for updates.
*/
virtual ReturnValue_t initializeLocalDataPool(
LocalDataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) = 0;
/** Can be used to get a handle to the local data pool manager. */
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
/**
* Returns the minimum sampling frequency in milliseconds, which will
* usually be the period the pool owner performs its periodic operation.
* @return
*/
virtual uint32_t getPeriodicOperationFrequency() const = 0;
/**
* This function is used by the pool manager to get a valid dataset
* from a SID
* @param sid Corresponding structure ID
* @return
*/
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0;
/**
* Similar to the function above, but used to get a local pool variable
* handle. This is only needed for update notifications, so it is not
* defined as abstract.
* @param localPoolId
* @return
*/
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden"
<< ". Returning nullptr!" << std::endl;
#endif
return nullptr;
}
/**
* Returns the minimum sampling frequency in milliseconds, which will
* usually be the period the pool owner performs its periodic operation.
* @return
*/
virtual uint32_t getPeriodicOperationFrequency() const = 0;
/**
* @brief This function will be called by the manager if an update
* notification is received.
* @details
* @details HasLocalDataPoolIF
* Can be overriden by the child class to handle changed datasets.
* @param sid
* @param storeId If a snapshot was requested, data will be located inside
@ -124,18 +85,68 @@ public:
return;
}
/* These function can be implemented by pool owner, as they are required
* by the housekeeping message interface */
virtual ReturnValue_t addDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t removeDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
float newIntervalSeconds) {
return HasReturnvaluesIF::RETURN_FAILED;
};
/**
* These function can be implemented by pool owner, if they are required
* and used by the housekeeping message interface.
* */
virtual ReturnValue_t addDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t removeDataSet(sid_t sid) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t changeCollectionInterval(sid_t sid, float newIntervalSeconds) {
return HasReturnvaluesIF::RETURN_FAILED;
};
/**
* This function can be used by data pool consumers to retrieve a handle
* which allows subscriptions to dataset and variable updates in form of messages.
* The consumers can then read the most recent variable value by calling read with
* an own pool variable or set instance or using the deserialized snapshot data.
* @return
*/
virtual ProvidesDataPoolSubscriptionIF* getSubscriptionInterface() = 0;
protected:
/**
* Accessor handle required for internal handling. Not intended for users and therefore
* declared protected. Users should instead use pool variables, sets or the subscription
* interface to access pool entries.
* @return
*/
virtual AccessPoolManagerIF* getAccessorHandle() = 0;
/**
* This function is used by the pool manager to get a valid dataset
* from a SID. This function is protected to prevent users from
* using raw data set pointers which could not be thread-safe. Users
* should use the #ProvidesDataPoolSubscriptionIF.
* @param sid Corresponding structure ID
* @return
*/
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0;
/**
* Similar to the function above, but used to get a local pool variable
* handle. This is only needed for update notifications, so it is not
* defined as abstract. This function is protected to prevent users from
* using raw pool variable pointers which could not be thread-safe.
* Users should use the #ProvidesDataPoolSubscriptionIF.
* @param localPoolId
* @return
*/
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden"
<< ". Returning nullptr!" << std::endl;
#else
sif::printWarning("HasLocalDataPoolIF::getPoolObjectHandle: "
"Not overriden. Returning nullptr!\n");
#endif
return nullptr;
}
};
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
#include "HasLocalDataPoolIF.h"
#include "ProvidesDataPoolSubscriptionIF.h"
#include "AccessLocalPoolF.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../housekeeping/HousekeepingPacketDownlink.h"
@ -16,6 +17,7 @@
#include "../ipc/MutexHelper.h"
#include <map>
#include <vector>
namespace Factory {
void setStaticFrameworkObjectIds();
@ -23,6 +25,8 @@ void setStaticFrameworkObjectIds();
class LocalPoolDataSetBase;
class HousekeepingPacketUpdate;
class HasLocalDataPoolIF;
class LocalDataPool;
/**
* @brief This class is the managing instance for the local data pool.
@ -48,19 +52,23 @@ class HousekeepingPacketUpdate;
* Each pool entry has a valid state too.
* @author R. Mueller
*/
class LocalDataPoolManager {
template<typename T> friend class LocalPoolVariable;
template<typename T, uint16_t vecSize> friend class LocalPoolVector;
friend class LocalPoolDataSetBase;
class LocalDataPoolManager: public ProvidesDataPoolSubscriptionIF,
public AccessPoolManagerIF {
friend void (Factory::setStaticFrameworkObjectIds)();
//! Some classes using the pool manager directly need to access class internals of the
//! manager. The attorney provides granular control of access to these internals.
friend class LocalDpManagerAttorney;
public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x0);
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_INVALID = MAKE_RETURN_CODE(0);
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(1);
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(2);
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(3);
static constexpr ReturnValue_t POOLOBJECT_NOT_FOUND = MAKE_RETURN_CODE(4);
static constexpr ReturnValue_t DATASET_NOT_FOUND = MAKE_RETURN_CODE(5);
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x02);
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x03);
/**
* This constructor is used by a class which wants to implement
@ -117,7 +125,7 @@ public:
*/
ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
float collectionInterval, bool isDiagnostics,
object_id_t packetDestination = defaultHkDestination);
object_id_t packetDestination = defaultHkDestination) override;
/**
* @brief Subscribe for the generation of packets if the dataset
@ -131,7 +139,7 @@ public:
*/
ReturnValue_t subscribeForUpdatePackets(sid_t sid, bool reportingEnabled,
bool isDiagnostics,
object_id_t packetDestination = defaultHkDestination);
object_id_t packetDestination = defaultHkDestination) override;
/**
* @brief Subscribe for a notification message which will be sent
@ -150,7 +158,7 @@ public:
ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
object_id_t destinationObject,
MessageQueueId_t targetQueueId,
bool generateSnapshot);
bool generateSnapshot) override;
/**
* @brief Subscribe for an notification message which will be sent if a
@ -169,7 +177,9 @@ public:
ReturnValue_t subscribeForVariableUpdateMessages(const lp_id_t localPoolId,
object_id_t destinationObject,
MessageQueueId_t targetQueueId,
bool generateSnapshot);
bool generateSnapshot) override;
MutexIF* getLocalPoolMutex() override;
/**
* Non-Diagnostics packets usually have a lower minimum sampling frequency
@ -248,8 +258,18 @@ public:
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
/**
* This function can be used to clear the receivers list. This is
* intended for test functions and not for regular operations, because
* the insertion operations allocate dynamically.
*/
void clearReceiversList();
object_id_t getCreatorObjectId() const;
virtual LocalDataPoolManager* getHkManagerHandle() override;
private:
LocalDataPool localPoolMap;
localpool::DataPool localPoolMap;
//! Every housekeeping data manager has a mutex to protect access
//! to it's data pool.
MutexIF* mutex = nullptr;
@ -368,6 +388,11 @@ private:
ReturnValue_t& status);
ReturnValue_t addUpdateToStore(HousekeepingPacketUpdate& updatePacket,
store_address_t& storeId);
void printWarningOrError(sif::OutputTypes outputType,
const char* functionName,
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
const char* errorPrint = nullptr);
};
@ -376,26 +401,16 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
PoolEntry<T> **poolEntry) {
auto poolIter = localPoolMap.find(localPoolId);
if (poolIter == localPoolMap.end()) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry "
"not found." << std::endl;
#else
fsfw::printWarning("HousekeepingManager::fechPoolEntry: Pool entry "
"not found.");
#endif
return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND;
printWarningOrError(sif::OutputTypes::OUT_ERROR, "fetchPoolEntry",
localpool::POOL_ENTRY_NOT_FOUND);
return localpool::POOL_ENTRY_NOT_FOUND;
}
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
if(*poolEntry == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "HousekeepingManager::fetchPoolEntry:"
" Pool entry type conflict." << std::endl;
#else
fsfw::printWarning("HousekeepingManager::fetchPoolEntry:"
" Pool entry type conflict.");
#endif
return HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT;
printWarningOrError(sif::OutputTypes::OUT_ERROR, "fetchPoolEntry",
localpool::POOL_ENTRY_TYPE_CONFLICT);
return localpool::POOL_ENTRY_TYPE_CONFLICT;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -9,13 +9,13 @@ LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, uint32_t setId,
const size_t maxNumberOfVariables):
LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables),
poolVarList(maxNumberOfVariables) {
this->setContainer(poolVarList.data());
this->setContainer(poolVarList.data());
}
LocalDataSet::LocalDataSet(sid_t sid, const size_t maxNumberOfVariables):
LocalPoolDataSetBase(sid, nullptr, maxNumberOfVariables),
poolVarList(maxNumberOfVariables) {
this->setContainer(poolVarList.data());
poolVarList(maxNumberOfVariables) {
this->setContainer(poolVarList.data());
}
LocalDataSet::~LocalDataSet() {}

View File

@ -7,7 +7,7 @@
class LocalDataSet: public LocalPoolDataSetBase {
public:
LocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId,
const size_t maxSize);
const size_t maxSize);
LocalDataSet(sid_t sid, const size_t maxSize);
virtual~ LocalDataSet();

View File

@ -1,4 +1,6 @@
#include "LocalPoolDataSetBase.h"
#include "HasLocalDataPoolIF.h"
#include "internal/HasLocalDpIFUserAttorney.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../datapoollocal/LocalDataPoolManager.h"
@ -18,17 +20,21 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
<< "invalid!" << std::endl;
#else
fsfw::printError("LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
sif::printError("LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
"invalid!\n\r");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
return;
}
hkManager = hkOwner->getHkManagerHandle();
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if(accessor != nullptr) {
poolManager = accessor->getHkManagerHandle();
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
}
this->sid.objectId = hkOwner->getObjectId();
this->sid.ownerSetId = setId;
mutex = MutexFactory::instance()->createMutex();
// Data creators get a periodic helper for periodic HK data generation.
if(periodicHandling) {
periodicHelper = new PeriodicHousekeepingHelper(this);
@ -38,39 +44,40 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
sid.objectId);
if(hkOwner != nullptr) {
hkManager = hkOwner->getHkManagerHandle();
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if(accessor != nullptr) {
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
}
}
this->sid = sid;
mutex = MutexFactory::instance()->createMutex();
this->sid = sid;
}
LocalPoolDataSetBase::LocalPoolDataSetBase(
PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool protectFunctions):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
if(protectFunctions) {
mutex = MutexFactory::instance()->createMutex();
}
PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool protectEveryReadCommitCall):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
this->setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
}
LocalPoolDataSetBase::~LocalPoolDataSetBase() {
if(periodicHelper != nullptr) {
delete periodicHelper;
}
}
ReturnValue_t LocalPoolDataSetBase::lockDataPool(
MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
if(hkManager != nullptr) {
MutexIF* poolMutex = hkManager->getMutexHandle();
return poolMutex->lockMutex(timeoutType, timeoutMs);
}
return HasReturnvaluesIF::RETURN_OK;
MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
if(mutexIfSingleDataCreator != nullptr) {
return mutexIfSingleDataCreator->lockMutex(timeoutType, timeoutMs);
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
@ -146,11 +153,10 @@ ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
}
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
if(hkManager != nullptr) {
MutexIF* mutex = hkManager->getMutexHandle();
return mutex->unlockMutex();
}
return HasReturnvaluesIF::RETURN_OK;
if(mutexIfSingleDataCreator != nullptr) {
return mutexIfSingleDataCreator->unlockMutex();
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
@ -169,10 +175,10 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
if(result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolDataSetBase::serializeLocalPoolIds: "
<< "Serialization error!" << std::endl;
<< "Serialization error!" << std::endl;
#else
fsfw::printWarning("LocalPoolDataSetBase::serializeLocalPoolIds: "
"Serialization error!\n\r");
sif::printWarning("LocalPoolDataSetBase::serializeLocalPoolIds: "
"Serialization error!\n\r");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
return result;
}
@ -235,8 +241,8 @@ void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const {
sif::warning << "LocalPoolDataSetBase::bitSetter: Invalid position!"
<< std::endl;
#else
fsfw::printWarning("LocalPoolDataSetBase::bitSetter: "
"Invalid position!\n\r");
sif::printWarning("LocalPoolDataSetBase::bitSetter: "
"Invalid position!\n\r");
#endif
return;
}
@ -268,19 +274,10 @@ void LocalPoolDataSetBase::initializePeriodicHelper(
}
void LocalPoolDataSetBase::setChanged(bool changed) {
if(mutex == nullptr) {
this->changed = changed;
return;
}
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
this->changed = changed;
}
bool LocalPoolDataSetBase::hasChanged() const {
if(mutex == nullptr) {
return changed;
}
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return changed;
}
@ -302,32 +299,21 @@ bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
}
bool LocalPoolDataSetBase::isValid() const {
if(mutex == nullptr) {
return this->valid;
}
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 5);
return this->valid;
}
void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
mutex->lockMutex(timeoutType, mutexTimeout);
if(setEntriesRecursively) {
for(size_t idx = 0; idx < this->getFillCount(); idx++) {
registeredVariables[idx] -> setValid(valid);
}
}
this->valid = valid;
mutex->unlockMutex();
}
void LocalPoolDataSetBase::setReadCommitProtectionBehaviour(
bool protectEveryReadCommit, uint32_t mutexTimeout) {
PoolDataSetBase::setReadCommitProtectionBehaviour(protectEveryReadCommit,
mutexTimeout);
}
void LocalPoolDataSetBase::setDataSetMutexTimeout(
MutexIF::TimeoutType timeoutType, uint32_t mutexTimeout) {
this->timeoutType = timeoutType;
this->mutexTimeout = mutexTimeout;
object_id_t LocalPoolDataSetBase::getCreatorObjectId() {
if(poolManager != nullptr) {
return poolManager->getCreatorObjectId();
}
return objects::NO_OBJECT;
}

View File

@ -1,16 +1,16 @@
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
#include "HasLocalDataPoolIF.h"
#include "MarkChangedIF.h"
#include "localPoolDefinitions.h"
#include "../datapool/DataSetIF.h"
#include "../datapool/PoolDataSetBase.h"
#include "../serialize/SerializeIF.h"
#include <vector>
class LocalDataPoolManager;
class HasLocalDataPoolIF;
class PeriodicHousekeepingHelper;
/**
@ -41,186 +41,185 @@ class PeriodicHousekeepingHelper;
*
* @ingroup data_pool
*/
class LocalPoolDataSetBase: public PoolDataSetBase,
class LocalPoolDataSetBase:
public PoolDataSetBase,
public MarkChangedIF {
friend class LocalDataPoolManager;
friend class PeriodicHousekeepingHelper;
friend class LocalPoolDataSetAttorney;
friend class PeriodicHousekeepingHelper;
public:
/**
* @brief Constructor for the creator of local pool data.
* @details
* This constructor also initializes the components required for
* periodic handling.
*/
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
uint32_t setId, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool periodicHandling = true);
/**
* @brief Constructor for the creator of local pool data.
* @details
* This constructor also initializes the components required for
* periodic handling.
*/
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
uint32_t setId, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool periodicHandling = true);
/**
* @brief Constructor for users of local pool data.
* @details
* @param sid Unique identifier of dataset consisting of object ID and
* set ID.
* @param registeredVariablesArray
* @param maxNumberOfVariables
*/
LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables);
/**
* @brief Constructor for users of the local pool data, which need
* to access data created by one (!) HK manager.
* @details
* Unlike the first constructor, no component for periodic handling
* will be initiated.
* @param sid Unique identifier of dataset consisting of object ID and
* set ID.
* @param registeredVariablesArray
* @param maxNumberOfVariables
*/
LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables);
/**
* Simple constructor, if the dataset is not owner permanently by
* a class with a HK manager.
* @param registeredVariablesArray
* @param maxNumberOfVariables
*/
LocalPoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool protectFunctions = true);
/**
* @brief Simple constructor, if the dataset is not the owner by
* a class with a HK manager.
* @details
* This constructor won't create components required for periodic handling
* and it also won't try to deduce the HK manager because no SID is
* supplied. This function should therefore be called by classes which need
* to access pool variables from different creators.
*
* If the class is intended to access pool variables from different
* creators, the third argument should be set to true. The mutex
* properties can be set with #setReadCommitProtectionBehaviour .
* @param registeredVariablesArray
* @param maxNumberOfVariables
* @param protectEveryReadCommitCall If the pool variables are created by
* multiple creators, this flag can be set to protect all read and
* commit calls separately.
*/
LocalPoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables,
bool protectEveryReadCommitCall = true);
/**
* @brief The destructor automatically manages writing the valid
* information of variables.
* @details
* In case the data set was read out, but not committed(indicated by state),
* the destructor parses all variables that are still registered to the set.
* For each, the valid flag in the data pool is set to "invalid".
*/
~LocalPoolDataSetBase();
/**
* @brief The destructor automatically manages writing the valid
* information of variables.
* @details
* In case the data set was read out, but not committed(indicated by state),
* the destructor parses all variables that are still registered to the set.
* For each, the valid flag in the data pool is set to "invalid".
*/
~LocalPoolDataSetBase();
/**
* If the data is pulled from different local data pools, every read and
* commit call should be mutex protected for thread safety.
* This can be specified with the second parameter.
* @param dataCreator
* @param protectEveryReadCommit
*/
void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
uint32_t mutexTimeout = 20);
void setValidityBufferGeneration(bool withValidityBuffer);
void setDataSetMutexTimeout(MutexIF::TimeoutType timeoutType,
uint32_t mutexTimeout);
sid_t getSid() const;
void setValidityBufferGeneration(bool withValidityBuffer);
/** SerializeIF overrides */
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t *size,
SerializeIF::Endianness streamEndianness) override;
size_t getSerializedSize() const override;
sid_t getSid() const;
/**
* Special version of the serilization function which appends a
* validity buffer at the end. Each bit of this validity buffer
* denotes whether the container data set entries are valid from left
* to right, MSB first. (length = ceil(N/8), N = number of pool variables)
* @param buffer
* @param size
* @param maxSize
* @param bigEndian
* @param withValidityBuffer
* @return
*/
ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const;
ReturnValue_t deSerializeWithValidityBuffer(const uint8_t** buffer,
size_t *size, SerializeIF::Endianness streamEndianness);
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness,
bool serializeFillCount = true) const;
uint8_t getLocalPoolIdsSerializedSize(bool serializeFillCount = true) const;
/** SerializeIF overrides */
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t *size,
SerializeIF::Endianness streamEndianness) override;
size_t getSerializedSize() const override;
/**
* Set the dataset valid or invalid. These calls are mutex protected.
* @param setEntriesRecursively
* If this is true, all contained datasets will also be set recursively.
*/
void setValidity(bool valid, bool setEntriesRecursively);
bool isValid() const override;
/**
* Special version of the serilization function which appends a
* validity buffer at the end. Each bit of this validity buffer
* denotes whether the container data set entries are valid from left
* to right, MSB first. (length = ceil(N/8), N = number of pool variables)
* @param buffer
* @param size
* @param maxSize
* @param bigEndian
* @param withValidityBuffer
* @return
*/
ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const;
ReturnValue_t deSerializeWithValidityBuffer(const uint8_t** buffer,
size_t *size, SerializeIF::Endianness streamEndianness);
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness,
bool serializeFillCount = true) const;
uint8_t getLocalPoolIdsSerializedSize(bool serializeFillCount = true) const;
/**
* Set the dataset valid or invalid. These calls are mutex protected.
* @param setEntriesRecursively
* If this is true, all contained datasets will also be set recursively.
*/
void setValidity(bool valid, bool setEntriesRecursively);
bool isValid() const override;
/**
* These calls are mutex protected.
* @param changed
*/
void setChanged(bool changed) override;
bool hasChanged() const override;
/**
* These calls are mutex protected.
* @param changed
*/
void setChanged(bool changed) override;
bool hasChanged() const override;
object_id_t getCreatorObjectId();
protected:
sid_t sid;
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t mutexTimeout = 20;
/**
* This mutex is required because the dataset can potentially be accessed
* by multiple threads for information like change status or validity.
*/
MutexIF* mutex = nullptr;
sid_t sid;
//! This mutex is used if the data is created by one object only.
MutexIF* mutexIfSingleDataCreator = nullptr;
bool diagnostic = false;
void setDiagnostic(bool diagnostics);
bool isDiagnostics() const;
bool diagnostic = false;
void setDiagnostic(bool diagnostics);
bool isDiagnostics() const;
/**
* Used for periodic generation.
*/
bool reportingEnabled = false;
void setReportingEnabled(bool enabled);
bool getReportingEnabled() 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);
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
* data set we can use this flag.
*/
bool valid = false;
/**
* If the valid state of a dataset is always relevant to the whole
* data set we can use this flag.
*/
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;
/**
* 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;
/**
* 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;
/**
* @brief This is a small helper function to facilitate locking
* the global data pool.
* @details
* It makes use of the lockDataPool method offered by the DataPool class.
*/
ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) override;
/**
* @brief This is a small helper function to facilitate locking
* the global data pool.
* @details
* It makes use of the lockDataPool method offered by the DataPool class.
*/
ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) override;
/**
* @brief This is a small helper function to facilitate
* unlocking the global data pool
* @details
* It makes use of the freeDataPoolLock method offered by the DataPool class.
*/
ReturnValue_t unlockDataPool() override;
/**
* @brief This is a small helper function to facilitate
* unlocking the global data pool
* @details
* It makes use of the freeDataPoolLock method offered by the DataPool class.
*/
ReturnValue_t unlockDataPool() override;
LocalDataPoolManager* hkManager = nullptr;
/**
* Set n-th bit of a byte, with n being the position from 0
* (most significant bit) to 7 (least significant bit)
*/
void bitSetter(uint8_t* byte, uint8_t position) const;
bool bitGetter(const uint8_t* byte, uint8_t position) const;
/**
* Set n-th bit of a byte, with n being the position from 0
* (most significant bit) to 7 (least significant bit)
*/
void bitSetter(uint8_t* byte, uint8_t position) const;
bool bitGetter(const uint8_t* byte, uint8_t position) const;
PeriodicHousekeepingHelper* periodicHelper = nullptr;
PeriodicHousekeepingHelper* periodicHelper = nullptr;
LocalDataPoolManager* poolManager = nullptr;
};

View File

@ -1,9 +1,13 @@
#include "LocalPoolObjectBase.h"
#include "LocalDataPoolManager.h"
#include "internal/HasLocalDpIFUserAttorney.h"
#include "HasLocalDataPoolIF.h"
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId,
HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode): localPoolId(poolId),
readWriteMode(setReadWriteMode) {
#include "../objectmanager/ObjectManagerIF.h"
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
DataSetIF* dataSet, pool_rwm_t setReadWriteMode):
localPoolId(poolId), readWriteMode(setReadWriteMode) {
if(poolId == PoolVariableIF::NO_PARAMETER) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
@ -17,23 +21,24 @@ LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId,
#endif
return;
}
hkManager = hkOwner->getHkManagerHandle();
AccessPoolManagerIF* poolManAccessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
hkManager = poolManAccessor->getHkManagerHandle();
if (dataSet != nullptr) {
dataSet->registerVariable(this);
}
}
LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode): localPoolId(poolId),
readWriteMode(setReadWriteMode) {
LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF *dataSet,
pool_rwm_t setReadWriteMode):
localPoolId(poolId), readWriteMode(setReadWriteMode) {
if(poolId == PoolVariableIF::NO_PARAMETER) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
<< "which is the NO_PARAMETER value!" << std::endl;
#endif
}
HasLocalDataPoolIF* hkOwner =
objectManager->get<HasLocalDataPoolIF>(poolOwner);
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(poolOwner);
if(hkOwner == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVariable: The supplied pool owner did not "
@ -42,7 +47,12 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
#endif
return;
}
hkManager = hkOwner->getHkManagerHandle();
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if(accessor != nullptr) {
hkManager = accessor->getHkManagerHandle();
}
if(dataSet != nullptr) {
dataSet->registerVariable(this);
}
@ -77,46 +87,44 @@ bool LocalPoolObjectBase::hasChanged() const {
}
void LocalPoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
this->readWriteMode = newReadWriteMode;
this->readWriteMode = newReadWriteMode;
}
void LocalPoolObjectBase::reportReadCommitError(const char* variableType,
ReturnValue_t error, bool read, object_id_t objectId, lp_id_t lpId) {
ReturnValue_t error, bool read, object_id_t objectId, lp_id_t lpId) {
#if FSFW_DISABLE_PRINTOUT == 0
const char* type = nullptr;
if(read) {
type = "read";
}
else {
type = "commit";
}
const char* type = nullptr;
if(read) {
type = "read";
}
else {
type = "commit";
}
const char* errMsg = nullptr;
if(error == HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND) {
errMsg = "Pool entry not found";
}
else if(error == HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT) {
errMsg = "Pool entry type conflict";
}
else if(error == PoolVariableIF::INVALID_READ_WRITE_MODE) {
errMsg = "Pool variable wrong read-write mode";
}
else if(error == PoolVariableIF::INVALID_POOL_ENTRY) {
errMsg = "Pool entry invalid";
}
else {
errMsg = "Unknown error code";
}
const char* errMsg = nullptr;
if(error == localpool::POOL_ENTRY_NOT_FOUND) {
errMsg = "Pool entry not found";
}
else if(error == localpool::POOL_ENTRY_TYPE_CONFLICT) {
errMsg = "Pool entry type conflict";
}
else if(error == PoolVariableIF::INVALID_READ_WRITE_MODE) {
errMsg = "Pool variable wrong read-write mode";
}
else if(error == PoolVariableIF::INVALID_POOL_ENTRY) {
errMsg = "Pool entry invalid";
}
else {
errMsg = "Unknown error code";
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << variableType << ": " << type << " call | " << errMsg
<< " | Owner: " << std::hex << std::setw(8)
<< std::setfill('0') << objectId << " LPID: 0x" << lpId
<< std::dec << std::endl;
sif::warning << variableType << ": " << type << " call | " << errMsg << " | Owner: 0x"
<< std::hex << std::setw(8) << std::setfill('0') << objectId << std::dec
<< " LPID: " << lpId << std::endl;
#else
fsfw::printWarning("LocalPoolVariable: %s of local pool variable of "
"object 0x%08x and lp ID 0x%08x failed.\n\r",
type, objectId, lpId);
sif::printWarning("%s: %s call | %s | Owner: 0x%08x LPID: %lu\n",
variableType, type, errMsg, objectId, lpId);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
}

View File

@ -2,10 +2,20 @@
#define FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_
#include "MarkChangedIF.h"
#include "../datapoollocal/LocalDataPoolManager.h"
#include "localPoolDefinitions.h"
#include "../objectmanager/SystemObjectIF.h"
#include "../datapool/PoolVariableIF.h"
#include "../returnvalues/HasReturnvaluesIF.h"
class LocalDataPoolManager;
class DataSetIF;
class HasLocalDataPoolIF;
/**
* @brief This class serves as a non-template base for pool objects like pool variables
* or pool vectors.
*/
class LocalPoolObjectBase: public PoolVariableIF,
public HasReturnvaluesIF,
public MarkChangedIF {
@ -54,12 +64,10 @@ protected:
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
//! @brief Pointer to the class which manages the HK pool.
LocalDataPoolManager* hkManager;
LocalDataPoolManager* hkManager = nullptr;
void reportReadCommitError(const char* variableType,
ReturnValue_t error, bool read, object_id_t objectId, lp_id_t lpId);
void reportReadCommitError(const char* variableType,
ReturnValue_t error, bool read, object_id_t objectId, lp_id_t lpId);
};
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_ */

View File

@ -4,6 +4,8 @@
#include "LocalPoolObjectBase.h"
#include "HasLocalDataPoolIF.h"
#include "LocalDataPoolManager.h"
#include "AccessLocalPoolF.h"
#include "internal/LocalDpManagerAttorney.h"
#include "../datapool/PoolVariableIF.h"
#include "../datapool/DataSetIF.h"
@ -25,159 +27,159 @@
template<typename T>
class LocalPoolVariable: public LocalPoolObjectBase {
public:
//! Default ctor is forbidden.
LocalPoolVariable() = delete;
//! Default ctor is forbidden.
LocalPoolVariable() = delete;
/**
* This constructor is used by the data creators to have pool variable
* instances which can also be stored in datasets.
*
* It does not fetch the current value from the data pool, which
* has to be done by calling the read() operation.
* Datasets can be used to access multiple local pool entries in an
* efficient way. A pointer to a dataset can be passed to register
* the pool variable in that dataset directly.
* @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling
* class itself which passes "this".
* @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered.
* @param setReadWriteMode Specify the read-write mode of the pool variable.
*/
LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* This constructor is used by the data creators to have pool variable
* instances which can also be stored in datasets.
*
* It does not fetch the current value from the data pool, which
* has to be done by calling the read() operation.
* Datasets can be used to access multiple local pool entries in an
* efficient way. A pointer to a dataset can be passed to register
* the pool variable in that dataset directly.
* @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling
* class itself which passes "this".
* @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered.
* @param setReadWriteMode Specify the read-write mode of the pool variable.
*/
LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* This constructor is used by data users like controllers to have
* access to the local pool variables of data creators by supplying
* the respective creator object ID.
*
* It does not fetch the current value from the data pool, which
* has to be done by calling the read() operation.
* Datasets can be used to access multiple local pool entries in an
* efficient way. A pointer to a dataset can be passed to register
* the pool variable in that dataset directly.
* @param poolId ID of the local pool entry.
* @param hkOwner object ID of the pool owner.
* @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered.
* @param setReadWriteMode Specify the read-write mode of the pool variable.
*
*/
LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* Variation which takes the global unique identifier of a pool variable.
* @param globalPoolId
* @param dataSet
* @param setReadWriteMode
*/
LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* This constructor is used by data users like controllers to have
* access to the local pool variables of data creators by supplying
* the respective creator object ID.
*
* It does not fetch the current value from the data pool, which
* has to be done by calling the read() operation.
* Datasets can be used to access multiple local pool entries in an
* efficient way. A pointer to a dataset can be passed to register
* the pool variable in that dataset directly.
* @param poolId ID of the local pool entry.
* @param hkOwner object ID of the pool owner.
* @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered.
* @param setReadWriteMode Specify the read-write mode of the pool variable.
*
*/
LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* Variation which takes the global unique identifier of a pool variable.
* @param globalPoolId
* @param dataSet
* @param setReadWriteMode
*/
LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
virtual~ LocalPoolVariable() {};
virtual~ LocalPoolVariable() {};
/**
* @brief This is the local copy of the data pool entry.
* @details The user can work on this attribute
* just like he would on a simple local variable.
*/
T value = 0;
/**
* @brief This is the local copy of the data pool entry.
* @details The user can work on this attribute
* just like he would on a simple local variable.
*/
T value = 0;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
/**
* @brief This is a call to read the array's values
* from the global data pool.
* @details
* When executed, this operation tries to fetch the pool entry with matching
* data pool id from the data pool and copies all array values and the valid
* information to its local attributes.
* In case of a failure (wrong type, size or pool id not found), the
* variable is set to zero and invalid.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*
*/
ReturnValue_t read(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief The commit call copies the array values back to the data pool.
* @details
* It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the local valid flag is written back as well.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*/
ReturnValue_t commit(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief This is a call to read the array's values
* from the global data pool.
* @details
* When executed, this operation tries to fetch the pool entry with matching
* data pool id from the data pool and copies all array values and the valid
* information to its local attributes.
* In case of a failure (wrong type, size or pool id not found), the
* variable is set to zero and invalid.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*
*/
ReturnValue_t read(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief The commit call copies the array values back to the data pool.
* @details
* It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the local valid flag is written back as well.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*/
ReturnValue_t commit(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief This commit function can be used to set the pool variable valid
* as well.
* @param setValid
* @param timeoutType
* @param timeoutMs
* @return
*/
ReturnValue_t commit(bool setValid, MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20);
/**
* @brief This commit function can be used to set the pool variable valid
* as well.
* @param setValid
* @param timeoutType
* @param timeoutMs
* @return
*/
ReturnValue_t commit(bool setValid, MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20);
LocalPoolVariable<T> &operator=(const T& newValue);
LocalPoolVariable<T> &operator=(const LocalPoolVariable<T>& newPoolVariable);
LocalPoolVariable<T> &operator=(const T& newValue);
LocalPoolVariable<T> &operator=(const LocalPoolVariable<T>& newPoolVariable);
//! Explicit type conversion operator. Allows casting the class to
//! its template type to perform operations on value.
explicit operator T() const;
//! Explicit type conversion operator. Allows casting the class to
//! its template type to perform operations on value.
explicit operator T() const;
bool operator==(const LocalPoolVariable<T>& other) const;
bool operator==(const T& other) const;
bool operator==(const LocalPoolVariable<T>& other) const;
bool operator==(const T& other) const;
bool operator!=(const LocalPoolVariable<T>& other) const;
bool operator!=(const T& other) const;
bool operator!=(const LocalPoolVariable<T>& other) const;
bool operator!=(const T& other) const;
bool operator<(const LocalPoolVariable<T>& other) const;
bool operator<(const T& other) const;
bool operator<(const LocalPoolVariable<T>& other) const;
bool operator<(const T& other) const;
bool operator>(const LocalPoolVariable<T>& other) const;
bool operator>(const T& other) const;
bool operator>(const LocalPoolVariable<T>& other) const;
bool operator>(const T& other) const;
protected:
/**
* @brief Like #read, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t readWithoutLock() override;
/**
* @brief Like #commit, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t commitWithoutLock() override;
/**
* @brief Like #read, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t readWithoutLock() override;
/**
* @brief Like #commit, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t commitWithoutLock() override;
#if FSFW_CPP_OSTREAM_ENABLED == 1
// std::ostream is the type for object std::cout
template <typename U>
friend std::ostream& operator<< (std::ostream &out,
const LocalPoolVariable<U> &var);
// std::ostream is the type for object std::cout
template <typename U>
friend std::ostream& operator<< (std::ostream &out,
const LocalPoolVariable<U> &var);
#endif
};

View File

@ -7,31 +7,32 @@
template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner,
lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner,
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template<typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode){}
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode){}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::read(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(hkManager->getMutexHandle(), timeoutType, timeoutMs);
return readWithoutLock();
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return readWithoutLock();
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
<<<<<<< HEAD
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getOwner()->getObjectId();
reportReadCommitError("LocalPoolVector",
@ -61,24 +62,58 @@ inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
this->value = *(poolEntry->address);
this->valid = poolEntry->valid;
return RETURN_OK;
=======
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
//ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
if(result != RETURN_OK) {
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVariable", result,
false, ownerObjectId, localPoolId);
return result;
}
// Actually this should never happen..
// if(poolEntry->address == nullptr) {
// result = PoolVariableIF::INVALID_POOL_ENTRY;
// object_id_t ownerObjectId = hkManager->getOwner()->getObjectId();
// reportReadCommitError("LocalPoolVariable", result,
// false, ownerObjectId, localPoolId);
// return result;
// }
this->value = *(poolEntry->getDataPtr());
this->valid = poolEntry->getValid();
return RETURN_OK;
>>>>>>> upstream/mueller/master
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::commit(bool setValid,
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
this->setValid(setValid);
return commit(timeoutType, timeoutMs);
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
this->setValid(setValid);
return commit(timeoutType, timeoutMs);
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::commit(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(hkManager->getMutexHandle(), timeoutType, timeoutMs);
return commitWithoutLock();
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return commitWithoutLock();
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
<<<<<<< HEAD
if(readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getOwner()->getObjectId();
reportReadCommitError("LocalPoolVector",
@ -99,31 +134,55 @@ inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
*(poolEntry->address) = this->value;
poolEntry->valid = this->valid;
return RETURN_OK;
=======
if(readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
//ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
if(result != RETURN_OK) {
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVariable", result,
false, ownerObjectId, localPoolId);
return result;
}
*(poolEntry->getDataPtr()) = this->value;
poolEntry->setValid(this->valid);
return RETURN_OK;
>>>>>>> upstream/mueller/master
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::serialize(uint8_t** buffer,
size_t* size, const size_t max_size,
SerializeIF::Endianness streamEndianness) const {
return SerializeAdapter::serialize(&value,
buffer, size ,max_size, streamEndianness);
size_t* size, const size_t max_size,
SerializeIF::Endianness streamEndianness) const {
return SerializeAdapter::serialize(&value,
buffer, size ,max_size, streamEndianness);
}
template<typename T>
inline size_t LocalPoolVariable<T>::getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&value);
return SerializeAdapter::getSerializedSize(&value);
}
template<typename T>
inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer,
size_t* size, SerializeIF::Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
size_t* size, SerializeIF::Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
template<typename T>
inline std::ostream& operator<< (std::ostream &out,
const LocalPoolVariable<T> &var) {
const LocalPoolVariable<T> &var) {
out << var.value;
return out;
}
@ -131,68 +190,68 @@ inline std::ostream& operator<< (std::ostream &out,
template<typename T>
inline LocalPoolVariable<T>::operator T() const {
return value;
return value;
}
template<typename T>
inline LocalPoolVariable<T> & LocalPoolVariable<T>::operator=(
const T& newValue) {
const T& newValue) {
value = newValue;
return *this;
}
template<typename T>
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator =(
const LocalPoolVariable<T>& newPoolVariable) {
value = newPoolVariable.value;
return *this;
const LocalPoolVariable<T>& newPoolVariable) {
value = newPoolVariable.value;
return *this;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator ==(
const LocalPoolVariable<T> &other) const {
return this->value == other.value;
const LocalPoolVariable<T> &other) const {
return this->value == other.value;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator ==(const T &other) const {
return this->value == other;
return this->value == other;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator !=(
const LocalPoolVariable<T> &other) const {
return not (*this == other);
const LocalPoolVariable<T> &other) const {
return not (*this == other);
}
template<typename T>
inline bool LocalPoolVariable<T>::operator !=(const T &other) const {
return not (*this == other);
return not (*this == other);
}
template<typename T>
inline bool LocalPoolVariable<T>::operator <(
const LocalPoolVariable<T> &other) const {
return this->value < other.value;
const LocalPoolVariable<T> &other) const {
return this->value < other.value;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator <(const T &other) const {
return this->value < other;
return this->value < other;
}
template<typename T>
inline bool LocalPoolVariable<T>::operator >(
const LocalPoolVariable<T> &other) const {
return not (*this < other);
const LocalPoolVariable<T> &other) const {
return not (*this < other);
}
template<typename T>
inline bool LocalPoolVariable<T>::operator >(const T &other) const {
return not (*this < other);
return not (*this < other);
}
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ */

View File

@ -2,6 +2,8 @@
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
#include "LocalPoolObjectBase.h"
#include "internal/LocalDpManagerAttorney.h"
#include "../datapool/DataSetIF.h"
#include "../datapool/PoolEntry.h"
#include "../datapool/PoolVariableIF.h"
@ -33,139 +35,148 @@
template<typename T, uint16_t vectorSize>
class LocalPoolVector: public LocalPoolObjectBase {
public:
LocalPoolVector() = delete;
/**
* This constructor is used by the data creators to have pool variable
* instances which can also be stored in datasets.
* It does not fetch the current value from the data pool. This is performed
* by the read() operation (which is not thread-safe).
* Datasets can be used to access local pool entires in a thread-safe way.
* @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling
* 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.
* If nullptr, the variable is not registered.
*/
LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
LocalPoolVector() = delete;
/**
* This constructor is used by the data creators to have pool variable
* instances which can also be stored in datasets.
* It does not fetch the current value from the data pool. This is performed
* by the read() operation (which is not thread-safe).
* Datasets can be used to access local pool entires in a thread-safe way.
* @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling
* 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.
* If nullptr, the variable is not registered.
*/
LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* This constructor is used by data users like controllers to have
* access to the local pool variables of data creators by supplying
* the respective creator object ID.
* It does not fetch the current value from the data pool. This is performed
* by the read() operation (which is not thread-safe).
* Datasets can be used to access local pool entires in a thread-safe way.
* @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling
* 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.
* If nullptr, the variable is not registered.
*/
LocalPoolVector(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* Variation which takes the unique global identifier of a local pool
* vector.
* @param globalPoolId
* @param dataSet
* @param setReadWriteMode
*/
LocalPoolVector(gp_id_t globalPoolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* This constructor is used by data users like controllers to have
* access to the local pool variables of data creators by supplying
* the respective creator object ID.
* It does not fetch the current value from the data pool. This is performed
* by the read() operation (which is not thread-safe).
* Datasets can be used to access local pool entires in a thread-safe way.
* @param poolId ID of the local pool entry.
* @param hkOwner Pointer of the owner. This will generally be the calling
* 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.
* If nullptr, the variable is not registered.
*/
LocalPoolVector(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* Variation which takes the unique global identifier of a local pool
* vector.
* @param globalPoolId
* @param dataSet
* @param setReadWriteMode
*/
LocalPoolVector(gp_id_t globalPoolId,
DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**
* @brief This is the local copy of the data pool entry.
* @details
* The user can work on this attribute just like he would on a local
* array of this type.
*/
T value[vectorSize];
/**
* @brief The classes destructor is empty.
* @details If commit() was not called, the local value is
* discarded and not written back to the data pool.
*/
~LocalPoolVector() {};
/**
* @brief The operation returns the number of array entries
* in this variable.
*/
uint8_t getSize() {
return vectorSize;
}
/**
* @brief This is the local copy of the data pool entry.
* @details
* The user can work on this attribute just like he would on a local
* array of this type.
*/
T value[vectorSize];
/**
* @brief The classes destructor is empty.
* @details If commit() was not called, the local value is
* discarded and not written back to the data pool.
*/
~LocalPoolVector() {};
/**
* @brief The operation returns the number of array entries
* in this variable.
*/
uint8_t getSize() {
return vectorSize;
}
T& operator [](int i);
const T &operator [](int i) const;
T& operator [](size_t i);
const T &operator [](size_t i) const;
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t maxSize,
SerializeIF::Endianness streamEndiannes) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t maxSize,
SerializeIF::Endianness streamEndiannes) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
/**
* @brief This is a call to read the array's values
* from the global data pool.
* @details
* When executed, this operation tries to fetch the pool entry with matching
* data pool id from the data pool and copies all array values and the valid
* information to its local attributes.
* In case of a failure (wrong type, size or pool id not found), the
* variable is set to zero and invalid.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*/
ReturnValue_t read(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief The commit call copies the array values back to the data pool.
* @details
* It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the local valid flag is written back as well.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*/
ReturnValue_t commit(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief This is a call to read the array's values
* from the global data pool.
* @details
* When executed, this operation tries to fetch the pool entry with matching
* data pool id from the data pool and copies all array values and the valid
* information to its local attributes.
* In case of a failure (wrong type, size or pool id not found), the
* variable is set to zero and invalid.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*/
ReturnValue_t read(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief The commit call copies the array values back to the data pool.
* @details
* It checks type and size, as well as if the variable is writable. If so,
* the value is copied and the local valid flag is written back as well.
* The read call is protected with a lock.
* It is recommended to use DataSets to read and commit multiple variables
* at once to avoid the overhead of unnecessary lock und unlock operations.
*/
ReturnValue_t commit(MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* @brief This commit call also sets the validity of the pool entry.
* @details
*/
ReturnValue_t commit(bool valid, MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20);
protected:
/**
* @brief Like #read, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t readWithoutLock() override;
/**
* @brief Like #commit, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t commitWithoutLock() override;
/**
* @brief Like #read, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t readWithoutLock() override;
/**
* @brief Like #commit, but without a lock protection of the global pool.
* @details
* The operation does NOT provide any mutual exclusive protection by itself.
* This can be used if the lock is handled externally to avoid the overhead
* of consecutive lock und unlock operations.
* Declared protected to discourage free public usage.
*/
ReturnValue_t commitWithoutLock() override;
private:
#if FSFW_CPP_OSTREAM_ENABLED == 1
// std::ostream is the type for object std::cout
template <typename U, uint16_t otherSize>
friend std::ostream& operator<< (std::ostream &out,
const LocalPoolVector<U, otherSize> &var);
// std::ostream is the type for object std::cout
template <typename U, uint16_t otherSize>
friend std::ostream& operator<< (std::ostream &out,
const LocalPoolVector<U, otherSize> &var);
#endif
};

View File

@ -7,143 +7,158 @@
template<typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(
HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template<typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(object_id_t poolOwner,
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template<typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode) {}
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode) {}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(hkManager->getMutexHandle(), timeoutType, timeoutMs);
return readWithoutLock();
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return readWithoutLock();
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getOwner()->getObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
memset(this->value, 0, vectorSize * sizeof(T));
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
memset(this->value, 0, vectorSize * sizeof(T));
if(result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getOwner()->getObjectId();
reportReadCommitError("LocalPoolVector", result, true, targetObjectId,
localPoolId);
return result;
}
std::memcpy(this->value, poolEntry->address, poolEntry->getByteSize());
this->valid = poolEntry->valid;
return RETURN_OK;
if(result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", result, true, targetObjectId,
localPoolId);
return result;
}
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
this->valid = poolEntry->getValid();
return RETURN_OK;
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(bool valid,
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
this->setValid(valid);
return commit(timeoutType, timeoutMs);
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(hkManager->getMutexHandle(), timeoutType, timeoutMs);
return commitWithoutLock();
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return commitWithoutLock();
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getOwner()->getObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
if(result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getOwner()->getObjectId();
reportReadCommitError("LocalPoolVector", result, false, targetObjectId,
localPoolId);
return result;
}
std::memcpy(poolEntry->address, this->value, poolEntry->getByteSize());
poolEntry->valid = this->valid;
return RETURN_OK;
if(readWriteMode == pool_rwm_t::VAR_READ) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector",
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
localPoolId);
return PoolVariableIF::INVALID_READ_WRITE_MODE;
}
PoolEntry<T>* poolEntry = nullptr;
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
&poolEntry);
if(result != RETURN_OK) {
object_id_t targetObjectId = hkManager->getCreatorObjectId();
reportReadCommitError("LocalPoolVector", result, false, targetObjectId,
localPoolId);
return result;
}
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
poolEntry->setValid(this->valid);
return RETURN_OK;
}
template<typename T, uint16_t vectorSize>
inline T& LocalPoolVector<T, vectorSize>::operator [](int i) {
if(i <= vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
inline T& LocalPoolVector<T, vectorSize>::operator [](size_t i) {
if(i < vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVector: Invalid index. Setting or returning"
" last value!" << std::endl;
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
" last value!" << std::endl;
#else
sif::printWarning("LocalPoolVector: Invalid index. Setting or returning"
" last value!\n");
#endif
return value[i];
return value[vectorSize - 1];
}
template<typename T, uint16_t vectorSize>
inline const T& LocalPoolVector<T, vectorSize>::operator [](int i) const {
if(i <= vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
inline const T& LocalPoolVector<T, vectorSize>::operator [](size_t i) const {
if(i < vectorSize) {
return value[i];
}
// If this happens, I have to set some value. I consider this
// a configuration error, but I wont exit here.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVector: Invalid index. Setting or returning"
" last value!" << std::endl;
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
" last value!" << std::endl;
#else
sif::printWarning("LocalPoolVector: Invalid index. Setting or returning"
" last value!\n");
#endif
return value[i];
return value[vectorSize - 1];
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::serialize(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
}
return result;
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
}
return result;
}
template<typename T, uint16_t vectorSize>
inline size_t LocalPoolVector<T, vectorSize>::getSerializedSize() const {
return vectorSize * SerializeAdapter::getSerializedSize(value);
return vectorSize * SerializeAdapter::getSerializedSize(value);
}
template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::deSerialize(
const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
}
return result;
const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
for (uint16_t i = 0; i < vectorSize; i++) {
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
break;
}
}
return result;
}
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,7 +1,8 @@
#ifndef FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_
#define FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_
#include <fsfw/datapoollocal/LocalPoolDataSetBase.h>
#include "LocalPoolDataSetBase.h"
#include "../serviceinterface/ServiceInterface.h"
#include <FSFWConfig.h>
/**
@ -9,36 +10,38 @@
*/
class PoolReadHelper {
public:
PoolReadHelper(ReadCommitIF* readObject,
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t mutexTimeout = 20):
readObject(readObject), mutexTimeout(mutexTimeout) {
if(readObject != nullptr) {
readResult = readObject->read(timeoutType, mutexTimeout);
#if FSFW_PRINT_VERBOSITY_LEVEL == 1
PoolReadHelper(ReadCommitIF* readObject,
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t mutexTimeout = 20):
readObject(readObject), mutexTimeout(mutexTimeout) {
if(readObject != nullptr) {
readResult = readObject->read(timeoutType, mutexTimeout);
#if FSFW_VERBOSE_LEVEL == 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PoolReadHelper: Read failed!" << std::endl;
#endif
#endif
}
}
sif::error << "PoolReadHelper: Read failed!" << std::endl;
#else
sif::printError("PoolReadHelper: Read failed!\n");
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
}
}
ReturnValue_t getReadResult() const {
return readResult;
}
ReturnValue_t getReadResult() const {
return readResult;
}
~PoolReadHelper() {
if(readObject != nullptr) {
readObject->commit(timeoutType, mutexTimeout);
}
~PoolReadHelper() {
if(readObject != nullptr) {
readObject->commit(timeoutType, mutexTimeout);
}
}
}
private:
ReadCommitIF* readObject = nullptr;
ReturnValue_t readResult = HasReturnvaluesIF::RETURN_OK;
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t mutexTimeout = 20;
ReadCommitIF* readObject = nullptr;
ReturnValue_t readResult = HasReturnvaluesIF::RETURN_OK;
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t mutexTimeout = 20;
};

View File

@ -0,0 +1,83 @@
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
#include "localPoolDefinitions.h"
#include "../ipc/messageQueueDefinitions.h"
#include "../returnvalues/HasReturnvaluesIF.h"
class ProvidesDataPoolSubscriptionIF {
public:
virtual ~ProvidesDataPoolSubscriptionIF(){};
/**
* @brief Subscribe for the generation of periodic packets.
* @details
* This subscription mechanism will generally be used by the data creator
* to generate housekeeping packets which are downlinked directly.
* @return
*/
virtual ReturnValue_t subscribeForPeriodicPacket(sid_t sid,
bool enableReporting,
float collectionInterval, bool isDiagnostics,
object_id_t packetDestination) = 0;
/**
* @brief Subscribe for the generation of packets if the dataset
* is marked as changed.
* @details
* This subscription mechanism will generally be used by the data creator.
* @param sid
* @param isDiagnostics
* @param packetDestination
* @return
*/
virtual ReturnValue_t subscribeForUpdatePackets(sid_t sid,
bool reportingEnabled,
bool isDiagnostics,
object_id_t packetDestination) = 0;
/**
* @brief Subscribe for a notification message which will be sent
* if a dataset has changed.
* @details
* This subscription mechanism will generally be used internally by
* other software components.
* @param setId Set ID of the set to receive update messages from.
* @param destinationObject
* @param targetQueueId
* @param generateSnapshot If this is set to true, a copy of the current
* data with a timestamp will be generated and sent via message.
* Otherwise, only an notification message is sent.
* @return
*/
virtual ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
object_id_t destinationObject,
MessageQueueId_t targetQueueId,
bool generateSnapshot) = 0;
/**
* @brief Subscribe for an notification message which will be sent if a
* pool variable has changed.
* @details
* This subscription mechanism will generally be used internally by
* other software components.
* @param localPoolId Pool ID of the pool variable
* @param destinationObject
* @param targetQueueId
* @param generateSnapshot If this is set to true, a copy of the current
* data with a timestamp will be generated and sent via message.
* Otherwise, only an notification message is sent.
* @return
*/
virtual ReturnValue_t subscribeForVariableUpdateMessages(
const lp_id_t localPoolId,
object_id_t destinationObject,
MessageQueueId_t targetQueueId,
bool generateSnapshot) = 0;
};
#endif /* FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ */

View File

@ -6,7 +6,15 @@
#include "../objectmanager/SystemObject.h"
#include <vector>
class SharedLocalDataSet: public SystemObject,
/**
* This local dataset variation can be used if the dataset is used concurrently across
* multiple threads. It provides a lock in addition to all other functionalities provided
* by the LocalPoolDataSetBase class.
*
* TODO: override and protect read, commit and some other calls used by pool manager.
*/
class SharedLocalDataSet:
public SystemObject,
public LocalPoolDataSetBase,
public SharedDataSetIF {
public:

View File

@ -20,26 +20,24 @@
template <uint8_t NUM_VARIABLES>
class StaticLocalDataSet: public LocalPoolDataSetBase {
public:
/**
* 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) {
/**
* 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) {
/**
* Constructor used by data users like controllers.
* @param hkOwner
* @param setId
*/
StaticLocalDataSet(sid_t sid): LocalPoolDataSetBase(sid, nullptr, NUM_VARIABLES) {
this->setContainer(poolVarList.data());
}

View File

@ -0,0 +1,5 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HasLocalDpIFUserAttorney.cpp
HasLocalDpIFManagerAttorney.cpp
)

View File

@ -0,0 +1,18 @@
#include "HasLocalDpIFManagerAttorney.h"
#include "../LocalPoolObjectBase.h"
#include "../LocalPoolDataSetBase.h"
#include "../HasLocalDataPoolIF.h"
LocalPoolDataSetBase* HasLocalDpIFManagerAttorney::getDataSetHandle(HasLocalDataPoolIF* clientIF,
sid_t sid) {
return clientIF->getDataSetHandle(sid);
}
LocalPoolObjectBase* HasLocalDpIFManagerAttorney::getPoolObjectHandle(HasLocalDataPoolIF* clientIF,
lp_id_t localPoolId) {
return clientIF->getPoolObjectHandle(localPoolId);
}
object_id_t HasLocalDpIFManagerAttorney::getObjectId(HasLocalDataPoolIF* clientIF) {
return clientIF->getObjectId();
}

View File

@ -0,0 +1,22 @@
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_
#include "../localPoolDefinitions.h"
class HasLocalDataPoolIF;
class LocalPoolDataSetBase;
class LocalPoolObjectBase;
class HasLocalDpIFManagerAttorney {
static LocalPoolDataSetBase* getDataSetHandle(HasLocalDataPoolIF* clientIF, sid_t sid);
static LocalPoolObjectBase* getPoolObjectHandle(HasLocalDataPoolIF* clientIF,
lp_id_t localPoolId);
static object_id_t getObjectId(HasLocalDataPoolIF* clientIF);
friend class LocalDataPoolManager;
};
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_ */

View File

@ -0,0 +1,7 @@
#include "HasLocalDpIFUserAttorney.h"
#include "../AccessLocalPoolF.h"
#include "../HasLocalDataPoolIF.h"
AccessPoolManagerIF* HasLocalDpIFUserAttorney::getAccessorHandle(HasLocalDataPoolIF *clientIF) {
return clientIF->getAccessorHandle();
}

View File

@ -0,0 +1,18 @@
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
class HasLocalDataPoolIF;
class AccessPoolManagerIF;
class HasLocalDpIFUserAttorney {
private:
static AccessPoolManagerIF* getAccessorHandle(HasLocalDataPoolIF* clientIF);
friend class LocalPoolObjectBase;
friend class LocalPoolDataSetBase;
};
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_ */

View File

@ -0,0 +1,32 @@
#ifndef FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
#define FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
#include "../LocalDataPoolManager.h"
/**
* @brief This is a helper class implements the Attorney-Client idiom for access to
* LocalDataPoolManager internals
* @details
* This helper class provides better control over which classes are allowed to access
* LocalDataPoolManager internals in a granular and encapsulated way when compared to
* other methods like direct friend declarations. It allows these classes to use
* an explicit subset of the pool manager private/protected functions.
* See: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Friendship_and_the_Attorney-Client
*/
class LocalDpManagerAttorney {
private:
template<typename T> static ReturnValue_t fetchPoolEntry(LocalDataPoolManager& manager,
lp_id_t localPoolId, PoolEntry<T> **poolEntry) {
return manager.fetchPoolEntry(localPoolId, poolEntry);
}
static MutexIF* getMutexHandle(LocalDataPoolManager& manager) {
return manager.getMutexHandle();
}
template<typename T> friend class LocalPoolVariable;
template<typename T, uint16_t vecSize> friend class LocalPoolVector;
};
#endif /* FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_ */

View File

@ -0,0 +1,39 @@
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_
#include "../LocalPoolDataSetBase.h"
class LocalPoolDataSetAttorney {
private:
static void setDiagnostic(LocalPoolDataSetBase& set, bool diagnostics) {
set.setDiagnostic(diagnostics);
}
static bool isDiagnostics(LocalPoolDataSetBase& set) {
return set.isDiagnostics();
}
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
uint32_t minimumPeriodicIntervalMs,
bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5) {
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs, isDiagnostics,
nonDiagIntervalFactor);
}
static void setReportingEnabled(LocalPoolDataSetBase& set, bool enabled) {
set.setReportingEnabled(enabled);
}
static bool getReportingEnabled(LocalPoolDataSetBase& set) {
return set.getReportingEnabled();
}
static PeriodicHousekeepingHelper* getPeriodicHelper(LocalPoolDataSetBase& set) {
return set.periodicHelper;
}
friend class LocalDataPoolManager;
};
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_ */

View File

@ -1,10 +1,13 @@
#ifndef FSFW_DATAPOOLLOCAL_LOCPOOLDEFINITIONS_H_
#define FSFW_DATAPOOLLOCAL_LOCPOOLDEFINITIONS_H_
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_
#include <cstdint>
#include "../datapool/PoolEntryIF.h"
#include "../objectmanager/SystemObjectIF.h"
#include "../objectmanager/frameworkObjects.h"
#include <cstdint>
#include <map>
/**
* @brief Type definition for local pool entries.
*/
@ -12,10 +15,21 @@ using lp_id_t = uint32_t;
namespace localpool {
static constexpr uint32_t INVALID_LPID = -1;
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
//! This is the core data structure of the local data pools. Users should insert all desired
//! pool variables, using the std::map interface.
using DataPool = std::map<lp_id_t, PoolEntryIF*>;
using DataPoolMapIter = DataPool::iterator;
}
/**
* Used as a unique identifier for data sets.
* Used as a unique identifier for data sets. Consists of 4 byte object ID and 4 byte set ID.
*/
union sid_t {
static constexpr uint64_t INVALID_SID = -1;
@ -26,8 +40,8 @@ union sid_t {
sid_t(): raw(INVALID_SID) {}
sid_t(object_id_t objectId, uint32_t setId):
objectId(objectId),
ownerSetId(setId) {}
objectId(objectId),
ownerSetId(setId) {}
struct {
object_id_t objectId ;
@ -57,29 +71,30 @@ union sid_t {
};
/**
* Used as a global unique identifier for local pool variables.
* Used as a global unique identifier for local pool variables. Consists of 4 byte object ID
* and 4 byte local pool ID.
*/
union gp_id_t {
static constexpr uint64_t INVALID_GPID = -1;
static constexpr uint64_t INVALID_GPID = -1;
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
gp_id_t(): raw(INVALID_GPID) {}
gp_id_t(): raw(INVALID_GPID) {}
gp_id_t(object_id_t objectId, lp_id_t localPoolId):
objectId(objectId),
localPoolId(localPoolId) {}
gp_id_t(object_id_t objectId, lp_id_t localPoolId):
objectId(objectId),
localPoolId(localPoolId) {}
struct {
object_id_t objectId;
lp_id_t localPoolId;
};
struct {
object_id_t objectId;
lp_id_t localPoolId;
};
uint64_t raw;
uint64_t raw;
bool notSet() const {
return raw == INVALID_GPID;
}
bool notSet() const {
return raw == INVALID_GPID;
}
bool operator==(const sid_t& other) const {
return raw == other.raw;
@ -90,4 +105,4 @@ union gp_id_t {
}
};
#endif /* FSFW_DATAPOOLLOCAL_LOCPOOLDEFINITIONS_H_ */
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_ */