From 2b63f1b3f3557ae05bdb55791d90e2febf8a17c8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 23 Aug 2020 21:00:25 +0200 Subject: [PATCH 1/5] New reporting mode --- datapoollocal/LocalDataPoolManager.cpp | 22 ++++------------------ datapoollocal/LocalDataPoolManager.h | 14 ++++++++++++-- devicehandlers/DeviceHandlerBase.cpp | 7 +------ devicehandlers/DeviceHandlerBase.h | 2 -- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index a437519e..1121ac7b 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -8,6 +8,8 @@ #include #include +object_id_t LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT; + LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse, bool appendValidityBuffer): appendValidityBuffer(appendValidityBuffer) { @@ -31,29 +33,13 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, } ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, - object_id_t hkDestination, uint8_t nonDiagInvlFactor) { + uint8_t nonDiagInvlFactor) { if(queueToUse == nullptr) { sif::error << "LocalDataPoolManager::initialize: Supplied queue " "invalid!" << std::endl; } hkQueue = queueToUse; - if(hkDestination == objects::NO_OBJECT) { - return initializeHousekeepingPoolEntriesOnce(); - } - - AcceptsHkPacketsIF* hkReceiver = - objectManager->get(hkDestination); - if(hkReceiver != nullptr) { - setHkPacketDestination(hkReceiver->getHkQueue()); - } - else { - sif::warning << "LocalDataPoolManager::initialize: Could not retrieve" - " queue ID from HK destination object ID. " << std::flush; - sif::warning << "Make sure it exists and the object impements " - "AcceptsHkPacketsIF!" << std::endl; - } - setNonDiagnosticIntervalFactor(nonDiagInvlFactor); diagnosticMinimumInterval = owner->getPeriodicOperationFrequency(); regularMinimumInterval = diagnosticMinimumInterval * nonDiagnosticIntervalFactor; @@ -228,7 +214,7 @@ ReturnValue_t LocalDataPoolManager::performHkOperation() { performPeriodicHkGeneration(receiver); break; } - case(ReportingType::ON_UPDATE): { + case(ReportingType::UPDATE_SNAPSHOT): { // check whether data has changed and send messages in case it has. break; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index a4113ffe..9403911b 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -15,8 +15,13 @@ #include +namespace Factory { +void setStaticFrameworkObjectIds(); +} + class LocalDataSetBase; + /** * @brief This class is the managing instance for local data pool. * @details @@ -40,6 +45,7 @@ class LocalDataPoolManager { template friend class LocalPoolVector; friend class LocalPoolDataSetBase; + friend void (Factory::setStaticFrameworkObjectIds)(); public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER; @@ -71,7 +77,7 @@ public: * @return */ ReturnValue_t initialize(MessageQueueIF* queueToUse, - object_id_t hkDestination, uint8_t nonDiagInvlFactor = 5); + uint8_t nonDiagInvlFactor = 5); /** * Non-Diagnostics packets usually have a lower minimum sampling frequency @@ -136,9 +142,10 @@ public: enum class ReportingType: uint8_t { // Periodic generation of HK packets. PERIODIC, + UPDATE_NOTIFICATION, // Notification will be sent out as message. // Data is accessed via shared data set or multiple local data sets. - ON_UPDATE, + UPDATE_SNAPSHOT, }; /* Copying forbidden */ @@ -157,6 +164,9 @@ private: dur_millis_t regularMinimumInterval = 0; dur_millis_t diagnosticMinimumInterval = 0; + /** Default receiver for periodic HK packets */ + static object_id_t defaultHkDestination; + /** The data pool manager will keep an internal map of HK receivers. */ struct HkReceiver { /** Different member of this union will be used depending on the diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 8d66411a..a3b861b5 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -19,7 +19,6 @@ object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; -object_id_t DeviceHandlerBase::defaultHkDestination = objects::NO_OBJECT; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, @@ -194,11 +193,7 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } - if(hkDestination == objects::NO_OBJECT) { - hkDestination = defaultHkDestination; - } - - result = hkManager.initialize(commandQueue, hkDestination); + result = hkManager.initialize(commandQueue); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 4aa54fd6..c3640e2f 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1043,8 +1043,6 @@ private: /** the object used to set power switches */ PowerSwitchIF *powerSwitcher = nullptr; - /** Cached for initialize() */ - static object_id_t defaultHkDestination; /** HK destination can also be set individually */ object_id_t hkDestination = objects::NO_OBJECT; From 687e124929f367f8009b517450e8f61322bb0613 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 23 Aug 2020 21:52:44 +0200 Subject: [PATCH 2/5] doc added --- datapoollocal/LocalDataPoolManager.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 9403911b..8700fd38 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -140,11 +140,12 @@ public: * full dataset updates. */ enum class ReportingType: uint8_t { - // Periodic generation of HK packets. + //! Periodic generation of HK packets. PERIODIC, + //! Update notification will be sent out as message. UPDATE_NOTIFICATION, - // Notification will be sent out as message. - // Data is accessed via shared data set or multiple local data sets. + //! Notification will be sent out as message and a snapshot of the + //! current data will be generated. UPDATE_SNAPSHOT, }; From a95bc6b293683e63c3070b5f2ce33a5e2b3f942f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 23 Aug 2020 22:33:22 +0200 Subject: [PATCH 3/5] sid cached now --- datapool/PoolDataSetBase.cpp | 3 --- datapoollocal/LocalDataSet.cpp | 32 +++++++------------------ datapoollocal/LocalDataSet.h | 5 ++-- datapoollocal/LocalPoolDataSetBase.cpp | 33 ++++++++++++++++---------- datapoollocal/LocalPoolDataSetBase.h | 16 ++++++------- datapoollocal/SharedLocalDataSet.cpp | 4 ++-- datapoollocal/SharedLocalDataSet.h | 2 +- datapoollocal/StaticLocalDataSet.h | 4 ++-- housekeeping/HousekeepingMessage.h | 4 ++++ 9 files changed, 47 insertions(+), 56 deletions(-) diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index f9a6f391..1acd3fd3 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -5,9 +5,6 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount): registeredVariables(registeredVariablesArray), maxFillCount(maxFillCount) { - for (uint8_t count = 0; count < maxFillCount; count++) { - registeredVariables[count] = nullptr; - } } PoolDataSetBase::~PoolDataSetBase() {} diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index fe9b7d59..f6f13313 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -5,32 +5,16 @@ #include #include -LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, - const size_t maxNumberOfVariables): - LocalPoolDataSetBase(hkOwner,poolVarList.data(), maxNumberOfVariables) { - poolVarList.reserve(maxNumberOfVariables); - poolVarList.resize(maxNumberOfVariables); - if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; - return; - } - hkManager = hkOwner->getHkManagerHandle(); +LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, uint32_t setId, + const size_t maxNumberOfVariables): poolVarList(maxNumberOfVariables), + LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables) { + this->setContainer(poolVarList.data()); } -LocalDataSet::LocalDataSet(object_id_t ownerId, - const size_t maxNumberOfVariables): - LocalPoolDataSetBase(ownerId, poolVarList.data(), maxNumberOfVariables) { - poolVarList.reserve(maxNumberOfVariables); - poolVarList.resize(maxNumberOfVariables); - HasLocalDataPoolIF* hkOwner = objectManager->get( - ownerId); - if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; - return; - } - hkManager = hkOwner->getHkManagerHandle(); +LocalDataSet::LocalDataSet(sid_t sid, const size_t maxNumberOfVariables): + LocalPoolDataSetBase(sid, nullptr, maxNumberOfVariables), + poolVarList(maxNumberOfVariables) { + this->setContainer(poolVarList.data()); } LocalDataSet::~LocalDataSet() {} diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index d306fae3..5641ebfb 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -5,8 +5,9 @@ class LocalDataSet: public LocalPoolDataSetBase { public: - LocalDataSet(HasLocalDataPoolIF* hkOwner, const size_t maxSize); - LocalDataSet(object_id_t owner, const size_t maxSize); + LocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId, + const size_t maxSize); + LocalDataSet(sid_t sid, const size_t maxSize); virtual~ LocalDataSet(); //! Copying forbidden for now. diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index cbf2eeef..8abdc0e3 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -6,7 +6,7 @@ #include LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, - PoolVariableIF** registeredVariablesArray, + uint32_t setId, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables): PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { if(hkOwner == nullptr) { @@ -15,20 +15,23 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, return; } hkManager = hkOwner->getHkManagerHandle(); + this->sid.objectId = hkOwner->getObjectId(); + this->sid.ownerSetId = setId; } -LocalPoolDataSetBase::LocalPoolDataSetBase(object_id_t ownerId, +LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables): PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { HasLocalDataPoolIF* hkOwner = objectManager->get( - ownerId); + sid.objectId); if(hkOwner == nullptr) { sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" << std::endl; return; } hkManager = hkOwner->getHkManagerHandle(); + this->sid = sid; } LocalPoolDataSetBase::~LocalPoolDataSetBase() { @@ -123,14 +126,6 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer, return HasReturnvaluesIF::RETURN_OK; } -void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const { - if(position > 7) { - sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; - return; - } - uint8_t shiftNumber = position + (7 - 2 * position); - *byte |= 1 << shiftNumber; -} size_t LocalPoolDataSetBase::getSerializedSize() const { if(withValidityBuffer) { @@ -170,9 +165,21 @@ ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size, } } -bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte, uint8_t position) const { +void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const { if(position > 7) { - sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; + sif::debug << "Pool Raw Access: Bit setting invalid position" + << std::endl; + return; + } + uint8_t shiftNumber = position + (7 - 2 * position); + *byte |= 1 << shiftNumber; +} + +bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte, + uint8_t position) const { + if(position > 7) { + sif::debug << "Pool Raw Access: Bit setting invalid position" + << std::endl; return false; } uint8_t shiftNumber = position + (7 - 2 * position); diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index 091670cf..bd127db4 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -30,28 +30,25 @@ class LocalDataPoolManager; * * @ingroup data_pool */ -// todo: make withValidityBuffer a member class LocalPoolDataSetBase: public PoolDataSetBase { public: /** * @brief Constructor for the creator of local pool data. - * The constructor simply sets the fill_count to zero and sets - * the state to "uninitialized". */ LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, - PoolVariableIF** registeredVariablesArray, + uint32_t setId, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables); /** * @brief Constructor for users of local pool data. The passed pool * owner should implement the HasHkPoolParametersIF. - * The constructor simply sets the fill_count to zero and sets - * the state to "uninitialized". * @details - * + * @param sid Unique identifier of dataset consisting of object ID and + * set ID. + * @param registeredVariablesArray + * @param maxNumberOfVariables */ - LocalPoolDataSetBase(object_id_t ownerId, - PoolVariableIF** registeredVariablesArray, + LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables); /** @@ -96,6 +93,7 @@ public: bool isValid() const override; protected: + sid_t sid; /** * If the valid state of a dataset is always relevant to the whole * data set we can use this flag. diff --git a/datapoollocal/SharedLocalDataSet.cpp b/datapoollocal/SharedLocalDataSet.cpp index d44d1eb3..73e0e1fb 100644 --- a/datapoollocal/SharedLocalDataSet.cpp +++ b/datapoollocal/SharedLocalDataSet.cpp @@ -1,8 +1,8 @@ #include "SharedLocalDataSet.h" -SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, object_id_t owner, +SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize): SystemObject(objectId), - LocalPoolDataSetBase(owner, nullptr, maxSize) { + LocalPoolDataSetBase(sid, nullptr, maxSize) { this->setContainer(poolVarVector.data()); datasetLock = MutexFactory::instance()->createMutex(); } diff --git a/datapoollocal/SharedLocalDataSet.h b/datapoollocal/SharedLocalDataSet.h index c5949e0a..f6748e4d 100644 --- a/datapoollocal/SharedLocalDataSet.h +++ b/datapoollocal/SharedLocalDataSet.h @@ -16,7 +16,7 @@ class SharedLocalDataSet: public SystemObject, public LocalPoolDataSetBase, public SharedDataSetIF { public: - SharedLocalDataSet(object_id_t objectId, object_id_t owner, + SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize); ReturnValue_t lockDataset(dur_millis_t mutexTimeout) override; ReturnValue_t unlockDataset() override; diff --git a/datapoollocal/StaticLocalDataSet.h b/datapoollocal/StaticLocalDataSet.h index 1819cc2d..b3e8422c 100644 --- a/datapoollocal/StaticLocalDataSet.h +++ b/datapoollocal/StaticLocalDataSet.h @@ -16,8 +16,8 @@ template class StaticLocalDataSet: public LocalPoolDataSetBase { public: - StaticLocalDataSet(object_id_t owner): - LocalPoolDataSetBase(owner, poolVarList.data(), NUM_VARIABLES) { + StaticLocalDataSet(sid_t sid): + LocalPoolDataSetBase(sid, poolVarList.data(), NUM_VARIABLES) { } private: diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index ff4b39f9..75b31505 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -12,6 +12,10 @@ union sid_t { std::numeric_limits::max(); sid_t(): raw(INVALID_ADDRESS) {} + sid_t(object_id_t objectId, uint32_t setId): + objectId(objectId), + ownerSetId(setId) {} + struct { object_id_t objectId ; /** From a5227115e5b0361ec33242453ae3435589033200 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 23 Aug 2020 23:24:48 +0200 Subject: [PATCH 4/5] first subscriptio nfunction written --- datapoollocal/LocalDataPoolManager.cpp | 157 ++++++++++++++----------- datapoollocal/LocalDataPoolManager.h | 27 ++--- 2 files changed, 100 insertions(+), 84 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 1121ac7b..a0f4337c 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -32,6 +32,8 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, hkQueue = queueToUse; } +LocalDataPoolManager::~LocalDataPoolManager() {} + ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, uint8_t nonDiagInvlFactor) { if(queueToUse == nullptr) { @@ -42,17 +44,11 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, setNonDiagnosticIntervalFactor(nonDiagInvlFactor); diagnosticMinimumInterval = owner->getPeriodicOperationFrequency(); - regularMinimumInterval = diagnosticMinimumInterval * nonDiagnosticIntervalFactor; + regularMinimumInterval = diagnosticMinimumInterval * + nonDiagnosticIntervalFactor; return initializeHousekeepingPoolEntriesOnce(); } -void LocalDataPoolManager::setHkPacketDestination( - MessageQueueId_t hkDestination) { - this->hkDestination = hkDestination; -} - -LocalDataPoolManager::~LocalDataPoolManager() {} - ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { if(not mapInitialized) { ReturnValue_t result = owner->initializePoolEntries(localPoolMap); @@ -66,6 +62,58 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t LocalDataPoolManager::performHkOperation() { + for(auto& hkReceiversIter: hkReceiversMap) { + HkReceiver* receiver = &hkReceiversIter.second; + if(not receiver->reportingEnabled) { + return HasReturnvaluesIF::RETURN_OK; + } + + switch(receiver->reportingType) { + case(ReportingType::PERIODIC): { + if(receiver->dataId.dataSetSid.notSet()) { + // Periodic packets shall only be generated from datasets. + continue; + } + performPeriodicHkGeneration(receiver); + break; + } + case(ReportingType::UPDATE_SNAPSHOT): { + // 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; +} + +ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, + bool enableReporting, float collectionInterval, bool isDiagnostics, + object_id_t packetDestination) { + AcceptsHkPacketsIF* hkReceiverObject = + objectManager->get(packetDestination); + if(hkReceiverObject == nullptr) { + sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:" + " Invalid receiver!"<< std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + + struct HkReceiver hkReceiver; + hkReceiver.dataId.dataSetSid = sid; + hkReceiver.reportingType = ReportingType::PERIODIC; + hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); + hkReceiver.reportingEnabled = enableReporting; + hkReceiver.hkParameter.collectionIntervalSeconds = collectionInterval; + hkReceiver.isDiagnostics = isDiagnostics; + hkReceiver.intervalCounter = 1; + + hkReceiversMap.emplace(packetDestination, hkReceiver); + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( CommandMessage* message) { Command_t command = message->getCommand(); @@ -106,46 +154,46 @@ const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } -ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, - float collectionInterval, MessageQueueId_t sendTo) { - LocalPoolDataSetBase* dataSetToSerialize = dynamic_cast( - owner->getDataSetHandle(sid)); +ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { + LocalPoolDataSetBase* dataSetToSerialize = + dynamic_cast(owner->getDataSetHandle(sid)); if(dataSetToSerialize == nullptr) { sif::warning << "HousekeepingManager::generateHousekeepingPacket:" " Set ID not found" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - store_address_t storeId; - HousekeepingPacketDownlink hkPacket(sid, collectionInterval, - dataSetToSerialize->getFillCount(), dataSetToSerialize); - ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } +// store_address_t storeId; +// HousekeepingPacketDownlink hkPacket(sid, collectionInterval, +// dataSetToSerialize->getFillCount(), dataSetToSerialize); +// ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId); +// if(result != HasReturnvaluesIF::RETURN_OK) { +// return result; +// } // and now we set a HK message and send it the HK packet destination. - CommandMessage hkMessage; - HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); - if(hkQueue == nullptr) { - return QUEUE_OR_DESTINATION_NOT_SET; - } +// CommandMessage hkMessage; +// HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); +// if(hkQueue == nullptr) { +// return QUEUE_OR_DESTINATION_NOT_SET; +// } +// +// if(sendTo != MessageQueueIF::NO_QUEUE) { +// result = hkQueue->sendMessage(sendTo, &hkMessage); +// } +// else { +// if(hkDestination == MessageQueueIF::NO_QUEUE) { +// sif::warning << "LocalDataPoolManager::generateHousekeepingPacket:" +// " Destination is not set properly!" << std::endl; +// return QUEUE_OR_DESTINATION_NOT_SET; +// } +// else { +// result = hkQueue->sendMessage(hkDestination, &hkMessage); +// } +// } - if(sendTo != MessageQueueIF::NO_QUEUE) { - result = hkQueue->sendMessage(sendTo, &hkMessage); - } - else { - if(hkDestination == MessageQueueIF::NO_QUEUE) { - sif::warning << "LocalDataPoolManager::generateHousekeepingPacket:" - " Destination is not set properly!" << std::endl; - return QUEUE_OR_DESTINATION_NOT_SET; - } - else { - result = hkQueue->sendMessage(hkDestination, &hkMessage); - } - } - - return result; +// return result; + return 0; } ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( @@ -198,40 +246,14 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor( } -ReturnValue_t LocalDataPoolManager::performHkOperation() { - for(auto& hkReceiversIter: hkReceiversMap) { - HkReceiver* receiver = &hkReceiversIter.second; - if(not receiver->reportingEnabled) { - return HasReturnvaluesIF::RETURN_OK; - } - switch(receiver->reportingType) { - case(ReportingType::PERIODIC): { - if(receiver->dataId.dataSetSid.notSet()) { - // Periodic packets shall only be generated from datasets. - continue; - } - performPeriodicHkGeneration(receiver); - break; - } - case(ReportingType::UPDATE_SNAPSHOT): { - // 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; -} void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) { if(receiver->intervalCounter >= intervalSecondsToInterval( receiver->isDiagnostics, receiver->hkParameter.collectionIntervalSeconds)) { ReturnValue_t result = generateHousekeepingPacket( - receiver->dataId.dataSetSid, receiver->destinationQueue); + receiver->dataId.dataSetSid /*, receiver->destinationQueue */); if(result != HasReturnvaluesIF::RETURN_OK) { // configuration error sif::debug << "LocalDataPoolManager::performHkOperation:" @@ -259,7 +281,8 @@ uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics, float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics, uint32_t collectionInterval) { if(isDiagnostics) { - return static_cast(collectionInterval * diagnosticMinimumInterval); + return static_cast(collectionInterval * + diagnosticMinimumInterval); } else { return static_cast(collectionInterval * regularMinimumInterval); diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 8700fd38..df2155ef 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -53,7 +53,6 @@ public: static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x1); static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x2); - //static constexpr ReturnValue_t SET_NOT_FOUND = MAKE_RETURN_CODE(0x3); /** * This constructor is used by a class which wants to implement @@ -79,6 +78,13 @@ public: ReturnValue_t initialize(MessageQueueIF* queueToUse, uint8_t nonDiagInvlFactor = 5); + /** + * @return + */ + ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting, + float collectionInterval, bool isDiagnostics, + object_id_t packetDestination = defaultHkDestination); + /** * Non-Diagnostics packets usually have a lower minimum sampling frequency * than diagnostic packets. @@ -96,20 +102,13 @@ public: * @return */ ReturnValue_t performHkOperation(); - /** - * 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); /** * Generate a housekeeping packet with a given SID. * @param sid * @return */ - ReturnValue_t generateHousekeepingPacket(sid_t sid, float collectionInterval, - MessageQueueId_t sendTo = MessageQueueIF::NO_QUEUE); + ReturnValue_t generateHousekeepingPacket(sid_t sid); ReturnValue_t generateSetStructurePacket(sid_t sid); ReturnValue_t handleHousekeepingMessage(CommandMessage* message); @@ -174,14 +173,15 @@ private: type of data the receiver is interested in (full datasets or single data variables. */ union DataId { + DataId(): dataSetSid() {} /** Will be initialized to INVALID_ADDRESS */ sid_t dataSetSid; lp_id_t localPoolId = HasLocalDataPoolIF::NO_POOL_ID; }; DataId dataId; - MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; ReportingType reportingType = ReportingType::PERIODIC; + MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; bool reportingEnabled = true; /** Different members of this union will be used depending on reporting type */ @@ -216,13 +216,6 @@ private: */ 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 hkDestination = MessageQueueIF::NO_QUEUE; - /** Global IPC store is used to store all packets. */ StorageManagerIF* ipcStore = nullptr; /** From 11ce3d025fc58fd4205ddc3ef4302ab5262f8c2b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 24 Aug 2020 22:08:27 +0200 Subject: [PATCH 5/5] srv3 received reply now --- datapoollocal/HasLocalDataPoolIF.h | 11 ++- datapoollocal/LocalDataPoolManager.cpp | 113 ++++++++++++---------- datapoollocal/LocalDataPoolManager.h | 12 ++- datapoollocal/LocalDataSet.cpp | 5 +- devicehandlers/DeviceHandlerBase.cpp | 39 +++++--- devicehandlers/DeviceHandlerBase.h | 17 ++-- housekeeping/HousekeepingPacketDownlink.h | 2 +- osal/FreeRTOS/FixedTimeslotTask.cpp | 12 ++- osal/FreeRTOS/FixedTimeslotTask.h | 2 +- osal/host/FixedTimeslotTask.cpp | 2 +- osal/host/FixedTimeslotTask.h | 2 +- osal/linux/FixedTimeslotTask.cpp | 2 +- osal/linux/FixedTimeslotTask.h | 2 +- osal/rtems/PollingTask.cpp | 2 +- osal/rtems/PollingTask.h | 2 +- tasks/FixedSequenceSlot.cpp | 13 +-- tasks/FixedSequenceSlot.h | 16 +-- tasks/FixedSlotSequence.cpp | 51 +++++----- tasks/FixedSlotSequence.h | 9 +- tasks/FixedTimeslotTaskIF.h | 8 +- 20 files changed, 193 insertions(+), 129 deletions(-) diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h index d923b391..9eb1c9f1 100644 --- a/datapoollocal/HasLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -48,9 +48,14 @@ public: /** Command queue for housekeeping messages. */ virtual MessageQueueId_t getCommandQueue() const = 0; - /** Is used by pool owner to initialize the pool map once */ - virtual ReturnValue_t initializePoolEntries( - LocalDataPool& localDataPoolMap) = 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; diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index a0f4337c..87a0a3cb 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -30,28 +30,41 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, } hkQueue = queueToUse; + + if(defaultHkDestination != objects::NO_OBJECT) { + AcceptsHkPacketsIF* hkPacketReceiver = + objectManager->get(defaultHkDestination); + if(hkPacketReceiver != nullptr) { + defaultHkDestinationId = hkPacketReceiver->getHkQueue(); + } + } } LocalDataPoolManager::~LocalDataPoolManager() {} -ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, - uint8_t nonDiagInvlFactor) { +ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { if(queueToUse == nullptr) { sif::error << "LocalDataPoolManager::initialize: Supplied queue " "invalid!" << std::endl; } hkQueue = queueToUse; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation( + uint8_t nonDiagInvlFactor) { setNonDiagnosticIntervalFactor(nonDiagInvlFactor); diagnosticMinimumInterval = owner->getPeriodicOperationFrequency(); regularMinimumInterval = diagnosticMinimumInterval * - nonDiagnosticIntervalFactor; + nonDiagnosticIntervalFactor; return initializeHousekeepingPoolEntriesOnce(); } ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { if(not mapInitialized) { - ReturnValue_t result = owner->initializePoolEntries(localPoolMap); + ReturnValue_t result = owner->initializeLocalDataPool(localPoolMap, + *this); if(result == HasReturnvaluesIF::RETURN_OK) { mapInitialized = true; } @@ -106,7 +119,16 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, hkReceiver.reportingType = ReportingType::PERIODIC; hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); hkReceiver.reportingEnabled = enableReporting; - hkReceiver.hkParameter.collectionIntervalSeconds = collectionInterval; + if(not isDiagnostics) { + hkReceiver.hkParameter.collectionIntervalTicks = + intervalSecondsToInterval(isDiagnostics, collectionInterval * + nonDiagnosticIntervalFactor); + } + else { + hkReceiver.hkParameter.collectionIntervalTicks = + intervalSecondsToInterval(isDiagnostics, collectionInterval); + } + hkReceiver.isDiagnostics = isDiagnostics; hkReceiver.intervalCounter = 1; @@ -154,54 +176,47 @@ const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } -ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { +ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, + float collectionInterval, MessageQueueId_t destination) { LocalPoolDataSetBase* dataSetToSerialize = dynamic_cast(owner->getDataSetHandle(sid)); if(dataSetToSerialize == nullptr) { sif::warning << "HousekeepingManager::generateHousekeepingPacket:" - " Set ID not found" << std::endl; + " Set ID not found or dataset not assigned!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - -// store_address_t storeId; -// HousekeepingPacketDownlink hkPacket(sid, collectionInterval, -// dataSetToSerialize->getFillCount(), dataSetToSerialize); -// ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId); -// if(result != HasReturnvaluesIF::RETURN_OK) { -// return result; -// } + sif::info << "hk gen called" << std::endl; + store_address_t storeId; + HousekeepingPacketDownlink hkPacket(sid, collectionInterval, + dataSetToSerialize->getFillCount(), dataSetToSerialize); + ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } // and now we set a HK message and send it the HK packet destination. -// CommandMessage hkMessage; -// HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); -// if(hkQueue == nullptr) { -// return QUEUE_OR_DESTINATION_NOT_SET; -// } -// -// if(sendTo != MessageQueueIF::NO_QUEUE) { -// result = hkQueue->sendMessage(sendTo, &hkMessage); -// } -// else { -// if(hkDestination == MessageQueueIF::NO_QUEUE) { -// sif::warning << "LocalDataPoolManager::generateHousekeepingPacket:" -// " Destination is not set properly!" << std::endl; -// return QUEUE_OR_DESTINATION_NOT_SET; -// } -// else { -// result = hkQueue->sendMessage(hkDestination, &hkMessage); -// } -// } + CommandMessage hkMessage; + HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); + if(hkQueue == nullptr) { + return QUEUE_OR_DESTINATION_NOT_SET; + } + if(destination == MessageQueueIF::NO_QUEUE) { + if(defaultHkDestinationId == MessageQueueIF::NO_QUEUE) { + // error, all destinations invalid + return HasReturnvaluesIF::RETURN_FAILED; + } + destination = defaultHkDestinationId; + } -// return result; - return 0; + return hkQueue->sendMessage(destination, &hkMessage); } ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( HousekeepingPacketDownlink& hkPacket, store_address_t *storeId) { uint8_t* dataPtr = nullptr; - size_t serializedSize = hkPacket.getSerializedSize(); - const size_t maxSize = serializedSize; + size_t serializedSize = 0; + const size_t maxSize = hkPacket.getSerializedSize(); ReturnValue_t result = ipcStore->getFreeElement(storeId, serializedSize, &dataPtr); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -246,20 +261,17 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor( } - - void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) { - if(receiver->intervalCounter >= intervalSecondsToInterval( - receiver->isDiagnostics, - receiver->hkParameter.collectionIntervalSeconds)) { + if(receiver->intervalCounter >= + receiver->hkParameter.collectionIntervalTicks) { ReturnValue_t result = generateHousekeepingPacket( - receiver->dataId.dataSetSid /*, receiver->destinationQueue */); + receiver->dataId.dataSetSid); 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; + << owner->getObjectId() << " Error generating " + << "HK packet" << std::setfill(' ') << std::endl; } receiver->intervalCounter = 1; } @@ -271,10 +283,12 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) { uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics, float collectionIntervalSeconds) { if(isDiagnostics) { - return std::ceil(collectionIntervalSeconds/diagnosticMinimumInterval); + return std::ceil(collectionIntervalSeconds * 1000 + /diagnosticMinimumInterval); } else { - return std::ceil(collectionIntervalSeconds/regularMinimumInterval); + return std::ceil(collectionIntervalSeconds * 1000 + /regularMinimumInterval); } } @@ -285,6 +299,7 @@ float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics, diagnosticMinimumInterval); } else { - return static_cast(collectionInterval * regularMinimumInterval); + return static_cast(collectionInterval * + regularMinimumInterval); } } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index df2155ef..c851978c 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -75,8 +75,9 @@ public: * @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc * @return */ - ReturnValue_t initialize(MessageQueueIF* queueToUse, - uint8_t nonDiagInvlFactor = 5); + ReturnValue_t initialize(MessageQueueIF* queueToUse); + + ReturnValue_t initializeAfterTaskCreation(uint8_t nonDiagInvlFactor = 5); /** * @return @@ -108,7 +109,9 @@ public: * @param sid * @return */ - ReturnValue_t generateHousekeepingPacket(sid_t sid); + ReturnValue_t generateHousekeepingPacket(sid_t sid, + float collectionInterval = 0, + MessageQueueId_t destination = MessageQueueIF::NO_QUEUE); ReturnValue_t generateSetStructurePacket(sid_t sid); ReturnValue_t handleHousekeepingMessage(CommandMessage* message); @@ -166,6 +169,7 @@ private: /** Default receiver for periodic HK packets */ static object_id_t defaultHkDestination; + MessageQueueId_t defaultHkDestinationId = MessageQueueIF::NO_QUEUE; /** The data pool manager will keep an internal map of HK receivers. */ struct HkReceiver { @@ -187,7 +191,7 @@ private: type */ union HkParameter { /** This parameter will be used for the PERIODIC type */ - float collectionIntervalSeconds = 0; + uint32_t collectionIntervalTicks = 0; /** This parameter will be used for the ON_UPDATE type */ bool hkDataChanged; }; diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index f6f13313..394a9abe 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -6,8 +6,9 @@ #include LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, uint32_t setId, - const size_t maxNumberOfVariables): poolVarList(maxNumberOfVariables), - LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables) { + const size_t maxNumberOfVariables): + LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables), + poolVarList(maxNumberOfVariables) { this->setContainer(poolVarList.data()); } diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index a3b861b5..0253d6a7 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -391,24 +391,28 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, - size_t replyLen, bool periodic, bool hasDifferentReplyId, - DeviceCommandId_t replyId) { + PoolDataSetIF* replyDataSet, size_t replyLen, bool periodic, + bool hasDifferentReplyId, DeviceCommandId_t replyId) { //No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand); if (hasDifferentReplyId) { - return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic); + return insertInReplyMap(replyId, maxDelayCycles, + replyDataSet, replyLen, periodic); } else { - return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic); + return insertInReplyMap(deviceCommand, maxDelayCycles, + replyDataSet, replyLen, periodic); } } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, - uint16_t maxDelayCycles, size_t replyLen, bool periodic) { + uint16_t maxDelayCycles, PoolDataSetIF* dataSet, + size_t replyLen, bool periodic) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; info.periodic = periodic; info.delayCycles = 0; info.replyLen = replyLen; + info.dataSet = dataSet; info.command = deviceCommandMap.end(); auto resultPair = deviceReplyMap.emplace(replyId, info); if (resultPair.second) { @@ -434,13 +438,12 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap( ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { - std::map::iterator iter = - deviceReplyMap.find(deviceReply); - if (iter == deviceReplyMap.end()) { + auto replyIter = deviceReplyMap.find(deviceReply); + if (replyIter == deviceReplyMap.end()) { triggerEvent(INVALID_DEVICE_COMMAND, deviceReply); return RETURN_FAILED; } else { - DeviceReplyInfo *info = &(iter->second); + DeviceReplyInfo *info = &(replyIter->second); if (maxDelayCycles != 0) { info->maxDelayCycles = maxDelayCycles; } @@ -450,6 +453,17 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep } } + +ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId, + PoolDataSetIF *dataSet) { + auto replyIter = deviceReplyMap.find(replyId); + if(replyIter == deviceReplyMap.end()) { + return HasReturnvaluesIF::RETURN_FAILED; + } + replyIter->second.dataSet = dataSet; + return HasReturnvaluesIF::RETURN_OK; +} + void DeviceHandlerBase::callChildStatemachine() { if (mode == _MODE_START_UP) { doStartUp(); @@ -1363,8 +1377,9 @@ void DeviceHandlerBase::debugInterface(uint8_t positionTracker, void DeviceHandlerBase::performOperationHook() { } -ReturnValue_t DeviceHandlerBase::initializePoolEntries( - LocalDataPool &localDataPoolMap) { +ReturnValue_t DeviceHandlerBase::initializeLocalDataPool( + LocalDataPool &localDataPoolMap, + LocalDataPoolManager& poolManager) { return RETURN_OK; } @@ -1379,6 +1394,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { if(executingTask != nullptr) { pstIntervalMs = executingTask->getPeriodMs(); } + this->hkManager.initializeAfterTaskCreation(); return HasReturnvaluesIF::RETURN_OK; } @@ -1399,3 +1415,4 @@ object_id_t DeviceHandlerBase::getObjectId() const { dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { return pstIntervalMs; } + diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index c3640e2f..5357148e 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -387,7 +387,8 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false, + uint16_t maxDelayCycles, PoolDataSetIF* replyDataSet = nullptr, + size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); /** @@ -401,7 +402,8 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false); + uint16_t maxDelayCycles, PoolDataSetIF* dataSet = nullptr, + size_t replyLen = 0, bool periodic = false); /** * @brief A simple command to add a command to the commandList. @@ -429,6 +431,9 @@ protected: uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic = false); + ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, + PoolDataSetIF* dataset); + /** * @brief Can be implemented by child handler to * perform debugging @@ -482,8 +487,8 @@ protected: * @param localDataPoolMap * @return */ - virtual ReturnValue_t initializePoolEntries( - LocalDataPool& localDataPoolMap) override; + virtual ReturnValue_t initializeLocalDataPool(LocalDataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; /** Get the HK manager object handle */ virtual LocalDataPoolManager* getHkManagerHandle() override; @@ -656,7 +661,7 @@ protected: //! The dataset used to access housekeeping data related to the //! respective device reply. Will point to a dataset held by //! the child handler (if one is specified) - DataSetIF* dataSet = nullptr; + PoolDataSetIF* dataSet = nullptr; //! The command that expects this reply. DeviceCommandMap::iterator command; }; @@ -1197,7 +1202,7 @@ private: ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); virtual ReturnValue_t initializeAfterTaskCreation() override; - DataSetIF* getDataSetHandle(sid_t sid) override; + virtual DataSetIF* getDataSetHandle(sid_t sid) override; void parseReply(const uint8_t* receivedData, size_t receivedDataLen); diff --git a/housekeeping/HousekeepingPacketDownlink.h b/housekeeping/HousekeepingPacketDownlink.h index 97b6a994..bee0bac1 100644 --- a/housekeeping/HousekeepingPacketDownlink.h +++ b/housekeeping/HousekeepingPacketDownlink.h @@ -25,7 +25,7 @@ public: /** * Helper functions which can be used to move HK data from the IPC store - * to the telemetry store. + * to the telemetry store. TODO: maybe not needed. * @param formerStore * @param storeId * @param newStore diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 769f31e1..a112092f 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -8,7 +8,7 @@ const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE; FixedTimeslotTask::FixedTimeslotTask(TaskName name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod overallPeriod, void (*setDeadlineMissedFunc)()) : - started(false), handle(NULL), pst(overallPeriod * 1000) { + started(false), handle(nullptr), pst(overallPeriod * 1000) { configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE); xTaskCreate(taskEntryPoint, name, stackSize, this, setPriority, &handle); // All additional attributes are applied to the object. @@ -62,8 +62,10 @@ ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { - if (objectManager->get(componentId) != nullptr) { - pst.addSlot(componentId, slotTimeMs, executionStep, this); + ExecutableObjectIF* handler = + objectManager->get(componentId); + if (handler != nullptr) { + pst.addSlot(componentId, slotTimeMs, executionStep, handler, this); return HasReturnvaluesIF::RETURN_OK; } @@ -76,8 +78,8 @@ uint32_t FixedTimeslotTask::getPeriodMs() const { return pst.getLengthMs(); } -ReturnValue_t FixedTimeslotTask::checkSequence() const { - return pst.checkSequence(); +ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const { + return pst.checkAndInitializeSequence(); } void FixedTimeslotTask::taskFunctionality() { diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 42af14b8..0e9611d2 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -54,7 +54,7 @@ public: uint32_t getPeriodMs() const override; - ReturnValue_t checkSequence() const override; + ReturnValue_t checkAndInitializeSequence() const override; ReturnValue_t sleepFor(uint32_t ms) override; diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 1999c9e6..2bb0f84d 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -132,7 +132,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() const { +ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const { return pollingSeqTable.checkSequence(); } diff --git a/osal/host/FixedTimeslotTask.h b/osal/host/FixedTimeslotTask.h index bbee94a6..861a072e 100644 --- a/osal/host/FixedTimeslotTask.h +++ b/osal/host/FixedTimeslotTask.h @@ -61,7 +61,7 @@ public: ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); - ReturnValue_t checkSequence() const; + ReturnValue_t checkAndInitializeSequence() const; uint32_t getPeriodMs() const; diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index 60ce9a63..c381bb78 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -49,7 +49,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() const { +ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const { return pst.checkSequence(); } diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 83bf203e..f7b6e954 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -33,7 +33,7 @@ public: virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); - virtual ReturnValue_t checkSequence() const; + virtual ReturnValue_t checkAndInitializeSequence() const; /** * This static function can be used as #deadlineMissedFunc. diff --git a/osal/rtems/PollingTask.cpp b/osal/rtems/PollingTask.cpp index 527df367..b53d6a5a 100644 --- a/osal/rtems/PollingTask.cpp +++ b/osal/rtems/PollingTask.cpp @@ -82,7 +82,7 @@ uint32_t PollingTask::getPeriodMs() const { return pst.getLengthMs(); } -ReturnValue_t PollingTask::checkSequence() const { +ReturnValue_t PollingTask::checkAndInitializeSequence() const { return pst.checkSequence(); } diff --git a/osal/rtems/PollingTask.h b/osal/rtems/PollingTask.h index 759ed43d..60ce0816 100644 --- a/osal/rtems/PollingTask.h +++ b/osal/rtems/PollingTask.h @@ -42,7 +42,7 @@ class PollingTask: public TaskBase, public FixedTimeslotTaskIF { uint32_t getPeriodMs() const; - ReturnValue_t checkSequence() const; + ReturnValue_t checkAndInitializeSequence() const; ReturnValue_t sleepFor(uint32_t ms); protected: diff --git a/tasks/FixedSequenceSlot.cpp b/tasks/FixedSequenceSlot.cpp index cccc6371..9d290d19 100644 --- a/tasks/FixedSequenceSlot.cpp +++ b/tasks/FixedSequenceSlot.cpp @@ -3,13 +3,14 @@ #include FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, - int8_t setSequenceId, PeriodicTaskIF* executingTask) : + int8_t setSequenceId, ExecutableObjectIF* executableObject, + PeriodicTaskIF* executingTask) : pollingTimeMs(setTime), opcode(setSequenceId) { - handler = objectManager->get(handlerId); - if(executingTask != nullptr) { - handler->setTaskIF(executingTask); - } - handler->initializeAfterTaskCreation(); + if(executableObject == nullptr) { + return; + } + this->executableObject = executableObject; + this->executableObject->setTaskIF(executingTask); } FixedSequenceSlot::~FixedSequenceSlot() {} diff --git a/tasks/FixedSequenceSlot.h b/tasks/FixedSequenceSlot.h index e33134de..9cf5894c 100644 --- a/tasks/FixedSequenceSlot.h +++ b/tasks/FixedSequenceSlot.h @@ -16,21 +16,23 @@ class PeriodicTaskIF; class FixedSequenceSlot { public: FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, - int8_t setSequenceId, PeriodicTaskIF* executingTask ); + int8_t setSequenceId, ExecutableObjectIF* executableObject, + PeriodicTaskIF* executingTask); virtual ~FixedSequenceSlot(); /** - * @brief Handler identifies which device handler object is executed in this slot. + * @brief Handler identifies which object is executed in this slot. */ - ExecutableObjectIF* handler = nullptr; + ExecutableObjectIF* executableObject = nullptr; /** * @brief This attribute defines when a device handler object is executed. - * - * @details The pollingTime attribute identifies the time the handler is executed in ms. - * It must be smaller than the period length of the polling sequence. + * @details + * The pollingTime attribute identifies the time the handler is + * executed in ms. It must be smaller than the period length of the + * polling sequence. */ - uint32_t pollingTimeMs; + uint32_t pollingTimeMs; /** * @brief This value defines the type of device communication. diff --git a/tasks/FixedSlotSequence.cpp b/tasks/FixedSlotSequence.cpp index 27dfff2b..e51762ea 100644 --- a/tasks/FixedSlotSequence.cpp +++ b/tasks/FixedSlotSequence.cpp @@ -13,7 +13,7 @@ FixedSlotSequence::~FixedSlotSequence() { } void FixedSlotSequence::executeAndAdvance() { - current->handler->performOperation(current->opcode); + current->executableObject->performOperation(current->opcode); // if (returnValue != RETURN_OK) { // this->sendErrorMessage( returnValue ); // } @@ -81,34 +81,38 @@ uint32_t FixedSlotSequence::getLengthMs() const { return this->lengthMs; } -ReturnValue_t FixedSlotSequence::checkSequence() const { +ReturnValue_t FixedSlotSequence::checkAndInitializeSequence() const { if(slotList.empty()) { sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - auto slotIt = slotList.begin(); + std::set uniqueObjects; uint32_t count = 0; uint32_t time = 0; - while (slotIt != slotList.end()) { - if (slotIt->handler == nullptr) { - sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!" - << std::endl; + for(const auto& slot: slotList) { + if (slot.executableObject == nullptr) { count++; - } else if (slotIt->pollingTimeMs < time) { - sif::error << "FixedSlotSequence::initialize: Time: " - << slotIt->pollingTimeMs - << " is smaller than previous with " << time << std::endl; - count++; - } else { - // All ok, print slot. - //info << "Current slot polling time: " << std::endl; - //info << std::dec << slotIt->pollingTimeMs << std::endl; } - time = slotIt->pollingTimeMs; - slotIt++; + else if (slot.pollingTimeMs < time) { + sif::error << "FixedSlotSequence::initialize: Time: " + << slot.pollingTimeMs << " is smaller than previous with " + << time << std::endl; + count++; + } + else { + // All ok, print slot. + //sif::info << "Current slot polling time: " << std::endl; + //sif::info << std::dec << slotIt->pollingTimeMs << std::endl; + } + time = slot.pollingTimeMs; + // Ensure that each unique object is initialized once. + if(uniqueObjects.find(slot.executableObject) == uniqueObjects.end()) { + slot.executableObject->initializeAfterTaskCreation(); + uniqueObjects.emplace(slot.executableObject); + } } - //info << "Number of elements in slot list: " + //sif::info << "Number of elements in slot list: " // << slotList.size() << std::endl; if (count > 0) { return HasReturnvaluesIF::RETURN_FAILED; @@ -117,8 +121,9 @@ ReturnValue_t FixedSlotSequence::checkSequence() const { } void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, - int8_t executionStep, PeriodicTaskIF* executingTask) { - this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep, - executingTask)); - this->current = slotList.begin(); + int8_t executionStep, ExecutableObjectIF* executableObject, + PeriodicTaskIF* executingTask) { + this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, + executionStep, executableObject, executingTask)); + this->current = slotList.begin(); } diff --git a/tasks/FixedSlotSequence.h b/tasks/FixedSlotSequence.h index 67ce0094..1aa420ce 100644 --- a/tasks/FixedSlotSequence.h +++ b/tasks/FixedSlotSequence.h @@ -59,7 +59,7 @@ public: * @param */ void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, - PeriodicTaskIF* executingTask); + ExecutableObjectIF* executableObject, PeriodicTaskIF* executingTask); /** * Checks if the current slot shall be executed immediately after the one before. @@ -125,11 +125,14 @@ public: SlotListIter current; /** - * Iterate through slotList and check successful creation. + * @brief Check and initialize slot list. + * @details * Checks if timing is ok (must be ascending) and if all handlers were found. + * Also calls any initialization steps which are required after task + * creation. * @return */ - ReturnValue_t checkSequence() const; + ReturnValue_t checkAndInitializeSequence() const; protected: diff --git a/tasks/FixedTimeslotTaskIF.h b/tasks/FixedTimeslotTaskIF.h index 3456dae7..d3155490 100644 --- a/tasks/FixedTimeslotTaskIF.h +++ b/tasks/FixedTimeslotTaskIF.h @@ -22,8 +22,12 @@ public: */ virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) = 0; - /** Check whether the sequence is valid */ - virtual ReturnValue_t checkSequence() const = 0; + + /** + * Check whether the sequence is valid and perform all other required + * initialization steps which are needed after task creation + */ + virtual ReturnValue_t checkAndInitializeSequence() const = 0; }; #endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */