srv3 received reply now

This commit is contained in:
Robin Müller 2020-08-24 22:08:27 +02:00
parent a5227115e5
commit 11ce3d025f
20 changed files with 193 additions and 129 deletions

View File

@ -48,9 +48,14 @@ public:
/** Command queue for housekeeping messages. */ /** Command queue for housekeeping messages. */
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;
/** Is used by pool owner to initialize the pool map once */ /**
virtual ReturnValue_t initializePoolEntries( * Is used by pool owner to initialize the pool map once
LocalDataPool& localDataPoolMap) = 0; * 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. */ /** Can be used to get a handle to the local data pool manager. */
virtual LocalDataPoolManager* getHkManagerHandle() = 0; virtual LocalDataPoolManager* getHkManagerHandle() = 0;

View File

@ -30,28 +30,41 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
} }
hkQueue = queueToUse; hkQueue = queueToUse;
if(defaultHkDestination != objects::NO_OBJECT) {
AcceptsHkPacketsIF* hkPacketReceiver =
objectManager->get<AcceptsHkPacketsIF>(defaultHkDestination);
if(hkPacketReceiver != nullptr) {
defaultHkDestinationId = hkPacketReceiver->getHkQueue();
}
}
} }
LocalDataPoolManager::~LocalDataPoolManager() {} LocalDataPoolManager::~LocalDataPoolManager() {}
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
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;
} }
hkQueue = queueToUse; hkQueue = queueToUse;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation(
uint8_t nonDiagInvlFactor) {
setNonDiagnosticIntervalFactor(nonDiagInvlFactor); setNonDiagnosticIntervalFactor(nonDiagInvlFactor);
diagnosticMinimumInterval = owner->getPeriodicOperationFrequency(); diagnosticMinimumInterval = owner->getPeriodicOperationFrequency();
regularMinimumInterval = diagnosticMinimumInterval * regularMinimumInterval = diagnosticMinimumInterval *
nonDiagnosticIntervalFactor; nonDiagnosticIntervalFactor;
return initializeHousekeepingPoolEntriesOnce(); return initializeHousekeepingPoolEntriesOnce();
} }
ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
if(not mapInitialized) { if(not mapInitialized) {
ReturnValue_t result = owner->initializePoolEntries(localPoolMap); ReturnValue_t result = owner->initializeLocalDataPool(localPoolMap,
*this);
if(result == HasReturnvaluesIF::RETURN_OK) { if(result == HasReturnvaluesIF::RETURN_OK) {
mapInitialized = true; mapInitialized = true;
} }
@ -106,7 +119,16 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
hkReceiver.reportingType = ReportingType::PERIODIC; hkReceiver.reportingType = ReportingType::PERIODIC;
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
hkReceiver.reportingEnabled = enableReporting; 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.isDiagnostics = isDiagnostics;
hkReceiver.intervalCounter = 1; hkReceiver.intervalCounter = 1;
@ -154,54 +176,47 @@ const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
return owner; return owner;
} }
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
float collectionInterval, MessageQueueId_t destination) {
LocalPoolDataSetBase* dataSetToSerialize = LocalPoolDataSetBase* dataSetToSerialize =
dynamic_cast<LocalPoolDataSetBase*>(owner->getDataSetHandle(sid)); dynamic_cast<LocalPoolDataSetBase*>(owner->getDataSetHandle(sid));
if(dataSetToSerialize == nullptr) { if(dataSetToSerialize == nullptr) {
sif::warning << "HousekeepingManager::generateHousekeepingPacket:" sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
" Set ID not found" << std::endl; " Set ID not found or dataset not assigned!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
sif::info << "hk gen called" << std::endl;
// store_address_t storeId; store_address_t storeId;
// HousekeepingPacketDownlink hkPacket(sid, collectionInterval, HousekeepingPacketDownlink hkPacket(sid, collectionInterval,
// dataSetToSerialize->getFillCount(), dataSetToSerialize); dataSetToSerialize->getFillCount(), dataSetToSerialize);
// ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId); ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId);
// if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
// return result; return result;
// } }
// and now we set a HK message and send it the HK packet destination. // and now we set a HK message and send it the HK packet destination.
// CommandMessage hkMessage; CommandMessage hkMessage;
// HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId);
// if(hkQueue == nullptr) { if(hkQueue == nullptr) {
// return QUEUE_OR_DESTINATION_NOT_SET; return QUEUE_OR_DESTINATION_NOT_SET;
// } }
// if(destination == MessageQueueIF::NO_QUEUE) {
// if(sendTo != MessageQueueIF::NO_QUEUE) { if(defaultHkDestinationId == MessageQueueIF::NO_QUEUE) {
// result = hkQueue->sendMessage(sendTo, &hkMessage); // error, all destinations invalid
// } return HasReturnvaluesIF::RETURN_FAILED;
// else { }
// if(hkDestination == MessageQueueIF::NO_QUEUE) { destination = defaultHkDestinationId;
// 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 hkQueue->sendMessage(destination, &hkMessage);
return 0;
} }
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
HousekeepingPacketDownlink& hkPacket, HousekeepingPacketDownlink& hkPacket,
store_address_t *storeId) { store_address_t *storeId) {
uint8_t* dataPtr = nullptr; uint8_t* dataPtr = nullptr;
size_t serializedSize = hkPacket.getSerializedSize(); size_t serializedSize = 0;
const size_t maxSize = serializedSize; const size_t maxSize = hkPacket.getSerializedSize();
ReturnValue_t result = ipcStore->getFreeElement(storeId, ReturnValue_t result = ipcStore->getFreeElement(storeId,
serializedSize, &dataPtr); serializedSize, &dataPtr);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
@ -246,20 +261,17 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
} }
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) { void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) {
if(receiver->intervalCounter >= intervalSecondsToInterval( if(receiver->intervalCounter >=
receiver->isDiagnostics, receiver->hkParameter.collectionIntervalTicks) {
receiver->hkParameter.collectionIntervalSeconds)) {
ReturnValue_t result = generateHousekeepingPacket( ReturnValue_t result = generateHousekeepingPacket(
receiver->dataId.dataSetSid /*, receiver->destinationQueue */); receiver->dataId.dataSetSid);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
// configuration error // configuration error
sif::debug << "LocalDataPoolManager::performHkOperation:" sif::debug << "LocalDataPoolManager::performHkOperation:"
<< "0x" << std::setfill('0') << std::setw(8) << "0x" << std::setfill('0') << std::setw(8)
<< owner->getObjectId() << " Error generating " << owner->getObjectId() << " Error generating "
<< "HK packet" << std::setfill(' ') << std::endl; << "HK packet" << std::setfill(' ') << std::endl;
} }
receiver->intervalCounter = 1; receiver->intervalCounter = 1;
} }
@ -271,10 +283,12 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) {
uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics, uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics,
float collectionIntervalSeconds) { float collectionIntervalSeconds) {
if(isDiagnostics) { if(isDiagnostics) {
return std::ceil(collectionIntervalSeconds/diagnosticMinimumInterval); return std::ceil(collectionIntervalSeconds * 1000
/diagnosticMinimumInterval);
} }
else { else {
return std::ceil(collectionIntervalSeconds/regularMinimumInterval); return std::ceil(collectionIntervalSeconds * 1000
/regularMinimumInterval);
} }
} }
@ -285,6 +299,7 @@ float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics,
diagnosticMinimumInterval); diagnosticMinimumInterval);
} }
else { else {
return static_cast<float>(collectionInterval * regularMinimumInterval); return static_cast<float>(collectionInterval *
regularMinimumInterval);
} }
} }

