From 11ce3d025fc58fd4205ddc3ef4302ab5262f8c2b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 24 Aug 2020 22:08:27 +0200 Subject: [PATCH] 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_ */