fsfw/datapoollocal/LocalDataPoolManager.h

186 lines
6.3 KiB
C
Raw Normal View History

2020-05-17 01:17:11 +02:00
#ifndef FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_
#define FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_
#include <framework/datapool/DataSetIF.h>
#include <framework/objectmanager/SystemObjectIF.h>
#include <framework/ipc/MutexIF.h>
2020-06-05 20:35:08 +02:00
#include <framework/housekeeping/HousekeepingMessage.h>
2020-05-17 01:17:11 +02:00
#include <framework/datapool/PoolEntry.h>
2020-06-07 02:22:18 +02:00
#include <framework/datapoollocal/OwnsLocalDataPoolIF.h>
2020-05-17 01:17:11 +02:00
#include <framework/ipc/CommandMessage.h>
#include <framework/ipc/MessageQueueIF.h>
#include <framework/ipc/MutexHelper.h>
#include <map>
2020-06-19 03:03:17 +02:00
class LocalDataSet;
2020-06-07 02:22:18 +02:00
/**
* @brief This class is the managing instance for local data pool.
* @details
* The actual data pool structure is a member of this class. Any class which
* has a local data pool shall have this class as a member and implement
* the OwnsLocalDataPoolIF.
*
* Users of the data pool use the helper classes LocalDataSet,
* LocalPoolVariable and LocalPoolVector to access pool entries in
* a thread-safe and efficient way.
*
* The local data pools employ a blackboard logic: Only the most recent
* value is stored. The helper classes offer a read() and commit() interface
* through the PoolVariableIF which is used to read and update values.
* Each pool entry has a valid state too.
*
*/
class LocalDataPoolManager {
2020-06-05 20:35:08 +02:00
template<typename T>
friend class LocalPoolVar;
template<typename T, uint16_t vecSize>
friend class LocalPoolVector;
friend class LocalDataSet;
2020-05-17 01:17:11 +02:00
public:
2020-06-19 03:03:17 +02:00
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x0);
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x1);
2020-06-30 21:22:26 +02:00
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x2);
2020-06-19 03:03:17 +02:00
//static constexpr ReturnValue_t SET_NOT_FOUND = MAKE_RETURN_CODE(0x3);
2020-05-17 01:17:11 +02:00
2020-06-30 21:22:26 +02:00
/**
* This constructor is used by a class which wants to implement
* a personal local data pool. The queueToUse can be supplied if it
* is already known.
*
* initialize() has to be called in any case before using the object!
* @param owner
* @param queueToUse
* @param appendValidityBuffer
*/
LocalDataPoolManager(OwnsLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
bool appendValidityBuffer = true);
/**
* Initializes the map by calling the map initialization function of the
* owner abd assigns the queue to use.
* @param queueToUse
* @return
*/
ReturnValue_t initialize(MessageQueueIF* queueToUse,
object_id_t hkDestination);
/**
* This function is used to set the default HK packet destination.
* This destination will usually only be set once.
* @param hkDestination
*/
void setHkPacketDestination(MessageQueueId_t hkDestination);
2020-05-17 01:17:11 +02:00
2020-06-30 21:22:26 +02:00
virtual~ LocalDataPoolManager();
2020-05-17 01:17:11 +02:00
2020-06-30 21:22:26 +02:00
/**
* Generate a housekeeping packet with a given SID.
* @param sid
* @return
*/
ReturnValue_t generateHousekeepingPacket(sid_t sid, MessageQueueId_t sendTo
= MessageQueueIF::NO_QUEUE);
ReturnValue_t generateSetStructurePacket(sid_t sid);
ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
2020-05-17 01:17:11 +02:00
/**
* This function is used to fill the local data pool map with pool
2020-06-05 20:35:08 +02:00
* entries. It should only be called once by the pool owner.
2020-05-17 01:17:11 +02:00
* @param localDataPoolMap
* @return
*/
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
2020-06-07 02:22:18 +02:00
const OwnsLocalDataPoolIF* getOwner() const;
2020-05-17 01:17:11 +02:00
2020-06-05 20:35:08 +02:00
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
2020-06-30 21:22:26 +02:00
/* Copying forbidden */
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
2020-06-05 20:35:08 +02:00
private:
2020-06-30 21:22:26 +02:00
/** This is the map holding the actual data. Should only be initialized
* once ! */
2020-05-17 01:17:11 +02:00
bool mapInitialized = false;
2020-06-30 21:22:26 +02:00
/** This specifies whether a validity buffer is appended at the end
* of generated housekeeping packets. */
2020-06-19 03:03:17 +02:00
bool appendValidityBuffer = true;
2020-06-07 02:22:18 +02:00
LocalDataPool localDpMap;
2020-05-17 01:17:11 +02:00
2020-06-30 21:22:26 +02:00
/** Every housekeeping data manager has a mutex to protect access
* to it's data pool. */
2020-05-17 01:17:11 +02:00
MutexIF * mutex = nullptr;
2020-06-30 21:22:26 +02:00
/** The class which actually owns the manager (and its datapool). */
2020-06-07 02:22:18 +02:00
OwnsLocalDataPoolIF* owner = nullptr;
2020-06-30 21:22:26 +02:00
/**
* @brief Queue used for communication, for example commands.
* Is also used to send messages. Can be set either in the constructor
* or in the initialize() function.
*/
2020-06-19 03:03:17 +02:00
MessageQueueIF* hkQueue = nullptr;
2020-06-30 21:22:26 +02:00
/**
* HK replies will always be a reply to the commander, but HK packet
* can be sent to another destination by specifying this message queue
* ID, for example to a dedicated housekeeping service implementation.
*/
MessageQueueId_t hkDestination = MessageQueueIF::NO_QUEUE;
2020-06-05 20:35:08 +02:00
2020-06-30 21:22:26 +02:00
/** Global IPC store is used to store all packets. */
2020-06-07 18:53:55 +02:00
StorageManagerIF* ipcStore = nullptr;
2020-06-05 20:35:08 +02:00
/**
* Get the pointer to the mutex. Can be used to lock the data pool
* eternally. Use with care and don't forget to unlock locked mutexes!
* For now, only friend classes can accss this function.
* @return
*/
MutexIF* getMutexHandle();
/**
* Read a variable by supplying its local pool ID and assign the pool
* entry to the supplied PoolEntry pointer. The type of the pool entry
* is deduced automatically. This call is not thread-safe!
* For now, only friend classes like LocalPoolVar may access this
* function.
* @tparam T Type of the pool entry
* @param localPoolId Pool ID of the variable to read
* @param poolVar [out] Corresponding pool entry will be assigned to the
* supplied pointer.
* @return
*/
2020-06-07 02:22:18 +02:00
template <class T> ReturnValue_t fetchPoolEntry(lp_id_t localPoolId,
PoolEntry<T> **poolEntry);
2020-06-05 20:35:08 +02:00
2020-06-07 02:22:18 +02:00
void setMinimalSamplingFrequency(float frequencySeconds);
2020-06-19 03:03:17 +02:00
ReturnValue_t serializeHkPacketIntoStore(store_address_t* storeId,
LocalDataSet* dataSet);
2020-05-17 01:17:11 +02:00
};
2020-06-07 02:22:18 +02:00
2020-05-17 01:17:11 +02:00
template<class T> inline
2020-06-07 02:22:18 +02:00
ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
2020-06-05 20:35:08 +02:00
PoolEntry<T> **poolEntry) {
2020-05-17 01:17:11 +02:00
auto poolIter = localDpMap.find(localPoolId);
if (poolIter == localDpMap.end()) {
2020-06-05 20:35:08 +02:00
sif::debug << "HousekeepingManager::fechPoolEntry:"
" Pool entry not found." << std::endl;
2020-06-19 03:03:17 +02:00
return POOL_ENTRY_NOT_FOUND;
2020-05-17 01:17:11 +02:00
}
2020-06-05 20:35:08 +02:00
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
if(*poolEntry == nullptr) {
sif::debug << "HousekeepingManager::fetchPoolEntry:"
" Pool entry not found." << std::endl;
2020-06-19 03:03:17 +02:00
return POOL_ENTRY_TYPE_CONFLICT;
2020-05-17 01:17:11 +02:00
}
return HasReturnvaluesIF::RETURN_OK;
}
2020-06-05 20:35:08 +02:00
2020-05-17 01:17:11 +02:00
#endif /* FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ */