added setting task IF

This commit is contained in:
Robin Müller 2020-06-23 01:14:28 +02:00
parent 31e5577763
commit 4507bdfb69
5 changed files with 87 additions and 30 deletions

View File

@ -70,39 +70,67 @@ void PeriodicTask::taskFunctionality() {
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
/* Enter the loop that defines the task behavior. */ /* Enter the loop that defines the task behavior. */
for (;;) { for (;;) {
for (ObjectList::iterator it = objectList.begin(); for (auto const& object: objectList) {
it != objectList.end(); ++it) { object->performOperation();
(*it)->performOperation();
} }
/* If all operations are finished and the difference of the checkMissedDeadline(xLastWakeTime, xPeriod);
* current time minus the last wake time is larger than the
* wait period, a deadline was missed. */
if(xTaskGetTickCount() - xLastWakeTime >= xPeriod) {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}
vTaskDelayUntil(&xLastWakeTime, xPeriod); vTaskDelayUntil(&xLastWakeTime, xPeriod);
} }
} }
ReturnValue_t PeriodicTask::addComponent(object_id_t object) { ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>( ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object); object);
if (newObject == NULL) { if (newObject == nullptr) {
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
"it implement ExecutableObjectIF" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject); objectList.push_back(newObject);
if(setTaskIF) {
newObject->setTaskIF(this);
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t PeriodicTask::getPeriodMs() const { uint32_t PeriodicTask::getPeriodMs() const {
return period * 1000; return period * 1000;
} }
void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown
if(currentTickCount < xLastWakeTime) {
// Time to wake has overflown as well. If the tick count
// is larger than the time to wake, a deadline was missed.
if(timeToWake < xLastWakeTime and
currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
// No tick count overflow. If the timeToWake has not overflown
// and the current tick count is larger than the time to wake,
// a deadline was missed.
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
void PeriodicTask::handleMissedDeadline() {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}

View File

@ -54,7 +54,7 @@ public:
* The address of the task object is passed as an argument * The address of the task object is passed as an argument
* to the system call. * to the system call.
*/ */
ReturnValue_t startTask(void); ReturnValue_t startTask() override;
/** /**
* Adds an object to the list of objects to be executed. * Adds an object to the list of objects to be executed.
* The objects are executed in the order added. * The objects are executed in the order added.
@ -63,11 +63,12 @@ public:
* -@c RETURN_OK on success * -@c RETURN_OK on success
* -@c RETURN_FAILED if the object could not be added. * -@c RETURN_FAILED if the object could not be added.
*/ */
ReturnValue_t addComponent(object_id_t object); ReturnValue_t addComponent(object_id_t object,
bool setTaskIF = true) override;
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms) override;
protected: protected:
bool started; bool started;
TaskHandle_t handle; TaskHandle_t handle;
@ -115,6 +116,10 @@ protected:
* On missing the deadline, the deadlineMissedFunction is executed. * On missing the deadline, the deadlineMissedFunction is executed.
*/ */
void taskFunctionality(void); void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
}; };
#endif /* PERIODICTASK_H_ */ #endif /* PERIODICTASK_H_ */

View File

@ -20,13 +20,18 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
return NULL; return NULL;
} }
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object,
bool addTaskIF) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>( ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object); object);
if (newObject == NULL) { if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject); objectList.push_back(newObject);
if(setTaskIF) {
newObject->setTaskIF(this);
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -26,11 +26,12 @@ public:
* @param object Id of the object to add. * @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/ */
ReturnValue_t addComponent(object_id_t object); ReturnValue_t addComponent(object_id_t object,
bool addTaskIF = true) override;
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms) override;
private: private:
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects. typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.

View File

@ -1,9 +1,11 @@
#ifndef PERIODICTASKIF_H_ #ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_
#define PERIODICTASKIF_H_ #define FRAMEWORK_TASK_PERIODICTASKIF_H_
#include <framework/objectmanager/SystemObjectIF.h> #include <framework/objectmanager/SystemObjectIF.h>
#include <framework/timemanager/Clock.h>
#include <cstddef> #include <cstddef>
class ExecutableObjectIF; class ExecutableObjectIF;
/** /**
* New version of TaskIF * New version of TaskIF
* Follows RAII principles, i.e. there's no create or delete method. * Follows RAII principles, i.e. there's no create or delete method.
@ -17,11 +19,27 @@ public:
*/ */
virtual ~PeriodicTaskIF() { } virtual ~PeriodicTaskIF() { }
/** /**
* @brief With the startTask method, a created task can be started for the first time. * @brief With the startTask method, a created task can be started
* for the first time.
*/ */
virtual ReturnValue_t startTask() = 0; virtual ReturnValue_t startTask() = 0;
virtual ReturnValue_t addComponent(object_id_t object) {return HasReturnvaluesIF::RETURN_FAILED;}; /**
* Add a component (object) to a periodic task. The pointer to the
* task can be set optionally
* @param object
* Add an object to the task. The most important case is to add an
* executable object with a function which will be called regularly
* (see ExecutableObjectIF)
* @param setTaskIF
* Can be used to specify whether the task object pointer is passed
* to the component.
* @return
*/
virtual ReturnValue_t addComponent(object_id_t object,
bool setTaskIF = true) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t sleepFor(uint32_t ms) = 0; virtual ReturnValue_t sleepFor(uint32_t ms) = 0;