View File

@ -75,8 +75,9 @@ public:
* @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc * @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc
* @return * @return
*/ */
ReturnValue_t initialize(MessageQueueIF* queueToUse, ReturnValue_t initialize(MessageQueueIF* queueToUse);
uint8_t nonDiagInvlFactor = 5);
ReturnValue_t initializeAfterTaskCreation(uint8_t nonDiagInvlFactor = 5);
/** /**
* @return * @return
@ -108,7 +109,9 @@ public:
* @param sid * @param sid
* @return * @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 generateSetStructurePacket(sid_t sid);
ReturnValue_t handleHousekeepingMessage(CommandMessage* message); ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
@ -166,6 +169,7 @@ private:
/** Default receiver for periodic HK packets */ /** Default receiver for periodic HK packets */
static object_id_t defaultHkDestination; static object_id_t defaultHkDestination;
MessageQueueId_t defaultHkDestinationId = MessageQueueIF::NO_QUEUE;
/** The data pool manager will keep an internal map of HK receivers. */ /** The data pool manager will keep an internal map of HK receivers. */
struct HkReceiver { struct HkReceiver {
@ -187,7 +191,7 @@ private:
type */ type */
union HkParameter { union HkParameter {
/** This parameter will be used for the PERIODIC type */ /** 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 */ /** This parameter will be used for the ON_UPDATE type */
bool hkDataChanged; bool hkDataChanged;
}; };

View File

@ -6,8 +6,9 @@
#include <cstring> #include <cstring>
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, uint32_t setId, LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, uint32_t setId,
const size_t maxNumberOfVariables): poolVarList(maxNumberOfVariables), const size_t maxNumberOfVariables):
LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables) { LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables),
poolVarList(maxNumberOfVariables) {
this->setContainer(poolVarList.data()); this->setContainer(poolVarList.data());
} }

