fsfw/src/fsfw/osal/linux/FixedTimeslotTask.cpp

66 lines
2.2 KiB
C++
Raw Normal View History

2021-07-13 20:58:45 +02:00
#include "fsfw/osal/linux/FixedTimeslotTask.h"
2021-06-05 19:52:38 +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;
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.
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
}
[[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
}
// 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.
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.
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.
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-20 15:02:16 +02:00
if(dlmFunc != nullptr){
dlmFunc();
}
2022-02-02 10:29:30 +01:00
}
}
// The device handler for this slot is executed and the next one is chosen.
pollingSeqTable.executeAndAdvance();
2022-02-02 10:29:30 +01:00
}
2018-07-13 18:28:26 +02:00
}