2021-01-27 18:12:48 +01:00
|
|
|
#include "FixedTimeslotTask.h"
|
2021-01-27 18:03:56 +01:00
|
|
|
#include "RtemsBasic.h"
|
|
|
|
|
2020-11-17 19:25:57 +01:00
|
|
|
#include "../../tasks/FixedSequenceSlot.h"
|
2020-08-13 20:53:35 +02:00
|
|
|
#include "../../objectmanager/SystemObjectIF.h"
|
2020-11-17 19:25:57 +01:00
|
|
|
#include "../../objectmanager/ObjectManagerIF.h"
|
2020-08-13 20:53:35 +02:00
|
|
|
#include "../../returnvalues/HasReturnvaluesIF.h"
|
2021-01-27 18:03:56 +01:00
|
|
|
#include "../../serviceinterface/ServiceInterface.h"
|
|
|
|
|
2018-07-13 18:28:26 +02:00
|
|
|
#include <rtems/bspIo.h>
|
|
|
|
#include <rtems/rtems/ratemon.h>
|
|
|
|
#include <rtems/rtems/status.h>
|
|
|
|
#include <rtems/rtems/tasks.h>
|
|
|
|
#include <rtems/rtems/types.h>
|
|
|
|
#include <sys/_stdint.h>
|
2021-01-27 18:03:56 +01:00
|
|
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2018-07-13 18:28:26 +02:00
|
|
|
#include <iostream>
|
2021-01-27 18:03:56 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <cstddef>
|
2018-07-13 18:28:26 +02:00
|
|
|
#include <list>
|
2018-07-12 16:29:32 +02:00
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
|
2018-07-12 16:29:32 +02:00
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
FixedTimeslotTask::FixedTimeslotTask(const char *name, rtems_task_priority setPriority,
|
2018-07-12 16:29:32 +02:00
|
|
|
size_t setStack, uint32_t setOverallPeriod,
|
|
|
|
void (*setDeadlineMissedFunc)()) :
|
2021-01-27 00:59:34 +01:00
|
|
|
RTEMSTaskBase(setPriority, setStack, name), periodId(0), pst(
|
2018-07-12 16:29:32 +02:00
|
|
|
setOverallPeriod) {
|
|
|
|
// All additional attributes are applied to the object.
|
|
|
|
this->deadlineMissedFunc = setDeadlineMissedFunc;
|
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
FixedTimeslotTask::~FixedTimeslotTask() {
|
2018-07-12 16:29:32 +02:00
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
rtems_task FixedTimeslotTask::taskEntryPoint(rtems_task_argument argument) {
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
//The argument is re-interpreted as PollingTask.
|
2021-01-27 18:12:12 +01:00
|
|
|
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(argument));
|
2018-07-12 16:29:32 +02:00
|
|
|
//The task's functionality is called.
|
2021-01-27 18:12:12 +01:00
|
|
|
return originalTask->taskFunctionality();
|
|
|
|
/* Should never be reached */
|
2021-01-04 15:34:08 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2021-01-27 18:12:12 +01:00
|
|
|
sif::error << "Polling task " << originalTask->getId() << " returned from taskFunctionality." <<
|
|
|
|
std::endl;
|
2021-01-04 15:34:08 +01:00
|
|
|
#endif
|
2018-07-12 16:29:32 +02:00
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
void FixedTimeslotTask::missedDeadlineCounter() {
|
|
|
|
FixedTimeslotTask::deadlineMissedCount++;
|
|
|
|
if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) {
|
2021-01-04 15:34:08 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2021-01-27 18:12:12 +01:00
|
|
|
sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount
|
2018-07-12 16:29:32 +02:00
|
|
|
<< " deadlines." << std::endl;
|
2021-01-04 15:34:08 +01:00
|
|
|
#endif
|
2018-07-12 16:29:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
ReturnValue_t FixedTimeslotTask::startTask() {
|
|
|
|
rtems_status_code status = rtems_task_start(id, FixedTimeslotTask::taskEntryPoint,
|
2018-07-12 16:29:32 +02:00
|
|
|
rtems_task_argument((void *) this));
|
|
|
|
if (status != RTEMS_SUCCESSFUL) {
|
2021-01-04 15:34:08 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-11-17 19:25:57 +01:00
|
|
|
sif::error << "PollingTask::startTask for " << std::hex << this->getId()
|
2018-07-12 16:29:32 +02:00
|
|
|
<< std::dec << " failed." << std::endl;
|
2021-01-04 15:34:08 +01:00
|
|
|
#endif
|
2018-07-12 16:29:32 +02:00
|
|
|
}
|
2018-07-13 18:28:26 +02:00
|
|
|
switch(status){
|
|
|
|
case RTEMS_SUCCESSFUL:
|
|
|
|
//ask started successfully
|
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
default:
|
|
|
|
/* 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;
|
|
|
|
}
|
2018-07-12 16:29:32 +02:00
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
|
2020-05-05 18:32:50 +02:00
|
|
|
uint32_t slotTimeMs, int8_t executionStep) {
|
2020-11-17 19:25:57 +01:00
|
|
|
ExecutableObjectIF* object = objectManager->get<ExecutableObjectIF>(componentId);
|
|
|
|
if (object != nullptr) {
|
|
|
|
pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
|
2020-05-05 18:32:50 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
2018-07-12 16:29:32 +02:00
|
|
|
|
2021-01-04 15:34:08 +01:00
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2020-11-17 19:25:57 +01:00
|
|
|
sif::error << "Component " << std::hex << componentId <<
|
2020-05-05 18:32:50 +02:00
|
|
|
" not found, not adding it to pst" << std::endl;
|
2021-01-04 15:34:08 +01:00
|
|
|
#endif
|
2020-05-05 18:32:50 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
}
|
2020-05-05 18:36:18 +02:00
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
uint32_t FixedTimeslotTask::getPeriodMs() const {
|
2018-07-12 16:29:32 +02:00
|
|
|
return pst.getLengthMs();
|
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
ReturnValue_t FixedTimeslotTask::checkSequence() const {
|
2018-07-12 16:29:32 +02:00
|
|
|
return pst.checkSequence();
|
|
|
|
}
|
|
|
|
|
2018-07-13 18:28:26 +02:00
|
|
|
#include <rtems/io.h>
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
void FixedTimeslotTask::taskFunctionality() {
|
2018-07-12 16:29:32 +02:00
|
|
|
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
2020-11-17 19:25:57 +01:00
|
|
|
FixedSlotSequence::SlotListIter it = pst.current;
|
2018-07-12 16:29:32 +02:00
|
|
|
|
|
|
|
//The start time for the first entry is read.
|
2020-11-17 19:25:57 +01:00
|
|
|
rtems_interval interval = RtemsBasic::convertMsToTicks(it->pollingTimeMs);
|
2021-01-27 00:59:34 +01:00
|
|
|
RTEMSTaskBase::setAndStartPeriod(interval,&periodId);
|
2018-07-12 16:29:32 +02:00
|
|
|
//The task's "infinite" inner loop is entered.
|
|
|
|
while (1) {
|
|
|
|
if (pst.slotFollowsImmediately()) {
|
|
|
|
//Do nothing
|
|
|
|
} else {
|
|
|
|
//The interval for the next polling slot is selected.
|
2018-07-13 15:56:37 +02:00
|
|
|
interval = RtemsBasic::convertMsToTicks(this->pst.getIntervalToNextSlotMs());
|
2018-07-12 16:29:32 +02:00
|
|
|
//The period is checked and restarted with the new interval.
|
|
|
|
//If the deadline was missed, the deadlineMissedFunc is called.
|
2021-01-27 00:59:34 +01:00
|
|
|
rtems_status_code status = RTEMSTaskBase::restartPeriod(interval,periodId);
|
2018-07-12 16:29:32 +02:00
|
|
|
if (status == RTEMS_TIMEOUT) {
|
2020-11-17 19:35:37 +01:00
|
|
|
if (this->deadlineMissedFunc != nullptr) {
|
2018-07-12 16:29:32 +02:00
|
|
|
this->deadlineMissedFunc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//The device handler for this slot is executed and the next one is chosen.
|
|
|
|
this->pst.executeAndAdvance();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-27 18:12:12 +01:00
|
|
|
ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms){
|
2021-01-27 00:59:34 +01:00
|
|
|
return RTEMSTaskBase::sleepFor(ms);
|
2018-07-12 16:29:32 +02:00
|
|
|
};
|