renormalizing pull request step2

This commit is contained in:
Robin Müller 2020-09-04 13:52:54 +02:00
parent 5eaf6cfd1f
commit 04532b8f6b
4 changed files with 382 additions and 378 deletions

View File

@ -1,17 +1,17 @@
#include "FixedSequenceSlot.h" #include "../objectmanager/SystemObjectIF.h"
#include "../objectmanager/SystemObjectIF.h" #include "../tasks/FixedSequenceSlot.h"
#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, ExecutableObjectIF* executableObject, int8_t setSequenceId, ExecutableObjectIF* executableObject,
PeriodicTaskIF* executingTask) : PeriodicTaskIF* executingTask) : handlerId(handlerId),
pollingTimeMs(setTime), opcode(setSequenceId) { pollingTimeMs(setTime), opcode(setSequenceId) {
if(executableObject == nullptr) { if(executableObject == nullptr) {
return; return;
} }
this->executableObject = executableObject; this->executableObject = executableObject;
this->executableObject->setTaskIF(executingTask); this->executableObject->setTaskIF(executingTask);
} }
FixedSequenceSlot::~FixedSequenceSlot() {} FixedSequenceSlot::~FixedSequenceSlot() {}

View File

@ -1,57 +1,59 @@
#ifndef FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_ #ifndef FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_
#define FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_ #define FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_
#include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/ObjectManagerIF.h"
#include "../tasks/ExecutableObjectIF.h" #include "../tasks/ExecutableObjectIF.h"
class PeriodicTaskIF; class PeriodicTaskIF;
/** /**
* @brief This class is the representation of a single polling sequence * @brief This class is the representation of a single polling sequence
* table entry. * table entry.
* @details * @details
* The PollingSlot class is the representation of a single polling * The PollingSlot class is the representation of a single polling
* sequence table entry. * sequence table entry.
* @author baetz * @author baetz
*/ */
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, ExecutableObjectIF* executableObject, int8_t setSequenceId, ExecutableObjectIF* executableObject,
PeriodicTaskIF* executingTask); PeriodicTaskIF* executingTask);
virtual ~FixedSequenceSlot(); virtual ~FixedSequenceSlot();
/** object_id_t handlerId;
* @brief Handler identifies which object is executed in this slot.
*/ /**
ExecutableObjectIF* executableObject = nullptr; * @brief Handler identifies which object is executed in this slot.
*/
/** ExecutableObjectIF* executableObject = nullptr;
* @brief This attribute defines when a device handler object is executed.
* @details /**
* The pollingTime attribute identifies the time the handler is * @brief This attribute defines when a device handler object is executed.
* executed in ms. It must be smaller than the period length of the * @details
* polling sequence. * The pollingTime attribute identifies the time the handler is
*/ * executed in ms. It must be smaller than the period length of the
uint32_t pollingTimeMs; * polling sequence.
*/
/** uint32_t pollingTimeMs;
* @brief This value defines the type of device communication.
* /**
* @details The state of this value decides what communication routine is * @brief This value defines the type of device communication.
* called in the PST executable or the device handler object. *
*/ * @details The state of this value decides what communication routine is
uint8_t opcode; * called in the PST executable or the device handler object.
*/
/** uint8_t opcode;
* @brief Operator overload for the comparison operator to
* allow sorting by polling time. /**
* @param fixedSequenceSlot * @brief Operator overload for the comparison operator to
* @return * allow sorting by polling time.
*/ * @param fixedSequenceSlot
bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const { * @return
return pollingTimeMs < fixedSequenceSlot.pollingTimeMs; */
} bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const {
}; return pollingTimeMs < fixedSequenceSlot.pollingTimeMs;
}
};
#endif /* FIXEDSEQUENCESLOT_H_ */
#endif /* FIXEDSEQUENCESLOT_H_ */

View File

