refactoring host osal

This commit is contained in:
Robin Müller 2022-05-18 15:42:18 +02:00
parent b47eb0a7ff
commit 1886da0d3f
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
12 changed files with 83 additions and 142 deletions

View File

@ -20,8 +20,8 @@
#endif #endif
PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack, PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack,
TaskPeriod setPeriod, void (*setDeadlineMissedFunc)()) TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_)
: started(false), taskName(name), period(setPeriod), deadlineMissedFunc(setDeadlineMissedFunc) { : PeriodicTaskBase(setPeriod, dlmFunc_), started(false), taskName(name) {
// It is probably possible to set task priorities by using the native // It is probably possible to set task priorities by using the native
// task handles for Windows / Linux // task handles for Windows / Linux
mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
@ -75,9 +75,7 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
} }
void PeriodicTask::taskFunctionality() { void PeriodicTask::taskFunctionality() {
for (const auto& object : objectList) { initObjsAfterTaskCreation();
object->initializeAfterTaskCreation();
}
std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period * 1000)); std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period * 1000));
auto currentStartTime{std::chrono::duration_cast<std::chrono::milliseconds>( auto currentStartTime{std::chrono::duration_cast<std::chrono::milliseconds>(
@ -89,33 +87,17 @@ void PeriodicTask::taskFunctionality() {
if (terminateThread.load()) { if (terminateThread.load()) {
break; break;
} }
for (const auto& object : objectList) { for (const auto& objectPair : objectList) {
object->performOperation(); objectPair.first->performOperation(objectPair.second);
} }
if (not delayForInterval(&currentStartTime, periodChrono)) { if (not delayForInterval(&currentStartTime, periodChrono)) {
if (deadlineMissedFunc != nullptr) { if (dlmFunc != nullptr) {
this->deadlineMissedFunc(); this->dlmFunc();
} }
} }
} }
} }
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
return addComponent(newObject);
}
ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
if (object == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
object->setTaskIF(this);
objectList.push_back(object);
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; }
bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) { bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) {
bool shouldDelay = false; bool shouldDelay = false;
// Get current wakeup time // Get current wakeup time

View File

@ -6,9 +6,9 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "../../objectmanager/ObjectManagerIF.h" #include "fsfw/objectmanager/ObjectManagerIF.h"
#include "../../tasks/PeriodicTaskIF.h" #include "fsfw/tasks/PeriodicTaskBase.h"
#include "../../tasks/Typedef.h" #include "fsfw/tasks/definitions.h"
class ExecutableObjectIF; class ExecutableObjectIF;
@ -19,7 +19,7 @@ class ExecutableObjectIF;
* *
* @ingroup task_handling * @ingroup task_handling
*/ */
class PeriodicTask : public PeriodicTaskIF { class PeriodicTask : public PeriodicTaskBase {
public: public:
/** /**
* @brief Standard constructor of the class. * @brief Standard constructor of the class.
@ -34,7 +34,7 @@ class PeriodicTask : public PeriodicTaskIF {
* assigned. * assigned.
*/ */
PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack, PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack,
TaskPeriod setPeriod, void (*setDeadlineMissedFunc)()); TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc);
/** /**
* @brief Currently, the executed object's lifetime is not coupled with * @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty. * the task object's lifetime, so the destructor is empty.
@ -49,62 +49,19 @@ class PeriodicTask : public PeriodicTaskIF {
* to the system call. * to the system call.
*/ */
ReturnValue_t startTask(void); ReturnValue_t startTask(void);
/**
* 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
* -@c RETURN_OK on success
* -@c RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(object_id_t object);
/**
* 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
* -@c RETURN_OK on success
* -@c RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(ExecutableObjectIF* object);
uint32_t getPeriodMs() const;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms);
protected: protected:
using chron_ms = std::chrono::milliseconds; using chron_ms = std::chrono::milliseconds;
bool started; bool started;
//!< Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList;
std::thread mainThread; std::thread mainThread;
std::atomic<bool> terminateThread{false}; std::atomic<bool> terminateThread{false};
/**
* @brief This attribute holds a list of objects to be executed.
*/
ObjectList objectList;
std::condition_variable initCondition; std::condition_variable initCondition;
std::mutex initMutex; std::mutex initMutex;
std::string taskName; std::string taskName;
/**
* @brief The period of the task.
* @details
* The period determines the frequency of the task's execution.
* It is expressed in clock ticks.
*/
TaskPeriod period;
/**
* @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)(void);
/** /**
* @brief This is the function executed in the new task's context. * @brief This is the function executed in the new task's context.
* @details * @details

View File

@ -9,8 +9,10 @@ uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_,
uint32_t periodMs_) TaskPeriod periodSeconds_)
: PosixThread(name_, priority_, stackSize_), pst(periodMs_), started(false) {} : posixThread(name_, priority_, stackSize_),
pst(static_cast<uint32_t>(periodSeconds_ * 1000)),
started(false) {}
FixedTimeslotTask::~FixedTimeslotTask() {} FixedTimeslotTask::~FixedTimeslotTask() {}
@ -26,7 +28,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) {
ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::startTask() {
started = true; started = true;
createTask(&taskEntryPoint, this); posixThread.createTask(&taskEntryPoint, this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -57,13 +59,13 @@ ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); }
void FixedTimeslotTask::taskFunctionality() { void FixedTimeslotTask::taskFunctionality() {
// Like FreeRTOS pthreads are running as soon as they are created // Like FreeRTOS pthreads are running as soon as they are created
if (!started) { if (!started) {
suspend(); posixThread.suspend();
} }
pst.intializeSequenceAfterTaskCreation(); pst.intializeSequenceAfterTaskCreation();
// The start time for the first entry is read. // The start time for the first entry is read.
uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs();
uint64_t interval = pst.getIntervalToNextSlotMs(); uint64_t interval = pst.getIntervalToNextSlotMs();
// The task's "infinite" inner loop is entered. // The task's "infinite" inner loop is entered.

View File

@ -3,11 +3,12 @@
#include <pthread.h> #include <pthread.h>
#include "../../tasks/FixedSlotSequence.h"
#include "../../tasks/FixedTimeslotTaskIF.h"
#include "PosixThread.h" #include "PosixThread.h"
#include "fsfw/tasks/FixedSlotSequence.h"
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
#include "fsfw/tasks/definitions.h"
class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread { class FixedTimeslotTask : public FixedTimeslotTaskIF {
public: public:
/** /**
* Create a generic periodic task. * Create a generic periodic task.
@ -21,7 +22,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
* @param period_ * @param period_
* @param deadlineMissedFunc_ * @param deadlineMissedFunc_
*/ */
FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod periodSeconds_);
virtual ~FixedTimeslotTask(); virtual ~FixedTimeslotTask();
ReturnValue_t startTask() override; ReturnValue_t startTask() override;
@ -59,6 +60,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
virtual void taskFunctionality(); virtual void taskFunctionality();
private: private:
PosixThread posixThread;
/** /**
* @brief This is the entry point in a new thread. * @brief This is the entry point in a new thread.
* *

View File

@ -1,16 +1,16 @@
#include "fsfw/osal/linux/PeriodicPosixTask.h" #include "fsfw/osal/linux/PeriodicPosixTask.h"
#include <set>
#include <cerrno> #include <cerrno>
#include <set>
#include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#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_, TaskDeadlineMissedFunction dlMissedFunc_) TaskPeriod period_, TaskDeadlineMissedFunction dlMissedFunc_)
: PosixThread(name_, priority_, stackSize_), : PeriodicTaskBase(period_, dlMissedFunc_),
PeriodicTaskBase(period_, dlMissedFunc_), posixThread(name_, priority_, stackSize_),
started(false) {} started(false) {}
PeriodicPosixTask::~PeriodicPosixTask() { PeriodicPosixTask::~PeriodicPosixTask() {
@ -34,18 +34,19 @@ ReturnValue_t PeriodicPosixTask::startTask(void) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
started = true; started = true;
PosixThread::createTask(&taskEntryPoint, this); posixThread.createTask(&taskEntryPoint, this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void PeriodicPosixTask::taskFunctionality(void) { void PeriodicPosixTask::taskFunctionality(void) {
if (not started) { if (not started) {
suspend(); posixThread.suspend();
} }
initObjsAfterTaskCreation(); initObjsAfterTaskCreation();
uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs();
uint64_t periodMs = getPeriodMs();
// The task's "infinite" inner loop is entered. // The task's "infinite" inner loop is entered.
while (1) { while (1) {
for (auto const& objOpCodePair : objectList) { for (auto const& objOpCodePair : objectList) {

View File

@ -1,17 +1,15 @@
#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 "PosixThread.h"
#include <vector> #include <vector>
#include "PosixThread.h"
#include "fsfw/objectmanager/ObjectManagerIF.h" #include "fsfw/objectmanager/ObjectManagerIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/tasks/PeriodicTaskIF.h"
#include "fsfw/tasks/PeriodicTaskBase.h" #include "fsfw/tasks/PeriodicTaskBase.h"
#include "fsfw/tasks/PeriodicTaskIF.h"
class PeriodicPosixTask : public PeriodicTaskBase {
class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
public: public:
/** /**
* Create a generic periodic task. * Create a generic periodic task.
@ -25,7 +23,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
* @param period_ * @param period_
* @param deadlineMissedFunc_ * @param deadlineMissedFunc_
*/ */
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
void (*deadlineMissedFunc_)()); void (*deadlineMissedFunc_)());
virtual ~PeriodicPosixTask(); virtual ~PeriodicPosixTask();
@ -41,6 +39,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
ReturnValue_t sleepFor(uint32_t ms) override; ReturnValue_t sleepFor(uint32_t ms) override;
private: private:
PosixThread posixThread;
/** /**
* @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

View File

@ -35,6 +35,21 @@ class PosixThread {
*/ */
void resume(); void resume();
/**
* @brief Function that has to be called by derived class because the
* derived class pointer has to be valid as argument.
* @details
* This function creates a pthread with the given parameters. As the
* function requires a pointer to the derived object it has to be called
* after the this pointer of the derived object is valid.
* Sets the taskEntryPoint as function to be called by new a thread.
* @param fnc_ Function which will be executed by the thread.
* @param arg_
* argument of the taskEntryPoint function, needs to be this pointer
* of derived class
*/
void createTask(void* (*fnc_)(void*), void* arg_);
/** /**
* Delay function similar to FreeRtos delayUntil function * Delay function similar to FreeRtos delayUntil function
* *
@ -55,21 +70,6 @@ class PosixThread {
protected: protected:
pthread_t thread; pthread_t thread;
/**
* @brief Function that has to be called by derived class because the
* derived class pointer has to be valid as argument.
* @details
* This function creates a pthread with the given parameters. As the
* function requires a pointer to the derived object it has to be called
* after the this pointer of the derived object is valid.
* Sets the taskEntryPoint as function to be called by new a thread.
* @param fnc_ Function which will be executed by the thread.
* @param arg_
* argument of the taskEntryPoint function, needs to be this pointer
* of derived class
*/
void createTask(void* (*fnc_)(void*), void* arg_);
private: private:
char name[PTHREAD_MAX_NAMELEN]; char name[PTHREAD_MAX_NAMELEN];
int priority; int priority;

