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/CHANGELOG.md b/CHANGELOG.md
index 6c0d8fb5..fd68ddf9 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
@@ -43,6 +47,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
@@ -84,6 +120,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 65a675df..15e7662a 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 c370ee37..e684b302 100644
--- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp
+++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp
@@ -215,7 +215,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
return result;
}
updateLinePolarity(fileDescriptor);
- 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 11faa4d0..f61980c6 100644
--- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
+++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
@@ -700,8 +700,7 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
if (result != HasReturnvaluesIF::RETURN_OK) {
/* Configuration error */
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed."
- << std::endl;
+ sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed." << std::endl;
#else
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 87d262f3..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::warning << "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 931e6a22..1d10b8d8 100644
--- a/src/fsfw/osal/host/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/host/FixedTimeslotTask.cpp
@@ -74,8 +74,10 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
return HasReturnvaluesIF::RETURN_OK;
}
-[[noreturn]] void FixedTimeslotTask::taskFunctionality() {
- pollingSeqTable.intializeSequenceAfterTaskCreation();
+void FixedTimeslotTask::taskFunctionality() {
+ 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.
@@ -109,26 +111,6 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
}
}
-ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) {
- auto* 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;
-}
-
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 d85ad34c..4e77f8fd 100644
--- a/src/fsfw/osal/host/FixedTimeslotTask.h
+++ b/src/fsfw/osal/host/FixedTimeslotTask.h
@@ -50,16 +50,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
*/
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) override;
-
ReturnValue_t sleepFor(uint32_t ms) override;
protected:
@@ -93,7 +83,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
* the checkAndRestartPeriod system call blocks the task until the next
* period. On missing the deadline, the deadlineMissedFunction is executed.
*/
- [[noreturn]] void taskFunctionality();
+ void taskFunctionality();
static bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval);
};
diff --git a/src/fsfw/osal/host/PeriodicTask.cpp b/src/fsfw/osal/host/PeriodicTask.cpp
index 5a80baa8..1f18d335 100644
--- a/src/fsfw/osal/host/PeriodicTask.cpp
+++ b/src/fsfw/osal/host/PeriodicTask.cpp
@@ -133,5 +133,3 @@ bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms
(*previousWakeTimeMs) = currentStartTime;
return false;
}
-
-bool PeriodicTask::isEmpty() const { return objectList.empty(); }
diff --git a/src/fsfw/osal/host/PeriodicTask.h b/src/fsfw/osal/host/PeriodicTask.h
index fad588a0..6fdaae4e 100644
--- a/src/fsfw/osal/host/PeriodicTask.h
+++ b/src/fsfw/osal/host/PeriodicTask.h
@@ -52,8 +52,6 @@ class PeriodicTask : public PeriodicTaskBase {
ReturnValue_t sleepFor(uint32_t ms) override;
- bool isEmpty() const override;
-
protected:
using chron_ms = std::chrono::milliseconds;
bool started;
diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp
index c2823b00..775acea8 100644
--- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp
@@ -4,7 +4,6 @@
#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_, TaskPriority priority_, size_t stackSize_,
@@ -37,7 +36,8 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
posixThread.suspend();
}
- pollingSeqTable.intializeSequenceAfterTaskCreation();
+ // Returnvalue ignored for now
+ static_cast(pollingSeqTable.intializeSequenceAfterTaskCreation());
// The start time for the first entry is read.
uint64_t lastWakeTime = PosixThread::getCurrentMonotonicTimeMs();
@@ -54,20 +54,12 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
// 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.
pollingSeqTable.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
- }
-}
diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h
index d6c7c0fb..1f5766a2 100644
--- a/src/fsfw/osal/linux/FixedTimeslotTask.h
+++ b/src/fsfw/osal/linux/FixedTimeslotTask.h
@@ -30,17 +30,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
ReturnValue_t sleepFor(uint32_t ms) override;
- /**
- * 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;
-
protected:
/**
* @brief This function holds the main functionality of the thread.
diff --git a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp
index d83a4d4a..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::warning << "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 e25dc59c..af121c5c 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/FixedSlotSequence.cpp b/src/fsfw/tasks/FixedSlotSequence.cpp
index 62c0e99c..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,8 +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 838963c1..2e38ee4b 100644
--- a/src/fsfw/tasks/FixedSlotSequence.h
+++ b/src/fsfw/tasks/FixedSlotSequence.h
@@ -30,7 +30,7 @@ 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.
@@ -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,9 +157,9 @@ class FixedSlotSequence {
* executing task!
* @return
*/
- ReturnValue_t intializeSequenceAfterTaskCreation() const;
+ [[nodiscard]] ReturnValue_t intializeSequenceAfterTaskCreation() const;
- bool isEmpty() const;
+ [[nodiscard]] bool isEmpty() const;
protected:
/**
@@ -175,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
index 05c08109..5d12d565 100644
--- a/src/fsfw/tasks/FixedTimeslotTaskBase.cpp
+++ b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp
@@ -11,19 +11,17 @@ bool FixedTimeslotTaskBase::isEmpty() const { return pollingSeqTable.isEmpty();
ReturnValue_t FixedTimeslotTaskBase::checkSequence() { return pollingSeqTable.checkSequence(); }
-ReturnValue_t FixedTimeslotTaskBase::addSlot(object_id_t componentId, uint32_t slotTimeMs,
- int8_t executionStep) {
- auto* executableObject = ObjectManager::instance()->get(componentId);
- if (executableObject != nullptr) {
- pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, executableObject, this);
- return HasReturnvaluesIF::RETURN_OK;
- }
-
+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') << componentId
- << std::setfill(' ') << " not found, not adding it to PST" << std::dec << std::endl;
+ 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");
+ sif::printError("Component 0x%08x not found, not adding it to PST\n");
#endif
- return HasReturnvaluesIF::RETURN_FAILED;
+ 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
index 6f08e3fe..b88b393c 100644
--- a/src/fsfw/tasks/FixedTimeslotTaskBase.h
+++ b/src/fsfw/tasks/FixedTimeslotTaskBase.h
@@ -37,7 +37,7 @@ class FixedTimeslotTaskBase : public FixedTimeslotTaskIF {
[[nodiscard]] bool isEmpty() const override;
- ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
+ ReturnValue_t addSlot(object_id_t execId, ExecutableObjectIF* componentId, uint32_t slotTimeMs,
int8_t executionStep) override;
};
diff --git a/src/fsfw/tasks/FixedTimeslotTaskIF.h b/src/fsfw/tasks/FixedTimeslotTaskIF.h
index dec382c3..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"
@@ -15,6 +16,19 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF {
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() = 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
index cc8784d9..ce925a45 100644
--- a/src/fsfw/tasks/PeriodicTaskBase.cpp
+++ b/src/fsfw/tasks/PeriodicTaskBase.cpp
@@ -21,8 +21,14 @@ uint32_t PeriodicTaskBase::getPeriodMs() const { return static_cast(pe
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::multiset uniqueObjects;
+ std::set uniqueObjects;
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
uint32_t count = 0;
for (const auto& obj : objectList) {
diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h
index 68791fb8..9023f104 100644
--- a/src/fsfw/tasks/PeriodicTaskBase.h
+++ b/src/fsfw/tasks/PeriodicTaskBase.h
@@ -17,6 +17,9 @@ class PeriodicTaskBase : public PeriodicTaskIF {
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;
diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h
index a6d6a6d6..03b709ab 100644
--- a/src/fsfw/tasks/PeriodicTaskIF.h
+++ b/src/fsfw/tasks/PeriodicTaskIF.h
@@ -31,9 +31,8 @@ class PeriodicTaskIF {
* @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, uint8_t opCode = 0) {
- 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); };
/**
* Adds an object to the list of objects to be executed.
@@ -41,15 +40,14 @@ class PeriodicTaskIF {
* @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, uint8_t opCode = 0) {
- 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;
- virtual bool isEmpty() const = 0;
+ [[nodiscard]] virtual bool isEmpty() const = 0;
};
-#endif /* PERIODICTASKIF_H_ */
+#endif /* FRAMEWORK_TASK_PERIODICTASKIF_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 fa4e0908..6af101dd 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 < 300);
- 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