new base class for periodic tasks

This commit is contained in:
Robin Müller 2022-05-18 14:32:35 +02:00
parent f9c42d3583
commit 86ca4f246b
8 changed files with 148 additions and 125 deletions

View File

@ -8,12 +8,10 @@
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
uint32_t period_, void(deadlineMissedFunc_)()) uint32_t period_, TaskDeadlineMissedFunction dlMissedFunc_)
: PosixThread(name_, priority_, stackSize_), : PosixThread(name_, priority_, stackSize_),
objectList(), PeriodicTaskBase(period_, dlMissedFunc_),
started(false), started(false) {}
periodMs(period_),
deadlineMissedFunc(deadlineMissedFunc_) {}
PeriodicPosixTask::~PeriodicPosixTask() { PeriodicPosixTask::~PeriodicPosixTask() {
// Not Implemented // Not Implemented
@ -27,31 +25,8 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
return nullptr; return nullptr;
} }
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
return addComponent(newObject, opCode);
}
ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_t opCode) {
if (object == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
<< " it implements ExecutableObjectIF!" << std::endl;
#else
sif::printError(
"PeriodicTask::addComponent: Invalid object. Make sure it "
"implements ExecutableObjectIF!\n");
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
objectList.push_back({object, opCode});
object->setTaskIF(this);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
return PosixThread::sleep((uint64_t)ms * 1000000); return PosixThread::sleep(static_cast<uint64_t>(ms * 1000000));
} }
ReturnValue_t PeriodicPosixTask::startTask(void) { ReturnValue_t PeriodicPosixTask::startTask(void) {
@ -84,27 +59,3 @@ void PeriodicPosixTask::taskFunctionality(void) {
} }
} }
} }
uint32_t PeriodicPosixTask::getPeriodMs() const { return periodMs; }
bool PeriodicPosixTask::isEmpty() const { return objectList.empty(); }
ReturnValue_t PeriodicPosixTask::initObjsAfterTaskCreation() {
std::multiset<ExecutableObjectIF*> uniqueObjects;
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
uint32_t count = 0;
for (const auto& obj : objectList) {
// Ensure that each unique object is initialized once.
if (uniqueObjects.find(obj.first) == uniqueObjects.end()) {
ReturnValue_t result = obj.first->initializeAfterTaskCreation();
if (result != HasReturnvaluesIF::RETURN_OK) {
count++;
status = result;
}
uniqueObjects.emplace(obj.first);
}
}
if (count > 0) {
}
return status;
}

View File

@ -1,14 +1,17 @@
#ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
#define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
#include <vector>
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../tasks/ExecutableObjectIF.h"
#include "../../tasks/PeriodicTaskIF.h"
#include "PosixThread.h" #include "PosixThread.h"
class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { #include <vector>
#include "fsfw/objectmanager/ObjectManagerIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/tasks/PeriodicTaskIF.h"
#include "fsfw/tasks/PeriodicTaskBase.h"
class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
public: public:
/** /**
* Create a generic periodic task. * Create a generic periodic task.
@ -34,48 +37,16 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* to the system call. * to the system call.
*/ */
ReturnValue_t startTask() override; ReturnValue_t startTask() override;
/**
* Adds an object to the list of objects to be executed.
* The objects are executed in the order added.
* @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override;
/**
* Adds an object to the list of objects to be executed.
* The objects are executed in the order added.
* @param object pointer to the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override;
uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms) override; ReturnValue_t sleepFor(uint32_t ms) override;
ReturnValue_t initObjsAfterTaskCreation();
bool isEmpty() const override;
private: private:
//! Typedef for the List of objects. Will contain the objects to execute and their respective
//! op codes
using ObjectList = std::vector<std::pair<ExecutableObjectIF*, uint8_t>>;
/**
* @brief This attribute holds a list of objects to be executed.
*/
ObjectList objectList;
/** /**
* @brief Flag to indicate that the task was started and is allowed to run * @brief Flag to indicate that the task was started and is allowed to run
*/ */
bool started; bool started;
/**
* @brief Period of the task in milliseconds
*/
uint32_t periodMs;
/** /**
* @brief The function containing the actual functionality of the task. * @brief The function containing the actual functionality of the task.
* @details The method sets and starts * @details The method sets and starts
@ -92,14 +63,6 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* of the child class. Needs a valid pointer to the derived class. * of the child class. Needs a valid pointer to the derived class.
*/ */
static void* taskEntryPoint(void* arg); static void* taskEntryPoint(void* arg);
/**
* @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed.
* So, each may react individually on a timing failure. The pointer may be
* NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution
* of the periodic task.
*/
void (*deadlineMissedFunc)();
}; };
#endif /* FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ */ #endif /* FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ */

View File