View File

@ -15,14 +15,14 @@ TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
PeriodicTaskIF* TaskFactory::createPeriodicTask( PeriodicTaskIF* TaskFactory::createPeriodicTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000, return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_); deadLineMissedFunction_);
} }
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask( FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000); return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_);
} }
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {

View File

@ -1,3 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp target_sources(
FixedSlotSequence.cpp ${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp FixedSlotSequence.cpp
PeriodicTaskBase.cpp) PeriodicTaskBase.cpp)

View File

@ -1,17 +1,15 @@
#include <fsfw/objectmanager/ObjectManager.h>
#include "PeriodicTaskBase.h" #include "PeriodicTaskBase.h"
#include <fsfw/objectmanager/ObjectManager.h>
#include <set> #include <set>
PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_, PeriodicTaskBase::PeriodicTaskBase(TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
TaskDeadlineMissedFunction deadlineMissedFunc_) : period(period), dlmFunc(dlmFunc_) {}
: periodMs(periodMs_), deadlineMissedFunc(deadlineMissedFunc_) {}
uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; } uint32_t PeriodicTaskBase::getPeriodMs() const { return static_cast<uint32_t>(period * 1000); }
bool PeriodicTaskBase::isEmpty() const { bool PeriodicTaskBase::isEmpty() const { return objectList.empty(); }
return objectList.empty();
}
ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() { ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() {
std::multiset<ExecutableObjectIF*> uniqueObjects; std::multiset<ExecutableObjectIF*> uniqueObjects;

View File

@ -1,16 +1,17 @@
#ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ #ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_
#define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ #define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_
#include <cstdint>
#include <vector>
#include "fsfw/tasks/PeriodicTaskIF.h" #include "fsfw/tasks/PeriodicTaskIF.h"
#include "fsfw/tasks/definitions.h" #include "fsfw/tasks/definitions.h"
#include <vector>
#include <cstdint>
class ExecutableObjectIF; class ExecutableObjectIF;
class PeriodicTaskBase : public PeriodicTaskIF { class PeriodicTaskBase : public PeriodicTaskIF {
public: public:
PeriodicTaskBase(uint32_t periodMs, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); PeriodicTaskBase(TaskPeriod period, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr);
ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override;
ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override;
@ -22,7 +23,6 @@ public:
ReturnValue_t initObjsAfterTaskCreation(); ReturnValue_t initObjsAfterTaskCreation();
protected: protected:
//! Typedef for the List of objects. Will contain the objects to execute and their respective //! Typedef for the List of objects. Will contain the objects to execute and their respective
//! operation codes //! operation codes
using ObjectList = std::vector<std::pair<ExecutableObjectIF*, uint8_t>>; using ObjectList = std::vector<std::pair<ExecutableObjectIF*, uint8_t>>;
@ -32,20 +32,19 @@ protected:
ObjectList objectList; ObjectList objectList;
/** /**
* @brief Period of the task in milliseconds * @brief Period of task in floating point seconds
*/ */
uint32_t periodMs; TaskPeriod period;
/** /**
* @brief The pointer to the deadline-missed function. * @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed. * @details
* So, each may react individually on a timing failure. The pointer may be * This pointer stores the function that is executed if the task's deadline
* NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution * is missed. So, each may react individually on a timing failure.
* of the periodic task. * 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; TaskDeadlineMissedFunction dlmFunc = nullptr;
}; };
#endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */ #endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */

View File

@ -1,11 +1,11 @@
#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/objectmanager/SystemObjectIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
#include <cstddef>
/** /**
* 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.