Compare commits

...

105 Commits

Author SHA1 Message Date
7de56f189b install etl library in ci/cd 2022-07-04 10:13:48 +02:00
541f563683 Merge pull request 'Fix StorageAccessor move assignment' (#643) from gaisser/fsfw:gaisser_storage_accessor_fix into development
Reviewed-on: fsfw/fsfw#643
2022-06-21 10:31:36 +02:00
28ea71a077 Merge branch 'development' into gaisser_storage_accessor_fix 2022-06-20 17:56:58 +02:00
a044d7d724 Merge pull request 'new cmake options for CICD build' (#623) from mueller/new-cicd-cmake-opts into development
Reviewed-on: fsfw/fsfw#623
2022-06-20 17:56:29 +02:00
687700cee8 Merge branch 'development' into gaisser_storage_accessor_fix 2022-06-20 16:36:49 +02:00
732b615cb3 Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-06-20 16:34:13 +02:00
394ce2ec3e Merge pull request 'LocalDataPoolManager Warning Text' (#642) from meier/debug-info into development
Reviewed-on: fsfw/fsfw#642
2022-06-20 16:15:30 +02:00
dde96ae220 Merge branch 'development' into gaisser_storage_accessor_fix 2022-06-20 16:15:05 +02:00
c3aaab4b93 Merge pull request 'Task IF refactoring' (#636) from mueller/task-if-refactoring into development
Reviewed-on: fsfw/fsfw#636
2022-06-20 16:08:03 +02:00
edf1d5ae8d Added more test cases 2022-06-20 16:02:35 +02:00
690991b4b5 include fix 2022-06-20 15:42:08 +02:00
1a294e6a13 include TestsConfig.h 2022-06-20 15:40:15 +02:00
8c4e34153b README updates 2022-06-20 15:36:48 +02:00
b60e4bcb90 Fix StorageAccessor move assignment
* Added Unittest for this
* Fixed missing include in test
2022-06-20 15:15:33 +02:00
b18410aa63 Merge remote-tracking branch 'refs/remotes/origin/mueller/task-if-refactoring' into mueller/task-if-refactoring 2022-06-20 15:02:38 +02:00
7f57a8784a Fixed deadline missed call on linux 2022-06-20 15:02:16 +02:00
4b33aa8262 bump ETL version 2022-06-20 14:25:39 +02:00
d47a908117 Merge branch 'development' into mueller/task-if-refactoring 2022-06-20 09:40:31 +02:00
fce95e04a8 Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-06-20 09:39:58 +02:00
fc742e4270 Merge branch 'development' into meier/debug-info 2022-06-16 07:22:43 +02:00
b5183a19fc minor change in debug text 2022-06-16 07:03:58 +02:00
ca453a8f16 Merge pull request 'run auto formatters' (#641) from KSat/fsfw:mueller/reapply-fmt into development
Reviewed-on: fsfw/fsfw#641
2022-06-13 17:04:11 +02:00
b7c0c07141 Merge remote-tracking branch 'origin/development' into mueller/new-cicd-cmake-opts 2022-06-13 16:28:01 +02:00
0158102f11 Merge pull request 'apply afmt, basic CLion support' (#625) from mueller/apply-afmt into development
Reviewed-on: fsfw/fsfw#625
2022-06-13 16:27:02 +02:00
69859fdbc9 rerun afmt 2022-06-13 16:21:20 +02:00
90bccc744e Merge pull request 'Fix SPI ComIF shadowing warning' (#639) from KSat/fsfw:mueller/spi-com-if-shadowing into development
Reviewed-on: fsfw/fsfw#639
2022-06-13 14:35:46 +02:00
ab89108c55 Merge pull request 'some fixes for TC Map printout function' (#640) from KSat/fsfw:mueller/pus-11-printout-fixes into development
Reviewed-on: fsfw/fsfw#640
2022-06-13 14:29:36 +02:00
a682bbe400 remove static missed deadline 2022-06-13 14:23:56 +02:00
e67fc2ab0d some fixes for TC Map printout function 2022-06-13 10:56:37 +02:00
71ce966531 Merge branch 'mueller/spi-com-if-shadowing' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/spi-com-if-shadowing 2022-06-13 10:54:25 +02:00
6b0f4a159f Merge remote-tracking branch 'upstream/development' into mueller/spi-com-if-shadowing 2022-06-13 10:54:20 +02:00
4a06b558c1 Fix SPI ComIF shadowing warning 2022-06-13 10:53:04 +02:00
6d921f03fd Fix SPI ComIF shadowing warning 2022-06-13 10:50:49 +02:00
65bc8213fe Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-06-13 09:43:32 +02:00
a0ee86ace8 use override instead of virtual as recommended 2022-06-08 17:36:20 +02:00
a07a368272 Merge branch 'development' into mueller/apply-afmt 2022-06-08 17:34:04 +02:00
cb8a4bbbec Merge remote-tracking branch 'origin/development' into mueller/task-if-refactoring 2022-06-08 17:33:12 +02:00
17f54006b8 Merge pull request 'rtems fixes' (#635) from mueller/rtems-fixes into development
Reviewed-on: fsfw/fsfw#635
2022-06-08 16:12:53 +02:00
395cf9cfa7 added clion base files 2022-06-08 12:12:33 +02:00
a3c0b441ec update changelog 2022-06-08 12:12:33 +02:00
b4132800ae apply afmt, update .gitignore 2022-06-08 12:12:33 +02:00
ad53b48fcb explicitely ignore returnvalue in linux OSAL 2022-06-08 12:12:09 +02:00
dee40f9079 fixed unittests 2022-06-08 12:12:09 +02:00
92ec24352f fix unit test 2022-06-08 12:12:09 +02:00
3f9e459f48 update changelog 2022-06-08 12:12:09 +02:00
e0c7f8d51d apply afmt 2022-06-08 12:12:09 +02:00
eb79386c92 new addSlot function taking executable pointer 2022-06-08 12:12:09 +02:00
4542f31c40 improved custom checker API
- More clang-tidy improvements
2022-06-08 12:12:09 +02:00
689fb378d8 a regular set should suffice here 2022-06-08 12:12:09 +02:00
98b711a872 update changelog 2022-06-08 12:12:09 +02:00
800aa131fa reverted some unrelated changes 2022-06-08 12:12:09 +02:00
6983980304 missing newline and clang-tidy improvement 2022-06-08 12:12:09 +02:00
7c0ba59993 remove include 2022-06-08 12:12:09 +02:00
28873fc87b refactores rtems task module 2022-06-08 12:12:09 +02:00
24e849ed9c avoid compiler warning 2022-06-08 12:12:09 +02:00
d8985c141e some clang tidy stuff and bugfixes 2022-06-08 12:12:09 +02:00
7602b15256 important bugfix 2022-06-08 12:12:09 +02:00
d1a82bceed rtems fixes 2022-06-08 12:12:09 +02:00
7292b02907 refactor freeRTOS task components 2022-06-08 12:12:09 +02:00
347714d53a refactored and tested hosted and linux task IF 2022-06-08 12:12:09 +02:00
f230fa1617 continued refactoring 2022-06-08 12:12:09 +02:00
93615b100c continued refactoring 2022-06-08 12:12:09 +02:00
e18d3d559e refactoring host osal 2022-06-08 12:12:09 +02:00
08ff061d07 minor bugfix 2022-06-08 12:12:09 +02:00
cc351c1066 new base class for periodic tasks 2022-06-08 12:12:09 +02:00
664a548c53 removed some changes which belong in separate PR 2022-06-08 12:12:09 +02:00
e9895559a3 vector as core container is ok 2022-06-08 12:12:09 +02:00
eda5b8f593 refactor task IF 2022-06-08 12:12:09 +02:00
e03f55604a rtems fixes 2022-06-08 12:11:26 +02:00
51d7df2dba Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-06-08 11:13:13 +02:00
12046a2db6 Merge pull request 'bump etl to 20.28.0' (#634) from mueller/bump-etl into development
Reviewed-on: fsfw/fsfw#634
2022-06-08 11:09:42 +02:00
c697d0f8ab bump etl to 20.28.0 2022-05-30 10:34:03 +02:00
c7cf8e710d Merge pull request 'return end iterator instead of crashing' (#633) from mueller/possible-fix-ccsds-distrib into development
Reviewed-on: fsfw/fsfw#633
2022-05-25 13:59:35 +02:00
7dddcdfd55 Merge branch 'development' into mueller/possible-fix-ccsds-distrib 2022-05-25 09:52:33 +02:00
261eea381e Merge pull request 'PUS11 TC sched update and bugfixes' (#632) from mueller/tc-11-tweaks into development
Reviewed-on: fsfw/fsfw#632
2022-05-24 17:48:06 +02:00
e59f1f26bf return end iterator instead of crashing 2022-05-24 14:33:18 +02:00
f7cde80088 added missing delete 2022-05-24 14:32:35 +02:00
e60a665de4 added 3 new subservices 2022-05-24 11:52:29 +02:00
34658ef7db afmt 2022-05-24 10:40:25 +02:00
940fd6f465 Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-05-23 15:59:13 +02:00
f288d5120d Merge branch 'development' into mueller/tc-11-tweaks 2022-05-23 15:34:00 +02:00
5a425a1c58 Merge pull request 'cache the TCP client address now' (#630) from eive/fsfw:mueller/tcp-server-cache-client-addr into development
Reviewed-on: fsfw/fsfw#630
2022-05-23 14:42:12 +02:00
5e62258aa6 Merge branch 'development' into mueller/tcp-server-cache-client-addr 2022-05-23 14:38:05 +02:00
0b53b4873f bugfix for srv11 2022-05-20 11:20:31 +02:00
8e2597f609 clang-format 2022-05-20 11:09:03 +02:00
dac700b80a static STORE renamed 2022-05-20 08:59:06 +02:00
d0fc360697 apply afmt 2022-05-20 08:34:14 +02:00
576414438c Merge pull request 'Apply cmake-format and auto-format script on all CMakeLists.txt file' (#628) from eive/fsfw:mueller/apply-clang-format-on-all-files into development
Reviewed-on: fsfw/fsfw#628
2022-05-18 13:14:18 +02:00
13cda86d23 remove commented code 2022-05-18 13:13:24 +02:00
e1dd27b9dd cache the TCP client address now 2022-05-17 13:16:36 +02:00
8e9d4b451c better printout if ping test fails 2022-05-16 16:18:44 +02:00
816550b69c Merge remote-tracking branch 'upstream/development' into mueller/new-cicd-cmake-opts 2022-05-16 14:58:25 +02:00
7fee852dbd re-apply updated auto-formatter 2022-05-16 14:55:15 +02:00
1e7032f89c minor improvements for auto-formatter 2022-05-16 14:54:43 +02:00
8a12a5097e Merge branch 'mueller/apply-afmt' into mueller/new-cicd-cmake-opts 2022-05-13 13:50:41 +02:00
87e4a57ef7 added clion base files 2022-05-13 13:48:13 +02:00
0375ee1881 update changelog 2022-05-13 13:46:54 +02:00
c8e034d975 Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-05-13 13:41:58 +02:00
2708b71d77 Merge remote-tracking branch 'origin/development' into mueller/new-cicd-cmake-opts 2022-05-13 12:00:40 +02:00
6366283ce2 Merge branch 'development' into mueller/apply-afmt 2022-05-13 11:50:03 +02:00
8dc640c162 apply afmt, update .gitignore 2022-05-13 11:39:37 +02:00
2e4b9bcd7c Merge remote-tracking branch 'origin/development' into mueller/new-cicd-cmake-opts 2022-05-12 17:42:49 +02:00
aacaf52fd9 Merge branch 'development' into mueller/new-cicd-cmake-opts 2022-05-09 15:34:36 +02:00
89f83f4e3d update changelog 2022-05-09 15:33:03 +02:00
39b7976056 new cmake options for CICD build 2022-05-09 15:26:38 +02:00
132 changed files with 1188 additions and 1409 deletions

8
.gitignore vendored
View File

@ -1,6 +1,14 @@
# PyCharm and CLion
/.idea/*
!/.idea/runConfigurations
!/.idea/cmake.xml
!/.idea/codeStyles
# Eclipse
.cproject
.project
.settings
.metadata
/build*
/cmake-build*

14
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,14 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
<codeStyleSettings language="CMake">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="0" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="fsfw-tests_coverage" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="fsfw-tests" TARGET_NAME="fsfw-tests_coverage" CONFIG_NAME="Debug Unittest" RUN_TARGET_PROJECT_NAME="fsfw-tests" RUN_TARGET_NAME="fsfw-tests">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
</component>

7
.run/fsfw.run.xml Normal file
View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="fsfw" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="fsfw-tests" TARGET_NAME="fsfw" CONFIG_NAME="Debug Unittest" RUN_TARGET_PROJECT_NAME="fsfw-tests" RUN_TARGET_NAME="fsfw-tests">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
</component>

View File

@ -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.

View File

@ -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)

View File

@ -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 ..
```

View File

@ -12,3 +12,9 @@ RUN git clone https://github.com/catchorg/Catch2.git && \
git checkout v3.0.0-preview5 && \
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
cmake --build build/ --target install
RUN git clone https://github.com/ETLCPP/etl.git && \
cd etl && \
git checkout 20.28.0 && \
cmake -B build . && \
cmake --install build/

View File

@ -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 ..'
}
}
}

View File

@ -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

View File

@ -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 {

View File

@ -4,9 +4,10 @@ if [[ ! -f README.md ]]; then
fi
cmake_fmt="cmake-format"
file_selectors="-iname CMakeLists.txt"
if command -v ${cmake_fmt} &> /dev/null; then
cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt"
eval ${cmake_fmt_cmd}
${cmake_fmt} -i CMakeLists.txt
find ./src ${file_selectors} | xargs ${cmake_fmt} -i
else
echo "No ${cmake_fmt} tool found, not formatting CMake files"
fi
@ -14,9 +15,9 @@ fi
cpp_format="clang-format"
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
if command -v ${cpp_format} &> /dev/null; then
find ./src ${file_selectors} | xargs clang-format --style=file -i
find ./hal ${file_selectors} | xargs clang-format --style=file -i
find ./tests ${file_selectors} | xargs clang-format --style=file -i
find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i
find ./hal ${file_selectors} | xargs ${cpp_format} --style=file -i
find ./tests ${file_selectors} | xargs ${cpp_format} --style=file -i
else
echo "No ${cpp_format} tool found, not formatting C++/C files"
fi

View File

@ -1,9 +1,6 @@
target_include_directories(${LIB_FSFW_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${LIB_FSFW_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${LIB_FSFW_NAME}
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(fsfw)

View File

@ -1,6 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
version.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE version.cpp)
# Core
@ -37,7 +35,7 @@ add_subdirectory(tmtcservices)
# Optional
if(FSFW_ADD_MONITORING)
add_subdirectory(monitoring)
add_subdirectory(monitoring)
endif()
if(FSFW_ADD_PUS)
add_subdirectory(pus)

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ActionHelper.cpp
ActionMessage.cpp
CommandActionHelper.cpp
SimpleActionHelper.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE ActionHelper.cpp ActionMessage.cpp
CommandActionHelper.cpp SimpleActionHelper.cpp)

View File

@ -1,7 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CFDPHandler.cpp
CFDPMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE CFDPHandler.cpp CFDPMessage.cpp)
add_subdirectory(pdu)
add_subdirectory(tlv)

View File

@ -1,11 +1,11 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
PduConfig.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE PduConfig.cpp
VarLenField.cpp
HeaderSerializer.cpp
HeaderDeserializer.cpp
FileDirectiveDeserializer.cpp
FileDirectiveSerializer.cpp
AckInfo.cpp
AckPduSerializer.cpp
AckPduDeserializer.cpp
@ -25,8 +25,6 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
KeepAlivePduDeserializer.cpp
PromptPduSerializer.cpp
PromptPduDeserializer.cpp
FileDataSerializer.cpp
FileDataDeserializer.cpp
FileDataInfo.cpp
)
FileDataInfo.cpp)

View File

@ -1,10 +1,10 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
EntityIdTlv.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE EntityIdTlv.cpp
FilestoreRequestTlv.cpp
FilestoreResponseTlv.cpp
Lv.cpp
Tlv.cpp
FlowLabelTlv.cpp
MessageToUserTlv.cpp
FaultHandlerOverrideTlv.cpp
)
FaultHandlerOverrideTlv.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
SharedRingBuffer.cpp
SimpleRingBuffer.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE SharedRingBuffer.cpp
SimpleRingBuffer.cpp)

View File

@ -1,4 +1,2 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
ControllerBase.cpp
ExtendedControllerBase.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ControllerBase.cpp
ExtendedControllerBase.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
CoordinateTransformations.cpp
Sgp4Propagator.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE CoordinateTransformations.cpp
Sgp4Propagator.cpp)

View File

@ -1,6 +1,6 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clcw.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clcw.cpp
DataLinkLayer.cpp
Farm1StateLockout.cpp
Farm1StateOpen.cpp
@ -8,5 +8,4 @@ target_sources(${LIB_FSFW_NAME}
MapPacketExtraction.cpp
TcTransferFrame.cpp
TcTransferFrameLocal.cpp
VirtualChannelReception.cpp
)
VirtualChannelReception.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
PoolDataSetBase.cpp
PoolEntry.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE PoolDataSetBase.cpp PoolEntry.cpp)

View File

@ -1,10 +1,6 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
LocalDataPoolManager.cpp
LocalDataSet.cpp
LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp
SharedLocalDataSet.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE LocalDataPoolManager.cpp LocalDataSet.cpp LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp SharedLocalDataSet.cpp)
add_subdirectory(internal)

View File

@ -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
}
}

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HasLocalDpIFUserAttorney.cpp
HasLocalDpIFManagerAttorney.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE HasLocalDpIFUserAttorney.cpp
HasLocalDpIFManagerAttorney.cpp)

View File

@ -1,11 +1,10 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
AssemblyBase.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE AssemblyBase.cpp
ChildHandlerBase.cpp
ChildHandlerFDIR.cpp
DeviceHandlerBase.cpp
DeviceHandlerFailureIsolation.cpp
DeviceHandlerMessage.cpp
DeviceTmReportingWrapper.cpp
HealthDevice.cpp
)
HealthDevice.cpp)

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
EventManager.cpp
EventMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE EventManager.cpp EventMessage.cpp)
add_subdirectory(eventmatching)

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
EventIdRangeMatcher.cpp
EventMatchTree.cpp
ReporterRangeMatcher.cpp
SeverityRangeMatcher.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE EventIdRangeMatcher.cpp EventMatchTree.cpp
ReporterRangeMatcher.cpp SeverityRangeMatcher.cpp)

View File

@ -27,6 +27,7 @@ enum : uint8_t {
PUS_SERVICE_6 = 86,
PUS_SERVICE_8 = 88,
PUS_SERVICE_9 = 89,
PUS_SERVICE_11 = 91,
PUS_SERVICE_17 = 97,
PUS_SERVICE_23 = 103,
MGM_LIS3MDL = 106,

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
EventCorrelation.cpp
FailureIsolationBase.cpp
FaultCounter.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE EventCorrelation.cpp FailureIsolationBase.cpp
FaultCounter.cpp)

View File

@ -1,13 +1,12 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
arrayprinter.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE arrayprinter.cpp
AsciiConverter.cpp
CRC.cpp
DleEncoder.cpp
PeriodicOperationDivider.cpp
timevalOperations.cpp
Type.cpp
bitutility.cpp
)
bitutility.cpp)
add_subdirectory(math)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
QuaternionOperations.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE QuaternionOperations.cpp)

View File

@ -1,6 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HealthHelper.cpp
HealthMessage.cpp
HealthTable.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE HealthHelper.cpp HealthMessage.cpp
HealthTable.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
HousekeepingMessage.cpp
PeriodicHousekeepingHelper.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE HousekeepingMessage.cpp
PeriodicHousekeepingHelper.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
InternalErrorReporter.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE InternalErrorReporter.cpp)

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
CommandMessage.cpp
CommandMessageCleaner.cpp
MessageQueueMessage.cpp
MessageQueueBase.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE CommandMessage.cpp CommandMessageCleaner.cpp
MessageQueueMessage.cpp MessageQueueBase.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
MemoryHelper.cpp
MemoryMessage.cpp
GenericFileSystemMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE MemoryHelper.cpp MemoryMessage.cpp
GenericFileSystemMessage.cpp)

View File

@ -1,5 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ModeHelper.cpp
ModeMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ModeHelper.cpp ModeMessage.cpp)

View File

@ -1,5 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
LimitViolationReporter.cpp
MonitoringMessage.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE LimitViolationReporter.cpp
MonitoringMessage.cpp)

View File

@ -1,5 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ObjectManager.cpp
SystemObject.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ObjectManager.cpp SystemObject.cpp)

View File

@ -14,6 +14,7 @@ enum framework_objects : object_id_t {
PUS_SERVICE_5_EVENT_REPORTING = 0x53000005,
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
PUS_SERVICE_17_TEST = 0x53000017,
PUS_SERVICE_20_PARAMETERS = 0x53000020,
PUS_SERVICE_200_MODE_MGMT = 0x53000200,

View File

@ -7,25 +7,23 @@ elseif(FSFW_OSAL MATCHES "linux")
add_subdirectory(linux)
elseif(FSFW_OSAL MATCHES "host")
add_subdirectory(host)
if (WIN32)
if(WIN32)
add_subdirectory(windows)
elseif(UNIX)
# We still need to pull in some Linux specific sources
target_sources(${LIB_FSFW_NAME} PUBLIC
linux/tcpipHelpers.cpp
)
endif ()
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
endif()
else()
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
# Not set. Assumuing this is a host build, try to determine host OS
if (WIN32)
if(WIN32)
add_subdirectory(host)
add_subdirectory(windows)
elseif (UNIX)
elseif(UNIX)
add_subdirectory(linux)
else ()
else()
# MacOS or other OSes have not been tested yet / are not supported.
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
endif()

View File

@ -1,17 +1,10 @@
if(DEFINED WIN32 OR DEFINED UNIX)
target_sources(${LIB_FSFW_NAME} PRIVATE
tcpipCommon.cpp
TcpIpBase.cpp
UdpTcPollingTask.cpp
UdpTmTcBridge.cpp
TcpTmTcServer.cpp
TcpTmTcBridge.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE tcpipCommon.cpp TcpIpBase.cpp UdpTcPollingTask.cpp
UdpTmTcBridge.cpp TcpTmTcServer.cpp TcpTmTcBridge.cpp)
endif()
if(WIN32)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
wsock32
ws2_32
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE wsock32 ws2_32)
endif()

View File

@ -109,8 +109,8 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); }
using namespace tcpip;
// If a connection is accepted, the corresponding socket will be assigned to the new socket
socket_t connSocket = 0;
// sockaddr clientSockAddr = {};
// socklen_t connectorSockAddrLen = 0;
sockaddr clientSockAddr = {};
socklen_t connectorSockAddrLen = 0;
int retval = 0;
// Listen for connection requests permanently for lifetime of program
@ -121,8 +121,7 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); }
continue;
}
// connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen);
connSocket = accept(listenerTcpSocket, nullptr, nullptr);
connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen);
if (connSocket == INVALID_SOCKET) {
handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500);
@ -137,6 +136,7 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); }
if (retval != 0) {
handleError(Protocol::TCP, ErrorSources::SHUTDOWN_CALL);
}
closeSocket(connSocket);
connSocket = 0;
}

View File

@ -1,6 +1,6 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clock.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
FixedTimeslotTask.cpp
BinarySemaphore.cpp
BinSemaphUsingTask.cpp
@ -15,18 +15,16 @@ target_sources(${LIB_FSFW_NAME}
TaskFactory.cpp
Timekeeper.cpp
TaskManagement.cpp
QueueMapManager.cpp
)
QueueMapManager.cpp)
# FreeRTOS is required to link the FSFW now. It is recommended to compile
# FreeRTOS as a static library and set LIB_OS_NAME to the target name of the
# library.
if(NOT LIB_OS_NAME)
message(STATUS
message(
STATUS
"LIB_OS_NAME is empty. Make sure to include the FreeRTOS header path properly."
)
else()
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
${LIB_OS_NAME}
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${LIB_OS_NAME})
endif()

View File

@ -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<FixedTimeslotTask*>(argument));
auto* originalTask(reinterpret_cast<FixedTimeslotTask*>(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<ExecutableObjectIF>(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();
}
}

View File

@ -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();
};

View File

@ -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. */

View File

@ -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<PeriodicTask*>(argument));
auto* originalTask(reinterpret_cast<PeriodicTask*>(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<ExecutableObjectIF>(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();
}
}

View File

@ -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<ExecutableObjectIF*> 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();
};

View File

@ -1,5 +1,6 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Clock.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
FixedTimeslotTask.cpp
MessageQueue.cpp
Mutex.cpp
@ -9,19 +10,14 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
QueueMapManager.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
taskHelpers.cpp
)
taskHelpers.cpp)
if(UNIX)
find_package(Threads REQUIRED)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
${CMAKE_THREAD_LIBS_INIT}
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
if(NOT APPLE)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
rt
)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE rt)
endif()
endif()

View File

@ -3,9 +3,7 @@
#include <chrono>
#include <thread>
#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<FixedTimeslotTask*>(argument));
auto* originalTask(reinterpret_cast<FixedTimeslotTask*>(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<void>(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(&currentStartTime, interval);
// TODO deadline missed check
if (not delayForInterval(&currentStartTime, interval)) {
if (dlmFunc != nullptr) {
dlmFunc();
}
}
}
}
}
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep) {
ExecutableObjectIF* executableObject =
ObjectManager::instance()->get<ExecutableObjectIF>(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<unsigned int>(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

View File

@ -6,10 +6,10 @@
#include <thread>
#include <vector>
#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<ExecutableObjectIF*> ObjectList;
std::thread mainThread;
std::atomic<bool> 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_ */

View File

@ -3,13 +3,10 @@
#include <chrono>
#include <thread>
#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 <processthreadsapi.h>
@ -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<PeriodicTask*>(argument));
auto* originalTask(reinterpret_cast<PeriodicTask*>(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<uint32_t>(period * 1000));
auto currentStartTime{std::chrono::duration_cast<std::chrono::milliseconds>(
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(&currentStartTime, periodChrono)) {
if (deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
if (dlmFunc != nullptr) {
this->dlmFunc();
}
}
}
}
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(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

View File

@ -6,9 +6,9 @@
#include <thread>
#include <vector>
#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<ExecutableObjectIF*> ObjectList;
std::thread mainThread;
std::atomic<bool> 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_ */

View File

@ -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; }

View File

@ -6,7 +6,7 @@
std::mutex nameMapLock;
std::map<std::thread::id, std::string> 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<std::mutex> lg(nameMapLock);
auto returnPair = taskNameMap.emplace(threadId, taskName);
if (not returnPair.second) {

View File

@ -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

View File

@ -1,5 +1,6 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Clock.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
BinarySemaphore.cpp
CountingSemaphore.cpp
FixedTimeslotTask.cpp
@ -13,17 +14,12 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
SemaphoreFactory.cpp
TaskFactory.cpp
tcpipHelpers.cpp
unixUtility.cpp
)
unixUtility.cpp)
find_package(Threads REQUIRED)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC
${CMAKE_THREAD_LIBS_INIT}
)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC ${CMAKE_THREAD_LIBS_INIT})
if(NOT APPLE)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC
rt
)
target_link_libraries(${LIB_FSFW_NAME} PUBLIC rt)
endif()

View File

@ -1,22 +1,20 @@
#include "fsfw/osal/linux/FixedTimeslotTask.h"
#include <limits.h>
#include <climits>
#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<FixedTimeslotTask*>(arg));
auto* originalTask(reinterpret_cast<FixedTimeslotTask*>(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<ExecutableObjectIF>(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<void>(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();
}
}

View File

@ -3,11 +3,12 @@
#include <pthread.h>
#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_ */

View File

@ -1,86 +1,54 @@
#include "fsfw/osal/linux/PeriodicPosixTask.h"
#include "PeriodicPosixTask.h"
#include <errno.h>
#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<PeriodicPosixTask*>(arg));
auto* originalTask(reinterpret_cast<PeriodicPosixTask*>(arg));
// The task's functionality is called.
originalTask->taskFunctionality();
return NULL;
}
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(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<uint64_t>(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; }

View File

@ -3,12 +3,13 @@
#include <vector>
#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<ExecutableObjectIF*> 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_ */

View File

@ -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;

View File

@ -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) {

View File

@ -1,6 +1,6 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clock.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE Clock.cpp
CpuUsage.cpp
InitTask.cpp
InternalErrorCodes.cpp
@ -14,7 +14,4 @@ target_sources(${LIB_FSFW_NAME}
RTEMSTaskBase.cpp
TaskFactory.cpp
BinarySemaphore.cpp
SemaphoreFactory.cpp
)
SemaphoreFactory.cpp)

View File

@ -1,42 +1,32 @@
#include "fsfw/osal/rtems/FixedTimeslotTask.h"
#include <rtems/bspIo.h>
#include <rtems/io.h>
#include <rtems/rtems/ratemon.h>
#include <rtems/rtems/status.h>
#include <rtems/rtems/tasks.h>
#include <rtems/rtems/types.h>
#include <sys/_stdint.h>
#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 <iostream>
#endif
#include <cstddef>
#include <list>
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<FixedTimeslotTask *>(argument));
auto *originalTask(reinterpret_cast<FixedTimeslotTask *>(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<ExecutableObjectIF>(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();
}
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -36,7 +36,7 @@ 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,
explicit MessageQueue(size_t message_depth = 3,
size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
MqArgs* args = nullptr);
@ -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;

View File

@ -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<uint32_t>(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<PeriodicTask*>(argument));
auto* originalTask(reinterpret_cast<PeriodicTask*>(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<ExecutableObjectIF>(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); }

View File

@ -3,9 +3,10 @@
#include <vector>
#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<ExecutableObjectIF *> 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_ */

View File

@ -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) {

View File

@ -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));

View File

@ -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);

View File

@ -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<PeriodicTaskIF*>(
new PeriodicTask(name_, taskPriority_, stackSize_, taskPeriod, deadLineMissedFunction_));
return static_cast<PeriodicTaskIF*>(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<FixedTimeslotTaskIF*>(
new FixedTimeslotTask(name_, taskPriority_, stackSize_, taskPeriod, deadLineMissedFunction_));
return static_cast<FixedTimeslotTaskIF*>(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<PeriodicTask*>(task));
return HasReturnvaluesIF::RETURN_FAILED;
}
@ -45,5 +44,3 @@ void TaskFactory::printMissedDeadline() {
/* TODO: Implement */
return;
}
TaskFactory::TaskFactory() {}

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
tcpipHelpers.cpp
winTaskHelpers.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE tcpipHelpers.cpp winTaskHelpers.cpp)

View File

@ -1,6 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ParameterHelper.cpp
ParameterMessage.cpp
ParameterWrapper.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE ParameterHelper.cpp ParameterMessage.cpp
ParameterWrapper.cpp)

View File

@ -1,8 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Fuse.cpp
PowerComponent.cpp
PowerSensor.cpp
PowerSwitcher.cpp
DummyPowerSwitcher.cpp
PowerSwitcherComponent.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE Fuse.cpp PowerComponent.cpp PowerSensor.cpp PowerSwitcher.cpp
DummyPowerSwitcher.cpp PowerSwitcherComponent.cpp)

View File

@ -3,8 +3,11 @@
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/power/PowerSwitchIF.h>
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t pwrSwitch)
: SystemObject(objectId), switcher(pwrSwitcher, pwrSwitch), modeHelper(this),
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
power::Switch_t pwrSwitch)
: SystemObject(objectId),
switcher(pwrSwitcher, pwrSwitch),
modeHelper(this),
healthHelper(this, objectId) {
queue = QueueFactory::instance()->createMessageQueue();
}
@ -25,12 +28,12 @@ ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) {
continue;
}
}
if(switcher.active()) {
if (switcher.active()) {
switcher.doStateMachine();
auto currState = switcher.getState();
if (currState == PowerSwitcher::SWITCH_IS_OFF) {
setMode(MODE_OFF, 0);
} else if(currState == PowerSwitcher::SWITCH_IS_ON) {
} else if (currState == PowerSwitcher::SWITCH_IS_ON) {
setMode(MODE_ON, 0);
}
}
@ -39,19 +42,17 @@ ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) {
ReturnValue_t PowerSwitcherComponent::initialize() {
ReturnValue_t result = modeHelper.initialize();
if(result != HasReturnvaluesIF::RETURN_OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = healthHelper.initialize();
if(result != HasReturnvaluesIF::RETURN_OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SystemObject::initialize();
}
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const {
return queue->getId();
}
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { return queue->getId(); }
void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) {
*mode = this->mode;
@ -66,23 +67,23 @@ ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) {
ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
*msToReachTheMode = 5000;
if(mode != MODE_ON and mode != MODE_OFF) {
if (mode != MODE_ON and mode != MODE_OFF) {
return TRANS_NOT_ALLOWED;
}
return RETURN_OK;
}
void PowerSwitcherComponent::startTransition(Mode_t mode, Submode_t submode) {
if(mode == MODE_OFF) {
if (mode == MODE_OFF) {
switcher.turnOff(true);
switcher.doStateMachine();
if(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
setMode(MODE_OFF, 0);
}
} else if (mode == MODE_ON) {
switcher.turnOn(true);
switcher.doStateMachine();
if(switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
setMode(MODE_ON, 0);
}
}
@ -103,6 +104,4 @@ void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) {
announceMode(false);
}
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() {
return healthHelper.getHealth();
}
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { return healthHelper.getHealth(); }

View File

@ -6,8 +6,8 @@
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/modes/ModeHelper.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/power/definitions.h>
#include <fsfw/power/PowerSwitcher.h>
#include <fsfw/power/definitions.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
class PowerSwitchIF;
@ -22,19 +22,17 @@ class PowerSwitchIF;
* Commanding this component to MODE_OFF will cause the switcher to turn the switch off while
* commanding in to MODE_ON will cause the switcher to turn the switch on.
*/
class PowerSwitcherComponent:
public SystemObject,
class PowerSwitcherComponent : public SystemObject,
public HasReturnvaluesIF,
public ExecutableObjectIF,
public HasModesIF,
public HasHealthIF {
public:
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
public:
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
power::Switch_t pwrSwitch);
private:
MessageQueueIF* queue = nullptr;
private:
MessageQueueIF *queue = nullptr;
PowerSwitcher switcher;
Mode_t mode = MODE_OFF;

View File

@ -1,5 +1,6 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
Service1TelecommandVerification.cpp
target_sources(
${LIB_FSFW_NAME}
PRIVATE Service1TelecommandVerification.cpp
Service2DeviceAccess.cpp
Service3Housekeeping.cpp
Service5EventReporting.cpp
@ -8,5 +9,4 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
Service17Test.cpp
Service20ParameterManagement.cpp
CService200ModeCommanding.cpp
CService201HealthCommanding.cpp
)
CService201HealthCommanding.cpp)

View File

@ -44,6 +44,12 @@ class Service11TelecommandScheduling final : public PusServiceBase {
static constexpr ReturnValue_t INVALID_RELATIVE_TIME =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3);
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
//! [EXPORT] : [COMMENT] Deletion of a TC from the map failed.
//! P1: First 32 bit of request ID, P2. Last 32 bit of Request ID
static constexpr Event TC_DELETION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
// The types of PUS-11 subservices
enum Subservice : uint8_t {
ENABLE_SCHEDULING = 1,
@ -73,7 +79,10 @@ class Service11TelecommandScheduling final : public PusServiceBase {
uint16_t releaseTimeMarginSeconds = DEFAULT_RELEASE_TIME_MARGIN,
bool debugMode = false);
~Service11TelecommandScheduling();
~Service11TelecommandScheduling() override;
void enableExpiredTcDeletion();
void disableExpiredTcDeletion();
/** PusServiceBase overrides */
ReturnValue_t handleRequest(uint8_t subservice) override;
@ -82,8 +91,8 @@ class Service11TelecommandScheduling final : public PusServiceBase {
private:
struct TelecommandStruct {
uint64_t requestId;
uint32_t seconds;
uint64_t requestId{};
uint32_t seconds{};
store_address_t storeAddr; // uint16
};
@ -92,9 +101,11 @@ class Service11TelecommandScheduling final : public PusServiceBase {
// minimum release time offset to insert into schedule
const uint16_t RELEASE_TIME_MARGIN_SECONDS = 5;
// the maximum amount of stored TCs is defined here
static constexpr uint16_t MAX_STORED_TELECOMMANDS = 500;
/**
* By default, the scheduling will be disabled. This is a standard requirement
*/
bool schedulingEnabled = false;
bool deleteExpiredTcWhenDisabled = true;
bool debugMode = false;
StorageManagerIF* tcStore = nullptr;
AcceptsTelecommandsIF* tcRecipient = nullptr;
@ -109,6 +120,7 @@ class Service11TelecommandScheduling final : public PusServiceBase {
TelecommandMap telecommandMap;
ReturnValue_t handleResetCommand();
/**
* @brief Logic to be performed on an incoming TC[11,4].
* @return RETURN_OK if successful
@ -139,17 +151,6 @@ class Service11TelecommandScheduling final : public PusServiceBase {
*/
ReturnValue_t doFilterTimeshiftActivity(const uint8_t* data, size_t size);
/**
* @brief Deserializes a generic type from a payload buffer by using the FSFW
* SerializeAdapter Interface.
* @param output Output to be deserialized
* @param buf Payload buffer (application data)
* @param bufsize Remaining size of payload buffer (application data size)
* @return RETURN_OK if successful
*/
template <typename T>
ReturnValue_t deserializeViaFsfwInterface(T& output, const uint8_t* buf, size_t bufsize);
/**
* @brief Extracts the Request ID from the Application Data of a TC by utilizing a ctor of the
* class TcPacketPus.
@ -177,7 +178,7 @@ class Service11TelecommandScheduling final : public PusServiceBase {
* @param ssc Source Sequence Count
* @return Request ID
*/
uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const;
[[nodiscard]] uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const;
/**
* @brief Gets the filter range for filter TCs from a data packet
@ -194,7 +195,7 @@ class Service11TelecommandScheduling final : public PusServiceBase {
/**
* @brief Prints content of multimap. Use for simple debugging only.
*/
void debugPrintMultimapContent(void) const;
void debugPrintMultimapContent() const;
};
#include "Service11TelecommandScheduling.tpp"

View File

@ -1,11 +1,12 @@
#pragma once
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/serialize/SerializeAdapter.h>
#include <fsfw/tmtcservices/AcceptsTelecommandsIF.h>
#include <cstddef>
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface.h"
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
template <size_t MAX_NUM_TCS>
@ -18,7 +19,7 @@ inline Service11TelecommandScheduling<MAX_NUM_TCS>::Service11TelecommandScheduli
tcRecipient(tcRecipient) {}
template <size_t MAX_NUM_TCS>
inline Service11TelecommandScheduling<MAX_NUM_TCS>::~Service11TelecommandScheduling() {}
inline Service11TelecommandScheduling<MAX_NUM_TCS>::~Service11TelecommandScheduling() = default;
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleRequest(
@ -37,6 +38,17 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleRequest(
return handleInvalidData("handleRequest");
}
switch (subservice) {
case Subservice::ENABLE_SCHEDULING: {
schedulingEnabled = true;
break;
}
case Subservice::DISABLE_SCHEDULING: {
schedulingEnabled = false;
break;
}
case Subservice::RESET_SCHEDULING: {
return handleResetCommand();
}
case Subservice::INSERT_ACTIVITY:
return doInsertActivity(data, size);
case Subservice::DELETE_ACTIVITY:
@ -48,25 +60,26 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleRequest(
case Subservice::FILTER_TIMESHIFT_ACTIVITY:
return doFilterTimeshiftActivity(data, size);
default:
break;
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
return HasReturnvaluesIF::RETURN_FAILED;
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService() {
// DEBUG
// DebugPrintMultimapContent();
if (not schedulingEnabled) {
return RETURN_OK;
}
// get current time as UNIX timestamp
timeval tNow = {};
Clock::getClock_timeval(&tNow);
// TODO: Optionally limit the max number of released TCs per cycle?
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
// does not work in this case as we are deleting the current element here.
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
if (it->first <= tNow.tv_sec) {
if (schedulingEnabled) {
// release tc
TmTcMessage releaseMsg(it->second.storeAddr);
auto sendRet = this->requestQueue->sendMessage(recipientMsgQueueId, &releaseMsg, false);
@ -74,9 +87,6 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
if (sendRet != HasReturnvaluesIF::RETURN_OK) {
return sendRet;
}
telecommandMap.erase(it++);
if (debugMode) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Released TC & erased it from TC map" << std::endl;
@ -84,6 +94,10 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
sif::printInfo("Released TC & erased it from TC map\n");
#endif
}
telecommandMap.erase(it++);
} else if (deleteExpiredTcWhenDisabled) {
telecommandMap.erase(it++);
}
continue;
}
it++;
@ -112,12 +126,30 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::initialize() {
return res;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleResetCommand() {
for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) {
ReturnValue_t result = tcStore->deleteData(it->second.storeAddr);
if (result != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
// This should not happen
sif::warning << "Service11TelecommandScheduling::handleRequestDeleting: Deletion failed"
<< std::endl;
#else
sif::printWarning("Service11TelecommandScheduling::handleRequestDeleting: Deletion failed\n");
#endif
triggerEvent(TC_DELETION_FAILED, (it->second.requestId >> 32) & 0xffffffff,
it->second.requestId & 0xffffffff);
}
}
telecommandMap.clear();
return RETURN_OK;
}
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivity(
const uint8_t *data, size_t size) {
uint32_t timestamp = 0;
const uint8_t *initData = data;
size_t initSz = size;
ReturnValue_t result = SerializeAdapter::deSerialize(&timestamp, &data, &size, DEF_END);
if (result != RETURN_OK) {
return result;
@ -142,7 +174,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
// store currentPacket and receive the store address
store_address_t addr{};
if (tcStore->addData(&addr, initData, initSz) != RETURN_OK ||
if (tcStore->addData(&addr, data, size) != RETURN_OK ||
addr.raw == storeId::INVALID_STORE_ADDRESS) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed"
@ -404,7 +436,6 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doFilterTimesh
// and then insert it again as new entry
telecommandMap.insert(std::make_pair(tempKey, tempTc));
shiftedItemsCount++;
continue;
}
if (debugMode) {
@ -463,9 +494,9 @@ template <size_t MAX_NUM_TCS>
inline uint64_t Service11TelecommandScheduling<MAX_NUM_TCS>::buildRequestId(uint32_t sourceId,
uint16_t apid,
uint16_t ssc) const {
uint64_t sourceId64 = static_cast<uint64_t>(sourceId);
uint64_t apid64 = static_cast<uint64_t>(apid);
uint64_t ssc64 = static_cast<uint64_t>(ssc);
auto sourceId64 = static_cast<uint64_t>(sourceId);
auto apid64 = static_cast<uint64_t>(apid);
auto ssc64 = static_cast<uint64_t>(ssc);
return (sourceId64 << 32) | (apid64 << 16) | ssc64;
}
@ -483,7 +514,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
if (typeRaw > 3) {
return INVALID_TYPE_TIME_WINDOW;
}
TypeOfTimeWindow type = static_cast<TypeOfTimeWindow>(typeRaw);
auto type = static_cast<TypeOfTimeWindow>(typeRaw);
// we now have the type of delete activity - so now we set the range to delete,
// according to the type of time window.
@ -558,7 +589,10 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
// additional security check, this should never be true
if (itBegin->first > itEnd->first) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
#else
sif::printError("11::GetMapFilterFromData: itBegin > itEnd\n");
#endif
return RETURN_FAILED;
}
@ -580,19 +614,32 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleInvalidD
}
template <size_t MAX_NUM_TCS>
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::debugPrintMultimapContent(void) const {
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::debugPrintMultimapContent() const {
#if FSFW_DISABLE_PRINTOUT == 0
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content"
<< std::endl;
sif::debug << "[" << dit->first << "]: Request ID: " << dit->second.requestId << " | "
<< "Store Address: " << dit->second.storeAddr << 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
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("[%d]: Request ID: %d | Store Address: %d\n", dit.first, dit.second.requestId,
dit.second.storeAddr);
#endif
}
#endif
#endif
}
template <size_t MAX_NUM_TCS>
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::enableExpiredTcDeletion() {
deleteExpiredTcWhenDisabled = true;
}
template <size_t MAX_NUM_TCS>
inline void Service11TelecommandScheduling<MAX_NUM_TCS>::disableExpiredTcDeletion() {
deleteExpiredTcWhenDisabled = false;
}

View File

@ -86,8 +86,8 @@ ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) {
// In addition to the default PUSServiceBase initialization, this service needs
// to be registered to the event manager to listen for events.
ReturnValue_t Service5EventReporting::initialize() {
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == NULL) {
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
return RETURN_FAILED;
}
// register Service 5 as listener for events

View File

@ -1,7 +1,2 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
RMAP.cpp
RMAPCookie.cpp
RmapDeviceCommunicationIF.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE RMAP.cpp RMAPCookie.cpp
RmapDeviceCommunicationIF.cpp)

View File

@ -1,4 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
SerialBufferAdapter.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE SerialBufferAdapter.cpp)

View File

@ -1,5 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
ServiceInterfaceStream.cpp
ServiceInterfaceBuffer.cpp
ServiceInterfacePrinter.cpp
)
target_sources(
${LIB_FSFW_NAME}
PRIVATE ServiceInterfaceStream.cpp ServiceInterfaceBuffer.cpp
ServiceInterfacePrinter.cpp)

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ConstStorageAccessor.cpp
StorageAccessor.cpp
LocalPool.cpp
PoolManager.cpp
)
target_sources(
${LIB_FSFW_NAME} PRIVATE ConstStorageAccessor.cpp StorageAccessor.cpp
LocalPool.cpp PoolManager.cpp)

View File

@ -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;
}

View File

@ -1,7 +1,3 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Subsystem.cpp
SubsystemBase.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp)
add_subdirectory(modes)

View File

@ -1,5 +1 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ModeSequenceMessage.cpp
ModeStore.cpp
)
target_sources(${LIB_FSFW_NAME} PRIVATE ModeSequenceMessage.cpp ModeStore.cpp)

View File

@ -1,5 +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)

View File

@ -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(); }

View File

@ -30,12 +30,12 @@ class FixedSlotSequence {
public:
using SlotList = std::multiset<FixedSequenceSlot>;
using SlotListIter = std::multiset<FixedSequenceSlot>::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;
};

View File

@ -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<uint32_t>(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;
}

View File

@ -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

View File

@ -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<ExecutableObjectIF>(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_ */

Some files were not shown because too many files have changed in this diff Show More