all fixed slot sequence improvenements #24
@ -16,6 +16,5 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime,
|
||||
handler->setTaskIF(executingTask);
|
||||
}
|
||||
|
||||
FixedSequenceSlot::~FixedSequenceSlot() {
|
||||
}
|
||||
FixedSequenceSlot::~FixedSequenceSlot() {}
|
||||
|
||||
|
@ -13,35 +13,47 @@
|
||||
class PeriodicTaskIF;
|
||||
|
||||
/**
|
||||
* \brief This class is the representation of a single polling sequence table entry.
|
||||
* @brief This class is the representation of a single polling sequence table entry.
|
||||
*
|
||||
* \details The PollingSlot class is the representation of a single polling sequence table entry.
|
||||
* @details The PollingSlot class is the representation of a single polling
|
||||
* sequence table entry.
|
||||
*/
|
||||
class FixedSequenceSlot {
|
||||
public:
|
||||
FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, int8_t setSequenceId, PeriodicTaskIF* executingTask );
|
||||
FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs,
|
||||
int8_t setSequenceId, PeriodicTaskIF* executingTask );
|
||||
virtual ~FixedSequenceSlot();
|
||||
|
||||
/**
|
||||
* \brief \c handler identifies which device handler object is executed in this slot.
|
||||
* @brief Handler identifies which device handler object is executed in this slot.
|
||||
*/
|
||||
ExecutableObjectIF* handler;
|
||||
|
||||
/**
|
||||
* \brief This attribute defines when a device handler object is executed.
|
||||
* @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, what is ensured by automated calculation
|
||||
* from a database.
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* \brief This value defines the type of device communication.
|
||||
* @brief This value defines the type of device communication.
|
||||
*
|
||||
* \details The state of this value decides what communication routine is called in the PST executable or the device handler object.
|
||||
* @details The state of this value decides what communication routine is
|
||||
* 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
|
||||
* @return
|
||||
*/
|
||||
bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const {
|
||||
return pollingTimeMs < fixedSequenceSlot.pollingTimeMs;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -7,17 +7,12 @@ FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) :
|
||||
}
|
||||
|
||||
FixedSlotSequence::~FixedSlotSequence() {
|
||||
std::list<FixedSequenceSlot*>::iterator slotIt;
|
||||
//Iterate through slotList and delete all entries.
|
||||
slotIt = this->slotList.begin();
|
||||
while (slotIt != this->slotList.end()) {
|
||||
delete (*slotIt);
|
||||
slotIt++;
|
||||
}
|
||||
// Call the destructor on each list entry.
|
||||
slotList.clear();
|
||||
}
|
||||
|
||||
void FixedSlotSequence::executeAndAdvance() {
|
||||
(*this->current)->handler->performOperation((*this->current)->opcode);
|
||||
current->handler->performOperation(current->opcode);
|
||||
// if (returnValue != RETURN_OK) {
|
||||
// this->sendErrorMessage( returnValue );
|
||||
// }
|
||||
@ -31,53 +26,50 @@ void FixedSlotSequence::executeAndAdvance() {
|
||||
|
||||
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
|
||||
uint32_t oldTime;
|
||||
std::list<FixedSequenceSlot*>::iterator it;
|
||||
it = current;
|
||||
SlotListIter slotListIter = current;
|
||||
// Get the pollingTimeMs of the current slot object.
|
||||
oldTime = (*it)->pollingTimeMs;
|
||||
oldTime = slotListIter->pollingTimeMs;
|
||||
// Advance to the next object.
|
||||
it++;
|
||||
slotListIter++;
|
||||
// Find the next interval which is not 0.
|
||||
while (it != slotList.end()) {
|
||||
if (oldTime != (*it)->pollingTimeMs) {
|
||||
return (*it)->pollingTimeMs - oldTime;
|
||||
while (slotListIter != slotList.end()) {
|
||||
if (oldTime != slotListIter->pollingTimeMs) {
|
||||
return slotListIter->pollingTimeMs - oldTime;
|
||||
} else {
|
||||
it++;
|
||||
slotListIter++;
|
||||
}
|
||||
}
|
||||
// If the list end is reached (this is definitely an interval != 0),
|
||||
// the interval is calculated by subtracting the remaining time of the PST
|
||||
// and adding the start time of the first handler in the list.
|
||||
it = slotList.begin();
|
||||
return lengthMs - oldTime + (*it)->pollingTimeMs;
|
||||
slotListIter = slotList.begin();
|
||||
return lengthMs - oldTime + slotListIter->pollingTimeMs;
|
||||
}
|
||||
|
||||
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
|
||||
uint32_t currentTime;
|
||||
std::list<FixedSequenceSlot*>::iterator it;
|
||||
it = current;
|
||||
SlotListIter slotListIter = current;
|
||||
// Get the pollingTimeMs of the current slot object.
|
||||
currentTime = (*it)->pollingTimeMs;
|
||||
currentTime = slotListIter->pollingTimeMs;
|
||||
|
||||
//if it is the first slot, calculate difference to last slot
|
||||
if (it == slotList.begin()){
|
||||
return lengthMs - (*(--slotList.end()))->pollingTimeMs + currentTime;
|
||||
if (slotListIter == slotList.begin()){
|
||||
return lengthMs - (--slotList.end())->pollingTimeMs + currentTime;
|
||||
}
|
||||
// get previous slot
|
||||
it--;
|
||||
slotListIter--;
|
||||
|
||||
return currentTime - (*it)->pollingTimeMs;
|
||||
return currentTime - slotListIter->pollingTimeMs;
|
||||
}
|
||||
|
||||
bool FixedSlotSequence::slotFollowsImmediately() {
|
||||
uint32_t currentTime = (*current)->pollingTimeMs;
|
||||
std::list<FixedSequenceSlot*>::iterator it;
|
||||
it = this->current;
|
||||
uint32_t currentTime = current->pollingTimeMs;
|
||||
SlotListIter fixedSequenceIter = this->current;
|
||||
// Get the pollingTimeMs of the current slot object.
|
||||
if (it == slotList.begin())
|
||||
if (fixedSequenceIter == slotList.begin())
|
||||
return false;
|
||||
it--;
|
||||
if ((*it)->pollingTimeMs == currentTime) {
|
||||
fixedSequenceIter--;
|
||||
if (fixedSequenceIter->pollingTimeMs == currentTime) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -93,26 +85,30 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
|
||||
sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
auto slotIt = slotList.begin();
|
||||
uint32_t count = 0;
|
||||
uint32_t time = 0;
|
||||
while (slotIt != slotList.end()) {
|
||||
if ((*slotIt)->handler == NULL) {
|
||||
if (slotIt->handler == nullptr) {
|
||||
sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!"
|
||||
<< std::endl;
|
||||
count++;
|
||||
} else if ((*slotIt)->pollingTimeMs < time) {
|
||||
} else if (slotIt->pollingTimeMs < time) {
|
||||
sif::error << "FixedSlotSequence::initialize: Time: "
|
||||
<< (*slotIt)->pollingTimeMs
|
||||
<< slotIt->pollingTimeMs
|
||||
<< " is smaller than previous with " << time << std::endl;
|
||||
count++;
|
||||
} else {
|
||||
// All ok, print slot.
|
||||
// (*slotIt)->print();
|
||||
//info << "Current slot polling time: " << std::endl;
|
||||
//info << std::dec << slotIt->pollingTimeMs << std::endl;
|
||||
}
|
||||
time = (*slotIt)->pollingTimeMs;
|
||||
time = slotIt->pollingTimeMs;
|
||||
slotIt++;
|
||||
}
|
||||
//info << "Number of elements in slot list: "
|
||||
// << slotList.size() << std::endl;
|
||||
if (count > 0) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
@ -121,8 +117,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
|
||||
|
||||
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
|
||||
int8_t executionStep, PeriodicTaskIF* executingTask) {
|
||||
this->slotList.push_back(
|
||||
new FixedSequenceSlot(componentId, slotTimeMs, executionStep,
|
||||
this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep,
|
||||
executingTask));
|
||||
this->current = slotList.begin();
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FIXEDSLOTSEQUENCE_H_
|
||||
#define FIXEDSLOTSEQUENCE_H_
|
||||
#ifndef FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
|
||||
#define FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
|
||||
|
||||
#include <framework/devicehandlers/FixedSequenceSlot.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
/**
|
||||
* @brief This class is the representation of a Polling Sequence Table in software.
|
||||
@ -24,30 +24,39 @@
|
||||
*/
|
||||
class FixedSlotSequence {
|
||||
public:
|
||||
using SlotList = std::multiset<FixedSequenceSlot>;
|
||||
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);
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
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.
|
||||
* Afterwards, the iterator current is set to the beginning of the list.
|
||||
* @param Object ID of the object to add
|
||||
* @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask
|
||||
* will be called inside the slot period.
|
||||
* @param setSequenceId ID which can be used to distinguish
|
||||
* different task operations
|
||||
* @param
|
||||
* @param
|
||||
*/
|
||||
void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId,
|
||||
PeriodicTaskIF* executingTask);
|
||||
@ -61,47 +70,59 @@ public:
|
||||
bool slotFollowsImmediately();
|
||||
|
||||
/**
|
||||
* \brief This method returns the time until the next software component is invoked.
|
||||
* @brief This method returns the time until the next software
|
||||
* component is invoked.
|
||||
*
|
||||
* \details This method is vitally important for the operation of the PST. 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)
|
||||
* it calculates and returns the interval in milliseconds within which the handler execution
|
||||
* shall take place. 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.
|
||||
* @details
|
||||
* This method is vitally important for the operation of the PST.
|
||||
* 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)
|
||||
* it calculates and returns the interval in milliseconds within
|
||||
* which the handler execution shall take place.
|
||||
* 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.
|
||||
*/
|
||||
uint32_t getIntervalToNextSlotMs();
|
||||
|
||||
/**
|
||||
* \brief This method returns the time difference between the current slot and the previous slot
|
||||
* @brief This method returns the time difference between the current
|
||||
* slot and the previous slot
|
||||
*
|
||||
* \details This method is vitally important for the operation of the PST. By fetching the polling time
|
||||
* of the current slot and that of the prevous 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 be delayed.
|
||||
* @details
|
||||
* 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
|
||||
* 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
|
||||
* be delayed.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* \brief The method to execute the device handler entered in the current OPUSPollingSlot object.
|
||||
* @brief The method to execute the device handler entered in the current
|
||||
* PollingSlot object.
|
||||
*
|
||||
* \details 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. Either the device handler's
|
||||
* talkToInterface or its listenToInterface method is invoked, depending on the isTalking flag
|
||||
* of the polling slot. After execution the iterator current is increased or, by reaching the
|
||||
* @details
|
||||
* 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.
|
||||
* Either the device handler's talkToInterface or its listenToInterface
|
||||
* method is invoked, depending on the isTalking flag of the polling slot.
|
||||
* After execution the iterator current is increased or, by reaching the
|
||||
* end of slotList, reset to the beginning.
|
||||
*/
|
||||
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 polling slot which is executed next.
|
||||
* @details This is an iterator for slotList and always points to the
|
||||
* polling slot which is executed next.
|
||||
*/
|
||||
std::list<FixedSequenceSlot*>::iterator current;
|
||||
SlotListIter current;
|
||||
|
||||
/**
|
||||
* Iterate through slotList and check successful creation.
|
||||
@ -109,18 +130,21 @@ public:
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t checkSequence() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the
|
||||
* device handler objects.
|
||||
* @brief This list contains all PollingSlot objects, defining order and
|
||||
* execution time of the device handler objects.
|
||||
*
|
||||
* \details The slot list is a std:list object that contains all created OPUSPollingSlot instances.
|
||||
* They are NOT ordered automatically, so by adding entries, the correct order needs to be ensured.
|
||||
* By iterating through this list the polling sequence is executed. Two entries with identical
|
||||
* polling times are executed immediately one after another.
|
||||
* @details
|
||||
* The slot list is a std:list object that contains all created
|
||||
* PollingSlot instances. They are NOT ordered automatically, so by
|
||||
* adding entries, the correct order needs to be ensured. By iterating
|
||||
* through this list the polling sequence is executed. Two entries with
|
||||
* identical polling times are executed immediately one after another.
|
||||
*/
|
||||
std::list<FixedSequenceSlot*> slotList;
|
||||
SlotList slotList;
|
||||
|
||||
uint32_t lengthMs;
|
||||
};
|
||||
|
@ -82,10 +82,10 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const {
|
||||
|
||||
void FixedTimeslotTask::taskFunctionality() {
|
||||
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
||||
std::list<FixedSequenceSlot*>::iterator it = pst.current;
|
||||
auto slotListIter = pst.current;
|
||||
|
||||
//The start time for the first entry is read.
|
||||
uint32_t intervalMs = (*it)->pollingTimeMs;
|
||||
uint32_t intervalMs = slotListIter->pollingTimeMs;
|
||||
TickType_t interval = pdMS_TO_TICKS(intervalMs);
|
||||
|
||||
TickType_t xLastWakeTime;
|
||||
@ -120,4 +120,3 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
|
||||
vTaskDelay(pdMS_TO_TICKS(ms));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user