@ -0,0 +1,57 @@
#include <fsfw/objectmanager/ObjectManager.h>
#include "PeriodicTaskBase.h"
#include <set>
PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_,
TaskDeadlineMissedFunction deadlineMissedFunc_)
: periodMs(periodMs_), deadlineMissedFunc(deadlineMissedFunc_) {}
uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; }
bool PeriodicTaskBase::isEmpty() const override {
return objectList.empty();
}
ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() {
std::multiset<ExecutableObjectIF*> uniqueObjects;
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
uint32_t count = 0;
for (const auto& obj : objectList) {
// Ensure that each unique object is initialized once.
if (uniqueObjects.find(obj.first) == uniqueObjects.end()) {
ReturnValue_t result = obj.first->initializeAfterTaskCreation();
if (result != HasReturnvaluesIF::RETURN_OK) {
count++;
status = result;
}
uniqueObjects.emplace(obj.first);
}
}
if (count > 0) {
}
return status;
}
ReturnValue_t PeriodicTaskBase::addComponent(object_id_t object, uint8_t opCode) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
return addComponent(newObject, opCode);
}
ReturnValue_t PeriodicTaskBase::addComponent(ExecutableObjectIF* object, uint8_t opCode) {
if (object == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
<< " it implements ExecutableObjectIF!" << std::endl;
#else
sif::printError(
"PeriodicTask::addComponent: Invalid object. Make sure it "
"implements ExecutableObjectIF!\n");
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
objectList.push_back({object, opCode});
object->setTaskIF(this);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,52 @@
#ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_
#define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_
#include "fsfw/tasks/PeriodicTaskIF.h"
#include "fsfw/tasks/definitions.h"
#include <vector>
#include <cstdint>
class ExecutableObjectIF;
class PeriodicTaskBase: public PeriodicTaskIF {
public:
PeriodicTaskBase(uint32_t periodMs, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr);
ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override;
ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override;
uint32_t getPeriodMs() const override;
bool isEmpty() const override;
ReturnValue_t initObjsAfterTaskCreation();
protected:
//! Typedef for the List of objects. Will contain the objects to execute and their respective
//! operation codes
using ObjectList = std::vector<std::pair<ExecutableObjectIF*, uint8_t>>;
/**
* @brief This attribute holds a list of objects to be executed.
*/
ObjectList objectList;
/**
* @brief Period of the task in milliseconds
*/
uint32_t periodMs;
/**
* @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed.
* So, each may react individually on a timing failure. The pointer may be
* NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution
* of the periodic task.
*/
TaskDeadlineMissedFunction deadlineMissedFunc = nullptr;
};
#endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */

View File

@ -1,11 +1,10 @@
#ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_ #ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_
#define FRAMEWORK_TASK_PERIODICTASKIF_H_ #define FRAMEWORK_TASK_PERIODICTASKIF_H_
#include <cstddef> #include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "../objectmanager/SystemObjectIF.h" #include <cstddef>
#include "../timemanager/Clock.h"
class ExecutableObjectIF;
/** /**
* New version of TaskIF * New version of TaskIF
@ -26,20 +25,21 @@ class PeriodicTaskIF {
virtual ReturnValue_t startTask() = 0; virtual ReturnValue_t startTask() = 0;
/** /**
* Add a component (object) to a periodic task. * Adds an object to the list of objects to be executed.
* @param object * The objects are executed in the order added. The object needs to implement
* Add an object to the task. The object needs to implement ExecutableObjectIF * ExecutableObjectIF
* @return * @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/ */
virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) { virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
}; };
/** /**
* Add an object to a periodic task. * Adds an object to the list of objects to be executed.
* @param object * The objects are executed in the order added.
* Add an object to the task. * @param object pointer to the object to add.
* @return * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/ */
virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) { virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -4,7 +4,7 @@
#include <cstdlib> #include <cstdlib>
#include "FixedTimeslotTaskIF.h" #include "FixedTimeslotTaskIF.h"
#include "Typedef.h" #include "definitions.h"
/** /**
* Singleton Class that produces Tasks. * Singleton Class that produces Tasks.

View File

@ -1,13 +0,0 @@
#ifndef FSFW_TASKS_TYPEDEF_H_
#define FSFW_TASKS_TYPEDEF_H_
#include <cstddef>
#include <cstdint>
typedef const char* TaskName;
typedef uint32_t TaskPriority;
typedef size_t TaskStackSize;
typedef double TaskPeriod;
typedef void (*TaskDeadlineMissedFunction)();
#endif /* FSFW_TASKS_TYPEDEF_H_ */

View File

@ -0,0 +1,13 @@
#ifndef FSFW_TASKS_TYPEDEF_H_
#define FSFW_TASKS_TYPEDEF_H_
#include <cstddef>
#include <cstdint>
using TaskName = const char*;
using TaskPriority = uint32_t;
using TaskStackSize = size_t;
using TaskPeriod = double;
using TaskDeadlineMissedFunction = void (*)();
#endif /* FSFW_TASKS_TYPEDEF_H_ */