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);
|
|
|
|
|
|
|
|
static constexpr ReturnValue_t QUEUE_NOT_SET = MAKE_RETURN_CODE(0x2);
|
|
|
|
//static constexpr ReturnValue_t SET_NOT_FOUND = MAKE_RETURN_CODE(0x3);
|
2020-05-17 01:17:11 +02:00
|
|
|
|
2020-06-19 03:03:17 +02:00
|
|
|
LocalDataPoolManager(OwnsLocalDataPoolIF* owner,
|
|
|
|
uint32_t replyQueueDepth = 20, bool appendValidityBuffer = true);
|
2020-06-07 02:22:18 +02:00
|
|
|
virtual~ LocalDataPoolManager();
|
2020-05-17 01:17:11 +02:00
|
|
|
|
2020-06-07 18:53:55 +02:00
|
|
|
/* Copying forbidden */
|
|
|
|
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
|
|
|
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
2020-05-17 01:17:11 +02:00
|
|
|
|
2020-06-07 18:53:55 +02:00
|
|
|
ReturnValue_t generateHousekeepingPacket(sid_t sid);
|
2020-06-19 14:25:03 +02:00
|
|
|
ReturnValue_t generateSetStructurePacket(sid_t sid);
|
|
|
|
|
2020-06-13 17:37:48 +02:00
|
|
|
ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& 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 18:53:55 +02:00
|
|
|
//! Set the queue for HK packets, which are sent unrequested.
|
2020-06-19 03:03:17 +02:00
|
|
|
void setHkPacketDestination(MessageQueueId_t destinationQueueId);
|
2020-06-07 18:53:55 +02:00
|
|
|
|
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);
|
|
|
|
|
|
|
|
private:
|
2020-05-17 01:17:11 +02:00
|
|
|
//! This is the map holding the actual data. Should only be initialized
|
|
|
|
//! once !
|
|
|
|
bool mapInitialized = false;
|
2020-06-19 03:03:17 +02:00
|
|
|
//! This specifies whether a validity buffer is appended at the end
|
|
|
|
//! of generated housekeeping packets.
|
|
|
|
bool appendValidityBuffer = true;
|
|
|
|
|
2020-06-07 02:22:18 +02:00
|
|
|
LocalDataPool localDpMap;
|
2020-05-17 01:17:11 +02:00
|
|
|
|
|
|
|
//! Every housekeeping data manager has a mutex to protect access
|
|
|
|
//! to it's data pool.
|
|
|
|
MutexIF * mutex = nullptr;
|
|
|
|
|
|
|
|
//! The class which actually owns the manager (and its datapool).
|
2020-06-07 02:22:18 +02:00
|
|
|
OwnsLocalDataPoolIF* owner = nullptr;
|
2020-05-17 01:17:11 +02:00
|
|
|
|
2020-06-19 03:03:17 +02:00
|
|
|
//! Queue used for communication, for example commands.
|
|
|
|
//! Is also used to send messages.
|
|
|
|
MessageQueueIF* hkQueue = nullptr;
|
|
|
|
|
|
|
|
//! 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 currentHkPacketDestination = MessageQueueIF::NO_QUEUE;
|
2020-06-05 20:35:08 +02:00
|
|
|
|
2020-06-07 18:53:55 +02:00
|
|
|
//! Global IPC store is used to store all packets.
|
|
|
|
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_ */
|