continued with implementation

This commit is contained in:
Robin Müller 2020-08-08 19:43:28 +02:00
parent 121e94a385
commit e7d28d630c
6 changed files with 129 additions and 15 deletions

View File

@ -43,6 +43,8 @@ public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF; static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
static constexpr lp_id_t NO_POOL_ID = 0xffffffff; static constexpr lp_id_t NO_POOL_ID = 0xffffffff;
virtual object_id_t getObjectId() const = 0;
/** Command queue for housekeeping messages. */ /** Command queue for housekeeping messages. */
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;
@ -53,6 +55,13 @@ public:
/** Can be used to get a handle to the local data pool manager. */ /** Can be used to get a handle to the local data pool manager. */
virtual LocalDataPoolManager* getHkManagerHandle() = 0; virtual LocalDataPoolManager* getHkManagerHandle() = 0;
/**
* Returns the minimum sampling frequency, which will usually be the
* period the pool owner performs its periodic operation-
* @return
*/
virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
/** /**
* This function is used by the pool manager to get a valid dataset * This function is used by the pool manager to get a valid dataset
* from a SID * from a SID

View File

@ -6,6 +6,7 @@
#include <framework/ipc/QueueFactory.h> #include <framework/ipc/QueueFactory.h>
#include <array> #include <array>
#include <cmath>
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
MessageQueueIF* queueToUse, bool appendValidityBuffer): MessageQueueIF* queueToUse, bool appendValidityBuffer):
@ -25,11 +26,12 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
sif::error << "LocalDataPoolManager::LocalDataPoolManager: " sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
"Could not set IPC store." << std::endl; "Could not set IPC store." << std::endl;
} }
hkQueue = queueToUse; hkQueue = queueToUse;
} }
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse,
object_id_t hkDestination) { object_id_t hkDestination, uint8_t nonDiagInvlFactor) {
if(queueToUse == nullptr) { if(queueToUse == nullptr) {
sif::error << "LocalDataPoolManager::initialize: Supplied queue " sif::error << "LocalDataPoolManager::initialize: Supplied queue "
"invalid!" << std::endl; "invalid!" << std::endl;
@ -51,6 +53,10 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse,
sif::warning << "Make sure it exists and the object impements " sif::warning << "Make sure it exists and the object impements "
"AcceptsHkPacketsIF!" << std::endl; "AcceptsHkPacketsIF!" << std::endl;
} }
setNonDiagnosticIntervalFactor(nonDiagInvlFactor);
diagnosticMinimumInterval = owner->getPeriodicOperationFrequency();
regularMinimumInterval = diagnosticMinimumInterval * nonDiagnosticIntervalFactor;
return initializeHousekeepingPoolEntriesOnce(); return initializeHousekeepingPoolEntriesOnce();
} }
@ -182,7 +188,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
return result; return result;
} }
void LocalDataPoolManager::setMinimalSamplingFrequency(float frequencySeconds) { void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
uint8_t nonDiagInvlFactor) {
this->nonDiagnosticIntervalFactor = nonDiagInvlFactor;
} }
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
@ -214,5 +222,63 @@ ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
} }
ReturnValue_t LocalDataPoolManager::performHkOperation() { ReturnValue_t LocalDataPoolManager::performHkOperation() {
for(auto& hkReceiversIter: hkReceiversMap) {
HkReceiver* receiver = &hkReceiversIter.second;
switch(receiver->reportingType) {
case(ReportingType::PERIODIC): {
performPeriodicHkGeneration(receiver);
break;
}
case(ReportingType::ON_UPDATE): {
// check whether data has changed and send messages in case it has.
break;
}
default:
// This should never happen.
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) {
if(receiver->reportingEnabled) {
if(receiver->intervalCounter >= intervalSecondsToInterval(
receiver->isDiagnostics,
receiver->hkParameter.collectionInterval)) {
ReturnValue_t result = generateHousekeepingPacket(
receiver->dataSetSid, receiver->destinationQueue);
if(result != HasReturnvaluesIF::RETURN_OK) {
// configuration error
sif::debug << "LocalDataPoolManager::performHkOperation:"
<< "0x" << std::setfill('0') << std::setw(8)
<< owner->getObjectId() << " Error generating "
<< "HK packet" << std::setfill(' ') << std::endl;
}
receiver->intervalCounter = 1;
}
else if(receiver->reportingEnabled){
receiver->intervalCounter++;
}
}
}
uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics,
float collectionIntervalSeconds) {
if(isDiagnostics) {
return std::ceil(collectionIntervalSeconds/diagnosticMinimumInterval);
}
else {
return std::ceil(collectionIntervalSeconds/regularMinimumInterval);
}
}
float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics,
uint32_t collectionInterval) {
if(isDiagnostics) {
return static_cast<float>(collectionInterval * diagnosticMinimumInterval);
}
else {
return static_cast<float>(collectionInterval * regularMinimumInterval);
}
}

View File

@ -66,10 +66,22 @@ public:
* Initializes the map by calling the map initialization function of the * Initializes the map by calling the map initialization function of the
* owner and assigns the queue to use. * owner and assigns the queue to use.
* @param queueToUse * @param queueToUse
* @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc
* @return * @return
*/ */
ReturnValue_t initialize(MessageQueueIF* queueToUse, ReturnValue_t initialize(MessageQueueIF* queueToUse,
object_id_t hkDestination); object_id_t hkDestination, uint8_t nonDiagInvlFactor = 5);
/**
* Non-Diagnostics packets usually have a lower minimum sampling frequency
* than diagnostic packets.
* A factor can be specified to determine the minimum sampling frequency
* for non-diagnostic packets. The minimum sampling frequency of the
* diagnostics packets,which is usually jusst the period of the
* performOperation calls, is multiplied with that factor.
* @param factor
*/
void setNonDiagnosticIntervalFactor(uint8_t nonDiagInvlFactor);
/** /**
* This should be called in the periodic handler of the owner. * This should be called in the periodic handler of the owner.
@ -144,29 +156,36 @@ public:
private: private:
LocalDataPool localPoolMap; LocalDataPool localPoolMap;
/** Every housekeeping data manager has a mutex to protect access //! Every housekeeping data manager has a mutex to protect access
* to it's data pool. */ //! to it's data pool.
MutexIF* mutex = nullptr; MutexIF* mutex = nullptr;
/** The class which actually owns the manager (and its datapool). */ /** The class which actually owns the manager (and its datapool). */
HasLocalDataPoolIF* owner = nullptr; HasLocalDataPoolIF* owner = nullptr;
/** uint8_t nonDiagnosticIntervalFactor = 0;
* The data pool manager will keep an internal map of HK receivers. dur_millis_t regularMinimumInterval = 0;
*/ dur_millis_t diagnosticMinimumInterval = 0;
/** The data pool manager will keep an internal map of HK receivers. */
struct HkReceiver { struct HkReceiver {
LocalPoolDataSetBase* dataSet = nullptr; sid_t dataSetSid;
//LocalPoolDataSetBase* dataSet = nullptr;
lp_id_t localPoolId = HasLocalDataPoolIF::NO_POOL_ID; lp_id_t localPoolId = HasLocalDataPoolIF::NO_POOL_ID;
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
ReportingType reportingType = ReportingType::PERIODIC; ReportingType reportingType = ReportingType::PERIODIC;
bool reportingStatus = true; bool reportingEnabled = true;
/** Different members of this union will be used depending on reporting /** Different members of this union will be used depending on reporting
* type */ * type */
union hkParameter { union HkParameter {
/** This parameter will be used for the PERIODIC type */ /** This parameter will be used for the PERIODIC type */
dur_seconds_t collectionInterval = 0; dur_seconds_t collectionInterval = 0;
/** This parameter will be used for the ON_UPDATE type */ /** This parameter will be used for the ON_UPDATE type */
bool hkDataChanged; bool hkDataChanged;
}; };
HkParameter hkParameter;
bool isDiagnostics;
//! General purpose counter which is used for periodic generation.
uint32_t intervalCounter;
}; };
/** Using a multimap as the same object might request multiple datasets */ /** Using a multimap as the same object might request multiple datasets */
@ -223,6 +242,13 @@ private:
void setMinimalSamplingFrequency(float frequencySeconds); void setMinimalSamplingFrequency(float frequencySeconds);
ReturnValue_t serializeHkPacketIntoStore(store_address_t* storeId, ReturnValue_t serializeHkPacketIntoStore(store_address_t* storeId,
LocalPoolDataSetBase* dataSet); LocalPoolDataSetBase* dataSet);
uint32_t intervalSecondsToInterval(bool isDiagnostics,
float collectionIntervalSeconds);
float intervalToIntervalSeconds(bool isDiagnostics,
uint32_t collectionInterval);
void performPeriodicHkGeneration(HkReceiver* hkReceiver);
}; };