@ -1,147 +1,147 @@
#include "FixedSlotSequence.h" #include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../tasks/FixedSlotSequence.h"
#include <cstdlib> #include <cstdlib>
FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) :
lengthMs(setLengthMs) { lengthMs(setLengthMs) {
current = slotList.begin(); current = slotList.begin();
} }
FixedSlotSequence::~FixedSlotSequence() { FixedSlotSequence::~FixedSlotSequence() {
// Call the destructor on each list entry. // Call the destructor on each list entry.
slotList.clear(); slotList.clear();
} }
void FixedSlotSequence::executeAndAdvance() { void FixedSlotSequence::executeAndAdvance() {
current->executableObject->performOperation(current->opcode); current->executableObject->performOperation(current->opcode);
// if (returnValue != RETURN_OK) { // if (returnValue != RETURN_OK) {
// this->sendErrorMessage( returnValue ); // this->sendErrorMessage( returnValue );
// } // }
//Increment the polling Sequence iterator //Increment the polling Sequence iterator
this->current++; this->current++;
//Set it to the beginning, if the list's end is reached. //Set it to the beginning, if the list's end is reached.
if (this->current == this->slotList.end()) { if (this->current == this->slotList.end()) {
this->current = this->slotList.begin(); this->current = this->slotList.begin();
} }
} }
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() { uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
uint32_t oldTime; uint32_t oldTime;
SlotListIter slotListIter = current; SlotListIter slotListIter = current;
// Get the pollingTimeMs of the current slot object. // Get the pollingTimeMs of the current slot object.
oldTime = slotListIter->pollingTimeMs; oldTime = slotListIter->pollingTimeMs;
// Advance to the next object. // Advance to the next object.
slotListIter++; slotListIter++;
// Find the next interval which is not 0. // Find the next interval which is not 0.
while (slotListIter != slotList.end()) { while (slotListIter != slotList.end()) {
if (oldTime != slotListIter->pollingTimeMs) { if (oldTime != slotListIter->pollingTimeMs) {
return slotListIter->pollingTimeMs - oldTime; return slotListIter->pollingTimeMs - oldTime;
} else { } else {
slotListIter++; slotListIter++;
} }
} }
// If the list end is reached (this is definitely an interval != 0), // If the list end is reached (this is definitely an interval != 0),
// the interval is calculated by subtracting the remaining time of the PST // the interval is calculated by subtracting the remaining time of the PST
// and adding the start time of the first handler in the list. // and adding the start time of the first handler in the list.
slotListIter = slotList.begin(); slotListIter = slotList.begin();
return lengthMs - oldTime + slotListIter->pollingTimeMs; return lengthMs - oldTime + slotListIter->pollingTimeMs;
} }
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() { uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
uint32_t currentTime; uint32_t currentTime;
SlotListIter slotListIter = current; SlotListIter slotListIter = current;
// Get the pollingTimeMs of the current slot object. // Get the pollingTimeMs of the current slot object.
currentTime = slotListIter->pollingTimeMs; currentTime = slotListIter->pollingTimeMs;
//if it is the first slot, calculate difference to last slot //if it is the first slot, calculate difference to last slot
if (slotListIter == slotList.begin()){ if (slotListIter == slotList.begin()){
return lengthMs - (--slotList.end())->pollingTimeMs + currentTime; return lengthMs - (--slotList.end())->pollingTimeMs + currentTime;
} }
// get previous slot // get previous slot
slotListIter--; slotListIter--;
return currentTime - slotListIter->pollingTimeMs; return currentTime - slotListIter->pollingTimeMs;
} }
bool FixedSlotSequence::slotFollowsImmediately() { bool FixedSlotSequence::slotFollowsImmediately() {
uint32_t currentTime = current->pollingTimeMs; uint32_t currentTime = current->pollingTimeMs;
SlotListIter fixedSequenceIter = this->current; SlotListIter fixedSequenceIter = this->current;
// Get the pollingTimeMs of the current slot object. // Get the pollingTimeMs of the current slot object.
if (fixedSequenceIter == slotList.begin()) if (fixedSequenceIter == slotList.begin())
return false; return false;
fixedSequenceIter--; fixedSequenceIter--;
if (fixedSequenceIter->pollingTimeMs == currentTime) { if (fixedSequenceIter->pollingTimeMs == currentTime) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
uint32_t FixedSlotSequence::getLengthMs() const { uint32_t FixedSlotSequence::getLengthMs() const {
return this->lengthMs; return this->lengthMs;
} }
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep, ExecutableObjectIF* executableObject, int8_t executionStep, ExecutableObjectIF* executableObject,
PeriodicTaskIF* executingTask) { PeriodicTaskIF* executingTask) {
this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs,
executionStep, executableObject, executingTask)); executionStep, executableObject, executingTask));
this->current = slotList.begin(); this->current = slotList.begin();
} }
ReturnValue_t FixedSlotSequence::checkSequence() const { ReturnValue_t FixedSlotSequence::checkSequence() 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;
} }
uint32_t count = 0; uint32_t count = 0;
uint32_t time = 0; uint32_t time = 0;
for(const auto& slot: slotList) { for(const auto& slot: slotList) {
if (slot.executableObject == nullptr) { if (slot.executableObject == nullptr) {
count++; count++;
} }
else if (slot.pollingTimeMs < time) { else if (slot.pollingTimeMs < time) {
sif::error << "FixedSlotSequence::initialize: Time: " sif::error << "FixedSlotSequence::initialize: Time: "
<< slot.pollingTimeMs << " is smaller than previous with " << slot.pollingTimeMs << " is smaller than previous with "
<< time << std::endl; << time << std::endl;
count++; count++;
} }
else { else {
// All ok, print slot. // All ok, print slot.
//sif::info << "Current slot polling time: " << std::endl; //sif::info << "Current slot polling time: " << std::endl;
//sif::info << std::dec << slotIt->pollingTimeMs << std::endl; //sif::info << std::dec << slotIt->pollingTimeMs << std::endl;
} }
time = slot.pollingTimeMs; time = slot.pollingTimeMs;
} }
//sif::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;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const { ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const {
std::set<ExecutableObjectIF*> uniqueObjects; std::set<ExecutableObjectIF*> uniqueObjects;
uint32_t count = 0; uint32_t count = 0;
for(const auto& slot: slotList) { for(const auto& slot: slotList) {
// Ensure that each unique object is initialized once. // Ensure that each unique object is initialized once.
if(uniqueObjects.find(slot.executableObject) == uniqueObjects.end()) { if(uniqueObjects.find(slot.executableObject) == uniqueObjects.end()) {
ReturnValue_t result = ReturnValue_t result =
slot.executableObject->initializeAfterTaskCreation(); slot.executableObject->initializeAfterTaskCreation();
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
count++; count++;
} }
uniqueObjects.emplace(slot.executableObject); uniqueObjects.emplace(slot.executableObject);
} }
} }
if (count > 0) { if (count > 0) {
sif::error << "FixedSlotSequence::intializeSequenceAfterTaskCreation:" sif::error << "FixedSlotSequence::intializeSequenceAfterTaskCreation:"
"Counted " << count << " failed initializations!" << std::endl; "Counted " << count << " failed initializations!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -1,157 +1,159 @@
#ifndef FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_ #ifndef FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_
#define FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_ #define FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_
#include "FixedSequenceSlot.h" #include "../objectmanager/SystemObject.h"
#include "../objectmanager/SystemObject.h" #include "../tasks/FixedSequenceSlot.h"
#include <set> #include <set>
/** /**
* @brief This class is the representation of a Polling Sequence Table in software. * @brief This class is the representation of a Polling Sequence Table in software.
* @details * @details
* The FixedSlotSequence object maintains the dynamic execution of * The FixedSlotSequence object maintains the dynamic execution of
* device handler objects. * device handler objects.
* *
* The main idea is to create a list of device handlers, to announce all * The main idea is to create a list of device handlers, to announce all
* handlers to thepolling sequence and to maintain a list of * handlers to thepolling sequence and to maintain a list of
* polling slot objects. This slot list represents the Polling Sequence Table * polling slot objects. This slot list represents the Polling Sequence Table
* in software. * in software.
* *
* Each polling slot contains information to indicate when and * Each polling slot contains information to indicate when and
* which device handler shall be executed within a given polling period. * which device handler shall be executed within a given polling period.
* The sequence is then executed by iterating through this slot list. * The sequence is then executed by iterating through this slot list.
* Handlers are invoking by calling a certain function stored in the handler list. * Handlers are invoking by calling a certain function stored in the handler list.
*/ */
class FixedSlotSequence { class FixedSlotSequence {
public: public:
using SlotList = std::multiset<FixedSequenceSlot>; using SlotList = std::multiset<FixedSequenceSlot>;
using SlotListIter = std::multiset<FixedSequenceSlot>::iterator; using SlotListIter = std::multiset<FixedSequenceSlot>::iterator;
/** /**
* @brief The constructor of the FixedSlotSequence object. * @brief The constructor of the FixedSlotSequence object.
* *
* @details The constructor takes two arguments, the period length and the init function. * @details The constructor takes two arguments, the period length and the init function.
* *
* @param setLength The period length, expressed in ms. * @param setLength The period length, expressed in ms.
*/ */
FixedSlotSequence(uint32_t setLengthMs); FixedSlotSequence(uint32_t setLengthMs);
/** /**
* @brief The destructor of the FixedSlotSequence object. * @brief The destructor of the FixedSlotSequence object.
* *
* @details The destructor frees all allocated memory by iterating through the slotList * @details The destructor frees all allocated memory by iterating through the slotList
* and deleting all allocated resources. * and deleting all allocated resources.
*/ */
virtual ~FixedSlotSequence(); virtual ~FixedSlotSequence();
/** /**
* @brief This is a method to add an PollingSlot object to slotList. * @brief This is a method to add an PollingSlot object to slotList.
* *
* @details Here, a polling slot object is added to the slot list. It is appended * @details Here, a polling slot object is added to the slot list. It is appended
* to the end of the list. The list is currently NOT reordered. * to the end of the list. The list is currently NOT reordered.
* Afterwards, the iterator current is set to the beginning of the list. * Afterwards, the iterator current is set to the beginning of the list.
* @param Object ID of the object to add * @param Object ID of the object to add
* @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask * @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask
* will be called inside the slot period. * will be called inside the slot period.
* @param setSequenceId ID which can be used to distinguish * @param setSequenceId ID which can be used to distinguish
* different task operations * different task operations
* @param * @param
* @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,
ExecutableObjectIF* executableObject, 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.
* This allows to distinguish between grouped and not grouped handlers. * This allows to distinguish between grouped and not grouped handlers.
* @return - @c true if the slot has the same polling time as the previous * @return - @c true if the slot has the same polling time as the previous
* - @c false else * - @c false else
*/ */
bool slotFollowsImmediately(); bool slotFollowsImmediately();
/** /**
* @brief This method returns the time until the next software * @brief This method returns the time until the next software
* component is invoked. * component is invoked.
* *
* @details * @details
* This method is vitally important for the operation of the PST. * This method is vitally important for the operation of the PST.
* By fetching the polling time of the current slot and that of the * By fetching the polling time of the current slot and that of the
* next one (or the first one, if the list end is reached) * next one (or the first one, if the list end is reached)
* it calculates and returns the interval in milliseconds within * it calculates and returns the interval in milliseconds within
* which the handler execution shall take place. * which the handler execution shall take place.
* If the next slot has the same time as the current one, it is ignored * If the next slot has the same time as the current one, it is ignored
* until a slot with different time or the end of the PST is found. * until a slot with different time or the end of the PST is found.
*/ */
uint32_t getIntervalToNextSlotMs(); uint32_t getIntervalToNextSlotMs();
/** /**
* @brief This method returns the time difference between the current * @brief This method returns the time difference between the current
* slot and the previous slot * slot and the previous slot
* *
* @details * @details
* This method is vitally important for the operation of the PST. * This method is vitally important for the operation of the PST.
* By fetching the polling time of the current slot and that of the previous * By fetching the polling time of the current slot and that of the previous
* one (or the last one, if the slot is the first one) it calculates and * one (or the last one, if the slot is the first one) it calculates and
* returns the interval in milliseconds that the handler execution shall * returns the interval in milliseconds that the handler execution shall
* be delayed. * be delayed.
*/ */
uint32_t getIntervalToPreviousSlotMs(); uint32_t getIntervalToPreviousSlotMs();
/** /**
* @brief This method returns the length of this FixedSlotSequence instance. * @brief This method returns the length of this FixedSlotSequence instance.
*/ */
uint32_t getLengthMs() const; uint32_t getLengthMs() const;
/** /**
* @brief The method to execute the device handler entered in the current * @brief The method to execute the device handler entered in the current
* PollingSlot object. * PollingSlot object.
* *
* @details * @details
* Within this method the device handler object to be executed is chosen by * Within this method the device handler object to be executed is chosen by
* looking up the handler address of the current slot in the handlerMap. * looking up the handler address of the current slot in the handlerMap.
* Either the device handler's talkToInterface or its listenToInterface * Either the device handler's talkToInterface or its listenToInterface
* method is invoked, depending on the isTalking flag of the polling slot. * method is invoked, depending on the isTalking flag of the polling slot.
* After execution the iterator current is increased or, by reaching the * After execution the iterator current is increased or, by reaching the
* end of slotList, reset to the beginning. * end of slotList, reset to the beginning.
*/ */
void executeAndAdvance(); void executeAndAdvance();
/** /**
* @brief An iterator that indicates the current polling slot to execute. * @brief An iterator that indicates the current polling slot to execute.
* *
* @details This is an iterator for slotList and always points to the * @details This is an iterator for slotList and always points to the
* polling slot which is executed next. * polling slot which is executed next.
*/ */
SlotListIter current; SlotListIter current;
/** /**
* @brief Check and initialize slot list. * @brief Check and initialize slot list.
* @details * @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 * Also calls any initialization steps which are required after task
* creation. * creation.
* @return * @return
*/ */
ReturnValue_t checkSequence() const; ReturnValue_t checkSequence() const;
ReturnValue_t intializeSequenceAfterTaskCreation() const; ReturnValue_t intializeSequenceAfterTaskCreation() const;
protected: protected:
/** /**
* @brief This list contains all PollingSlot objects, defining order and * @brief This list contains all PollingSlot objects, defining order and
* execution time of the device handler objects. * execution time of the device handler objects.
* *
* @details * @details
* The slot list is a std:list object that contains all created * The slot list is a std:list object that contains all created
* PollingSlot instances. They are NOT ordered automatically, so by * PollingSlot instances. They are NOT ordered automatically, so by
* adding entries, the correct order needs to be ensured. By iterating * adding entries, the correct order needs to be ensured. By iterating
* through this list the polling sequence is executed. Two entries with * through this list the polling sequence is executed. Two entries with
* identical polling times are executed immediately one after another. * identical polling times are executed immediately one after another.
*/ */
SlotList slotList; SlotList slotList;
uint32_t lengthMs; uint32_t lengthMs;
};
bool isEmpty = false;
#endif /* FIXEDSLOTSEQUENCE_H_ */ };
#endif /* FIXEDSLOTSEQUENCE_H_ */