2021-07-13 20:58:45 +02:00
|
|
|
#include "fsfw/osal/linux/FixedTimeslotTask.h"
|
2021-06-05 19:52:38 +02:00
|
|
|
|
2022-05-19 00:44:34 +02:00
|
|
|
#include <climits>
|
2022-02-02 10:29:30 +01:00
|
|
|
|
2021-07-13 20:58:45 +02:00
|
|
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
2018-07-13 18:28:26 +02:00
|
|
|
|
|
|
|
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
|
|
|
|
2022-05-19 00:44:34 +02:00
|
|
|
FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
|
|
|
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_)
|
|
|
|
: FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
|
|
|
|
posixThread(name_, priority_, stackSize_),
|
2022-05-18 15:42:18 +02:00
|
|
|
started(false) {}
|
2018-07-13 18:28:26 +02:00
|
|
|
|
|
|
|
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
|
2022-02-02 10:29:30 +01:00
|
|
|
// The argument is re-interpreted as PollingTask.
|
2022-05-19 00:44:34 +02:00
|
|
|
auto* originalTask(reinterpret_cast<FixedTimeslotTask*>(arg));
|
2022-02-02 10:29:30 +01:00
|
|
|
// The task's functionality is called.
|
|
|
|
originalTask->taskFunctionality();
|
|
|
|
return nullptr;
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t FixedTimeslotTask::startTask() {
|
2022-02-02 10:29:30 +01:00
|
|
|
started = true;
|
2022-05-18 15:42:18 +02:00
|
|
|
posixThread.createTask(&taskEntryPoint, this);
|
2022-02-02 10:29:30 +01:00
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
|
2022-02-02 10:29:30 +01:00
|
|
|
return PosixThread::sleep((uint64_t)ms * 1000000);
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|
|
|
|
|
2022-05-19 00:44:34 +02:00
|
|
|
[[noreturn]] void FixedTimeslotTask::taskFunctionality() {
|
2022-02-02 10:29:30 +01:00
|
|
|
// Like FreeRTOS pthreads are running as soon as they are created
|
|
|
|
if (!started) {
|
2022-05-18 15:42:18 +02:00
|
|
|
posixThread.suspend();
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
|
|
|
|
2022-05-30 12:21:18 +02:00
|
|
|
// Returnvalue ignored for now
|
|
|
|
static_cast<void>(pollingSeqTable.intializeSequenceAfterTaskCreation());
|
2022-02-02 10:29:30 +01:00
|
|
|
|
|
|
|
// The start time for the first entry is read.
|
2022-05-19 00:44:34 +02:00
|
|
|
uint64_t lastWakeTime = PosixThread::getCurrentMonotonicTimeMs();
|
|
|
|
uint32_t interval = 0;
|
2022-02-02 10:29:30 +01:00
|
|
|
|
|
|
|
// The task's "infinite" inner loop is entered.
|
2022-05-19 00:44:34 +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-19 00:44:34 +02:00
|
|
|
interval = pollingSeqTable.getIntervalToPreviousSlotMs();
|
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.
|
|
|
|
if (!PosixThread::delayUntil(&lastWakeTime, interval)) {
|
|
|
|
// No time left on timer -> we missed the deadline
|
2022-06-23 11:56:46 +02:00
|
|
|
if (dlmFunc != nullptr) {
|
2022-06-20 15:02:16 +02:00
|
|
|
dlmFunc();
|
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// The device handler for this slot is executed and the next one is chosen.
|
2022-05-19 00:44:34 +02:00
|
|
|
pollingSeqTable.executeAndAdvance();
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|