refactoring host osal
This commit is contained in:
parent
08ff061d07
commit
e18d3d559e
@ -20,8 +20,8 @@
|
||||
#endif
|
||||
|
||||
PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack,
|
||||
TaskPeriod setPeriod, void (*setDeadlineMissedFunc)())
|
||||
: started(false), taskName(name), period(setPeriod), deadlineMissedFunc(setDeadlineMissedFunc) {
|
||||
TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_)
|
||||
: PeriodicTaskBase(setPeriod, dlmFunc_), started(false), taskName(name) {
|
||||
// It is probably possible to set task priorities by using the native
|
||||
// task handles for Windows / Linux
|
||||
mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
|
||||
@ -75,9 +75,7 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
|
||||
}
|
||||
|
||||
void PeriodicTask::taskFunctionality() {
|
||||
for (const auto& object : objectList) {
|
||||
object->initializeAfterTaskCreation();
|
||||
}
|
||||
initObjsAfterTaskCreation();
|
||||
|
||||
std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period * 1000));
|
||||
auto currentStartTime{std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
@ -89,33 +87,17 @@ void PeriodicTask::taskFunctionality() {
|
||||
if (terminateThread.load()) {
|
||||
break;
|
||||
}
|
||||
for (const auto& object : objectList) {
|
||||
object->performOperation();
|
||||
for (const auto& objectPair : objectList) {
|
||||
objectPair.first->performOperation(objectPair.second);
|
||||
}
|
||||
if (not delayForInterval(¤tStartTime, periodChrono)) {
|
||||
if (deadlineMissedFunc != nullptr) {
|
||||
this->deadlineMissedFunc();
|
||||
if (dlmFunc != nullptr) {
|
||||
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 shouldDelay = false;
|
||||
// Get current wakeup time
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "../../objectmanager/ObjectManagerIF.h"
|
||||
#include "../../tasks/PeriodicTaskIF.h"
|
||||
#include "../../tasks/Typedef.h"
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/tasks/PeriodicTaskBase.h"
|
||||
#include "fsfw/tasks/definitions.h"
|
||||
|
||||
class ExecutableObjectIF;
|
||||
|
||||
@ -19,7 +19,7 @@ class ExecutableObjectIF;
|
||||
*
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class PeriodicTask : public PeriodicTaskIF {
|
||||
class PeriodicTask : public PeriodicTaskBase {
|
||||
public:
|
||||
/**
|
||||
* @brief Standard constructor of the class.
|
||||
@ -34,7 +34,7 @@ class PeriodicTask : public PeriodicTaskIF {
|
||||
* assigned.
|
||||
*/
|
||||
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
|
||||
* the task object's lifetime, so the destructor is empty.
|
||||
@ -49,62 +49,19 @@ class PeriodicTask : public PeriodicTaskIF {
|
||||
* to the system call.
|
||||
*/
|
||||
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);
|
||||
|
||||
protected:
|
||||
using chron_ms = std::chrono::milliseconds;
|
||||
bool started;
|
||||
//!< Typedef for the List of objects.
|
||||
typedef std::vector<ExecutableObjectIF*> ObjectList;
|
||||
std::thread mainThread;
|
||||
std::atomic<bool> terminateThread{false};
|
||||
|
||||
/**
|
||||
* @brief This attribute holds a list of objects to be executed.
|
||||
*/
|
||||
ObjectList objectList;
|
||||
|
||||
std::condition_variable initCondition;
|
||||
std::mutex initMutex;
|
||||
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.
|
||||
* @details
|
||||
|
@ -9,8 +9,10 @@ uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
|
||||
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
||||
|
||||
FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_,
|
||||
uint32_t periodMs_)
|
||||
: PosixThread(name_, priority_, stackSize_), pst(periodMs_), started(false) {}
|
||||
TaskPeriod periodSeconds_)
|
||||
: posixThread(name_, priority_, stackSize_),
|
||||
pst(static_cast<uint32_t>(periodSeconds_ * 1000)),
|
||||
started(false) {}
|
||||
|
||||
FixedTimeslotTask::~FixedTimeslotTask() {}
|
||||
|
||||
@ -26,7 +28,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) {
|
||||
|
||||
ReturnValue_t FixedTimeslotTask::startTask() {
|
||||
started = true;
|
||||
createTask(&taskEntryPoint, this);
|
||||
posixThread.createTask(&taskEntryPoint, this);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -57,13 +59,13 @@ ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); }
|
||||
void FixedTimeslotTask::taskFunctionality() {
|
||||
// Like FreeRTOS pthreads are running as soon as they are created
|
||||
if (!started) {
|
||||
suspend();
|
||||
posixThread.suspend();
|
||||
}
|
||||
|
||||
pst.intializeSequenceAfterTaskCreation();
|
||||
|
||||
// The start time for the first entry is read.
|
||||
uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
|
||||
uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs();
|
||||
uint64_t interval = pst.getIntervalToNextSlotMs();
|
||||
|
||||
// The task's "infinite" inner loop is entered.
|
||||
|
@ -3,11 +3,12 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "../../tasks/FixedSlotSequence.h"
|
||||
#include "../../tasks/FixedTimeslotTaskIF.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:
|
||||
/**
|
||||
* Create a generic periodic task.
|
||||
@ -21,7 +22,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
|
||||
* @param period_
|
||||
* @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();
|
||||
|
||||
ReturnValue_t startTask() override;
|
||||
@ -59,6 +60,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
|
||||
virtual void taskFunctionality();
|
||||
|
||||
private:
|
||||
PosixThread posixThread;
|
||||
|
||||
/**
|
||||
* @brief This is the entry point in a new thread.
|
||||
*
|
||||
|
@ -1,16 +1,16 @@
|
||||
#include "fsfw/osal/linux/PeriodicPosixTask.h"
|
||||
|
||||
#include <set>
|
||||
#include <cerrno>
|
||||
#include <set>
|
||||
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
|
||||
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
|
||||
uint32_t period_, TaskDeadlineMissedFunction dlMissedFunc_)
|
||||
: PosixThread(name_, priority_, stackSize_),
|
||||
PeriodicTaskBase(period_, dlMissedFunc_),
|
||||
TaskPeriod period_, TaskDeadlineMissedFunction dlMissedFunc_)
|
||||
: PeriodicTaskBase(period_, dlMissedFunc_),
|
||||
posixThread(name_, priority_, stackSize_),
|
||||
started(false) {}
|
||||
|
||||
PeriodicPosixTask::~PeriodicPosixTask() {
|
||||
@ -34,18 +34,19 @@ ReturnValue_t PeriodicPosixTask::startTask(void) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
started = true;
|
||||
PosixThread::createTask(&taskEntryPoint, this);
|
||||
posixThread.createTask(&taskEntryPoint, this);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void PeriodicPosixTask::taskFunctionality(void) {
|
||||
if (not started) {
|
||||
suspend();
|
||||
posixThread.suspend();
|
||||
}
|
||||
|
||||
initObjsAfterTaskCreation();
|
||||
|
||||
uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
|
||||
uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs();
|
||||
uint64_t periodMs = getPeriodMs();
|
||||
// The task's "infinite" inner loop is entered.
|
||||
while (1) {
|
||||
for (auto const& objOpCodePair : objectList) {
|
||||
|
@ -1,17 +1,15 @@
|
||||
#ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
|
||||
#define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
|
||||
|
||||
#include "PosixThread.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PosixThread.h"
|
||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||
#include "fsfw/tasks/PeriodicTaskBase.h"
|
||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||
|
||||
|
||||
class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
|
||||
class PeriodicPosixTask : public PeriodicTaskBase {
|
||||
public:
|
||||
/**
|
||||
* Create a generic periodic task.
|
||||
@ -25,7 +23,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
|
||||
* @param period_
|
||||
* @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_)());
|
||||
virtual ~PeriodicPosixTask();
|
||||
|
||||
@ -41,6 +39,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase {
|
||||
ReturnValue_t sleepFor(uint32_t ms) override;
|
||||
|
||||
private:
|
||||
PosixThread posixThread;
|
||||
|
||||
/**
|
||||
* @brief Flag to indicate that the task was started and is allowed to run
|
||||
|
@ -35,6 +35,21 @@ class PosixThread {
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -55,21 +70,6 @@ class PosixThread {
|
||||
protected:
|
||||
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:
|
||||
char name[PTHREAD_MAX_NAMELEN];
|
||||
int priority;
|
||||
|
@ -15,14 +15,14 @@ TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(
|
||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000,
|
||||
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||
deadLineMissedFunction_);
|
||||
}
|
||||
|
||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||
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) {
|
||||
|
@ -1,3 +1,3 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp
|
||||
FixedSlotSequence.cpp
|
||||
PeriodicTaskBase.cpp)
|
||||
target_sources(
|
||||
${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp FixedSlotSequence.cpp
|
||||
PeriodicTaskBase.cpp)
|
||||
|
@ -1,17 +1,15 @@
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include "PeriodicTaskBase.h"
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_,
|
||||
TaskDeadlineMissedFunction deadlineMissedFunc_)
|
||||
: periodMs(periodMs_), deadlineMissedFunc(deadlineMissedFunc_) {}
|
||||
PeriodicTaskBase::PeriodicTaskBase(TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
|
||||
: period(period), dlmFunc(dlmFunc_) {}
|
||||
|
||||
uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; }
|
||||
uint32_t PeriodicTaskBase::getPeriodMs() const { return static_cast<uint32_t>(period * 1000); }
|
||||
|
||||
bool PeriodicTaskBase::isEmpty() const {
|
||||
return objectList.empty();
|
||||
}
|
||||
bool PeriodicTaskBase::isEmpty() const { return objectList.empty(); }
|
||||
|
||||
ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() {
|
||||
std::multiset<ExecutableObjectIF*> uniqueObjects;
|
||||
|
@ -1,16 +1,17 @@
|
||||
#ifndef 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/definitions.h"
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
class ExecutableObjectIF;
|
||||
|
||||
class PeriodicTaskBase: public PeriodicTaskIF {
|
||||
public:
|
||||
PeriodicTaskBase(uint32_t periodMs, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr);
|
||||
class PeriodicTaskBase : public PeriodicTaskIF {
|
||||
public:
|
||||
PeriodicTaskBase(TaskPeriod period, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr);
|
||||
|
||||
ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override;
|
||||
ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override;
|
||||
@ -21,8 +22,7 @@ public:
|
||||
|
||||
ReturnValue_t initObjsAfterTaskCreation();
|
||||
|
||||
protected:
|
||||
|
||||
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>>;
|
||||
@ -32,20 +32,19 @@ protected:
|
||||
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.
|
||||
* @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.
|
||||
* @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;
|
||||
TaskDeadlineMissedFunction dlmFunc = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_
|
||||
#define FRAMEWORK_TASK_PERIODICTASKIF_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/**
|
||||
* New version of TaskIF
|
||||
* Follows RAII principles, i.e. there's no create or delete method.
|
||||
|
Loading…
Reference in New Issue
Block a user