2021-07-14 10:50:44 +02:00
|
|
|
#include "fsfw/osal/rtems/FixedTimeslotTask.h"
|
2021-01-28 11:28:28 +01:00
|
|
|
|
|
|
|
#include <rtems/io.h>
|
|
|
|
#include <rtems/rtems/status.h>
|
|
|
|
#include <rtems/rtems/tasks.h>
|
|
|
|
#include <rtems/rtems/types.h>
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
#include "fsfw/osal/rtems/RtemsBasic.h"
|
|
|
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
|
|
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
|
|
|
2021-01-28 11:28:28 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
#include <iostream>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
FixedTimeslotTask::FixedTimeslotTask(const char *name, rtems_task_priority setPriority,
|
2022-05-29 20:52:52 +02:00
|
|
|
size_t setStack, TaskPeriod setOverallPeriod,
|
|
|
|
TaskDeadlineMissedFunction dlmFunc_)
|
|
|
|
: FixedTimeslotTaskBase(setOverallPeriod, dlmFunc_),
|
|
|
|
RTEMSTaskBase(setPriority, setStack, name),
|
|
|
|
periodId(0) {}
|
2021-01-28 11:28:28 +01:00
|
|
|
|
2022-05-29 20:52:52 +02:00
|
|
|
FixedTimeslotTask::~FixedTimeslotTask() = default;
|
2021-01-28 11:28:28 +01:00
|
|
|
|
|
|
|
rtems_task FixedTimeslotTask::taskEntryPoint(rtems_task_argument argument) {
|
2022-02-02 10:29:30 +01:00
|
|
|
/* The argument is re-interpreted as a FixedTimeslotTask */
|
2022-05-29 20:52:52 +02:00
|
|
|
auto *originalTask(reinterpret_cast<FixedTimeslotTask *>(argument));
|
2022-02-02 10:29:30 +01:00
|
|
|
/* The task's functionality is called. */
|
|
|
|
return originalTask->taskFunctionality();
|
|
|
|
/* Should never be reached */
|
2021-01-28 11:28:28 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2022-02-02 10:29:30 +01:00
|
|
|
sif::error << "Polling task " << originalTask->getId() << " returned from taskFunctionality."
|
|
|
|
<< std::endl;
|
2021-01-28 11:28:28 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t FixedTimeslotTask::startTask() {
|
2022-02-02 10:29:30 +01:00
|
|
|
rtems_status_code status =
|
|
|
|
rtems_task_start(id, FixedTimeslotTask::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-02-02 10:29:30 +01:00
|
|
|
sif::error << "PollingTask::startTask for " << std::hex << this->getId() << std::dec
|
|
|
|
<< " failed." << std::endl;
|
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
|
|
|
// ask 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-05-29 20:52:52 +02:00
|
|
|
[[noreturn]] void FixedTimeslotTask::taskFunctionality() {
|
2022-02-02 10:29:30 +01:00
|
|
|
/* A local iterator for the Polling Sequence Table is created to find the start time for
|
|
|
|
the first entry. */
|
2022-05-29 20:52:52 +02:00
|
|
|
auto it = pollingSeqTable.current;
|
2022-02-02 10:29:30 +01:00
|
|
|
|
|
|
|
/* Initialize the PST with the correct calling task */
|
2022-05-29 20:52:52 +02:00
|
|
|
pollingSeqTable.intializeSequenceAfterTaskCreation();
|
2022-02-02 10:29:30 +01:00
|
|
|
|
|
|
|
/* The start time for the first entry is read. */
|
|
|
|
rtems_interval interval = RtemsBasic::convertMsToTicks(it->pollingTimeMs);
|
|
|
|
RTEMSTaskBase::setAndStartPeriod(interval, &periodId);
|
|
|
|
// The task's "infinite" inner loop is entered.
|
2022-05-29 20:52:52 +02:00
|
|
|
while (true) {
|
|
|
|
if (pollingSeqTable.slotFollowsImmediately()) {
|
2022-02-02 10:29:30 +01:00
|
|
|
/* Do nothing */
|
|
|
|
} else {
|
|
|
|
/* The interval for the next polling slot is selected. */
|
2022-05-29 20:52:52 +02:00
|
|
|
interval = RtemsBasic::convertMsToTicks(pollingSeqTable.getIntervalToNextSlotMs());
|
2022-02-02 10:29:30 +01:00
|
|
|
/* The period is checked and restarted with the new interval.
|
|
|
|
If the deadline was missed, the deadlineMissedFunc is called. */
|
|
|
|
rtems_status_code status = RTEMSTaskBase::restartPeriod(interval, periodId);
|
|
|
|
if (status == RTEMS_TIMEOUT) {
|
2022-05-29 20:52:52 +02:00
|
|
|
if (dlmFunc != nullptr) {
|
|
|
|
dlmFunc();
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
/* The device handler for this slot is executed and the next one is chosen. */
|
2022-05-29 20:52:52 +02:00
|
|
|
this->pollingSeqTable.executeAndAdvance();
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2021-01-28 11:28:28 +01:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { return RTEMSTaskBase::sleepFor(ms); };
|