View File

@ -82,6 +82,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
decrementDeviceReplyMap(); decrementDeviceReplyMap();
fdirInstance->checkForFailures(); fdirInstance->checkForFailures();
hkSwitcher.performOperation(); hkSwitcher.performOperation();
hkManager.performHkOperation();
performOperationHook(); performOperationHook();
} }
if (mode == MODE_OFF) { if (mode == MODE_OFF) {
@ -1395,3 +1396,11 @@ DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) {
return nullptr; return nullptr;
} }
} }
object_id_t DeviceHandlerBase::getObjectId() const {
return SystemObject::getObjectId();
}
dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
return pstIntervalMs;
}

View File

@ -493,7 +493,11 @@ protected:
* performOperation(). Default implementation is empty. * performOperation(). Default implementation is empty.
*/ */
virtual void performOperationHook(); virtual void performOperationHook();
public: public:
/** Explicit interface implementation of getObjectId */
virtual object_id_t getObjectId() const override;
/** /**
* @param parentQueueId * @param parentQueueId
*/ */
@ -653,8 +657,6 @@ protected:
//! respective device reply. Will point to a dataset held by //! respective device reply. Will point to a dataset held by
//! the child handler (if one is specified) //! the child handler (if one is specified)
DataSetIF* dataSet = nullptr; DataSetIF* dataSet = nullptr;
float collectionInterval = 0.0;
uint32_t intervalCounter = 0;
//! The command that expects this reply. //! The command that expects this reply.
DeviceCommandMap::iterator command; DeviceCommandMap::iterator command;
}; };
@ -1201,6 +1203,8 @@ private:
void parseReply(const uint8_t* receivedData, void parseReply(const uint8_t* receivedData,
size_t receivedDataLen); size_t receivedDataLen);
virtual dur_millis_t getPeriodicOperationFrequency() const override;
}; };
#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ #endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */

View File

@ -51,8 +51,8 @@ public:
* @brief On destruction, the object removes itself from the list. * @brief On destruction, the object removes itself from the list.
*/ */
virtual ~SystemObject(); virtual ~SystemObject();
object_id_t getObjectId() const; object_id_t getObjectId() const override;
virtual ReturnValue_t initialize(); virtual ReturnValue_t initialize() override;
virtual ReturnValue_t checkObjectConnections(); virtual ReturnValue_t checkObjectConnections();
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const; virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const;