2021-07-14 10:50:44 +02:00
|
|
|
#include "fsfw/osal/rtems/PeriodicTask.h"
|
2021-01-28 11:28:28 +01:00
|
|
|
|
2021-07-14 10:50:44 +02:00
|
|
|
#include "fsfw/objectmanager/ObjectManager.h"
|
2022-02-02 10:29:30 +01:00
|
|
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
2021-07-14 10:50:44 +02:00
|
|
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
2021-01-28 11:28:28 +01:00
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
PeriodicTask::PeriodicTask(const char* name, rtems_task_priority setPriority, size_t setStack,
|
2022-05-29 20:52:52 +02:00
|
|
|
TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_)
|
|
|
|
: PeriodicTaskBase(setPeriod, dlmFunc_),
|
|
|
|
RTEMSTaskBase(setPriority, setStack, name),
|
|
|
|
periodTicks(RtemsBasic::convertMsToTicks(static_cast<uint32_t>(setPeriod * 1000.0))) {}
|
2021-01-28 11:28:28 +01:00
|
|
|
|
2022-05-29 20:52:52 +02:00
|
|
|
PeriodicTask::~PeriodicTask() {
|
2022-02-02 10:29:30 +01:00
|
|
|
/* Do not delete objects, we were responsible for pointers only. */
|
|
|
|
rtems_rate_monotonic_delete(periodId);
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rtems_task PeriodicTask::taskEntryPoint(rtems_task_argument argument) {
|
2022-02-02 10:29:30 +01:00
|
|
|
/* The argument is re-interpreted as MultiObjectTask. The Task object is global,
|
|
|
|
so it is found from any place. */
|
2022-05-29 20:52:52 +02:00
|
|
|
auto* originalTask(reinterpret_cast<PeriodicTask*>(argument));
|
2022-02-02 10:29:30 +01:00
|
|
|
return originalTask->taskFunctionality();
|
|
|
|
;
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PeriodicTask::startTask() {
|
2022-02-02 10:29:30 +01:00
|
|
|
rtems_status_code status =
|
|
|
|
rtems_task_start(id, PeriodicTask::taskEntryPoint, rtems_task_argument((void*)this));
|
|
|
|
if (status != RTEMS_SUCCESSFUL) {
|
2021-01-28 11:28:28 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2022-05-29 20:52:52 +02:00
|
|
|
sif::error << "PeriodicTask::startTask for " << std::hex << this->getId() << std::dec
|
|
|
|
<< " failed" << std::endl;
|
|
|
|
#else
|
|
|
|
sif::printError("PeriodicTask::startTask for 0x%08x failed\n", getId());
|
2021-01-28 11:28:28 +01:00
|
|
|
#endif
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
|
|
|
switch (status) {
|
2021-01-28 11:28:28 +01:00
|
|
|
case RTEMS_SUCCESSFUL:
|
2022-02-02 10:29:30 +01:00
|
|
|
/* Task started successfully */
|
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
2021-01-28 11:28:28 +01:00
|
|
|
default:
|
2022-02-02 10:29:30 +01:00
|
|
|
/* RTEMS_INVALID_ADDRESS - invalid task entry point
|
|
|
|
RTEMS_INVALID_ID - invalid task id
|
|
|
|
RTEMS_INCORRECT_STATE - task not in the dormant state
|
|
|
|
RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task */
|
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
}
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) { return RTEMSTaskBase::sleepFor(ms); }
|
2021-01-28 11:28:28 +01:00
|
|
|
|
2022-05-29 20:52:52 +02:00
|
|
|
[[noreturn]] void PeriodicTask::taskFunctionality() {
|
2022-02-02 10:29:30 +01:00
|
|
|
RTEMSTaskBase::setAndStartPeriod(periodTicks, &periodId);
|
2022-05-29 20:52:52 +02:00
|
|
|
initObjsAfterTaskCreation();
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
/* The task's "infinite" inner loop is entered. */
|
2022-05-29 20:52:52 +02:00
|
|
|
while (true) {
|
|
|
|
for (const auto& objectPair : objectList) {
|
|
|
|
objectPair.first->performOperation(objectPair.second);
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
rtems_status_code status = RTEMSTaskBase::restartPeriod(periodTicks, periodId);
|
|
|
|
if (status == RTEMS_TIMEOUT) {
|
2022-05-29 20:52:52 +02:00
|
|
|
if (dlmFunc != nullptr) {
|
|
|
|
dlmFunc();
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|