View File

@ -391,24 +391,28 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
size_t replyLen, bool periodic, bool hasDifferentReplyId, PoolDataSetIF* replyDataSet, size_t replyLen, bool periodic,
DeviceCommandId_t replyId) { bool hasDifferentReplyId, DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times. //No need to check, as we may try to insert multiple times.
insertInCommandMap(deviceCommand); insertInCommandMap(deviceCommand);
if (hasDifferentReplyId) { if (hasDifferentReplyId) {
return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic); return insertInReplyMap(replyId, maxDelayCycles,
replyDataSet, replyLen, periodic);
} else { } else {
return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic); return insertInReplyMap(deviceCommand, maxDelayCycles,
replyDataSet, replyLen, periodic);
} }
} }
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, 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; DeviceReplyInfo info;
info.maxDelayCycles = maxDelayCycles; info.maxDelayCycles = maxDelayCycles;
info.periodic = periodic; info.periodic = periodic;
info.delayCycles = 0; info.delayCycles = 0;
info.replyLen = replyLen; info.replyLen = replyLen;
info.dataSet = dataSet;
info.command = deviceCommandMap.end(); info.command = deviceCommandMap.end();
auto resultPair = deviceReplyMap.emplace(replyId, info); auto resultPair = deviceReplyMap.emplace(replyId, info);
if (resultPair.second) { if (resultPair.second) {
@ -434,13 +438,12 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) {
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter = auto replyIter = deviceReplyMap.find(deviceReply);
deviceReplyMap.find(deviceReply); if (replyIter == deviceReplyMap.end()) {
if (iter == deviceReplyMap.end()) {
triggerEvent(INVALID_DEVICE_COMMAND, deviceReply); triggerEvent(INVALID_DEVICE_COMMAND, deviceReply);
return RETURN_FAILED; return RETURN_FAILED;
} else { } else {
DeviceReplyInfo *info = &(iter->second); DeviceReplyInfo *info = &(replyIter->second);
if (maxDelayCycles != 0) { if (maxDelayCycles != 0) {
info->maxDelayCycles = maxDelayCycles; 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() { void DeviceHandlerBase::callChildStatemachine() {
if (mode == _MODE_START_UP) { if (mode == _MODE_START_UP) {
doStartUp(); doStartUp();
@ -1363,8 +1377,9 @@ void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
void DeviceHandlerBase::performOperationHook() { void DeviceHandlerBase::performOperationHook() {
} }
ReturnValue_t DeviceHandlerBase::initializePoolEntries( ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(
LocalDataPool &localDataPoolMap) { LocalDataPool &localDataPoolMap,
LocalDataPoolManager& poolManager) {
return RETURN_OK; return RETURN_OK;
} }
@ -1379,6 +1394,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
if(executingTask != nullptr) { if(executingTask != nullptr) {
pstIntervalMs = executingTask->getPeriodMs(); pstIntervalMs = executingTask->getPeriodMs();
} }
this->hkManager.initializeAfterTaskCreation();
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -1399,3 +1415,4 @@ object_id_t DeviceHandlerBase::getObjectId() const {
dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
return pstIntervalMs; return pstIntervalMs;
} }

View File

@ -387,7 +387,8 @@ protected:
* - @c RETURN_FAILED else. * - @c RETURN_FAILED else.
*/ */
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, 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); bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0);
/** /**
@ -401,7 +402,8 @@ protected:
* - @c RETURN_FAILED else. * - @c RETURN_FAILED else.
*/ */
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, 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. * @brief A simple command to add a command to the commandList.
@ -429,6 +431,9 @@ protected:
uint16_t delayCycles, uint16_t maxDelayCycles, uint16_t delayCycles, uint16_t maxDelayCycles,
bool periodic = false); bool periodic = false);
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId,
PoolDataSetIF* dataset);
/** /**
* @brief Can be implemented by child handler to * @brief Can be implemented by child handler to
* perform debugging * perform debugging
@ -482,8 +487,8 @@ protected:
* @param localDataPoolMap * @param localDataPoolMap
* @return * @return
*/ */
virtual ReturnValue_t initializePoolEntries( virtual ReturnValue_t initializeLocalDataPool(LocalDataPool& localDataPoolMap,
LocalDataPool& localDataPoolMap) override; LocalDataPoolManager& poolManager) override;
/** Get the HK manager object handle */ /** Get the HK manager object handle */
virtual LocalDataPoolManager* getHkManagerHandle() override; virtual LocalDataPoolManager* getHkManagerHandle() override;
@ -656,7 +661,7 @@ protected:
//! The dataset used to access housekeeping data related to the //! The dataset used to access housekeeping data related to the
//! 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; PoolDataSetIF* dataSet = nullptr;
//! The command that expects this reply. //! The command that expects this reply.
DeviceCommandMap::iterator command; DeviceCommandMap::iterator command;
}; };
@ -1197,7 +1202,7 @@ private:
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
virtual ReturnValue_t initializeAfterTaskCreation() override; virtual ReturnValue_t initializeAfterTaskCreation() override;
DataSetIF* getDataSetHandle(sid_t sid) override; virtual DataSetIF* getDataSetHandle(sid_t sid) override;
void parseReply(const uint8_t* receivedData, void parseReply(const uint8_t* receivedData,
size_t receivedDataLen); size_t receivedDataLen);

View File

@ -25,7 +25,7 @@ public:
/** /**
* Helper functions which can be used to move HK data from the IPC store * 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 formerStore
* @param storeId * @param storeId
* @param newStore * @param newStore

View File

@ -8,7 +8,7 @@ const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
FixedTimeslotTask::FixedTimeslotTask(TaskName name, TaskPriority setPriority, FixedTimeslotTask::FixedTimeslotTask(TaskName name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod overallPeriod, TaskStackSize setStack, TaskPeriod overallPeriod,
void (*setDeadlineMissedFunc)()) : 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); configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE);
xTaskCreate(taskEntryPoint, name, stackSize, this, setPriority, &handle); xTaskCreate(taskEntryPoint, name, stackSize, this, setPriority, &handle);
// All additional attributes are applied to the object. // All additional attributes are applied to the object.
@ -62,8 +62,10 @@ ReturnValue_t FixedTimeslotTask::startTask() {
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) { uint32_t slotTimeMs, int8_t executionStep) {
if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) { ExecutableObjectIF* handler =
pst.addSlot(componentId, slotTimeMs, executionStep, this); objectManager->get<ExecutableObjectIF>(componentId);
if (handler != nullptr) {
pst.addSlot(componentId, slotTimeMs, executionStep, handler, this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -76,8 +78,8 @@ uint32_t FixedTimeslotTask::getPeriodMs() const {
return pst.getLengthMs(); return pst.getLengthMs();
} }
ReturnValue_t FixedTimeslotTask::checkSequence() const { ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const {
return pst.checkSequence(); return pst.checkAndInitializeSequence();
} }
void FixedTimeslotTask::taskFunctionality() { void FixedTimeslotTask::taskFunctionality() {

View File

@ -54,7 +54,7 @@ public:
uint32_t getPeriodMs() const override; uint32_t getPeriodMs() const override;
ReturnValue_t checkSequence() const override; ReturnValue_t checkAndInitializeSequence() const override;
ReturnValue_t sleepFor(uint32_t ms) override; ReturnValue_t sleepFor(uint32_t ms) override;

View File

@ -132,7 +132,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t FixedTimeslotTask::checkSequence() const { ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const {
return pollingSeqTable.checkSequence(); return pollingSeqTable.checkSequence();
} }

View File

@ -61,7 +61,7 @@ public:
ReturnValue_t addSlot(object_id_t componentId, ReturnValue_t addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep); uint32_t slotTimeMs, int8_t executionStep);
ReturnValue_t checkSequence() const; ReturnValue_t checkAndInitializeSequence() const;
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const;

View File

@ -49,7 +49,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t FixedTimeslotTask::checkSequence() const { ReturnValue_t FixedTimeslotTask::checkAndInitializeSequence() const {
return pst.checkSequence(); return pst.checkSequence();
} }

View File

@ -33,7 +33,7 @@ public:
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep); int8_t executionStep);
virtual ReturnValue_t checkSequence() const; virtual ReturnValue_t checkAndInitializeSequence() const;
/** /**
* This static function can be used as #deadlineMissedFunc. * This static function can be used as #deadlineMissedFunc.

View File

@ -82,7 +82,7 @@ uint32_t PollingTask::getPeriodMs() const {
return pst.getLengthMs(); return pst.getLengthMs();
} }
ReturnValue_t PollingTask::checkSequence() const { ReturnValue_t PollingTask::checkAndInitializeSequence() const {
return pst.checkSequence(); return pst.checkSequence();
} }

View File

@ -42,7 +42,7 @@ class PollingTask: public TaskBase, public FixedTimeslotTaskIF {
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const;
ReturnValue_t checkSequence() const; ReturnValue_t checkAndInitializeSequence() const;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms);
protected: protected:

View File

@ -3,13 +3,14 @@
#include <cstddef> #include <cstddef>
FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, 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) { pollingTimeMs(setTime), opcode(setSequenceId) {
handler = objectManager->get<ExecutableObjectIF>(handlerId); if(executableObject == nullptr) {
if(executingTask != nullptr) { return;
handler->setTaskIF(executingTask); }
} this->executableObject = executableObject;
handler->initializeAfterTaskCreation(); this->executableObject->setTaskIF(executingTask);
} }
FixedSequenceSlot::~FixedSequenceSlot() {} FixedSequenceSlot::~FixedSequenceSlot() {}

View File

@ -16,21 +16,23 @@ class PeriodicTaskIF;
class FixedSequenceSlot { class FixedSequenceSlot {
public: public:
FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs,
int8_t setSequenceId, PeriodicTaskIF* executingTask ); int8_t setSequenceId, ExecutableObjectIF* executableObject,
PeriodicTaskIF* executingTask);
virtual ~FixedSequenceSlot(); 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. * @brief This attribute defines when a device handler object is executed.
* * @details
* @details The pollingTime attribute identifies the time the handler is executed in ms. * The pollingTime attribute identifies the time the handler is
* It must be smaller than the period length of the polling sequence. * 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. * @brief This value defines the type of device communication.

View File

@ -13,7 +13,7 @@ FixedSlotSequence::~FixedSlotSequence() {
} }
void FixedSlotSequence::executeAndAdvance() { void FixedSlotSequence::executeAndAdvance() {
current->handler->performOperation(current->opcode); current->executableObject->performOperation(current->opcode);
// if (returnValue != RETURN_OK) { // if (returnValue != RETURN_OK) {
// this->sendErrorMessage( returnValue ); // this->sendErrorMessage( returnValue );
// } // }
@ -81,34 +81,38 @@ uint32_t FixedSlotSequence::getLengthMs() const {
return this->lengthMs; return this->lengthMs;
} }
ReturnValue_t FixedSlotSequence::checkSequence() const { ReturnValue_t FixedSlotSequence::checkAndInitializeSequence() const {
if(slotList.empty()) { if(slotList.empty()) {
sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
auto slotIt = slotList.begin(); std::set<ExecutableObjectIF*> uniqueObjects;
uint32_t count = 0; uint32_t count = 0;
uint32_t time = 0; uint32_t time = 0;
while (slotIt != slotList.end()) { for(const auto& slot: slotList) {
if (slotIt->handler == nullptr) { if (slot.executableObject == nullptr) {
sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!"
<< std::endl;
count++; 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; else if (slot.pollingTimeMs < time) {
slotIt++; 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; // << slotList.size() << std::endl;
if (count > 0) { if (count > 0) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
@ -117,8 +121,9 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
} }
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep, PeriodicTaskIF* executingTask) { int8_t executionStep, ExecutableObjectIF* executableObject,
this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep, PeriodicTaskIF* executingTask) {
executingTask)); this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs,
this->current = slotList.begin(); executionStep, executableObject, executingTask));
this->current = slotList.begin();
} }

View File

@ -59,7 +59,7 @@ public:
* @param * @param
*/ */
void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, 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. * Checks if the current slot shall be executed immediately after the one before.
@ -125,11 +125,14 @@ public:
SlotListIter current; 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. * 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 * @return
*/ */
ReturnValue_t checkSequence() const; ReturnValue_t checkAndInitializeSequence() const;
protected: protected:

View File

@ -22,8 +22,12 @@ public:
*/ */
virtual ReturnValue_t addSlot(object_id_t componentId, virtual ReturnValue_t addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) = 0; 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_ */ #endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */