refactor task IF

This commit is contained in:
2022-05-14 09:38:59 +02:00
committed by Gitea
parent 12046a2db6
commit eda5b8f593
11 changed files with 113 additions and 30 deletions

View File

@ -14,6 +14,8 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t st
FixedTimeslotTask::~FixedTimeslotTask() {}
bool FixedTimeslotTask::isEmpty() const { return pst.isEmpty(); }
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask.
FixedTimeslotTask* originalTask(reinterpret_cast<FixedTimeslotTask*>(arg));
@ -50,7 +52,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotT
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t FixedTimeslotTask::checkSequence() const { return pst.checkSequence(); }
ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); }
void FixedTimeslotTask::taskFunctionality() {
// Like FreeRTOS pthreads are running as soon as they are created

View File

@ -24,15 +24,18 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_);
virtual ~FixedTimeslotTask();
virtual ReturnValue_t startTask();
ReturnValue_t startTask() override;
virtual ReturnValue_t sleepFor(uint32_t ms);
ReturnValue_t sleepFor(uint32_t ms) override;
virtual uint32_t getPeriodMs() const;
uint32_t getPeriodMs() const override;
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep);
ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep) override;
virtual ReturnValue_t checkSequence() const;
ReturnValue_t checkSequence() override;
bool isEmpty() const override;
/**
* This static function can be used as #deadlineMissedFunc.

View File

@ -26,12 +26,12 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
return NULL;
}
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
return addComponent(newObject);
return addComponent(newObject, opCode);
}
ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) {
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"
@ -43,7 +43,7 @@ ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) {
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
objectList.push_back(object);
objectList.emplace(object, opCode);
object->setTaskIF(this);
return HasReturnvaluesIF::RETURN_OK;
@ -54,6 +54,9 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
}
ReturnValue_t PeriodicPosixTask::startTask(void) {
if (isEmpty()) {
return HasReturnvaluesIF::RETURN_FAILED;
}
started = true;
PosixThread::createTask(&taskEntryPoint, this);
return HasReturnvaluesIF::RETURN_OK;
@ -64,15 +67,13 @@ void PeriodicPosixTask::taskFunctionality(void) {
suspend();
}
for (auto const& object : objectList) {
object->initializeAfterTaskCreation();
}
initObjsAfterTaskCreation();
uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
// The task's "infinite" inner loop is entered.
while (1) {
for (auto const& object : objectList) {
object->performOperation();
for (auto const& objOpCodePair : objectList) {
objOpCodePair.first->performOperation(objOpCodePair.second);
}
if (not PosixThread::delayUntil(&lastWakeTime, periodMs)) {
@ -84,3 +85,25 @@ 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,7 +1,7 @@
#ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
#define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
#include <vector>
#include <set>
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../tasks/ExecutableObjectIF.h"
@ -40,7 +40,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* @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) override;
ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override;
/**
* Adds an object to the list of objects to be executed.
@ -48,14 +48,20 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* @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) override;
ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override;
uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms) override;
ReturnValue_t initObjsAfterTaskCreation();
bool isEmpty() const override;
private:
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
//! Typedef for the List of objects. Will contain the objects to execute and their respective
//! op codes
using ObjectList = std::multiset<std::pair<ExecutableObjectIF*, uint8_t>>;
/**
* @brief This attribute holds a list of objects to be executed.
*/

View File

@ -164,3 +164,5 @@ ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const {
void FixedSlotSequence::addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList&)) {
this->customCheckFunction = customCheckFunction;
}
bool FixedSlotSequence::isEmpty() const { return slotList.empty(); }

View File

@ -159,6 +159,8 @@ class FixedSlotSequence {
*/
ReturnValue_t intializeSequenceAfterTaskCreation() const;
bool isEmpty() const;
protected:
/**
* @brief This list contains all PollingSlot objects, defining order and

View File

@ -30,7 +30,7 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF {
* Check whether the sequence is valid and perform all other required
* initialization steps which are needed after task creation
*/
virtual ReturnValue_t checkSequence() const = 0;
virtual ReturnValue_t checkSequence() = 0;
};
#endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */

View File

@ -31,7 +31,7 @@ class PeriodicTaskIF {
* Add an object to the task. The object needs to implement ExecutableObjectIF
* @return
*/
virtual ReturnValue_t addComponent(object_id_t object) {
virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) {
return HasReturnvaluesIF::RETURN_FAILED;
};
@ -41,13 +41,15 @@ class PeriodicTaskIF {
* Add an object to the task.
* @return
*/
virtual ReturnValue_t addComponent(ExecutableObjectIF* object) {
virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) {
return HasReturnvaluesIF::RETURN_FAILED;
};
virtual ReturnValue_t sleepFor(uint32_t ms) = 0;
virtual uint32_t getPeriodMs() const = 0;
virtual bool isEmpty() const = 0;
};
#endif /* PERIODICTASKIF_H_ */