diff --git a/.gitignore b/.gitignore
index d6efb9cf..eb461072 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,14 @@
+# PyCharm and CLion
+/.idea/*
+!/.idea/runConfigurations
+!/.idea/cmake.xml
+!/.idea/codeStyles
+
+# Eclipse
.cproject
.project
.settings
.metadata
/build*
+/cmake-build*
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..0f3b1a4b
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..79ee123c
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/fsfw-tests_coverage.run.xml b/.run/fsfw-tests_coverage.run.xml
new file mode 100644
index 00000000..49d9b135
--- /dev/null
+++ b/.run/fsfw-tests_coverage.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/fsfw.run.xml b/.run/fsfw.run.xml
new file mode 100644
index 00000000..72f74939
--- /dev/null
+++ b/.run/fsfw.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66e177c5..8bb8ad27 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Changes
+- Renamed auto-formatting script to `auto-formatter.sh` and made it more robust.
+ If `cmake-format` is installed, it will also auto-format the `CMakeLists.txt` files now.
+ PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/625
+ PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/626
- Bump C++ required version to C++17. Every project which uses the FSFW and every modern
compiler supports it
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/622
@@ -46,6 +50,38 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583
+### Task Module Refactoring
+
+PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/636
+
+**Refactoring general task code**
+
+- There was a lot of duplicate/boilerplate code inside the individual task IF OSAL implementations.
+ Remove it by introducing base classes `PeriodicTaskBase` and `FixedTimeslotTaskBase`.
+
+**Refactor PeriodicTaskIF**
+
+- Convert `virtual ReturnValue_t addComponent(object_id_t object)` to
+ `virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0)`, allowing to pass
+ the operation code passed to `performOperation`. Updated API taking
+ an `ExecutableObjectIF` accordingly
+
+**Refactor FixedTimeslotTaskIF**
+
+- Add additional `addSlot` function which takes an `ExecutableObjectIF` pointer and its Object ID
+
+**Refactor FixedSequenceSlot**
+
+- Introduce typedef `CustomCheckFunc` for `ReturnValue_t (*customCheckFunction)(const SlotList&)`.
+- Convert `ReturnValue_t (*customCheckFunction)(const SlotList&)` to
+ `ReturnValue_t (*customCheckFunction)(const SlotList&, void*)`, allowing arbitrary user arguments
+ for the custom checker
+
+**Linux Task Module**
+
+- Use composition instead of inheritance for the `PeriodicPosixTask` and make the `PosixTask` a
+ member of the class
+
### HAL
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
@@ -87,6 +123,11 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
## Additions
+- Added options for CI/CD builds: `FSFW_CICD_BUILD`. This allows the source code to know
+ whether it is running in CI/CD
+ PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/623
+- Basic `clion` support: Update `.gitignore` and add some basic run configurations
+ PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/625
- LTO support: Allow using LTO/IPO by setting `FSFW_ENABLE_LTO=1`. CMake is able to detect whether
the user compiler supports IPO/LPO. LTO is on by default now. Most modern compilers support it,
can make good use of it and it usually makes the code faster and/or smaller.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 40c0b879..d8163f3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -71,7 +71,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION
20
CACHE STRING "ETL library major version requirement")
set(FSFW_ETL_LIB_VERSION
- ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3
+ ${FSFW_ETL_LIB_MAJOR_VERSION}.28.0
CACHE STRING "ETL library exact version requirement")
set(FSFW_ETL_LINK_TARGET etl::etl)
@@ -105,6 +105,7 @@ endif()
option(FSFW_BUILD_UNITTESTS
"Build unittest binary in addition to static library" OFF)
+option(FSFW_CICD_BUILD "Build for CI/CD. This can disable problematic test" OFF)
option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF)
if(FSFW_BUILD_UNITTESTS)
option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON)
diff --git a/README.md b/README.md
index 99c842af..8d611c57 100644
--- a/README.md
+++ b/README.md
@@ -99,7 +99,7 @@ add and link against the FSFW library in general.
4. Link against the FSFW library
- ```cmake
+ ```sh
target_link_libraries(${YourProjectName} PRIVATE fsfw)
```
@@ -131,7 +131,7 @@ default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF
You can use the following commands inside the `fsfw` folder to set up the build system
```sh
-mkdir build-Unittest && cd build-Unittest
+mkdir build-tests && cd build-tests
cmake -DFSFW_BUILD_UNITTESTS=ON -DFSFW_OSAL=host -DCMAKE_BUILD_TYPE=Debug ..
```
diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile
index 6abf5636..798b6b1a 100644
--- a/automation/Jenkinsfile
+++ b/automation/Jenkinsfile
@@ -14,7 +14,7 @@ pipeline {
stage('Configure') {
steps {
dir(BUILDDIR) {
- sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_UNITTESTS=ON ..'
+ sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_UNITTESTS=ON -DFSFW_CICD_BUILD=ON ..'
}
}
}
diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp
index dcf92b5d..b06def69 100644
--- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp
+++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp
@@ -210,7 +210,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
#endif
return result;
}
- ReturnValue_t result = gpioComIF->pullLow(gpioId);
+ result = gpioComIF->pullLow(gpioId);
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
diff --git a/hal/src/fsfw_hal/stm32h7/devicetest/GyroL3GD20H.h b/hal/src/fsfw_hal/stm32h7/devicetest/GyroL3GD20H.h
index a6c3376a..a0c3748a 100644
--- a/hal/src/fsfw_hal/stm32h7/devicetest/GyroL3GD20H.h
+++ b/hal/src/fsfw_hal/stm32h7/devicetest/GyroL3GD20H.h
@@ -10,6 +10,10 @@
#include "stm32h7xx_hal.h"
#include "stm32h7xx_hal_spi.h"
+#ifndef STM_USE_PERIPHERAL_TX_BUFFER_MPU_PROTECTION
+#define STM_USE_PERIPHERAL_TX_BUFFER_MPU_PROTECTION 1
+#endif
+
enum class TransferStates { IDLE, WAIT, SUCCESS, FAILURE };
class GyroL3GD20H {
diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
index 781d8f71..215d1753 100644
--- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
+++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
@@ -696,9 +696,9 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
if (result != HasReturnvaluesIF::RETURN_OK) {
/* Configuration error */
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::warning << "LocalDataPoolManager::performHkOperation: HK generation failed." << std::endl;
+ sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed." << std::endl;
#else
- sif::printWarning("LocalDataPoolManager::performHkOperation: HK generation failed.\n");
+ sif::printWarning("LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
#endif
}
}
diff --git a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp
index e0e3779e..e86636ab 100644
--- a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp
@@ -1,27 +1,23 @@
#include "fsfw/osal/freertos/FixedTimeslotTask.h"
-#include "fsfw/objectmanager/ObjectManager.h"
-#include "fsfw/serviceinterface/ServiceInterface.h"
+#include "fsfw/serviceinterface.h"
-uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
FixedTimeslotTask::FixedTimeslotTask(TaskName name, TaskPriority setPriority,
- TaskStackSize setStack, TaskPeriod overallPeriod,
- void (*setDeadlineMissedFunc)())
- : started(false), handle(nullptr), pst(overallPeriod * 1000) {
+ TaskStackSize setStack, TaskPeriod period,
+ TaskDeadlineMissedFunction dlmFunc_)
+ : FixedTimeslotTaskBase(period, dlmFunc_), started(false), handle(nullptr) {
configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE);
xTaskCreate(taskEntryPoint, name, stackSize, this, setPriority, &handle);
- // All additional attributes are applied to the object.
- this->deadlineMissedFunc = setDeadlineMissedFunc;
}
-FixedTimeslotTask::~FixedTimeslotTask() {}
+FixedTimeslotTask::~FixedTimeslotTask() = default;
void FixedTimeslotTask::taskEntryPoint(void* argument) {
// The argument is re-interpreted as FixedTimeslotTask. The Task object is
// global, so it is found from any place.
- FixedTimeslotTask* originalTask(reinterpret_cast(argument));
+ auto* originalTask(reinterpret_cast(argument));
/* Task should not start until explicitly requested,
* but in FreeRTOS, tasks start as soon as they are created if the scheduler
* is running but not if the scheduler is not running.
@@ -32,26 +28,18 @@ void FixedTimeslotTask::taskEntryPoint(void* argument) {
* can continue */
if (not originalTask->started) {
- vTaskSuspend(NULL);
+ vTaskSuspend(nullptr);
}
originalTask->taskFunctionality();
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "Polling task " << originalTask->handle << " returned from taskFunctionality."
<< std::endl;
+#else
+ sif::printDebug("Polling task returned from taskFunctionality\n");
#endif
}
-void FixedTimeslotTask::missedDeadlineCounter() {
- FixedTimeslotTask::deadlineMissedCount++;
- if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines."
- << std::endl;
-#endif
- }
-}
-
ReturnValue_t FixedTimeslotTask::startTask() {
started = true;
@@ -63,31 +51,12 @@ ReturnValue_t FixedTimeslotTask::startTask() {
return HasReturnvaluesIF::RETURN_OK;
}
-ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) {
- ExecutableObjectIF* handler = ObjectManager::instance()->get(componentId);
- if (handler != nullptr) {
- pst.addSlot(componentId, slotTimeMs, executionStep, handler, this);
- return HasReturnvaluesIF::RETURN_OK;
- }
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "Component " << std::hex << componentId << " not found, not adding it to pst"
- << std::endl;
-#endif
- return HasReturnvaluesIF::RETURN_FAILED;
-}
-
-uint32_t FixedTimeslotTask::getPeriodMs() const { return pst.getLengthMs(); }
-
-ReturnValue_t FixedTimeslotTask::checkSequence() const { return pst.checkSequence(); }
-
-void FixedTimeslotTask::taskFunctionality() {
+[[noreturn]] void FixedTimeslotTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the
// start time for the first entry.
- auto slotListIter = pst.current;
+ auto slotListIter = pollingSeqTable.current;
- pst.intializeSequenceAfterTaskCreation();
+ pollingSeqTable.intializeSequenceAfterTaskCreation();
// The start time for the first entry is read.
uint32_t intervalMs = slotListIter->pollingTimeMs;
@@ -108,10 +77,10 @@ void FixedTimeslotTask::taskFunctionality() {
/* Enter the loop that defines the task behavior. */
for (;;) {
// The component for this slot is executed and the next one is chosen.
- this->pst.executeAndAdvance();
- if (not pst.slotFollowsImmediately()) {
+ this->pollingSeqTable.executeAndAdvance();
+ if (not pollingSeqTable.slotFollowsImmediately()) {
// Get the interval till execution of the next slot.
- intervalMs = this->pst.getIntervalToPreviousSlotMs();
+ intervalMs = this->pollingSeqTable.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs);
#if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || tskKERNEL_VERSION_MAJOR > 10
@@ -132,8 +101,8 @@ void FixedTimeslotTask::taskFunctionality() {
}
void FixedTimeslotTask::handleMissedDeadline() {
- if (deadlineMissedFunc != nullptr) {
- this->deadlineMissedFunc();
+ if (dlmFunc != nullptr) {
+ dlmFunc();
}
}
diff --git a/src/fsfw/osal/freertos/FixedTimeslotTask.h b/src/fsfw/osal/freertos/FixedTimeslotTask.h
index 77999d71..53c9a11c 100644
--- a/src/fsfw/osal/freertos/FixedTimeslotTask.h
+++ b/src/fsfw/osal/freertos/FixedTimeslotTask.h
@@ -4,11 +4,11 @@
#include "FreeRTOS.h"
#include "FreeRTOSTaskIF.h"
#include "fsfw/tasks/FixedSlotSequence.h"
-#include "fsfw/tasks/FixedTimeslotTaskIF.h"
-#include "fsfw/tasks/Typedef.h"
+#include "fsfw/tasks/FixedTimeslotTaskBase.h"
+#include "fsfw/tasks/definitions.h"
#include "task.h"
-class FixedTimeslotTask : public FixedTimeslotTaskIF, public FreeRTOSTaskIF {
+class FixedTimeslotTask : public FixedTimeslotTaskBase, public FreeRTOSTaskIF {
public:
/**
* Keep in mind that you need to call before vTaskStartScheduler()!
@@ -23,7 +23,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public FreeRTOSTaskIF {
* @return Pointer to the newly created task.
*/
FixedTimeslotTask(TaskName name, TaskPriority setPriority, TaskStackSize setStack,
- TaskPeriod overallPeriod, void (*setDeadlineMissedFunc)());
+ TaskPeriod overallPeriod, TaskDeadlineMissedFunction dlmFunc);
/**
* @brief The destructor of the class.
@@ -32,26 +32,9 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public FreeRTOSTaskIF {
* initialization for the PST and the device handlers. This is done by
* calling the PST's destructor.
*/
- virtual ~FixedTimeslotTask(void);
+ ~FixedTimeslotTask() override;
- ReturnValue_t startTask(void);
- /**
- * This static function can be used as #deadlineMissedFunc.
- * It counts missedDeadlines and prints the number of missed deadlines
- * every 10th time.
- */
- static void missedDeadlineCounter();
- /**
- * A helper variable to count missed deadlines.
- */
- static uint32_t deadlineMissedCount;
-
- ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) override;
-
- uint32_t getPeriodMs() const override;
-
- ReturnValue_t checkSequence() const override;
+ ReturnValue_t startTask() override;
ReturnValue_t sleepFor(uint32_t ms) override;
@@ -61,17 +44,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public FreeRTOSTaskIF {
bool started;
TaskHandle_t handle;
- FixedSlotSequence pst;
-
- /**
- * @brief This attribute holds a function pointer that is executed when
- * a deadline was missed.
- * @details
- * Another function may be announced to determine the actions to perform
- * when a deadline was missed. Currently, only one function for missing
- * any deadline is allowed. If not used, it shall be declared NULL.
- */
- void (*deadlineMissedFunc)(void);
/**
* @brief This is the entry point for a new task.
* @details
@@ -88,7 +60,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public FreeRTOSTaskIF {
* It links the functionalities provided by FixedSlotSequence with the
* OS's System Calls to keep the timing of the periods.
*/
- void taskFunctionality(void);
+ [[noreturn]] void taskFunctionality();
void handleMissedDeadline();
};
diff --git a/src/fsfw/osal/freertos/FreeRTOSTaskIF.h b/src/fsfw/osal/freertos/FreeRTOSTaskIF.h
index ad5c9f7f..dbefc6c1 100644
--- a/src/fsfw/osal/freertos/FreeRTOSTaskIF.h
+++ b/src/fsfw/osal/freertos/FreeRTOSTaskIF.h
@@ -6,11 +6,11 @@
class FreeRTOSTaskIF {
public:
- virtual ~FreeRTOSTaskIF() {}
+ virtual ~FreeRTOSTaskIF() = default;
virtual TaskHandle_t getTaskHandle() = 0;
protected:
- bool checkMissedDeadline(const TickType_t xLastWakeTime, const TickType_t interval) {
+ static bool checkMissedDeadline(const TickType_t xLastWakeTime, const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
diff --git a/src/fsfw/osal/freertos/PeriodicTask.cpp b/src/fsfw/osal/freertos/PeriodicTask.cpp
index d2c46ea8..665be06c 100644
--- a/src/fsfw/osal/freertos/PeriodicTask.cpp
+++ b/src/fsfw/osal/freertos/PeriodicTask.cpp
@@ -5,27 +5,28 @@
#include "fsfw/tasks/ExecutableObjectIF.h"
PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack,
- TaskPeriod setPeriod, TaskDeadlineMissedFunction deadlineMissedFunc)
- : started(false), handle(NULL), period(setPeriod), deadlineMissedFunc(deadlineMissedFunc) {
+ TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_)
+ : PeriodicTaskBase(setPeriod, dlmFunc_), started(false), handle(nullptr) {
configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE);
BaseType_t status = xTaskCreate(taskEntryPoint, name, stackSize, this, setPriority, &handle);
if (status != pdPASS) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::debug << "PeriodicTask Insufficient heap memory remaining. "
- "Status: "
+ sif::debug << "PeriodicTask::PeriodicTask Insufficient heap memory remaining. Status: "
<< status << std::endl;
+#else
+ sif::printDebug("PeriodicTask::PeriodicTask: Insufficient heap memory remaining. Status: %d\n",
+ status);
#endif
}
}
-PeriodicTask::~PeriodicTask(void) {
- // Do not delete objects, we were responsible for ptrs only.
-}
+// Do not delete objects, we were responsible for ptrs only.
+PeriodicTask::~PeriodicTask() = default;
void PeriodicTask::taskEntryPoint(void* argument) {
// The argument is re-interpreted as PeriodicTask. The Task object is
// global, so it is found from any place.
- PeriodicTask* originalTask(reinterpret_cast(argument));
+ auto* originalTask(reinterpret_cast(argument));
/* Task should not start until explicitly requested,
* but in FreeRTOS, tasks start as soon as they are created if the scheduler
* is running but not if the scheduler is not running.
@@ -36,7 +37,7 @@ void PeriodicTask::taskEntryPoint(void* argument) {
* can continue */
if (not originalTask->started) {
- vTaskSuspend(NULL);
+ vTaskSuspend(nullptr);
}
originalTask->taskFunctionality();
@@ -62,13 +63,11 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
return HasReturnvaluesIF::RETURN_OK;
}
-void PeriodicTask::taskFunctionality() {
+[[noreturn]] void PeriodicTask::taskFunctionality() {
TickType_t xLastWakeTime;
const TickType_t xPeriod = pdMS_TO_TICKS(this->period * 1000.);
- for (auto const& object : objectList) {
- object->initializeAfterTaskCreation();
- }
+ initObjsAfterTaskCreation();
/* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to
@@ -77,8 +76,8 @@ void PeriodicTask::taskFunctionality() {
xLastWakeTime = xTaskGetTickCount();
/* Enter the loop that defines the task behavior. */
for (;;) {
- for (auto const& object : objectList) {
- object->performOperation();
+ for (auto const& objectPair : objectList) {
+ objectPair.first->performOperation(objectPair.second);
}
#if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || tskKERNEL_VERSION_MAJOR > 10
@@ -95,32 +94,10 @@ void PeriodicTask::taskFunctionality() {
}
}
-ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
- ExecutableObjectIF* newObject = ObjectManager::instance()->get(object);
- return addComponent(newObject);
-}
-
-ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
- if (object == nullptr) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
- "it implement ExecutableObjectIF"
- << std::endl;
-#endif
- return HasReturnvaluesIF::RETURN_FAILED;
- }
- objectList.push_back(object);
- object->setTaskIF(this);
-
- return HasReturnvaluesIF::RETURN_OK;
-}
-
-uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; }
-
TaskHandle_t PeriodicTask::getTaskHandle() { return handle; }
void PeriodicTask::handleMissedDeadline() {
- if (deadlineMissedFunc != nullptr) {
- this->deadlineMissedFunc();
+ if (dlmFunc != nullptr) {
+ dlmFunc();
}
}
diff --git a/src/fsfw/osal/freertos/PeriodicTask.h b/src/fsfw/osal/freertos/PeriodicTask.h
index fc8e9092..c3fb9d70 100644
--- a/src/fsfw/osal/freertos/PeriodicTask.h
+++ b/src/fsfw/osal/freertos/PeriodicTask.h
@@ -6,8 +6,8 @@
#include "FreeRTOS.h"
#include "FreeRTOSTaskIF.h"
#include "fsfw/objectmanager/ObjectManagerIF.h"
-#include "fsfw/tasks/PeriodicTaskIF.h"
-#include "fsfw/tasks/Typedef.h"
+#include "fsfw/tasks/PeriodicTaskBase.h"
+#include "fsfw/tasks/definitions.h"
#include "task.h"
class ExecutableObjectIF;
@@ -17,7 +17,7 @@ class ExecutableObjectIF;
* periodic activities of multiple objects.
* @ingroup task_handling
*/
-class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF {
+class PeriodicTask : public PeriodicTaskBase, public FreeRTOSTaskIF {
public:
/**
* Keep in Mind that you need to call before this vTaskStartScheduler()!
@@ -43,7 +43,7 @@ class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF {
* @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty.
*/
- virtual ~PeriodicTask(void);
+ ~PeriodicTask() override;
/**
* @brief The method to start the task.
@@ -53,27 +53,6 @@ class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF {
* to the system call.
*/
ReturnValue_t startTask() override;
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object Id of the object to add.
- * @return
- * -@c RETURN_OK on success
- * -@c RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(object_id_t object) override;
-
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object Id of the object to add.
- * @return
- * -@c RETURN_OK on success
- * -@c RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(ExecutableObjectIF* object) override;
-
- uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms) override;
@@ -83,28 +62,6 @@ class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF {
bool started;
TaskHandle_t handle;
- //! Typedef for the List of objects.
- typedef std::vector ObjectList;
- /**
- * @brief This attribute holds a list of objects to be executed.
- */
- ObjectList objectList;
- /**
- * @brief The period of the task.
- * @details
- * The period determines the frequency of the task's execution.
- * It is expressed in clock ticks.
- */
- TaskPeriod period;
- /**
- * @brief The pointer to the deadline-missed function.
- * @details
- * This pointer stores the function that is executed if the task's deadline
- * is missed so each may react individually on a timing failure.
- * The pointer may be NULL, then nothing happens on missing the deadline.
- * The deadline is equal to the next execution of the periodic task.
- */
- void (*deadlineMissedFunc)(void);
/**
* @brief This is the function executed in the new task's context.
* @details
@@ -125,7 +82,7 @@ class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF {
* the next period.
* On missing the deadline, the deadlineMissedFunction is executed.
*/
- void taskFunctionality(void);
+ [[noreturn]] void taskFunctionality();
void handleMissedDeadline();
};
diff --git a/src/fsfw/osal/host/FixedTimeslotTask.cpp b/src/fsfw/osal/host/FixedTimeslotTask.cpp
index 07853938..1d10b8d8 100644
--- a/src/fsfw/osal/host/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/host/FixedTimeslotTask.cpp
@@ -3,9 +3,7 @@
#include
#include
-#include "fsfw/ipc/MutexFactory.h"
#include "fsfw/objectmanager/ObjectManager.h"
-#include "fsfw/osal/host/FixedTimeslotTask.h"
#include "fsfw/osal/host/Mutex.h"
#include "fsfw/osal/host/taskHelpers.h"
#include "fsfw/platform.h"
@@ -22,12 +20,8 @@
FixedTimeslotTask::FixedTimeslotTask(const char* name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod setPeriod,
- void (*setDeadlineMissedFunc)())
- : started(false),
- pollingSeqTable(setPeriod * 1000),
- taskName(name),
- period(setPeriod),
- deadlineMissedFunc(setDeadlineMissedFunc) {
+ TaskDeadlineMissedFunction dlmFunc_)
+ : FixedTimeslotTaskBase(setPeriod, dlmFunc_), started(false), taskName(name) {
// It is propably possible to set task priorities by using the native
// task handles for Windows / Linux
mainThread = std::thread(&FixedTimeslotTask::taskEntryPoint, this, this);
@@ -39,7 +33,7 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name, TaskPriority setPriority,
tasks::insertTaskName(mainThread.get_id(), taskName);
}
-FixedTimeslotTask::~FixedTimeslotTask(void) {
+FixedTimeslotTask::~FixedTimeslotTask() {
// Do not delete objects, we were responsible for ptrs only.
terminateThread = true;
if (mainThread.joinable()) {
@@ -48,7 +42,7 @@ FixedTimeslotTask::~FixedTimeslotTask(void) {
}
void FixedTimeslotTask::taskEntryPoint(void* argument) {
- FixedTimeslotTask* originalTask(reinterpret_cast(argument));
+ auto* originalTask(reinterpret_cast(argument));
if (not originalTask->started) {
// we have to suspend/block here until the task is started.
@@ -81,7 +75,9 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
}
void FixedTimeslotTask::taskFunctionality() {
- pollingSeqTable.intializeSequenceAfterTaskCreation();
+ ReturnValue_t result = pollingSeqTable.intializeSequenceAfterTaskCreation();
+ // Ignore returnvalue for now
+ static_cast(result);
// A local iterator for the Polling Sequence Table is created to
// find the start time for the first entry.
@@ -106,37 +102,15 @@ void FixedTimeslotTask::taskFunctionality() {
// we need to wait before executing the current slot
// this gives us the time to wait:
interval = chron_ms(this->pollingSeqTable.getIntervalToPreviousSlotMs());
- delayForInterval(¤tStartTime, interval);
- // TODO deadline missed check
+ if (not delayForInterval(¤tStartTime, interval)) {
+ if (dlmFunc != nullptr) {
+ dlmFunc();
+ }
+ }
}
}
}
-ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) {
- ExecutableObjectIF* executableObject =
- ObjectManager::instance()->get(componentId);
- if (executableObject != nullptr) {
- pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, executableObject, this);
- return HasReturnvaluesIF::RETURN_OK;
- }
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "Component " << std::hex << "0x" << componentId
- << "not found, "
- "not adding it to PST.."
- << std::dec << std::endl;
-#else
- sif::printError("Component 0x%08x not found, not adding it to PST..\n",
- static_cast(componentId));
-#endif
- return HasReturnvaluesIF::RETURN_FAILED;
-}
-
-ReturnValue_t FixedTimeslotTask::checkSequence() const { return pollingSeqTable.checkSequence(); }
-
-uint32_t FixedTimeslotTask::getPeriodMs() const { return period * 1000; }
-
bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) {
bool shouldDelay = false;
// Get current wakeup time
diff --git a/src/fsfw/osal/host/FixedTimeslotTask.h b/src/fsfw/osal/host/FixedTimeslotTask.h
index cdbc6f23..4e77f8fd 100644
--- a/src/fsfw/osal/host/FixedTimeslotTask.h
+++ b/src/fsfw/osal/host/FixedTimeslotTask.h
@@ -6,10 +6,10 @@
#include
#include
-#include "../../objectmanager/ObjectManagerIF.h"
-#include "../../tasks/FixedSlotSequence.h"
-#include "../../tasks/FixedTimeslotTaskIF.h"
-#include "../../tasks/Typedef.h"
+#include "fsfw/objectmanager/ObjectManagerIF.h"
+#include "fsfw/tasks/FixedSlotSequence.h"
+#include "fsfw/tasks/FixedTimeslotTaskBase.h"
+#include "fsfw/tasks/definitions.h"
class ExecutableObjectIF;
@@ -19,7 +19,7 @@ class ExecutableObjectIF;
* @details
* @ingroup task_handling
*/
-class FixedTimeslotTask : public FixedTimeslotTaskIF {
+class FixedTimeslotTask : public FixedTimeslotTaskBase {
public:
/**
* @brief Standard constructor of the class.
@@ -39,7 +39,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF {
* @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty.
*/
- virtual ~FixedTimeslotTask(void);
+ ~FixedTimeslotTask() override;
/**
* @brief The method to start the task.
@@ -48,56 +48,22 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF {
* The address of the task object is passed as an argument
* to the system call.
*/
- ReturnValue_t startTask(void);
+ ReturnValue_t startTask() override;
- /**
- * Add timeslot to the polling sequence table.
- * @param componentId
- * @param slotTimeMs
- * @param executionStep
- * @return
- */
- ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep);
-
- ReturnValue_t checkSequence() const override;
-
- uint32_t getPeriodMs() const;
-
- ReturnValue_t sleepFor(uint32_t ms);
+ ReturnValue_t sleepFor(uint32_t ms) override;
protected:
using chron_ms = std::chrono::milliseconds;
bool started;
- //!< Typedef for the List of objects.
- typedef std::vector ObjectList;
+
std::thread mainThread;
std::atomic terminateThread{false};
- //! Polling sequence table which contains the object to execute
- //! and information like the timeslots and the passed execution step.
- FixedSlotSequence pollingSeqTable;
-
std::condition_variable initCondition;
std::mutex initMutex;
std::string taskName;
- /**
- * @brief The period of the task.
- * @details
- * The period determines the frequency of the task's execution.
- * It is expressed in clock ticks.
- */
- TaskPeriod period;
- /**
- * @brief The pointer to the deadline-missed function.
- * @details
- * This pointer stores the function that is executed if the task's deadline
- * is missed. So, each may react individually on a timing failure.
- * The pointer may be NULL, then nothing happens on missing the deadline.
- * The deadline is equal to the next execution of the periodic task.
- */
- void (*deadlineMissedFunc)(void);
/**
* @brief This is the function executed in the new task's context.
* @details
@@ -117,9 +83,9 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF {
* the checkAndRestartPeriod system call blocks the task until the next
* period. On missing the deadline, the deadlineMissedFunction is executed.
*/
- void taskFunctionality(void);
+ void taskFunctionality();
- bool delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval);
+ static bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval);
};
#endif /* FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ */
diff --git a/src/fsfw/osal/host/PeriodicTask.cpp b/src/fsfw/osal/host/PeriodicTask.cpp
index cdcfafa6..1f18d335 100644
--- a/src/fsfw/osal/host/PeriodicTask.cpp
+++ b/src/fsfw/osal/host/PeriodicTask.cpp
@@ -3,13 +3,10 @@
#include
#include
-#include "fsfw/ipc/MutexFactory.h"
-#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/osal/host/Mutex.h"
#include "fsfw/osal/host/taskHelpers.h"
#include "fsfw/platform.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
-#include "fsfw/tasks/ExecutableObjectIF.h"
#if defined(PLATFORM_WIN)
#include
@@ -20,8 +17,8 @@
#endif
PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack,
- TaskPeriod setPeriod, void (*setDeadlineMissedFunc)())
- : started(false), taskName(name), period(setPeriod), deadlineMissedFunc(setDeadlineMissedFunc) {
+ TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_)
+ : PeriodicTaskBase(setPeriod, dlmFunc_), started(false), taskName(name) {
// It is probably possible to set task priorities by using the native
// task handles for Windows / Linux
mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
@@ -33,7 +30,7 @@ PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStack
tasks::insertTaskName(mainThread.get_id(), taskName);
}
-PeriodicTask::~PeriodicTask(void) {
+PeriodicTask::~PeriodicTask() {
// Do not delete objects, we were responsible for ptrs only.
terminateThread = true;
if (mainThread.joinable()) {
@@ -42,7 +39,7 @@ PeriodicTask::~PeriodicTask(void) {
}
void PeriodicTask::taskEntryPoint(void* argument) {
- PeriodicTask* originalTask(reinterpret_cast(argument));
+ auto* originalTask(reinterpret_cast(argument));
if (not originalTask->started) {
// we have to suspend/block here until the task is started.
@@ -75,47 +72,27 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
}
void PeriodicTask::taskFunctionality() {
- for (const auto& object : objectList) {
- object->initializeAfterTaskCreation();
- }
+ initObjsAfterTaskCreation();
std::chrono::milliseconds periodChrono(static_cast(period * 1000));
auto currentStartTime{std::chrono::duration_cast(
std::chrono::system_clock::now().time_since_epoch())};
- auto nextStartTime{currentStartTime};
-
/* Enter the loop that defines the task behavior. */
for (;;) {
if (terminateThread.load()) {
break;
}
- for (const auto& object : objectList) {
- object->performOperation();
+ for (const auto& objectPair : objectList) {
+ objectPair.first->performOperation(objectPair.second);
}
if (not delayForInterval(¤tStartTime, periodChrono)) {
- if (deadlineMissedFunc != nullptr) {
- this->deadlineMissedFunc();
+ if (dlmFunc != nullptr) {
+ this->dlmFunc();
}
}
}
}
-ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
- ExecutableObjectIF* newObject = ObjectManager::instance()->get(object);
- return addComponent(newObject);
-}
-
-ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
- if (object == nullptr) {
- return HasReturnvaluesIF::RETURN_FAILED;
- }
- object->setTaskIF(this);
- objectList.push_back(object);
- return HasReturnvaluesIF::RETURN_OK;
-}
-
-uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; }
-
bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) {
bool shouldDelay = false;
// Get current wakeup time
diff --git a/src/fsfw/osal/host/PeriodicTask.h b/src/fsfw/osal/host/PeriodicTask.h
index 6c4d5e8b..6fdaae4e 100644
--- a/src/fsfw/osal/host/PeriodicTask.h
+++ b/src/fsfw/osal/host/PeriodicTask.h
@@ -6,9 +6,9 @@
#include
#include
-#include "../../objectmanager/ObjectManagerIF.h"
-#include "../../tasks/PeriodicTaskIF.h"
-#include "../../tasks/Typedef.h"
+#include "fsfw/objectmanager/ObjectManagerIF.h"
+#include "fsfw/tasks/PeriodicTaskBase.h"
+#include "fsfw/tasks/definitions.h"
class ExecutableObjectIF;
@@ -19,7 +19,7 @@ class ExecutableObjectIF;
*
* @ingroup task_handling
*/
-class PeriodicTask : public PeriodicTaskIF {
+class PeriodicTask : public PeriodicTaskBase {
public:
/**
* @brief Standard constructor of the class.
@@ -34,12 +34,12 @@ class PeriodicTask : public PeriodicTaskIF {
* assigned.
*/
PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack,
- TaskPeriod setPeriod, void (*setDeadlineMissedFunc)());
+ TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc);
/**
* @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty.
*/
- virtual ~PeriodicTask(void);
+ ~PeriodicTask() override;
/**
* @brief The method to start the task.
@@ -48,63 +48,20 @@ class PeriodicTask : public PeriodicTaskIF {
* The address of the task object is passed as an argument
* to the system call.
*/
- ReturnValue_t startTask(void);
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object Id of the object to add.
- * @return
- * -@c RETURN_OK on success
- * -@c RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(object_id_t object);
+ ReturnValue_t startTask() override;
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object pointer to the object to add.
- * @return
- * -@c RETURN_OK on success
- * -@c RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(ExecutableObjectIF* object);
-
- uint32_t getPeriodMs() const;
-
- ReturnValue_t sleepFor(uint32_t ms);
+ ReturnValue_t sleepFor(uint32_t ms) override;
protected:
using chron_ms = std::chrono::milliseconds;
bool started;
- //!< Typedef for the List of objects.
- typedef std::vector ObjectList;
std::thread mainThread;
std::atomic terminateThread{false};
- /**
- * @brief This attribute holds a list of objects to be executed.
- */
- ObjectList objectList;
-
std::condition_variable initCondition;
std::mutex initMutex;
std::string taskName;
- /**
- * @brief The period of the task.
- * @details
- * The period determines the frequency of the task's execution.
- * It is expressed in clock ticks.
- */
- TaskPeriod period;
- /**
- * @brief The pointer to the deadline-missed function.
- * @details
- * This pointer stores the function that is executed if the task's deadline
- * is missed. So, each may react individually on a timing failure.
- * The pointer may be NULL, then nothing happens on missing the deadline.
- * The deadline is equal to the next execution of the periodic task.
- */
- void (*deadlineMissedFunc)(void);
+
/**
* @brief This is the function executed in the new task's context.
* @details
@@ -124,9 +81,9 @@ class PeriodicTask : public PeriodicTaskIF {
* the checkAndRestartPeriod system call blocks the task until the next
* period. On missing the deadline, the deadlineMissedFunction is executed.
*/
- void taskFunctionality(void);
+ void taskFunctionality();
- bool delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval);
+ static bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval);
};
-#endif /* PERIODICTASK_H_ */
+#endif /* FRAMEWORK_OSAL_HOST_PERIODICTASK_H_ */
diff --git a/src/fsfw/osal/host/TaskFactory.cpp b/src/fsfw/osal/host/TaskFactory.cpp
index 6e74fd57..ec4c1554 100644
--- a/src/fsfw/osal/host/TaskFactory.cpp
+++ b/src/fsfw/osal/host/TaskFactory.cpp
@@ -14,9 +14,9 @@ TaskFactory* TaskFactory::factoryInstance = new TaskFactory();
// Not used for the host implementation for now because C++ thread abstraction is used
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = 0;
-TaskFactory::TaskFactory() {}
+TaskFactory::TaskFactory() = default;
-TaskFactory::~TaskFactory() {}
+TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
diff --git a/src/fsfw/osal/host/taskHelpers.cpp b/src/fsfw/osal/host/taskHelpers.cpp
index aba2948a..432cf30c 100644
--- a/src/fsfw/osal/host/taskHelpers.cpp
+++ b/src/fsfw/osal/host/taskHelpers.cpp
@@ -6,7 +6,7 @@
std::mutex nameMapLock;
std::map taskNameMap;
-ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) {
+ReturnValue_t tasks::insertTaskName(std::thread::id threadId, const std::string& taskName) {
std::lock_guard lg(nameMapLock);
auto returnPair = taskNameMap.emplace(threadId, taskName);
if (not returnPair.second) {
diff --git a/src/fsfw/osal/host/taskHelpers.h b/src/fsfw/osal/host/taskHelpers.h
index cf553011..13a71d16 100644
--- a/src/fsfw/osal/host/taskHelpers.h
+++ b/src/fsfw/osal/host/taskHelpers.h
@@ -7,7 +7,7 @@
namespace tasks {
-ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName);
+ReturnValue_t insertTaskName(std::thread::id threadId, const std::string& taskName);
std::string getTaskName(std::thread::id threadId);
} // namespace tasks
diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp
index 1f4d6e23..775acea8 100644
--- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp
@@ -1,22 +1,20 @@
#include "fsfw/osal/linux/FixedTimeslotTask.h"
-#include
+#include
-#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
-uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
-FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_,
- uint32_t periodMs_)
- : PosixThread(name_, priority_, stackSize_), pst(periodMs_), started(false) {}
-
-FixedTimeslotTask::~FixedTimeslotTask() {}
+FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
+ TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_)
+ : FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
+ posixThread(name_, priority_, stackSize_),
+ started(false) {}
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask.
- FixedTimeslotTask* originalTask(reinterpret_cast(arg));
+ auto* originalTask(reinterpret_cast(arg));
// The task's functionality is called.
originalTask->taskFunctionality();
return nullptr;
@@ -24,7 +22,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) {
ReturnValue_t FixedTimeslotTask::startTask() {
started = true;
- createTask(&taskEntryPoint, this);
+ posixThread.createTask(&taskEntryPoint, this);
return HasReturnvaluesIF::RETURN_OK;
}
@@ -32,63 +30,36 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
return PosixThread::sleep((uint64_t)ms * 1000000);
}
-uint32_t FixedTimeslotTask::getPeriodMs() const { return pst.getLengthMs(); }
-
-ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) {
- ExecutableObjectIF* executableObject =
- ObjectManager::instance()->get(componentId);
- if (executableObject != nullptr) {
- pst.addSlot(componentId, slotTimeMs, executionStep, executableObject, this);
- return HasReturnvaluesIF::RETURN_OK;
- }
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "Component " << std::hex << componentId << " not found, not adding it to pst"
- << std::dec << std::endl;
-#endif
- return HasReturnvaluesIF::RETURN_FAILED;
-}
-
-ReturnValue_t FixedTimeslotTask::checkSequence() const { return pst.checkSequence(); }
-
-void FixedTimeslotTask::taskFunctionality() {
+[[noreturn]] void FixedTimeslotTask::taskFunctionality() {
// Like FreeRTOS pthreads are running as soon as they are created
if (!started) {
- suspend();
+ posixThread.suspend();
}
- pst.intializeSequenceAfterTaskCreation();
+ // Returnvalue ignored for now
+ static_cast(pollingSeqTable.intializeSequenceAfterTaskCreation());
// The start time for the first entry is read.
- uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
- uint64_t interval = pst.getIntervalToNextSlotMs();
+ uint64_t lastWakeTime = PosixThread::getCurrentMonotonicTimeMs();
+ uint32_t interval = 0;
// The task's "infinite" inner loop is entered.
- while (1) {
- if (pst.slotFollowsImmediately()) {
+ while (true) {
+ if (pollingSeqTable.slotFollowsImmediately()) {
// Do nothing
} else {
// The interval for the next polling slot is selected.
- interval = this->pst.getIntervalToPreviousSlotMs();
+ interval = pollingSeqTable.getIntervalToPreviousSlotMs();
// 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
- missedDeadlineCounter();
+ if(dlmFunc != nullptr){
+ dlmFunc();
+ }
}
}
// The device handler for this slot is executed and the next one is chosen.
- this->pst.executeAndAdvance();
- }
-}
-
-void FixedTimeslotTask::missedDeadlineCounter() {
- FixedTimeslotTask::deadlineMissedCount++;
- if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines."
- << std::endl;
-#endif
+ pollingSeqTable.executeAndAdvance();
}
}
diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h
index 76b92db3..1f5766a2 100644
--- a/src/fsfw/osal/linux/FixedTimeslotTask.h
+++ b/src/fsfw/osal/linux/FixedTimeslotTask.h
@@ -3,11 +3,12 @@
#include
-#include "../../tasks/FixedSlotSequence.h"
-#include "../../tasks/FixedTimeslotTaskIF.h"
#include "PosixThread.h"
+#include "fsfw/tasks/FixedSlotSequence.h"
+#include "fsfw/tasks/FixedTimeslotTaskBase.h"
+#include "fsfw/tasks/definitions.h"
-class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
+class FixedTimeslotTask : public FixedTimeslotTaskBase {
public:
/**
* Create a generic periodic task.
@@ -21,29 +22,13 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
* @param period_
* @param deadlineMissedFunc_
*/
- FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_);
- virtual ~FixedTimeslotTask();
+ FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
+ TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_);
+ ~FixedTimeslotTask() override = default;
- virtual ReturnValue_t startTask();
+ ReturnValue_t startTask() override;
- virtual ReturnValue_t sleepFor(uint32_t ms);
-
- virtual uint32_t getPeriodMs() const;
-
- virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep);
-
- virtual ReturnValue_t checkSequence() const;
-
- /**
- * This static function can be used as #deadlineMissedFunc.
- * It counts missedDeadlines and prints the number of missed deadlines every 10th time.
- */
- static void missedDeadlineCounter();
-
- /**
- * A helper variable to count missed deadlines.
- */
- static uint32_t deadlineMissedCount;
+ ReturnValue_t sleepFor(uint32_t ms) override;
protected:
/**
@@ -53,9 +38,12 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
* It links the functionalities provided by FixedSlotSequence with the
* OS's System Calls to keep the timing of the periods.
*/
- virtual void taskFunctionality();
+ [[noreturn]] virtual void taskFunctionality();
private:
+ PosixThread posixThread;
+ bool started;
+
/**
* @brief This is the entry point in a new thread.
*
@@ -68,9 +56,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread {
* arbitrary data.
*/
static void* taskEntryPoint(void* arg);
- FixedSlotSequence pst;
-
- bool started;
};
#endif /* FSFW_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ */
diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp
index e1937df4..09b106ed 100644
--- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp
+++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp
@@ -1,86 +1,54 @@
-#include "fsfw/osal/linux/PeriodicPosixTask.h"
+#include "PeriodicPosixTask.h"
-#include
-
-#include "fsfw/objectmanager/ObjectManager.h"
-#include "fsfw/serviceinterface/ServiceInterface.h"
+#include "fsfw/serviceinterface.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
- uint32_t period_, void(deadlineMissedFunc_)())
- : PosixThread(name_, priority_, stackSize_),
- objectList(),
- started(false),
- periodMs(period_),
- deadlineMissedFunc(deadlineMissedFunc_) {}
-
-PeriodicPosixTask::~PeriodicPosixTask() {
- // Not Implemented
-}
+ TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
+ : PeriodicTaskBase(period_, dlmFunc_),
+ posixThread(name_, priority_, stackSize_),
+ started(false) {}
void* PeriodicPosixTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask.
- PeriodicPosixTask* originalTask(reinterpret_cast(arg));
+ auto* originalTask(reinterpret_cast(arg));
// The task's functionality is called.
originalTask->taskFunctionality();
- return NULL;
-}
-
-ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
- ExecutableObjectIF* newObject = ObjectManager::instance()->get(object);
- return addComponent(newObject);
-}
-
-ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) {
- if (object == nullptr) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
- << " it implements ExecutableObjectIF!" << std::endl;
-#else
- sif::printError(
- "PeriodicTask::addComponent: Invalid object. Make sure it "
- "implements ExecutableObjectIF!\n");
-#endif
- return HasReturnvaluesIF::RETURN_FAILED;
- }
- objectList.push_back(object);
- object->setTaskIF(this);
-
- return HasReturnvaluesIF::RETURN_OK;
+ return nullptr;
}
ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
- return PosixThread::sleep((uint64_t)ms * 1000000);
+ return PosixThread::sleep(static_cast(ms) * 1000000);
}
-ReturnValue_t PeriodicPosixTask::startTask(void) {
+ReturnValue_t PeriodicPosixTask::startTask() {
+ if (isEmpty()) {
+ return HasReturnvaluesIF::RETURN_FAILED;
+ }
started = true;
- PosixThread::createTask(&taskEntryPoint, this);
+ posixThread.createTask(&taskEntryPoint, this);
return HasReturnvaluesIF::RETURN_OK;
}
-void PeriodicPosixTask::taskFunctionality(void) {
+[[noreturn]] void PeriodicPosixTask::taskFunctionality() {
if (not started) {
- suspend();
+ posixThread.suspend();
}
- for (auto const& object : objectList) {
- object->initializeAfterTaskCreation();
- }
+ initObjsAfterTaskCreation();
- uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
+ uint64_t lastWakeTime = PosixThread::getCurrentMonotonicTimeMs();
+ uint64_t periodMs = getPeriodMs();
// The task's "infinite" inner loop is entered.
- while (1) {
- for (auto const& object : objectList) {
- object->performOperation();
+ while (true) {
+ for (auto const& objOpCodePair : objectList) {
+ objOpCodePair.first->performOperation(objOpCodePair.second);
}
if (not PosixThread::delayUntil(&lastWakeTime, periodMs)) {
- if (this->deadlineMissedFunc != nullptr) {
- this->deadlineMissedFunc();
+ if (dlmFunc != nullptr) {
+ dlmFunc();
}
}
}
}
-
-uint32_t PeriodicPosixTask::getPeriodMs() const { return periodMs; }
diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h
index 3cd9847a..085c10b9 100644
--- a/src/fsfw/osal/linux/PeriodicPosixTask.h
+++ b/src/fsfw/osal/linux/PeriodicPosixTask.h
@@ -3,12 +3,13 @@
#include
-#include "../../objectmanager/ObjectManagerIF.h"
-#include "../../tasks/ExecutableObjectIF.h"
-#include "../../tasks/PeriodicTaskIF.h"
#include "PosixThread.h"
+#include "fsfw/objectmanager/ObjectManagerIF.h"
+#include "fsfw/tasks/ExecutableObjectIF.h"
+#include "fsfw/tasks/PeriodicTaskBase.h"
+#include "fsfw/tasks/PeriodicTaskIF.h"
-class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
+class PeriodicPosixTask : public PeriodicTaskBase {
public:
/**
* Create a generic periodic task.
@@ -22,9 +23,9 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* @param period_
* @param deadlineMissedFunc_
*/
- PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_,
- void (*deadlineMissedFunc_)());
- virtual ~PeriodicPosixTask();
+ PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
+ TaskDeadlineMissedFunction dlmFunc_);
+ ~PeriodicPosixTask() override = default;
/**
* @brief The method to start the task.
@@ -34,42 +35,17 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* to the system call.
*/
ReturnValue_t startTask() override;
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object Id of the object to add.
- * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(object_id_t object) override;
-
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object pointer to the object to add.
- * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(ExecutableObjectIF* object) override;
-
- uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms) override;
private:
- typedef std::vector ObjectList; //!< Typedef for the List of objects.
- /**
- * @brief This attribute holds a list of objects to be executed.
- */
- ObjectList objectList;
+ PosixThread posixThread;
/**
* @brief Flag to indicate that the task was started and is allowed to run
*/
bool started;
- /**
- * @brief Period of the task in milliseconds
- */
- uint32_t periodMs;
/**
* @brief The function containing the actual functionality of the task.
* @details The method sets and starts
@@ -78,7 +54,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is
* executed.
*/
- virtual void taskFunctionality(void);
+ [[noreturn]] virtual void taskFunctionality();
/**
* @brief This is the entry point in a new thread.
*
@@ -86,14 +62,6 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
* of the child class. Needs a valid pointer to the derived class.
*/
static void* taskEntryPoint(void* arg);
- /**
- * @brief The pointer to the deadline-missed function.
- * @details This pointer stores the function that is executed if the task's deadline is missed.
- * So, each may react individually on a timing failure. The pointer may be
- * NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution
- * of the periodic task.
- */
- void (*deadlineMissedFunc)();
};
#endif /* FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ */
diff --git a/src/fsfw/osal/linux/PosixThread.h b/src/fsfw/osal/linux/PosixThread.h
index 69c6c5b7..78fdfa2b 100644
--- a/src/fsfw/osal/linux/PosixThread.h
+++ b/src/fsfw/osal/linux/PosixThread.h
@@ -35,6 +35,21 @@ class PosixThread {
*/
void resume();
+ /**
+ * @brief Function that has to be called by derived class because the
+ * derived class pointer has to be valid as argument.
+ * @details
+ * This function creates a pthread with the given parameters. As the
+ * function requires a pointer to the derived object it has to be called
+ * after the this pointer of the derived object is valid.
+ * Sets the taskEntryPoint as function to be called by new a thread.
+ * @param fnc_ Function which will be executed by the thread.
+ * @param arg_
+ * argument of the taskEntryPoint function, needs to be this pointer
+ * of derived class
+ */
+ void createTask(void* (*fnc_)(void*), void* arg_);
+
/**
* Delay function similar to FreeRtos delayUntil function
*
@@ -55,21 +70,6 @@ class PosixThread {
protected:
pthread_t thread;
- /**
- * @brief Function that has to be called by derived class because the
- * derived class pointer has to be valid as argument.
- * @details
- * This function creates a pthread with the given parameters. As the
- * function requires a pointer to the derived object it has to be called
- * after the this pointer of the derived object is valid.
- * Sets the taskEntryPoint as function to be called by new a thread.
- * @param fnc_ Function which will be executed by the thread.
- * @param arg_
- * argument of the taskEntryPoint function, needs to be this pointer
- * of derived class
- */
- void createTask(void* (*fnc_)(void*), void* arg_);
-
private:
char name[PTHREAD_MAX_NAMELEN];
int priority;
diff --git a/src/fsfw/osal/linux/TaskFactory.cpp b/src/fsfw/osal/linux/TaskFactory.cpp
index 8503039f..a28e685d 100644
--- a/src/fsfw/osal/linux/TaskFactory.cpp
+++ b/src/fsfw/osal/linux/TaskFactory.cpp
@@ -8,21 +8,22 @@
// TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
TaskFactory* TaskFactory::factoryInstance = new TaskFactory();
-TaskFactory::~TaskFactory() {}
+TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
PeriodicTaskIF* TaskFactory::createPeriodicTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
- return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000,
+ return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_);
}
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
- return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000);
+ return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
+ deadLineMissedFunction_);
}
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
diff --git a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp
index 3347739a..f400c213 100644
--- a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp
@@ -1,42 +1,32 @@
#include "fsfw/osal/rtems/FixedTimeslotTask.h"
-#include
#include
-#include
#include
#include
#include
-#include
-#include "fsfw/objectmanager/ObjectManager.h"
-#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/osal/rtems/RtemsBasic.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
-#include "fsfw/tasks/FixedSequenceSlot.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1
#include
#endif
#include
-#include
-
-uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
FixedTimeslotTask::FixedTimeslotTask(const char *name, rtems_task_priority setPriority,
- size_t setStack, uint32_t setOverallPeriod,
- void (*setDeadlineMissedFunc)(void))
- : RTEMSTaskBase(setPriority, setStack, name), periodId(0), pst(setOverallPeriod) {
- // All additional attributes are applied to the object.
- this->deadlineMissedFunc = setDeadlineMissedFunc;
-}
+ size_t setStack, TaskPeriod setOverallPeriod,
+ TaskDeadlineMissedFunction dlmFunc_)
+ : FixedTimeslotTaskBase(setOverallPeriod, dlmFunc_),
+ RTEMSTaskBase(setPriority, setStack, name),
+ periodId(0) {}
-FixedTimeslotTask::~FixedTimeslotTask() {}
+FixedTimeslotTask::~FixedTimeslotTask() = default;
rtems_task FixedTimeslotTask::taskEntryPoint(rtems_task_argument argument) {
/* The argument is re-interpreted as a FixedTimeslotTask */
- FixedTimeslotTask *originalTask(reinterpret_cast(argument));
+ auto *originalTask(reinterpret_cast(argument));
/* The task's functionality is called. */
return originalTask->taskFunctionality();
/* Should never be reached */
@@ -46,16 +36,6 @@ rtems_task FixedTimeslotTask::taskEntryPoint(rtems_task_argument argument) {
#endif
}
-void FixedTimeslotTask::missedDeadlineCounter() {
- FixedTimeslotTask::deadlineMissedCount++;
- if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines."
- << std::endl;
-#endif
- }
-}
-
ReturnValue_t FixedTimeslotTask::startTask() {
rtems_status_code status =
rtems_task_start(id, FixedTimeslotTask::taskEntryPoint, rtems_task_argument((void *)this));
@@ -79,54 +59,35 @@ ReturnValue_t FixedTimeslotTask::startTask() {
}
}
-ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) {
- ExecutableObjectIF *object = ObjectManager::instance()->get(componentId);
- if (object != nullptr) {
- pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
- return HasReturnvaluesIF::RETURN_OK;
- }
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "Component " << std::hex << componentId << " not found, not adding it to pst"
- << std::endl;
-#endif
- return HasReturnvaluesIF::RETURN_FAILED;
-}
-
-uint32_t FixedTimeslotTask::getPeriodMs() const { return pst.getLengthMs(); }
-
-ReturnValue_t FixedTimeslotTask::checkSequence() const { return pst.checkSequence(); }
-
-void FixedTimeslotTask::taskFunctionality() {
+[[noreturn]] void FixedTimeslotTask::taskFunctionality() {
/* A local iterator for the Polling Sequence Table is created to find the start time for
the first entry. */
- FixedSlotSequence::SlotListIter it = pst.current;
+ auto it = pollingSeqTable.current;
/* Initialize the PST with the correct calling task */
- pst.intializeSequenceAfterTaskCreation();
+ pollingSeqTable.intializeSequenceAfterTaskCreation();
/* 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.
- while (1) {
- if (pst.slotFollowsImmediately()) {
+ while (true) {
+ if (pollingSeqTable.slotFollowsImmediately()) {
/* Do nothing */
} else {
/* The interval for the next polling slot is selected. */
- interval = RtemsBasic::convertMsToTicks(this->pst.getIntervalToNextSlotMs());
+ interval = RtemsBasic::convertMsToTicks(pollingSeqTable.getIntervalToNextSlotMs());
/* 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) {
- if (this->deadlineMissedFunc != nullptr) {
- this->deadlineMissedFunc();
+ if (dlmFunc != nullptr) {
+ dlmFunc();
}
}
}
/* The device handler for this slot is executed and the next one is chosen. */
- this->pst.executeAndAdvance();
+ this->pollingSeqTable.executeAndAdvance();
}
}
diff --git a/src/fsfw/osal/rtems/FixedTimeslotTask.h b/src/fsfw/osal/rtems/FixedTimeslotTask.h
index 6dedfa44..781c93db 100644
--- a/src/fsfw/osal/rtems/FixedTimeslotTask.h
+++ b/src/fsfw/osal/rtems/FixedTimeslotTask.h
@@ -1,11 +1,11 @@
#ifndef FSFW_OSAL_RTEMS_FIXEDTIMESLOTTASK_H_
#define FSFW_OSAL_RTEMS_FIXEDTIMESLOTTASK_H_
-#include "../../tasks/FixedSlotSequence.h"
-#include "../../tasks/FixedTimeslotTaskIF.h"
#include "RTEMSTaskBase.h"
+#include "fsfw/tasks/FixedSlotSequence.h"
+#include "fsfw/tasks/FixedTimeslotTaskBase.h"
-class FixedTimeslotTask : public RTEMSTaskBase, public FixedTimeslotTaskIF {
+class FixedTimeslotTask : public FixedTimeslotTaskBase, public RTEMSTaskBase {
public:
/**
* @brief The standard constructor of the class.
@@ -17,7 +17,7 @@ class FixedTimeslotTask : public RTEMSTaskBase, public FixedTimeslotTaskIF {
* @param getPst The object id of the completely initialized polling sequence.
*/
FixedTimeslotTask(const char *name, rtems_task_priority setPriority, size_t setStackSize,
- uint32_t overallPeriod, void (*setDeadlineMissedFunc)());
+ TaskPeriod overallPeriod, TaskDeadlineMissedFunction dlmFunc);
/**
* @brief The destructor of the class.
@@ -25,44 +25,17 @@ class FixedTimeslotTask : public RTEMSTaskBase, public FixedTimeslotTaskIF {
* The destructor frees all heap memory that was allocated on thread initialization
* for the PST andthe device handlers. This is done by calling the PST's destructor.
*/
- virtual ~FixedTimeslotTask(void);
+ ~FixedTimeslotTask() override;
ReturnValue_t startTask(void);
- /**
- * This static function can be used as #deadlineMissedFunc.
- * It counts missedDeadlines and prints the number of missed deadlines every 10th time.
- */
- static void missedDeadlineCounter();
- /**
- * A helper variable to count missed deadlines.
- */
- static uint32_t deadlineMissedCount;
- ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep);
-
- uint32_t getPeriodMs() const;
-
- ReturnValue_t checkSequence() const;
-
- ReturnValue_t sleepFor(uint32_t ms);
+ ReturnValue_t sleepFor(uint32_t ms) override;
protected:
/**
* @brief id of the associated OS period
*/
rtems_id periodId;
-
- FixedSlotSequence pst;
-
- /**
- * @brief This attribute holds a function pointer that is executed when a deadline was missed.
- *
- * @details
- * Another function may be announced to determine the actions to perform when a deadline
- * was missed. Currently, only one function for missing any deadline is allowed.
- * If not used, it shall be declared NULL.
- */
- void (*deadlineMissedFunc)(void) = nullptr;
/**
* @brief This is the entry point in a new polling thread.
* @details This method is the entry point in the new thread
@@ -76,7 +49,7 @@ class FixedTimeslotTask : public RTEMSTaskBase, public FixedTimeslotTaskIF {
* It links the functionalities provided by FixedSlotSequence with the OS's system calls to
* keep the timing of the periods.
*/
- void taskFunctionality(void);
+ [[noreturn]] void taskFunctionality();
};
#endif /* FSFW_OSAL_RTEMS_FIXEDTIMESLOTTASK_H_ */
diff --git a/src/fsfw/osal/rtems/MessageQueue.cpp b/src/fsfw/osal/rtems/MessageQueue.cpp
index f52f1852..534015dc 100644
--- a/src/fsfw/osal/rtems/MessageQueue.cpp
+++ b/src/fsfw/osal/rtems/MessageQueue.cpp
@@ -65,7 +65,7 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueu
}
ReturnValue_t returnCode = convertReturnCode(result);
- if (result == MessageQueueIF::EMPTY) {
+ if (returnCode == MessageQueueIF::EMPTY) {
return HasReturnvaluesIF::RETURN_FAILED;
}
diff --git a/src/fsfw/osal/rtems/MessageQueue.h b/src/fsfw/osal/rtems/MessageQueue.h
index bb31a508..6f1ce568 100644
--- a/src/fsfw/osal/rtems/MessageQueue.h
+++ b/src/fsfw/osal/rtems/MessageQueue.h
@@ -36,9 +36,9 @@ class MessageQueue : public MessageQueueBase {
* @param max_message_size With this parameter, the maximum message size can be adjusted.
* This should be left default.
*/
- MessageQueue(size_t message_depth = 3,
- size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
- MqArgs* args = nullptr);
+ explicit MessageQueue(size_t message_depth = 3,
+ size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
+ MqArgs* args = nullptr);
/** Copying message queues forbidden */
MessageQueue(const MessageQueue&) = delete;
@@ -48,18 +48,19 @@ class MessageQueue : public MessageQueueBase {
* @brief The destructor deletes the formerly created message queue.
* @details This is accomplished by using the delete call provided by the operating system.
*/
- virtual ~MessageQueue();
+ ~MessageQueue() override;
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
ReturnValue_t flush(uint32_t* count) override;
+
+ ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
- MessageQueueId_t sentFrom = NO_QUEUE,
- bool ignoreFault = false) override;
+ MessageQueueId_t sentFrom, bool ignoreFault) override;
private:
/**
- * \brief This attribute stores a reference to the internal error reporter for reporting full
- * queues. \details In the event of a full destination queue, the reporter will be notified. The
+ * @brief This attribute stores a reference to the internal error reporter for reporting full
+ * queues. @details In the event of a full destination queue, the reporter will be notified. The
* reference is set by lazy loading
*/
InternalErrorReporterIF* internalErrorReporter;
diff --git a/src/fsfw/osal/rtems/PeriodicTask.cpp b/src/fsfw/osal/rtems/PeriodicTask.cpp
index ae2ec426..cccf937f 100644
--- a/src/fsfw/osal/rtems/PeriodicTask.cpp
+++ b/src/fsfw/osal/rtems/PeriodicTask.cpp
@@ -5,12 +5,12 @@
#include "fsfw/tasks/ExecutableObjectIF.h"
PeriodicTask::PeriodicTask(const char* name, rtems_task_priority setPriority, size_t setStack,
- rtems_interval setPeriod, void (*setDeadlineMissedFunc)())
- : RTEMSTaskBase(setPriority, setStack, name),
- periodTicks(RtemsBasic::convertMsToTicks(setPeriod)),
- deadlineMissedFunc(setDeadlineMissedFunc) {}
+ TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_)
+ : PeriodicTaskBase(setPeriod, dlmFunc_),
+ RTEMSTaskBase(setPriority, setStack, name),
+ periodTicks(RtemsBasic::convertMsToTicks(static_cast(setPeriod * 1000.0))) {}
-PeriodicTask::~PeriodicTask(void) {
+PeriodicTask::~PeriodicTask() {
/* Do not delete objects, we were responsible for pointers only. */
rtems_rate_monotonic_delete(periodId);
}
@@ -18,7 +18,7 @@ PeriodicTask::~PeriodicTask(void) {
rtems_task PeriodicTask::taskEntryPoint(rtems_task_argument argument) {
/* The argument is re-interpreted as MultiObjectTask. The Task object is global,
so it is found from any place. */
- PeriodicTask* originalTask(reinterpret_cast(argument));
+ auto* originalTask(reinterpret_cast(argument));
return originalTask->taskFunctionality();
;
}
@@ -28,8 +28,10 @@ ReturnValue_t PeriodicTask::startTask() {
rtems_task_start(id, PeriodicTask::taskEntryPoint, rtems_task_argument((void*)this));
if (status != RTEMS_SUCCESSFUL) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::error << "ObjectTask::startTask for " << std::hex << this->getId() << std::dec
- << " failed." << std::endl;
+ 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());
#endif
}
switch (status) {
@@ -47,38 +49,20 @@ ReturnValue_t PeriodicTask::startTask() {
ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) { return RTEMSTaskBase::sleepFor(ms); }
-void PeriodicTask::taskFunctionality() {
+[[noreturn]] void PeriodicTask::taskFunctionality() {
RTEMSTaskBase::setAndStartPeriod(periodTicks, &periodId);
- for (const auto& object : objectList) {
- object->initializeAfterTaskCreation();
- }
+ initObjsAfterTaskCreation();
+
/* The task's "infinite" inner loop is entered. */
- while (1) {
- for (const auto& object : objectList) {
- object->performOperation();
+ while (true) {
+ for (const auto& objectPair : objectList) {
+ objectPair.first->performOperation(objectPair.second);
}
rtems_status_code status = RTEMSTaskBase::restartPeriod(periodTicks, periodId);
if (status == RTEMS_TIMEOUT) {
- if (this->deadlineMissedFunc != nullptr) {
- this->deadlineMissedFunc();
+ if (dlmFunc != nullptr) {
+ dlmFunc();
}
}
}
}
-
-ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
- ExecutableObjectIF* newObject = ObjectManager::instance()->get(object);
- return addComponent(newObject);
-}
-
-ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
- if (object == nullptr) {
- return HasReturnvaluesIF::RETURN_FAILED;
- }
- objectList.push_back(object);
- object->setTaskIF(this);
-
- return HasReturnvaluesIF::RETURN_OK;
-}
-
-uint32_t PeriodicTask::getPeriodMs() const { return RtemsBasic::convertTicksToMs(periodTicks); }
diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h
index 9f47dfc6..d987a82e 100644
--- a/src/fsfw/osal/rtems/PeriodicTask.h
+++ b/src/fsfw/osal/rtems/PeriodicTask.h
@@ -3,9 +3,10 @@
#include
-#include "../../objectmanager/ObjectManagerIF.h"
-#include "../../tasks/PeriodicTaskIF.h"
#include "RTEMSTaskBase.h"
+#include "fsfw/objectmanager/ObjectManagerIF.h"
+#include "fsfw/tasks/PeriodicTaskBase.h"
+#include "fsfw/tasks/PeriodicTaskIF.h"
class ExecutableObjectIF;
@@ -18,7 +19,7 @@ class ExecutableObjectIF;
* @author baetz
* @ingroup task_handling
*/
-class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF {
+class PeriodicTask : public PeriodicTaskBase, public RTEMSTaskBase {
public:
/**
* @brief Standard constructor of the class.
@@ -36,12 +37,12 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF {
* that shall be assigned.
*/
PeriodicTask(const char *name, rtems_task_priority setPriority, size_t setStack,
- rtems_interval setPeriod, void (*setDeadlineMissedFunc)());
+ TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc);
/**
* @brief Currently, the executed object's lifetime is not coupled with the task object's
* lifetime, so the destructor is empty.
*/
- virtual ~PeriodicTask(void);
+ ~PeriodicTask() override;
/**
* @brief The method to start the task.
@@ -50,33 +51,11 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF {
* The address of the task object is passed as an argument
* to the system call.
*/
- ReturnValue_t startTask(void);
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object Id of the object to add.
- * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(object_id_t object) override;
-
- /**
- * Adds an object to the list of objects to be executed.
- * The objects are executed in the order added.
- * @param object pointer to the object to add.
- * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
- */
- ReturnValue_t addComponent(ExecutableObjectIF *object) override;
-
- uint32_t getPeriodMs() const override;
+ ReturnValue_t startTask() override;
ReturnValue_t sleepFor(uint32_t ms) override;
protected:
- typedef std::vector ObjectList; //!< Typedef for the List of objects.
- /**
- * @brief This attribute holds a list of objects to be executed.
- */
- ObjectList objectList;
/**
* @brief The period of the task.
* @details The period determines the frequency of the task's execution. It is expressed in
@@ -87,14 +66,7 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF {
* @brief id of the associated OS period
*/
rtems_id periodId = 0;
- /**
- * @brief The pointer to the deadline-missed function.
- * @details This pointer stores the function that is executed if the task's deadline is missed.
- * So, each may react individually on a timing failure. The pointer may be
- * nullptr, then nothing happens on missing the deadline. The deadline is equal to the next
- * execution of the periodic task.
- */
- void (*deadlineMissedFunc)(void);
+
/**
* @brief This is the function executed in the new task's context.
* @details It converts the argument back to the thread object type and copies the class
@@ -110,7 +82,7 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF {
* are called. Afterwards the checkAndRestartPeriod system call blocks the task until the next
* period. On missing the deadline, the deadlineMissedFunction is executed.
*/
- void taskFunctionality(void);
+ [[noreturn]] void taskFunctionality();
};
#endif /* FSFW_OSAL_RTEMS_PERIODICTASK_H_ */
diff --git a/src/fsfw/osal/rtems/QueueFactory.cpp b/src/fsfw/osal/rtems/QueueFactory.cpp
index 2519f444..074ce273 100644
--- a/src/fsfw/osal/rtems/QueueFactory.cpp
+++ b/src/fsfw/osal/rtems/QueueFactory.cpp
@@ -45,9 +45,9 @@ QueueFactory* QueueFactory::instance() {
return factoryInstance;
}
-QueueFactory::QueueFactory() {}
+QueueFactory::QueueFactory() = default;
-QueueFactory::~QueueFactory() {}
+QueueFactory::~QueueFactory() = default;
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
MqArgs* args) {
diff --git a/src/fsfw/osal/rtems/RTEMSTaskBase.cpp b/src/fsfw/osal/rtems/RTEMSTaskBase.cpp
index a01b7802..a306b9e2 100644
--- a/src/fsfw/osal/rtems/RTEMSTaskBase.cpp
+++ b/src/fsfw/osal/rtems/RTEMSTaskBase.cpp
@@ -32,7 +32,7 @@ RTEMSTaskBase::RTEMSTaskBase(rtems_task_priority set_priority, size_t stack_size
RTEMSTaskBase::~RTEMSTaskBase() { rtems_task_delete(id); }
-rtems_id RTEMSTaskBase::getId() { return this->id; }
+rtems_id RTEMSTaskBase::getId() const { return this->id; }
ReturnValue_t RTEMSTaskBase::sleepFor(uint32_t ms) {
rtems_status_code status = rtems_task_wake_after(RtemsBasic::convertMsToTicks(ms));
diff --git a/src/fsfw/osal/rtems/RTEMSTaskBase.h b/src/fsfw/osal/rtems/RTEMSTaskBase.h
index 9ae9e755..ed9972d3 100644
--- a/src/fsfw/osal/rtems/RTEMSTaskBase.h
+++ b/src/fsfw/osal/rtems/RTEMSTaskBase.h
@@ -36,9 +36,9 @@ class RTEMSTaskBase {
/**
* @brief This method returns the task id of this class.
*/
- rtems_id getId();
+ rtems_id getId() const;
- ReturnValue_t sleepFor(uint32_t ms);
+ static ReturnValue_t sleepFor(uint32_t ms);
static ReturnValue_t setAndStartPeriod(rtems_interval period, rtems_id *periodId);
static rtems_status_code restartPeriod(rtems_interval period, rtems_id periodId);
diff --git a/src/fsfw/osal/rtems/TaskFactory.cpp b/src/fsfw/osal/rtems/TaskFactory.cpp
index 8bfd53ed..fb52eb0e 100644
--- a/src/fsfw/osal/rtems/TaskFactory.cpp
+++ b/src/fsfw/osal/rtems/TaskFactory.cpp
@@ -1,7 +1,6 @@
#include "fsfw/tasks/TaskFactory.h"
#include "fsfw/osal/rtems/FixedTimeslotTask.h"
-#include "fsfw/osal/rtems/InitTask.h"
#include "fsfw/osal/rtems/PeriodicTask.h"
#include "fsfw/osal/rtems/RtemsBasic.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
@@ -9,29 +8,29 @@
// TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
TaskFactory* TaskFactory::factoryInstance = new TaskFactory();
-TaskFactory::~TaskFactory() {}
+TaskFactory::TaskFactory() = default;
+
+TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
PeriodicTaskIF* TaskFactory::createPeriodicTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
- rtems_interval taskPeriod = periodInSeconds_ * Clock::getTicksPerSecond();
-
- return static_cast(
- new PeriodicTask(name_, taskPriority_, stackSize_, taskPeriod, deadLineMissedFunction_));
+ return static_cast(new PeriodicTask(name_, taskPriority_, stackSize_,
+ periodInSeconds_, deadLineMissedFunction_));
}
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
- rtems_interval taskPeriod = periodInSeconds_ * Clock::getTicksPerSecond();
- return static_cast(
- new FixedTimeslotTask(name_, taskPriority_, stackSize_, taskPeriod, deadLineMissedFunction_));
+ return static_cast(new FixedTimeslotTask(
+ name_, taskPriority_, stackSize_, periodInSeconds_, deadLineMissedFunction_));
}
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
- // TODO not implemented
+ // This should call the OS specific destructor
+ delete (dynamic_cast(task));
return HasReturnvaluesIF::RETURN_FAILED;
}
@@ -45,5 +44,3 @@ void TaskFactory::printMissedDeadline() {
/* TODO: Implement */
return;
}
-
-TaskFactory::TaskFactory() {}
diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp
index cb43e8e8..968a59ff 100644
--- a/src/fsfw/pus/Service11TelecommandScheduling.tpp
+++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp
@@ -615,23 +615,23 @@ inline ReturnValue_t Service11TelecommandScheduling::handleInvalidD
template
inline void Service11TelecommandScheduling::debugPrintMultimapContent() const {
- for ([[maybe_unused]] const auto &dit : telecommandMap) {
#if FSFW_DISABLE_PRINTOUT == 0
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content"
- << std::endl;
+ sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content"
+ << std::endl;
+#else
+ sif::printDebug("Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content\n");
+#endif
+ for (const auto &dit : telecommandMap) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "[" << dit.first << "]: Request ID: " << dit.second.requestId << " | "
<< "Store Address: " << dit.second.storeAddr.raw << std::endl;
#else
- sif::printDebug(
- "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content\n");
- for (auto dit = telecommandMap.begin(); dit != telecommandMap.end(); ++dit) {
- sif::printDebug("[%d]: Request ID: %d | Store Address: %d\n", dit->first,
- dit->second.requestId, dit->second.storeAddr);
- }
-#endif
+ sif::printDebug("[%d]: Request ID: %d | Store Address: %d\n", dit.first, dit.second.requestId,
+ dit.second.storeAddr);
#endif
}
+#endif
}
template
diff --git a/src/fsfw/storagemanager/StorageAccessor.cpp b/src/fsfw/storagemanager/StorageAccessor.cpp
index e2b083b2..b8096c1e 100644
--- a/src/fsfw/storagemanager/StorageAccessor.cpp
+++ b/src/fsfw/storagemanager/StorageAccessor.cpp
@@ -13,7 +13,7 @@ StorageAccessor::StorageAccessor(store_address_t storeId, StorageManagerIF* stor
StorageAccessor& StorageAccessor::operator=(StorageAccessor&& other) {
// Call the parent move assignment and also assign own member.
dataPointer = other.dataPointer;
- StorageAccessor::operator=(std::move(other));
+ ConstStorageAccessor::operator=(std::move(other));
return *this;
}
diff --git a/src/fsfw/tasks/CMakeLists.txt b/src/fsfw/tasks/CMakeLists.txt
index df69520a..1d4ab4e1 100644
--- a/src/fsfw/tasks/CMakeLists.txt
+++ b/src/fsfw/tasks/CMakeLists.txt
@@ -1,2 +1,3 @@
-target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp
- FixedSlotSequence.cpp)
+target_sources(
+ ${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp FixedSlotSequence.cpp
+ PeriodicTaskBase.cpp FixedTimeslotTaskBase.cpp)
diff --git a/src/fsfw/tasks/FixedSlotSequence.cpp b/src/fsfw/tasks/FixedSlotSequence.cpp
index d4c67b4d..9305b441 100644
--- a/src/fsfw/tasks/FixedSlotSequence.cpp
+++ b/src/fsfw/tasks/FixedSlotSequence.cpp
@@ -29,7 +29,7 @@ void FixedSlotSequence::executeAndAdvance() {
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
uint32_t oldTime;
- SlotListIter slotListIter = current;
+ auto slotListIter = current;
// Get the pollingTimeMs of the current slot object.
oldTime = slotListIter->pollingTimeMs;
// Advance to the next object.
@@ -51,7 +51,7 @@ uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
uint32_t currentTime;
- SlotListIter slotListIter = current;
+ auto slotListIter = current;
// Get the pollingTimeMs of the current slot object.
currentTime = slotListIter->pollingTimeMs;
@@ -67,7 +67,7 @@ uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
bool FixedSlotSequence::slotFollowsImmediately() {
uint32_t currentTime = current->pollingTimeMs;
- SlotListIter fixedSequenceIter = this->current;
+ auto fixedSequenceIter = this->current;
// Get the pollingTimeMs of the current slot object.
if (fixedSequenceIter == slotList.begin()) return false;
fixedSequenceIter--;
@@ -96,8 +96,8 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
return FixedTimeslotTaskIF::SLOT_LIST_EMPTY;
}
- if (customCheckFunction != nullptr) {
- ReturnValue_t result = customCheckFunction(slotList);
+ if (customChecker != nullptr) {
+ ReturnValue_t result = customChecker(slotList, customCheckArgs);
if (result != HasReturnvaluesIF::RETURN_OK) {
// Continue for now but print error output.
#if FSFW_CPP_OSTREAM_ENABLED == 1
@@ -161,6 +161,9 @@ ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const {
return HasReturnvaluesIF::RETURN_OK;
}
-void FixedSlotSequence::addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList&)) {
- this->customCheckFunction = customCheckFunction;
+void FixedSlotSequence::addCustomCheck(CustomCheckFunc customChecker_, void* checkerArgs_) {
+ customChecker = customChecker_;
+ customCheckArgs = checkerArgs_;
}
+
+bool FixedSlotSequence::isEmpty() const { return slotList.empty(); }
diff --git a/src/fsfw/tasks/FixedSlotSequence.h b/src/fsfw/tasks/FixedSlotSequence.h
index a287c5b2..2e38ee4b 100644
--- a/src/fsfw/tasks/FixedSlotSequence.h
+++ b/src/fsfw/tasks/FixedSlotSequence.h
@@ -30,12 +30,12 @@ class FixedSlotSequence {
public:
using SlotList = std::multiset;
using SlotListIter = std::multiset::iterator;
-
+ using CustomCheckFunc = ReturnValue_t (*)(const SlotList&, void* args);
/**
* @brief The constructor of the FixedSlotSequence object.
* @param setLength The period length, expressed in ms.
*/
- FixedSlotSequence(uint32_t setLengthMs);
+ explicit FixedSlotSequence(uint32_t setLengthMs);
/**
* @brief The destructor of the FixedSlotSequence object.
@@ -106,7 +106,7 @@ class FixedSlotSequence {
/**
* @brief This method returns the length of this FixedSlotSequence instance.
*/
- uint32_t getLengthMs() const;
+ [[nodiscard]] uint32_t getLengthMs() const;
/**
* @brief The method to execute the device handler entered in the current
@@ -137,7 +137,7 @@ class FixedSlotSequence {
* @return
* - SLOT_LIST_EMPTY if the slot list is empty
*/
- ReturnValue_t checkSequence() const;
+ [[nodiscard]] ReturnValue_t checkSequence() const;
/**
* @brief A custom check can be injected for the respective slot list.
@@ -149,7 +149,7 @@ class FixedSlotSequence {
* @param customCheckFunction
*
*/
- void addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList&));
+ void addCustomCheck(CustomCheckFunc func, void* userArgs);
/**
* @brief Perform any initialization steps required after the executing
@@ -157,7 +157,9 @@ class FixedSlotSequence {
* executing task!
* @return
*/
- ReturnValue_t intializeSequenceAfterTaskCreation() const;
+ [[nodiscard]] ReturnValue_t intializeSequenceAfterTaskCreation() const;
+
+ [[nodiscard]] bool isEmpty() const;
protected:
/**
@@ -173,7 +175,8 @@ class FixedSlotSequence {
*/
SlotList slotList;
- ReturnValue_t (*customCheckFunction)(const SlotList&) = nullptr;
+ CustomCheckFunc customChecker = nullptr;
+ void* customCheckArgs = nullptr;
uint32_t lengthMs;
};
diff --git a/src/fsfw/tasks/FixedTimeslotTaskBase.cpp b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp
new file mode 100644
index 00000000..5d12d565
--- /dev/null
+++ b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp
@@ -0,0 +1,27 @@
+#include "FixedTimeslotTaskBase.h"
+
+#include "fsfw/objectmanager/ObjectManager.h"
+
+FixedTimeslotTaskBase::FixedTimeslotTaskBase(TaskPeriod period_,
+ TaskDeadlineMissedFunction dlmFunc_)
+ : period(period_), pollingSeqTable(getPeriodMs()), dlmFunc(dlmFunc_) {}
+uint32_t FixedTimeslotTaskBase::getPeriodMs() const { return static_cast(period * 1000); }
+
+bool FixedTimeslotTaskBase::isEmpty() const { return pollingSeqTable.isEmpty(); }
+
+ReturnValue_t FixedTimeslotTaskBase::checkSequence() { return pollingSeqTable.checkSequence(); }
+
+ReturnValue_t FixedTimeslotTaskBase::addSlot(object_id_t execId, ExecutableObjectIF* execObj,
+ uint32_t slotTimeMs, int8_t executionStep) {
+ if (execObj == nullptr) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+ sif::error << "Component 0x" << std::hex << std::setw(8) << std::setfill('0') << execObj
+ << std::setfill(' ') << " not found, not adding it to PST" << std::dec << std::endl;
+#else
+ sif::printError("Component 0x%08x not found, not adding it to PST\n");
+#endif
+ return HasReturnvaluesIF::RETURN_FAILED;
+ }
+ pollingSeqTable.addSlot(execId, slotTimeMs, executionStep, execObj, this);
+ return HasReturnvaluesIF::RETURN_OK;
+}
diff --git a/src/fsfw/tasks/FixedTimeslotTaskBase.h b/src/fsfw/tasks/FixedTimeslotTaskBase.h
new file mode 100644
index 00000000..b88b393c
--- /dev/null
+++ b/src/fsfw/tasks/FixedTimeslotTaskBase.h
@@ -0,0 +1,44 @@
+#ifndef FSFW_EXAMPLE_HOSTED_FIXEDTIMESLOTTASKBASE_H
+#define FSFW_EXAMPLE_HOSTED_FIXEDTIMESLOTTASKBASE_H
+
+#include "FixedSlotSequence.h"
+#include "FixedTimeslotTaskIF.h"
+#include "definitions.h"
+
+class FixedTimeslotTaskBase : public FixedTimeslotTaskIF {
+ public:
+ explicit FixedTimeslotTaskBase(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc = nullptr);
+ ~FixedTimeslotTaskBase() override = default;
+ ;
+
+ protected:
+ /**
+ * @brief Period of task in floating point seconds
+ */
+ TaskPeriod period;
+
+ //! Polling sequence table which contains the object to execute
+ //! and information like the timeslots and the passed execution step.
+ FixedSlotSequence pollingSeqTable;
+
+ /**
+ * @brief The pointer to the deadline-missed function.
+ * @details
+ * This pointer stores the function that is executed if the task's deadline
+ * is missed. So, each may react individually on a timing failure.
+ * The pointer may be NULL, then nothing happens on missing the deadline.
+ * The deadline is equal to the next execution of the periodic task.
+ */
+ TaskDeadlineMissedFunction dlmFunc = nullptr;
+
+ ReturnValue_t checkSequence() override;
+
+ [[nodiscard]] uint32_t getPeriodMs() const override;
+
+ [[nodiscard]] bool isEmpty() const override;
+
+ ReturnValue_t addSlot(object_id_t execId, ExecutableObjectIF* componentId, uint32_t slotTimeMs,
+ int8_t executionStep) override;
+};
+
+#endif // FSFW_EXAMPLE_HOSTED_FIXEDTIMESLOTTASKBASE_H
diff --git a/src/fsfw/tasks/FixedTimeslotTaskIF.h b/src/fsfw/tasks/FixedTimeslotTaskIF.h
index 497db245..3f5e30d8 100644
--- a/src/fsfw/tasks/FixedTimeslotTaskIF.h
+++ b/src/fsfw/tasks/FixedTimeslotTaskIF.h
@@ -2,6 +2,7 @@
#define FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_
#include "PeriodicTaskIF.h"
+#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/objectmanager/ObjectManagerIF.h"
#include "fsfw/returnvalues/FwClassIds.h"
@@ -11,10 +12,23 @@
*/
class FixedTimeslotTaskIF : public PeriodicTaskIF {
public:
- virtual ~FixedTimeslotTaskIF() {}
+ ~FixedTimeslotTaskIF() override = default;
static constexpr ReturnValue_t SLOT_LIST_EMPTY =
HasReturnvaluesIF::makeReturnCode(CLASS_ID::FIXED_SLOT_TASK_IF, 0);
+
+ /**
+ * Add an object with a slot time and the execution step to the task.
+ * The execution step will be passed to the object (e.g. as an operation
+ * code in #performOperation)
+ * @param componentId
+ * @param slotTimeMs
+ * @param executionStep
+ * @return
+ */
+ virtual ReturnValue_t addSlot(object_id_t execId, ExecutableObjectIF* obj, uint32_t slotTimeMs,
+ int8_t executionStep) = 0;
+
/**
* Add an object with a slot time and the execution step to the task.
* The execution step will be passed to the object (e.g. as an operation
@@ -25,12 +39,24 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF {
* @return
*/
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) = 0;
+ int8_t executionStep) {
+ auto* execObj = ObjectManager::instance()->get(componentId);
+ return addSlot(componentId, execObj, slotTimeMs, executionStep);
+ }
+
/**
* Check whether the sequence is valid and perform all other required
* initialization steps which are needed after task creation
*/
- virtual ReturnValue_t checkSequence() const = 0;
+ virtual ReturnValue_t checkSequence() = 0;
+
+ ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override {
+ return HasReturnvaluesIF::RETURN_FAILED;
+ }
+
+ ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override {
+ return HasReturnvaluesIF::RETURN_FAILED;
+ }
};
#endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */
diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp
new file mode 100644
index 00000000..ce925a45
--- /dev/null
+++ b/src/fsfw/tasks/PeriodicTaskBase.cpp
@@ -0,0 +1,71 @@
+#include "PeriodicTaskBase.h"
+
+#include
+
+#include "fsfw/objectmanager/ObjectManager.h"
+#include "fsfw/serviceinterface.h"
+
+PeriodicTaskBase::PeriodicTaskBase(TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
+ : period(period_), dlmFunc(dlmFunc_) {
+ // Hints at configuration error
+ if (PeriodicTaskBase::getPeriodMs() <= 1) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+ sif::warning << "Passed task period 0 or smaller than 1 ms" << std::endl;
+#else
+ sif::printWarning("Passed task period 0 or smaller than 1ms\n");
+#endif
+ }
+}
+
+uint32_t PeriodicTaskBase::getPeriodMs() const { return static_cast(period * 1000); }
+
+bool PeriodicTaskBase::isEmpty() const { return objectList.empty(); }
+
+ReturnValue_t PeriodicTaskBase::addComponent(object_id_t object) { return addComponent(object, 0); }
+
+ReturnValue_t PeriodicTaskBase::addComponent(ExecutableObjectIF* object) {
+ return addComponent(object, 0);
+}
+
+ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() {
+ std::set uniqueObjects;
+ ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
+ uint32_t count = 0;
+ for (const auto& obj : objectList) {
+ // Ensure that each unique object is initialized once.
+ if (uniqueObjects.find(obj.first) == uniqueObjects.end()) {
+ ReturnValue_t result = obj.first->initializeAfterTaskCreation();
+ if (result != HasReturnvaluesIF::RETURN_OK) {
+ count++;
+ status = result;
+ }
+ uniqueObjects.emplace(obj.first);
+ }
+ }
+ if (count > 0) {
+ }
+ return status;
+}
+
+ReturnValue_t PeriodicTaskBase::addComponent(object_id_t object, uint8_t opCode) {
+ auto* newObject = ObjectManager::instance()->get(object);
+ return addComponent(newObject, opCode);
+}
+
+ReturnValue_t PeriodicTaskBase::addComponent(ExecutableObjectIF* object, uint8_t opCode) {
+ if (object == nullptr) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+ sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
+ << " it implements ExecutableObjectIF!" << std::endl;
+#else
+ sif::printError(
+ "PeriodicTask::addComponent: Invalid object. Make sure it "
+ "implements ExecutableObjectIF!\n");
+#endif
+ return HasReturnvaluesIF::RETURN_FAILED;
+ }
+ objectList.push_back({object, opCode});
+ object->setTaskIF(this);
+
+ return HasReturnvaluesIF::RETURN_OK;
+}
diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h
new file mode 100644
index 00000000..9023f104
--- /dev/null
+++ b/src/fsfw/tasks/PeriodicTaskBase.h
@@ -0,0 +1,54 @@
+#ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_
+#define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_
+
+#include
+#include
+
+#include "fsfw/tasks/PeriodicTaskIF.h"
+#include "fsfw/tasks/definitions.h"
+
+class ExecutableObjectIF;
+
+class PeriodicTaskBase : public PeriodicTaskIF {
+ public:
+ explicit PeriodicTaskBase(TaskPeriod period,
+ TaskDeadlineMissedFunction deadlineMissedFunc = nullptr);
+
+ ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override;
+ ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override;
+
+ ReturnValue_t addComponent(object_id_t object) override;
+ ReturnValue_t addComponent(ExecutableObjectIF* object) override;
+
+ [[nodiscard]] uint32_t getPeriodMs() const override;
+
+ [[nodiscard]] bool isEmpty() const override;
+
+ ReturnValue_t initObjsAfterTaskCreation();
+
+ protected:
+ //! Typedef for the List of objects. Will contain the objects to execute and their respective
+ //! operation codes
+ using ObjectList = std::vector>;
+ /**
+ * @brief This attribute holds a list of objects to be executed.
+ */
+ ObjectList objectList;
+
+ /**
+ * @brief Period of task in floating point seconds
+ */
+ TaskPeriod period;
+
+ /**
+ * @brief The pointer to the deadline-missed function.
+ * @details
+ * This pointer stores the function that is executed if the task's deadline
+ * is missed. So, each may react individually on a timing failure.
+ * The pointer may be NULL, then nothing happens on missing the deadline.
+ * The deadline is equal to the next execution of the periodic task.
+ */
+ TaskDeadlineMissedFunction dlmFunc = nullptr;
+};
+
+#endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */
diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h
index c78a32de..03b709ab 100644
--- a/src/fsfw/tasks/PeriodicTaskIF.h
+++ b/src/fsfw/tasks/PeriodicTaskIF.h
@@ -3,9 +3,8 @@
#include
-#include "../objectmanager/SystemObjectIF.h"
-#include "../timemanager/Clock.h"
-class ExecutableObjectIF;
+#include "fsfw/objectmanager/SystemObjectIF.h"
+#include "fsfw/tasks/ExecutableObjectIF.h"
/**
* New version of TaskIF
@@ -18,7 +17,7 @@ class PeriodicTaskIF {
/**
* @brief A virtual destructor as it is mandatory for interfaces.
*/
- virtual ~PeriodicTaskIF() {}
+ virtual ~PeriodicTaskIF() = default;
/**
* @brief With the startTask method, a created task can be started
* for the first time.
@@ -26,28 +25,29 @@ class PeriodicTaskIF {
virtual ReturnValue_t startTask() = 0;
/**
- * Add a component (object) to a periodic task.
- * @param object
- * Add an object to the task. The object needs to implement ExecutableObjectIF
- * @return
+ * Adds an object to the list of objects to be executed.
+ * The objects are executed in the order added. The object needs to implement
+ * ExecutableObjectIF
+ * @param object Id of the object to add.
+ * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/
- virtual ReturnValue_t addComponent(object_id_t object) {
- return HasReturnvaluesIF::RETURN_FAILED;
- };
+ virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode) = 0;
+ virtual ReturnValue_t addComponent(object_id_t object) { return addComponent(object, 0); };
/**
- * Add an object to a periodic task.
- * @param object
- * Add an object to the task.
- * @return
+ * Adds an object to the list of objects to be executed.
+ * The objects are executed in the order added.
+ * @param object pointer to the object to add.
+ * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/
- virtual ReturnValue_t addComponent(ExecutableObjectIF* object) {
- return HasReturnvaluesIF::RETURN_FAILED;
- };
+ virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) = 0;
+ virtual ReturnValue_t addComponent(ExecutableObjectIF* object) { return addComponent(object, 0); }
virtual ReturnValue_t sleepFor(uint32_t ms) = 0;
- virtual uint32_t getPeriodMs() const = 0;
+ [[nodiscard]] virtual uint32_t getPeriodMs() const = 0;
+
+ [[nodiscard]] virtual bool isEmpty() const = 0;
};
-#endif /* PERIODICTASKIF_H_ */
+#endif /* FRAMEWORK_TASK_PERIODICTASKIF_H_ */
diff --git a/src/fsfw/tasks/TaskFactory.h b/src/fsfw/tasks/TaskFactory.h
index fcd62678..828c533e 100644
--- a/src/fsfw/tasks/TaskFactory.h
+++ b/src/fsfw/tasks/TaskFactory.h
@@ -4,7 +4,7 @@
#include
#include "FixedTimeslotTaskIF.h"
-#include "Typedef.h"
+#include "definitions.h"
/**
* Singleton Class that produces Tasks.
diff --git a/src/fsfw/tasks/Typedef.h b/src/fsfw/tasks/Typedef.h
deleted file mode 100644
index 1bb75131..00000000
--- a/src/fsfw/tasks/Typedef.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef FSFW_TASKS_TYPEDEF_H_
-#define FSFW_TASKS_TYPEDEF_H_
-
-#include
-#include
-
-typedef const char* TaskName;
-typedef uint32_t TaskPriority;
-typedef size_t TaskStackSize;
-typedef double TaskPeriod;
-typedef void (*TaskDeadlineMissedFunction)();
-
-#endif /* FSFW_TASKS_TYPEDEF_H_ */
diff --git a/src/fsfw/tasks/definitions.h b/src/fsfw/tasks/definitions.h
new file mode 100644
index 00000000..586884b6
--- /dev/null
+++ b/src/fsfw/tasks/definitions.h
@@ -0,0 +1,13 @@
+#ifndef FSFW_TASKS_TYPEDEF_H_
+#define FSFW_TASKS_TYPEDEF_H_
+
+#include
+#include
+
+using TaskName = const char*;
+using TaskPriority = int;
+using TaskStackSize = size_t;
+using TaskPeriod = double;
+using TaskDeadlineMissedFunction = void (*)();
+
+#endif /* FSFW_TASKS_TYPEDEF_H_ */
diff --git a/tests/src/fsfw_tests/integration/devices/TestDeviceHandler.cpp b/tests/src/fsfw_tests/integration/devices/TestDeviceHandler.cpp
index cd15d6e0..36f1ea8c 100644
--- a/tests/src/fsfw_tests/integration/devices/TestDeviceHandler.cpp
+++ b/tests/src/fsfw_tests/integration/devices/TestDeviceHandler.cpp
@@ -13,14 +13,14 @@ TestDevice::TestDevice(object_id_t objectId, object_id_t comIF, CookieIF* cookie
dataset(this),
fullInfoPrintout(fullInfoPrintout) {}
-TestDevice::~TestDevice() {}
+TestDevice::~TestDevice() = default;
void TestDevice::performOperationHook() {
if (periodicPrintout) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "TestDevice" << deviceIdx << "::performOperationHook: Alive!" << std::endl;
#else
- sif::printInfo("TestDevice%d::performOperationHook: Alive!", deviceIdx);
+ sif::printInfo("TestDevice%d::performOperationHook: Alive!\n", deviceIdx);
#endif
}
diff --git a/tests/src/fsfw_tests/integration/task/TestTask.cpp b/tests/src/fsfw_tests/integration/task/TestTask.cpp
index 765f780e..a6a4a30b 100644
--- a/tests/src/fsfw_tests/integration/task/TestTask.cpp
+++ b/tests/src/fsfw_tests/integration/task/TestTask.cpp
@@ -12,7 +12,7 @@ TestTask::TestTask(object_id_t objectId) : SystemObject(objectId), testMode(test
IPCStore = ObjectManager::instance()->get(objects::IPC_STORE);
}
-TestTask::~TestTask() {}
+TestTask::~TestTask() = default;
ReturnValue_t TestTask::performOperation(uint8_t operationCode) {
ReturnValue_t result = RETURN_OK;
diff --git a/tests/src/fsfw_tests/integration/task/TestTask.h b/tests/src/fsfw_tests/integration/task/TestTask.h
index cd630ee3..038355c3 100644
--- a/tests/src/fsfw_tests/integration/task/TestTask.h
+++ b/tests/src/fsfw_tests/integration/task/TestTask.h
@@ -13,9 +13,9 @@
*/
class TestTask : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
public:
- TestTask(object_id_t objectId);
- virtual ~TestTask();
- virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
+ explicit TestTask(object_id_t objectId);
+ ~TestTask() override;
+ ReturnValue_t performOperation(uint8_t operationCode) override;
protected:
virtual ReturnValue_t performOneShotAction();
diff --git a/tests/src/fsfw_tests/unit/hal/testCommandExecutor.cpp b/tests/src/fsfw_tests/unit/hal/testCommandExecutor.cpp
index 20677298..09d31280 100644
--- a/tests/src/fsfw_tests/unit/hal/testCommandExecutor.cpp
+++ b/tests/src/fsfw_tests/unit/hal/testCommandExecutor.cpp
@@ -2,7 +2,9 @@
#include
#include
+#include
+#include "tests/TestsConfig.h"
#include "fsfw/container/DynamicFIFO.h"
#include "fsfw/container/SimpleRingBuffer.h"
#include "fsfw/platform.h"
@@ -61,6 +63,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
std::string cmpString = "Hello World\n";
CHECK(readString == cmpString);
outputBuffer.deleteData(12, true);
+
+ // Issues with CI/CD
+#if FSFW_CICD_BUILD == 0
// Test more complex command
result = cmdExecutor.load("ping -c 1 localhost", false, false);
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::COMMAND_LOADED);
@@ -81,16 +86,27 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
readBytes = 0;
sizesFifo.retrieve(&readBytes);
- // That's about the size of the reply
- bool beTrue = (readBytes > 200) and (readBytes < 400);
- REQUIRE(beTrue);
uint8_t largerReadBuffer[1024] = {};
+ // That's about the size of the reply
+ bool beTrue = (readBytes > 100) and (readBytes < 400);
+ if (not beTrue) {
+ size_t readLen = outputBuffer.getAvailableReadData();
+ if (readLen > sizeof(largerReadBuffer) - 1) {
+ readLen = sizeof(largerReadBuffer) - 1;
+ }
+ outputBuffer.readData(largerReadBuffer, readLen);
+ std::string readString(reinterpret_cast(largerReadBuffer));
+ std::cerr << "Catch2 tag cmd-exec: Read " << readBytes << ": " << std::endl;
+ std::cerr << readString << std::endl;
+ }
+ REQUIRE(beTrue);
outputBuffer.readData(largerReadBuffer, readBytes);
// You can also check this output in the debugger
std::string allTheReply(reinterpret_cast(largerReadBuffer));
// I am just going to assume that this string is the same across ping implementations
// of different Linux systems
REQUIRE(allTheReply.find("PING localhost") != std::string::npos);
+#endif
// Now check failing command
result = cmdExecutor.load("false", false, false);
diff --git a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp
index 92c3ff22..a993fff6 100644
--- a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp
+++ b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp
@@ -16,7 +16,7 @@
#include "fsfw_tests/unit/mocks/PeriodicTaskIFMock.h"
TEST_CASE("Internal Error Reporter", "[TestInternalError]") {
- PeriodicTaskMock task(10);
+ PeriodicTaskMock task(10, nullptr);
ObjectManagerIF* manager = ObjectManager::instance();
if (manager == nullptr) {
FAIL();
@@ -27,6 +27,8 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") {
FAIL();
}
task.addComponent(objects::INTERNAL_ERROR_REPORTER);
+ // This calls the initializeAfterTaskCreation function
+ task.startTask();
MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1);
MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1);
internalErrorReporter->getSubscriptionInterface()->subscribeForSetUpdateMessage(
@@ -115,4 +117,4 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") {
}
QueueFactory::instance()->deleteMessageQueue(testQueue);
QueueFactory::instance()->deleteMessageQueue(hkQueue);
-}
\ No newline at end of file
+}
diff --git a/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h b/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h
index ebd9a2e7..dc0ccefc 100644
--- a/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h
+++ b/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h
@@ -2,36 +2,24 @@
#define FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_
#include
-#include
+#include
-class PeriodicTaskMock : public PeriodicTaskIF {
+class PeriodicTaskMock : public PeriodicTaskBase {
public:
- PeriodicTaskMock(uint32_t period = 5) : period(period) {}
- /**
- * @brief A virtual destructor as it is mandatory for interfaces.
- */
+ PeriodicTaskMock(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc)
+ : PeriodicTaskBase(period, dlmFunc) {}
+
virtual ~PeriodicTaskMock() {}
/**
* @brief With the startTask method, a created task can be started
* for the first time.
*/
- virtual ReturnValue_t startTask() override { return HasReturnvaluesIF::RETURN_OK; };
-
- virtual ReturnValue_t addComponent(object_id_t object) override {
- ExecutableObjectIF* executableObject =
- ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER);
- if (executableObject == nullptr) {
- return HasReturnvaluesIF::RETURN_FAILED;
- }
- executableObject->setTaskIF(this);
- executableObject->initializeAfterTaskCreation();
+ virtual ReturnValue_t startTask() override {
+ initObjsAfterTaskCreation();
return HasReturnvaluesIF::RETURN_OK;
};
virtual ReturnValue_t sleepFor(uint32_t ms) override { return HasReturnvaluesIF::RETURN_OK; };
-
- virtual uint32_t getPeriodMs() const override { return period; };
- uint32_t period;
};
-#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_
\ No newline at end of file
+#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_
diff --git a/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp b/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp
index e1db9ce0..9631de38 100644
--- a/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp
+++ b/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp
@@ -156,4 +156,31 @@ TEST_CASE("New Accessor", "[NewAccessor]") {
CHECK(receptionArray[i] == 42);
}
}
+
+ SECTION("Operators"){
+ result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
+ REQUIRE(result == retval::CATCH_OK);
+ {
+ StorageAccessor accessor(testStoreId);
+ StorageAccessor accessor2(0);
+ accessor2 = std::move(accessor);
+ REQUIRE(accessor.data() == nullptr);
+ std::array data;
+ size_t size = 6;
+ result = accessor.write(data.data(), data.size());
+ REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
+ result = SimplePool.modifyData(testStoreId, accessor2);
+ REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
+ CHECK(accessor2.getId() == testStoreId);
+ CHECK(accessor2.size() == 10);
+
+ std::array newData;
+ // Expect data to be invalid so this must return RETURN_FAILED
+ result = accessor.getDataCopy(newData.data(),newData.size());
+ REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
+ // Expect data to be too small
+ result = accessor2.getDataCopy(data.data(),data.size());
+ REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
+ }
+ }
}
diff --git a/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp b/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp
index 2cbf951d..ce1f8518 100644
--- a/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp
+++ b/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp
@@ -3,6 +3,7 @@
#include
#include
+#include
#include "fsfw_tests/unit/CatchDefinitions.h"
diff --git a/tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in b/tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in
index 7d950070..1865c41a 100644
--- a/tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in
+++ b/tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in
@@ -1,6 +1,8 @@
#ifndef FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_
#define FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_
+#cmakedefine01 FSFW_CICD_BUILD
+
#define FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS 1
#ifdef __cplusplus