Compare commits
81 Commits
mueller/up
...
mueller/re
Author | SHA1 | Date | |
---|---|---|---|
af7ebd3564 | |||
9a2e68b37e | |||
91067cde98 | |||
428018e4f1 | |||
6e5239e9a0 | |||
78b09ed0c9 | |||
fdf35232ee | |||
8465670374 | |||
3b23fb77b4 | |||
6f7be281ef | |||
a6ff3bb328 | |||
3686bbc486 | |||
ecac08814e | |||
e8b8fff0b5 | |||
4d34f93cfc | |||
adbf375f38 | |||
2e42f53682 | |||
c519b70302 | |||
45ee307bc4 | |||
8a2068aca6 | |||
aa60484111 | |||
e99c7f3824 | |||
2ee3ef1f1d | |||
ce48827ee5 | |||
0d80fad685 | |||
c6253bf0dd | |||
93933dee02 | |||
0e49640306 | |||
32fea9838e | |||
0519083894 | |||
14bac9a418 | |||
3bef73708f | |||
fef6ddceff | |||
5a9db72814 | |||
5cccd5caba | |||
7de56f189b | |||
df97bbc691 | |||
2d2f65bf89 | |||
42a1e784c0 | |||
67b67de753 | |||
3e9ae62b28 | |||
059e60cada | |||
21eb386f3c | |||
ade36e65c6 | |||
103661facc | |||
ae2f7219fd | |||
4fba2704aa | |||
161dbde0d7 | |||
2fa4fd61d0 | |||
bf673c56c6 | |||
9f83894d4c | |||
adcb646c9b | |||
16f8262a79 | |||
1a41d37f20 | |||
a3b9937f32 | |||
618f76ae78 | |||
ee2f8d6956 | |||
b11ae1c11d | |||
aea4e5d42c | |||
8d966de735 | |||
1611a4e1f0 | |||
842f1b22af | |||
cb9c1806ef | |||
cdc431ebc5 | |||
7ab617accb | |||
e2d3158506 | |||
23c6145971 | |||
eafbab9c65 | |||
16bbc0f597 | |||
7afe30ea88 | |||
8d85da66f2 | |||
fb1d775b52 | |||
e8a5f1e095 | |||
f518bc53db | |||
b45b6b3758 | |||
83a2882f9d | |||
1b34b90ae0 | |||
77055a1579 | |||
0aee86442e | |||
951c077abc | |||
adfefdd93f |
@ -40,6 +40,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
creation call. It allows passing context information and an arbitrary user argument into
|
creation call. It allows passing context information and an arbitrary user argument into
|
||||||
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
|
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583
|
||||||
|
- Internal API change: Moved the `fsfw_hal` to the `src` folder and integration and internal
|
||||||
|
tests part of `fsfw_tests` to `src`. Unittests are now in a dedicated folder called `unittests`
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/653
|
||||||
|
|
||||||
### Task Module Refactoring
|
### Task Module Refactoring
|
||||||
|
|
||||||
@ -85,7 +88,6 @@ PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/636
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||||
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
|
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585
|
||||||
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
|
||||||
|
|
||||||
### Time
|
### Time
|
||||||
|
|
||||||
@ -115,6 +117,8 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
|
|
||||||
## Additions
|
## Additions
|
||||||
|
|
||||||
|
- New constructor for PoolEntry which allows to simply specify the length of the pool entry.
|
||||||
|
This is also the new default constructor for scalar value with 0 as an initial value
|
||||||
- Added options for CI/CD builds: `FSFW_CICD_BUILD`. This allows the source code to know
|
- Added options for CI/CD builds: `FSFW_CICD_BUILD`. This allows the source code to know
|
||||||
whether it is running in CI/CD
|
whether it is running in CI/CD
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/623
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/623
|
||||||
@ -134,6 +138,7 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||||
Easiest solution for now: Keep this option OFF by default.
|
Easiest solution for now: Keep this option OFF by default.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
||||||
|
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
||||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||||
inside `fsfw/version.h`
|
inside `fsfw/version.h`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||||
|
@ -67,13 +67,13 @@ endif()
|
|||||||
set(FSFW_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw")
|
set(FSFW_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw")
|
||||||
|
|
||||||
set(FSFW_ETL_LIB_NAME etl)
|
set(FSFW_ETL_LIB_NAME etl)
|
||||||
|
set(FSFW_ETL_LINK_TARGET etl::etl)
|
||||||
set(FSFW_ETL_LIB_MAJOR_VERSION
|
set(FSFW_ETL_LIB_MAJOR_VERSION
|
||||||
20
|
20
|
||||||
CACHE STRING "ETL library major version requirement")
|
CACHE STRING "ETL library major version requirement")
|
||||||
set(FSFW_ETL_LIB_VERSION
|
set(FSFW_ETL_LIB_VERSION
|
||||||
${FSFW_ETL_LIB_MAJOR_VERSION}.28.0
|
${FSFW_ETL_LIB_MAJOR_VERSION}.28.0
|
||||||
CACHE STRING "ETL library exact version requirement")
|
CACHE STRING "ETL library exact version requirement")
|
||||||
set(FSFW_ETL_LINK_TARGET etl::etl)
|
|
||||||
|
|
||||||
set(FSFW_CATCH2_LIB_MAJOR_VERSION
|
set(FSFW_CATCH2_LIB_MAJOR_VERSION
|
||||||
3
|
3
|
||||||
@ -82,6 +82,15 @@ set(FSFW_CATCH2_LIB_VERSION
|
|||||||
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5
|
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5
|
||||||
CACHE STRING "Catch2 library exact version requirement")
|
CACHE STRING "Catch2 library exact version requirement")
|
||||||
|
|
||||||
|
set(FSFW_FMT_LIB_NAME fmt)
|
||||||
|
set(FSFW_FMT_LINK_TARGET fmt::fmt)
|
||||||
|
set(FSFW_FMT_LIB_MAJOR_VERSION
|
||||||
|
8
|
||||||
|
CACHE STRING "{fmt} library major version requirement")
|
||||||
|
set(FSFW_FMT_LIB_VERSION
|
||||||
|
${FSFW_FMT_LIB_MAJOR_VERSION}.1.1
|
||||||
|
CACHE STRING "{fmt} library exact version requirement")
|
||||||
|
|
||||||
# Keep this off by default for now. See PR:
|
# Keep this off by default for now. See PR:
|
||||||
# https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 for information which
|
# https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 for information which
|
||||||
# keeping this on by default is problematic
|
# keeping this on by default is problematic
|
||||||
@ -103,11 +112,11 @@ if(FSFW_GENERATE_SECTIONS)
|
|||||||
option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON)
|
option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(FSFW_BUILD_UNITTESTS
|
option(FSFW_BUILD_TESTS
|
||||||
"Build unittest binary in addition to static library" OFF)
|
"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_CICD_BUILD "Build for CI/CD. This can disable problematic test" OFF)
|
||||||
option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF)
|
option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF)
|
||||||
if(FSFW_BUILD_UNITTESTS)
|
if(FSFW_BUILD_TESTS)
|
||||||
option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON)
|
option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -139,7 +148,7 @@ if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
|||||||
TRUE)
|
TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FSFW_BUILD_UNITTESTS)
|
if(FSFW_BUILD_TESTS)
|
||||||
message(
|
message(
|
||||||
STATUS
|
STATUS
|
||||||
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||||
@ -162,18 +171,17 @@ if(FSFW_BUILD_UNITTESTS)
|
|||||||
list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2)
|
list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg)
|
set(FSFW_CONFIG_PATH unittests/testcfg)
|
||||||
configure_file(tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
||||||
configure_file(tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in
|
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
||||||
tests/TestsConfig.h)
|
|
||||||
|
|
||||||
project(${FSFW_TEST_TGT} CXX C)
|
project(${FSFW_TEST_TGT} CXX C)
|
||||||
add_executable(${FSFW_TEST_TGT})
|
add_executable(${FSFW_TEST_TGT})
|
||||||
|
|
||||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||||
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
||||||
TRUE)
|
TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FSFW_TESTS_GEN_COV)
|
if(FSFW_TESTS_GEN_COV)
|
||||||
message(STATUS "${MSG_PREFIX} Generating coverage data for the library")
|
message(STATUS "${MSG_PREFIX} Generating coverage data for the library")
|
||||||
message(STATUS "${MSG_PREFIX} Targets linking against ${LIB_FSFW_NAME} "
|
message(STATUS "${MSG_PREFIX} Targets linking against ${LIB_FSFW_NAME} "
|
||||||
@ -183,10 +191,7 @@ if(FSFW_BUILD_UNITTESTS)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(
|
message(STATUS "${MSG_PREFIX} Finding and/or etl (Embedded Template Library)")
|
||||||
STATUS
|
|
||||||
"${MSG_PREFIX} Finding and/or providing etl library with version ${FSFW_ETL_LIB_MAJOR_VERSION}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check whether the user has already installed ETL first
|
# Check whether the user has already installed ETL first
|
||||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||||
@ -194,7 +199,7 @@ find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
|||||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||||
message(
|
message(
|
||||||
STATUS
|
STATUS
|
||||||
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
|
"No ETL installation was found with find_package. Installing and providing "
|
||||||
"etl with FindPackage")
|
"etl with FindPackage")
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
@ -206,6 +211,26 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
|||||||
list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME})
|
list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Finding and/or providing {fmt} formatting library")
|
||||||
|
|
||||||
|
# Check whether the user has already installed ETL first
|
||||||
|
find_package(fmt ${FSFW_FMT_LIB_MAJOR_VERSION} QUIET)
|
||||||
|
# Not installed, so use FetchContent to download and provide etl
|
||||||
|
if(NOT ${FSFW_FMT_LIB_NAME}_FOUND)
|
||||||
|
message(
|
||||||
|
STATUS
|
||||||
|
"No {fmt} installation was found with find_package. Installing and providing "
|
||||||
|
"{fmt} with FindPackage")
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
${FSFW_FMT_LIB_NAME}
|
||||||
|
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||||
|
GIT_TAG ${FSFW_FMT_LIB_VERSION})
|
||||||
|
|
||||||
|
list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_FMT_LIB_NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
# The documentation for FetchContent recommends declaring all the dependencies
|
# The documentation for FetchContent recommends declaring all the dependencies
|
||||||
# before making them available. We make all declared dependency available here
|
# before making them available. We make all declared dependency available here
|
||||||
# after their declaration
|
# after their declaration
|
||||||
@ -215,7 +240,7 @@ if(FSFW_FETCH_CONTENT_TARGETS)
|
|||||||
add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME})
|
add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME})
|
||||||
endif()
|
endif()
|
||||||
if(TARGET Catch2)
|
if(TARGET Catch2)
|
||||||
# Fixes regression -preview4, to be confirmed in later releases Related
|
# Fixes regression -preview4, to be confirmed in later releases. Related
|
||||||
# GitHub issue: https://github.com/catchorg/Catch2/issues/2417
|
# GitHub issue: https://github.com/catchorg/Catch2/issues/2417
|
||||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||||
endif()
|
endif()
|
||||||
@ -284,16 +309,15 @@ message(
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(tests)
|
|
||||||
if(FSFW_ADD_HAL)
|
|
||||||
add_subdirectory(hal)
|
|
||||||
endif()
|
|
||||||
add_subdirectory(contrib)
|
add_subdirectory(contrib)
|
||||||
|
if(FSFW_BUILD_TESTS)
|
||||||
|
add_subdirectory(unittests)
|
||||||
|
endif()
|
||||||
if(FSFW_BUILD_DOCS)
|
if(FSFW_BUILD_DOCS)
|
||||||
add_subdirectory(docs)
|
add_subdirectory(docs)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FSFW_BUILD_UNITTESTS)
|
if(FSFW_BUILD_TESTS)
|
||||||
if(FSFW_TESTS_GEN_COV)
|
if(FSFW_TESTS_GEN_COV)
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
include(CodeCoverage)
|
include(CodeCoverage)
|
||||||
@ -449,9 +473,8 @@ target_include_directories(
|
|||||||
|
|
||||||
target_compile_options(${LIB_FSFW_NAME} PRIVATE ${FSFW_WARNING_FLAGS}
|
target_compile_options(${LIB_FSFW_NAME} PRIVATE ${FSFW_WARNING_FLAGS}
|
||||||
${COMPILER_FLAGS})
|
${COMPILER_FLAGS})
|
||||||
|
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${FSFW_ADDITIONAL_LINK_LIBS})
|
||||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${FSFW_ETL_LINK_TARGET}
|
target_link_libraries(${LIB_FSFW_NAME} PUBLIC ${FSFW_ETL_LINK_TARGET} ${FSFW_FMT_LINK_TARGET})
|
||||||
${FSFW_ADDITIONAL_LINK_LIBS})
|
|
||||||
|
|
||||||
string(
|
string(
|
||||||
CONCAT
|
CONCAT
|
||||||
@ -461,6 +484,13 @@ string(
|
|||||||
"Target OSAL: ${FSFW_OS_NAME}\n"
|
"Target OSAL: ${FSFW_OS_NAME}\n"
|
||||||
"######################################################################\n")
|
"######################################################################\n")
|
||||||
|
|
||||||
|
# The additional / is important to remove the last character from the path. Note
|
||||||
|
# that it does not matter if the OS uses / or \, because we are only saving the
|
||||||
|
# path size.
|
||||||
|
string(LENGTH "${CMAKE_SOURCE_DIR}/" FSFW_SOURCE_PATH_SIZE)
|
||||||
|
target_compile_definitions(
|
||||||
|
${LIB_FSFW_NAME} PRIVATE "-DFSFW_SOURCE_PATH_SIZE=${FSFW_SOURCE_PATH_SIZE}")
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${LIB_FSFW_NAME}
|
TARGET ${LIB_FSFW_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
|
@ -139,7 +139,7 @@ You can also use `-DFSFW_OSAL=linux` on Linux systems.
|
|||||||
|
|
||||||
Coverage data in HTML format can be generated using the `CodeCoverage`
|
Coverage data in HTML format can be generated using the `CodeCoverage`
|
||||||
[CMake module](https://github.com/bilke/cmake-modules/tree/master).
|
[CMake module](https://github.com/bilke/cmake-modules/tree/master).
|
||||||
To build the unittests, run them and then generare the coverage data in this format,
|
To build the unittests, run them and then generate the coverage data in this format,
|
||||||
the following command can be used inside the build directory after the build system was set up
|
the following command can be used inside the build directory after the build system was set up
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@ -188,7 +188,10 @@ and open the documentation conveniently. Try `helper.py -h for more information.
|
|||||||
|
|
||||||
The formatting is done by the `clang-format` tool. The configuration is contained within the
|
The formatting is done by the `clang-format` tool. The configuration is contained within the
|
||||||
`.clang-format` file in the repository root. As long as `clang-format` is installed, you
|
`.clang-format` file in the repository root. As long as `clang-format` is installed, you
|
||||||
can run the `apply-clang-format.sh` helper script to format all source files consistently.
|
can run the `auto-format.sh` helper script to format all source files consistently. Furthermore cmake-format is required to format CMake files which can be installed with:
|
||||||
|
````sh
|
||||||
|
sudo pip install cmakelang
|
||||||
|
````
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
|
@ -12,3 +12,9 @@ RUN git clone https://github.com/catchorg/Catch2.git && \
|
|||||||
git checkout v3.0.0-preview5 && \
|
git checkout v3.0.0-preview5 && \
|
||||||
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||||
cmake --build build/ --target install
|
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/
|
||||||
|
4
automation/Jenkinsfile
vendored
4
automation/Jenkinsfile
vendored
@ -3,7 +3,7 @@ pipeline {
|
|||||||
BUILDDIR = 'build-tests'
|
BUILDDIR = 'build-tests'
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker { image 'fsfw-ci:d2'}
|
docker { image 'fsfw-ci:d3'}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('Clean') {
|
stage('Clean') {
|
||||||
@ -14,7 +14,7 @@ pipeline {
|
|||||||
stage('Configure') {
|
stage('Configure') {
|
||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR) {
|
||||||
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_UNITTESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
|
||||||
|
|
||||||
# Can also be changed by upper CMakeLists.txt file
|
|
||||||
find_library(LIB_FSFW_NAME fsfw REQUIRED)
|
|
||||||
|
|
||||||
option(FSFW_HAL_ADD_LINUX "Add the Linux HAL to the sources. Requires gpiod library" OFF)
|
|
||||||
# On by default for now because I did not have an issue including and compiling those files
|
|
||||||
# and libraries on a Desktop Linux system and the primary target of the FSFW is still embedded
|
|
||||||
# Linux. The only exception from this is the gpiod library which requires a dedicated installation,
|
|
||||||
# but CMake is able to determine whether this library is installed with find_library.
|
|
||||||
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add peripheral drivers for embedded Linux" ON)
|
|
||||||
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Target implements libgpiod" ON)
|
|
||||||
|
|
||||||
option(FSFW_HAL_ADD_RASPBERRY_PI "Add Raspberry Pi specific code to the sources" OFF)
|
|
||||||
option(FSFW_HAL_ADD_STM32H7 "Add the STM32H7 HAL to the sources" OFF)
|
|
||||||
option(FSFW_HAL_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON)
|
|
||||||
|
|
||||||
set(LINUX_HAL_PATH_NAME linux)
|
|
||||||
set(STM32H7_PATH_NAME stm32h7)
|
|
||||||
|
|
||||||
add_subdirectory(src)
|
|
||||||
|
|
||||||
foreach(INCLUDE_PATH ${FSFW_HAL_ADDITIONAL_INC_PATHS})
|
|
||||||
if(IS_ABSOLUTE ${INCLUDE_PATH})
|
|
||||||
set(CURR_ABS_INC_PATH "${INCLUDE_PATH}")
|
|
||||||
else()
|
|
||||||
get_filename_component(CURR_ABS_INC_PATH
|
|
||||||
${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_VERBOSE)
|
|
||||||
message(STATUS "FSFW include path: ${CURR_ABS_INC_PATH}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND FSFW_HAL_ADD_INC_PATHS_ABS ${CURR_ABS_INC_PATH})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
target_include_directories(${LIB_FSFW_NAME} PRIVATE
|
|
||||||
${FSFW_HAL_ADD_INC_PATHS_ABS}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(${LIB_FSFW_NAME} PRIVATE
|
|
||||||
${FSFW_HAL_DEFINES}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
|
||||||
${FSFW_HAL_LINK_LIBS}
|
|
||||||
)
|
|
@ -1,9 +0,0 @@
|
|||||||
target_include_directories(${LIB_FSFW_NAME} PRIVATE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(${LIB_FSFW_NAME} INTERFACE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_subdirectory(fsfw_hal)
|
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
|
||||||
#define FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
|
||||||
|
|
||||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
|
||||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Additional abstraction layer for handling GPIOs.
|
|
||||||
*
|
|
||||||
* @author J. Meier
|
|
||||||
*/
|
|
||||||
class Gpio {
|
|
||||||
public:
|
|
||||||
Gpio(gpioId_t gpioId, GpioIF* gpioIF) : gpioId(gpioId), gpioIF(gpioIF) {
|
|
||||||
if (gpioIF == nullptr) {
|
|
||||||
sif::error << "Gpio::Gpio: Invalid GpioIF" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReturnValue_t pullHigh() { return gpioIF->pullHigh(gpioId); }
|
|
||||||
ReturnValue_t pullLow() { return gpioIF->pullLow(gpioId); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
gpioId_t gpioId = gpio::NO_GPIO;
|
|
||||||
GpioIF* gpioIF = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_ */
|
|
@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
|
||||||
|
|
||||||
class ManualCsLockWrapper : public HasReturnvaluesIF {
|
|
||||||
public:
|
|
||||||
ManualCsLockWrapper(MutexIF* lock, GpioIF* gpioIF, SpiCookie* cookie,
|
|
||||||
MutexIF::TimeoutType type = MutexIF::TimeoutType::BLOCKING,
|
|
||||||
uint32_t timeoutMs = 0)
|
|
||||||
: lock(lock), gpioIF(gpioIF), cookie(cookie), type(type), timeoutMs(timeoutMs) {
|
|
||||||
if (cookie == nullptr) {
|
|
||||||
// TODO: Error? Or maybe throw exception..
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cookie->setCsLockManual(true);
|
|
||||||
lockResult = lock->lockMutex(type, timeoutMs);
|
|
||||||
if (lockResult != RETURN_OK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gpioResult = gpioIF->pullLow(cookie->getChipSelectPin());
|
|
||||||
}
|
|
||||||
|
|
||||||
~ManualCsLockWrapper() {
|
|
||||||
if (gpioResult == RETURN_OK) {
|
|
||||||
gpioIF->pullHigh(cookie->getChipSelectPin());
|
|
||||||
}
|
|
||||||
cookie->setCsLockManual(false);
|
|
||||||
if (lockResult == RETURN_OK) {
|
|
||||||
lock->unlockMutex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReturnValue_t lockResult;
|
|
||||||
ReturnValue_t gpioResult;
|
|
||||||
|
|
||||||
private:
|
|
||||||
MutexIF* lock;
|
|
||||||
GpioIF* gpioIF;
|
|
||||||
SpiCookie* cookie;
|
|
||||||
MutexIF::TimeoutType type;
|
|
||||||
uint32_t timeoutMs = 0;
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
#include "fsfw_hal/linux/utility.h"
|
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "fsfw/FSFW.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
|
|
||||||
void utility::handleIoctlError(const char* const customPrintout) {
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
if (customPrintout != nullptr) {
|
|
||||||
sif::warning << customPrintout << std::endl;
|
|
||||||
}
|
|
||||||
sif::warning << "handleIoctlError: Error code " << errno << ", " << strerror(errno) << std::endl;
|
|
||||||
#else
|
|
||||||
if (customPrintout != nullptr) {
|
|
||||||
sif::printWarning("%s\n", customPrintout);
|
|
||||||
}
|
|
||||||
sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno));
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
}
|
|
@ -57,10 +57,10 @@ class ServiceInterfaceStream : public std::ostream {
|
|||||||
// Forward declaration of interface streams. These should be instantiated in
|
// Forward declaration of interface streams. These should be instantiated in
|
||||||
// main. They can then be used like std::cout or std::cerr.
|
// main. They can then be used like std::cout or std::cerr.
|
||||||
namespace sif {
|
namespace sif {
|
||||||
extern ServiceInterfaceStream debug;
|
// extern ServiceInterfaceStream debug;
|
||||||
extern ServiceInterfaceStream info;
|
// extern ServiceInterfaceStream info;
|
||||||
extern ServiceInterfaceStream warning;
|
// extern ServiceInterfaceStream warning;
|
||||||
extern ServiceInterfaceStream error;
|
// extern ServiceInterfaceStream error;
|
||||||
} // namespace sif
|
} // namespace sif
|
||||||
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
@ -3,12 +3,6 @@ if [[ ! -f README.md ]]; then
|
|||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
folder_list=(
|
|
||||||
"./src"
|
|
||||||
"./hal"
|
|
||||||
"./tests"
|
|
||||||
)
|
|
||||||
|
|
||||||
cmake_fmt="cmake-format"
|
cmake_fmt="cmake-format"
|
||||||
file_selectors="-iname CMakeLists.txt"
|
file_selectors="-iname CMakeLists.txt"
|
||||||
if command -v ${cmake_fmt} &> /dev/null; then
|
if command -v ${cmake_fmt} &> /dev/null; then
|
||||||
@ -21,10 +15,9 @@ fi
|
|||||||
cpp_format="clang-format"
|
cpp_format="clang-format"
|
||||||
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
||||||
if command -v ${cpp_format} &> /dev/null; then
|
if command -v ${cpp_format} &> /dev/null; then
|
||||||
for dir in ${folder_list[@]}; do
|
find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||||
echo "Auto-formatting ${dir} recursively"
|
find ./hal ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||||
find ${dir} ${file_selectors} | xargs clang-format --style=file -i
|
find ./tests ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||||
done
|
|
||||||
else
|
else
|
||||||
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
||||||
fi
|
fi
|
||||||
|
@ -48,6 +48,20 @@ def main():
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Run valgrind on generated test binary",
|
help="Run valgrind on generated test binary",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-g",
|
||||||
|
"--generators",
|
||||||
|
default = "Ninja",
|
||||||
|
action="store",
|
||||||
|
help="CMake generators",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-w",
|
||||||
|
"--windows",
|
||||||
|
default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Run on windows",
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if args.all:
|
if args.all:
|
||||||
@ -115,14 +129,14 @@ def handle_tests_type(args, build_dir_list: list):
|
|||||||
if args.create:
|
if args.create:
|
||||||
if os.path.exists(UNITTEST_FOLDER_NAME):
|
if os.path.exists(UNITTEST_FOLDER_NAME):
|
||||||
shutil.rmtree(UNITTEST_FOLDER_NAME)
|
shutil.rmtree(UNITTEST_FOLDER_NAME)
|
||||||
create_tests_build_cfg()
|
create_tests_build_cfg(args)
|
||||||
build_directory = UNITTEST_FOLDER_NAME
|
build_directory = UNITTEST_FOLDER_NAME
|
||||||
elif len(build_dir_list) == 0:
|
elif len(build_dir_list) == 0:
|
||||||
print(
|
print(
|
||||||
"No valid CMake tests build directory found. "
|
"No valid CMake tests build directory found. "
|
||||||
"Trying to set up test build system"
|
"Trying to set up test build system"
|
||||||
)
|
)
|
||||||
create_tests_build_cfg()
|
create_tests_build_cfg(args)
|
||||||
build_directory = UNITTEST_FOLDER_NAME
|
build_directory = UNITTEST_FOLDER_NAME
|
||||||
elif len(build_dir_list) == 1:
|
elif len(build_dir_list) == 1:
|
||||||
build_directory = build_dir_list[0]
|
build_directory = build_dir_list[0]
|
||||||
@ -147,10 +161,15 @@ def handle_tests_type(args, build_dir_list: list):
|
|||||||
os.chdir("..")
|
os.chdir("..")
|
||||||
|
|
||||||
|
|
||||||
def create_tests_build_cfg():
|
def create_tests_build_cfg(args):
|
||||||
os.mkdir(UNITTEST_FOLDER_NAME)
|
os.mkdir(UNITTEST_FOLDER_NAME)
|
||||||
os.chdir(UNITTEST_FOLDER_NAME)
|
os.chdir(UNITTEST_FOLDER_NAME)
|
||||||
cmd_runner("cmake -DFSFW_OSAL=host -DFSFW_BUILD_UNITTESTS=ON ..")
|
if args.windows:
|
||||||
|
cmake_cmd = 'cmake -G "' + args.generators + '" -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON \
|
||||||
|
-DGCOVR_PATH="py -m gcovr" ..'
|
||||||
|
else:
|
||||||
|
cmake_cmd = 'cmake -G "' + args.generators + '" -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON ..'
|
||||||
|
cmd_runner(cmake_cmd)
|
||||||
os.chdir("..")
|
os.chdir("..")
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,3 +4,8 @@ target_include_directories(${LIB_FSFW_NAME}
|
|||||||
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
add_subdirectory(fsfw)
|
add_subdirectory(fsfw)
|
||||||
|
if(FSFW_ADD_HAL)
|
||||||
|
add_subdirectory(fsfw_hal)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(fsfw_tests)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "fsfw/action.h"
|
#include "fsfw/action.h"
|
||||||
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||||
: owner(setOwner), queueToUse(useThisQueue) {}
|
: owner(setOwner), queueToUse(useThisQueue) {}
|
||||||
|
|
||||||
ActionHelper::~ActionHelper() {}
|
ActionHelper::~ActionHelper() = default;
|
||||||
|
|
||||||
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||||
@ -28,13 +28,7 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (queueToUse == nullptr) {
|
if (queueToUse == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGW("{}", "initialize: No queue set\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "ActionHelper::initialize: No queue set" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("ActionHelper::initialize: No queue set\n");
|
|
||||||
#endif
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +53,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
|||||||
|
|
||||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||||
store_address_t dataAddress) {
|
store_address_t dataAddress) {
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
@ -96,14 +90,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
|||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr);
|
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{}", "reportData: Getting free element from IPC store failed\n");
|
||||||
sif::warning << "ActionHelper::reportData: Getting free element from IPC store failed!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"ActionHelper::reportData: Getting free element from IPC "
|
|
||||||
"store failed!\n");
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
|
result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||||
@ -138,11 +125,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
|||||||
store_address_t storeAddress;
|
store_address_t storeAddress;
|
||||||
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
|
ReturnValue_t result = ipcStore->addData(&storeAddress, data, dataSize);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{}", "reportData: Adding data to IPC store failed\n");
|
||||||
sif::warning << "ActionHelper::reportData: Adding data to IPC store failed!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("ActionHelper::reportData: Adding data to IPC store failed!\n");
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||||
#define FSFW_ACTION_ACTIONHELPER_H_
|
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||||
|
|
||||||
#include "../ipc/MessageQueueIF.h"
|
|
||||||
#include "../serialize/SerializeIF.h"
|
|
||||||
#include "ActionMessage.h"
|
#include "ActionMessage.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
/**
|
/**
|
||||||
* @brief Action Helper is a helper class which handles action messages
|
* @brief Action Helper is a helper class which handles action messages
|
||||||
*
|
*
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
|
|
||||||
ActionMessage::ActionMessage() {}
|
ActionMessage::ActionMessage() = default;
|
||||||
|
|
||||||
ActionMessage::~ActionMessage() {}
|
ActionMessage::~ActionMessage() = default;
|
||||||
|
|
||||||
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
||||||
store_address_t parameters) {
|
store_address_t parameters) {
|
||||||
@ -64,9 +64,8 @@ void ActionMessage::clear(CommandMessage* message) {
|
|||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
case EXECUTE_ACTION:
|
case EXECUTE_ACTION:
|
||||||
case DATA_REPLY: {
|
case DATA_REPLY: {
|
||||||
StorageManagerIF* ipcStore =
|
auto* ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
if (ipcStore != nullptr) {
|
||||||
if (ipcStore != NULL) {
|
|
||||||
ipcStore->deleteData(getStoreId(message));
|
ipcStore->deleteData(getStoreId(message));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
|
||||||
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner)
|
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner)
|
||||||
: owner(setOwner), queueToUse(NULL), ipcStore(NULL), commandCount(0), lastTarget(0) {}
|
: owner(setOwner), queueToUse(nullptr), ipcStore(nullptr), commandCount(0), lastTarget(0) {}
|
||||||
|
|
||||||
CommandActionHelper::~CommandActionHelper() {}
|
CommandActionHelper::~CommandActionHelper() = default;
|
||||||
|
|
||||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||||
SerializeIF *data) {
|
SerializeIF *data) {
|
||||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||||
if (receiver == NULL) {
|
if (receiver == nullptr) {
|
||||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||||
}
|
}
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
@ -29,11 +29,8 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId
|
|||||||
|
|
||||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||||
const uint8_t *data, uint32_t size) {
|
const uint8_t *data, uint32_t size) {
|
||||||
// if (commandCount != 0) {
|
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||||
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
if (receiver == nullptr) {
|
||||||
// }
|
|
||||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
|
||||||
if (receiver == NULL) {
|
|
||||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||||
}
|
}
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
@ -59,12 +56,12 @@ ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionI
|
|||||||
|
|
||||||
ReturnValue_t CommandActionHelper::initialize() {
|
ReturnValue_t CommandActionHelper::initialize() {
|
||||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if (ipcStore == NULL) {
|
if (ipcStore == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
queueToUse = owner->getCommandQueuePtr();
|
queueToUse = owner->getCommandQueuePtr();
|
||||||
if (queueToUse == NULL) {
|
if (queueToUse == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -104,7 +101,7 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
|||||||
uint8_t CommandActionHelper::getCommandCount() const { return commandCount; }
|
uint8_t CommandActionHelper::getCommandCount() const { return commandCount; }
|
||||||
|
|
||||||
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
||||||
const uint8_t *data = NULL;
|
const uint8_t *data = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
@ -14,14 +14,14 @@ class CommandActionHelper {
|
|||||||
friend class CommandsActionsIF;
|
friend class CommandsActionsIF;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CommandActionHelper(CommandsActionsIF* owner);
|
explicit CommandActionHelper(CommandsActionsIF* owner);
|
||||||
virtual ~CommandActionHelper();
|
virtual ~CommandActionHelper();
|
||||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
|
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
||||||
const uint8_t* data = nullptr, uint32_t size = 0);
|
uint32_t size);
|
||||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
ReturnValue_t handleReply(CommandMessage* reply);
|
ReturnValue_t handleReply(CommandMessage* reply);
|
||||||
uint8_t getCommandCount() const;
|
[[nodiscard]] uint8_t getCommandCount() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CommandsActionsIF* owner;
|
CommandsActionsIF* owner;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef FSFW_ACTION_COMMANDSACTIONSIF_H_
|
#ifndef FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||||
#define FSFW_ACTION_COMMANDSACTIONSIF_H_
|
#define FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||||
|
|
||||||
#include "../ipc/MessageQueueIF.h"
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "CommandActionHelper.h"
|
#include "CommandActionHelper.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to separate commanding actions of other objects.
|
* Interface to separate commanding actions of other objects.
|
||||||
@ -21,7 +21,7 @@ class CommandsActionsIF {
|
|||||||
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
||||||
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||||
virtual ~CommandsActionsIF() {}
|
virtual ~CommandsActionsIF() = default;
|
||||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#ifndef FSFW_ACTION_HASACTIONSIF_H_
|
#ifndef FSFW_ACTION_HASACTIONSIF_H_
|
||||||
#define FSFW_ACTION_HASACTIONSIF_H_
|
#define FSFW_ACTION_HASACTIONSIF_H_
|
||||||
|
|
||||||
#include "../ipc/MessageQueueIF.h"
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "ActionHelper.h"
|
#include "ActionHelper.h"
|
||||||
#include "ActionMessage.h"
|
#include "ActionMessage.h"
|
||||||
#include "SimpleActionHelper.h"
|
#include "SimpleActionHelper.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
@ -40,12 +40,12 @@ class HasActionsIF {
|
|||||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||||
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
||||||
virtual ~HasActionsIF() {}
|
virtual ~HasActionsIF() = default;
|
||||||
/**
|
/**
|
||||||
* Function to get the MessageQueueId_t of the implementing object
|
* Function to get the MessageQueueId_t of the implementing object
|
||||||
* @return MessageQueueId_t of the object
|
* @return MessageQueueId_t of the object
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
/**
|
/**
|
||||||
* Execute or initialize the execution of a certain function.
|
* Execute or initialize the execution of a certain function.
|
||||||
* The ActionHelpers will execute this function and behave differently
|
* The ActionHelpers will execute this function and behave differently
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||||
: ActionHelper(setOwner, useThisQueue), isExecuting(false) {}
|
: ActionHelper(setOwner, useThisQueue), isExecuting(false) {}
|
||||||
|
|
||||||
SimpleActionHelper::~SimpleActionHelper() {}
|
SimpleActionHelper::~SimpleActionHelper() = default;
|
||||||
|
|
||||||
void SimpleActionHelper::step(ReturnValue_t result) {
|
void SimpleActionHelper::step(ReturnValue_t result) {
|
||||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||||
@ -38,7 +38,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId
|
|||||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::IS_BUSY);
|
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::IS_BUSY);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
}
|
}
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
class SimpleActionHelper : public ActionHelper {
|
class SimpleActionHelper : public ActionHelper {
|
||||||
public:
|
public:
|
||||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||||
virtual ~SimpleActionHelper();
|
~SimpleActionHelper() override;
|
||||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
ReturnValue_t reportData(SerializeIF* data);
|
ReturnValue_t reportData(SerializeIF* data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||||
store_address_t dataAddress);
|
store_address_t dataAddress) override;
|
||||||
virtual void resetHelper();
|
void resetHelper() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isExecuting;
|
bool isExecuting;
|
||||||
@ -28,4 +28,4 @@ class SimpleActionHelper : public ActionHelper {
|
|||||||
uint8_t stepCount = 0;
|
uint8_t stepCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SIMPLEACTIONHELPER_H_ */
|
#endif /* FSFW_ACTION_SIMPLEACTIONHELPER_H_ */
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "fsfw/ipc/CommandMessage.h"
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/storagemanager/storeAddress.h"
|
#include "fsfw/storagemanager/storeAddress.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||||
|
|
||||||
@ -12,9 +13,7 @@ object_id_t CFDPHandler::packetDestination = 0;
|
|||||||
|
|
||||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||||
: SystemObject(setObjectId) {
|
: SystemObject(setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
CFDP_HANDLER_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
distributor = dist;
|
distributor = dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,13 +29,7 @@ ReturnValue_t CFDPHandler::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CFDPHandler::handleRequest(store_address_t storeId) {
|
ReturnValue_t CFDPHandler::handleRequest(store_address_t storeId) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGDT("{}", "CFDPHandler::handleRequest\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::debug << "CFDPHandler::handleRequest" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printDebug("CFDPHandler::handleRequest\n");
|
|
||||||
#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO read out packet from store using storeId
|
// TODO read out packet from store using storeId
|
||||||
|
|
||||||
|
@ -50,17 +50,9 @@ ReturnValue_t EofPduDeserializer::parseData() {
|
|||||||
if (info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
if (info.getConditionCode() != cfdp::ConditionCode::NO_ERROR) {
|
||||||
EntityIdTlv* tlvPtr = info.getFaultLoc();
|
EntityIdTlv* tlvPtr = info.getFaultLoc();
|
||||||
if (tlvPtr == nullptr) {
|
if (tlvPtr == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGW("{}",
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
"parseData: Ca not deserialize fault location,"
|
||||||
sif::warning << "EofPduDeserializer::parseData: Ca not deserialize fault location,"
|
" given TLV pointer invalid\n");
|
||||||
" given TLV pointer invalid"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"EofPduDeserializer::parseData: Ca not deserialize fault location,"
|
|
||||||
" given TLV pointer invalid");
|
|
||||||
#endif
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
result = tlvPtr->deSerialize(&bufPtr, &deserLen, endianness);
|
result = tlvPtr->deSerialize(&bufPtr, &deserLen, endianness);
|
||||||
|
@ -7,13 +7,7 @@
|
|||||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
||||||
ReturnValue_t result = this->setValue(width, value);
|
ReturnValue_t result = this->setValue(width, value);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
FSFW_LOGW("{}", "cfdp::VarLenField: Setting value failed\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "cfdp::VarLenField: Setting value failed" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("cfdp::VarLenField: Setting value failed\n");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <fsfw/cfdp/tlv/Tlv.h>
|
#include <fsfw/cfdp/tlv/Tlv.h>
|
||||||
#include <fsfw/cfdp/tlv/TlvIF.h>
|
#include <fsfw/cfdp/tlv/TlvIF.h>
|
||||||
#include <fsfw/serialize/SerializeIF.h>
|
#include <fsfw/serialize/SerializeIF.h>
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -128,17 +128,7 @@ class FilestoreTlvBase : public TlvIF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void secondFileNameMissing() const {
|
void secondFileNameMissing() const {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGWT("{}", "secondFileNameMissing: Second file name required but TLV pointer not set\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "FilestoreRequestTlv::deSerialize: Second file name required"
|
|
||||||
" but TLV pointer not set"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"FilestoreRequestTlv::deSerialize: Second file name required"
|
|
||||||
" but TLV pointer not set\n");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilestoreActionCode getActionCode() const { return actionCode; }
|
FilestoreActionCode getActionCode() const { return actionCode; }
|
||||||
|
@ -13,9 +13,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
|||||||
submode(SUBMODE_NONE),
|
submode(SUBMODE_NONE),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
@ -28,7 +26,7 @@ ReturnValue_t ControllerBase::initialize() {
|
|||||||
|
|
||||||
MessageQueueId_t parentQueue = 0;
|
MessageQueueId_t parentQueue = 0;
|
||||||
if (parentId != objects::NO_OBJECT) {
|
if (parentId != objects::NO_OBJECT) {
|
||||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
auto* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||||
if (parent == nullptr) {
|
if (parent == nullptr) {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -54,7 +52,7 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->
|
|||||||
|
|
||||||
void ControllerBase::handleQueue() {
|
void ControllerBase::handleQueue() {
|
||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result;
|
||||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||||
result = commandQueue->receiveMessage(&command)) {
|
result = commandQueue->receiveMessage(&command)) {
|
||||||
result = modeHelper.handleModeCommand(&command);
|
result = modeHelper.handleModeCommand(&command);
|
||||||
@ -75,20 +73,20 @@ void ControllerBase::handleQueue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::startTransition(Mode_t mode, Submode_t submode) {
|
void ControllerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
||||||
changeHK(this->mode, this->submode, false);
|
changeHK(this->mode, this->submode, false);
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
this->mode = mode;
|
mode = mode_;
|
||||||
this->submode = submode;
|
submode = submode_;
|
||||||
modeHelper.modeChanged(mode, submode);
|
modeHelper.modeChanged(mode, submode);
|
||||||
modeChanged(mode, submode);
|
modeChanged(mode, submode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
changeHK(this->mode, this->submode, true);
|
changeHK(this->mode, this->submode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) {
|
void ControllerBase::getMode(Mode_t* mode_, Submode_t* submode_) {
|
||||||
*mode = this->mode;
|
*mode_ = this->mode;
|
||||||
*submode = this->submode;
|
*submode_ = this->submode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
|
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
|
||||||
@ -101,7 +99,7 @@ ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
|||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBase::modeChanged(Mode_t mode, Submode_t submode) { return; }
|
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||||
switch (health) {
|
switch (health) {
|
||||||
@ -117,6 +115,6 @@ ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
|||||||
HasHealthIF::HealthState ControllerBase::getHealth() { return healthHelper.getHealth(); }
|
HasHealthIF::HealthState ControllerBase::getHealth() { return healthHelper.getHealth(); }
|
||||||
void ControllerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
void ControllerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
||||||
|
|
||||||
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {}
|
void ControllerBase::changeHK(Mode_t mode_, Submode_t submode_, bool enable) {}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return HasReturnvaluesIF::RETURN_OK; }
|
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return HasReturnvaluesIF::RETURN_OK; }
|
||||||
|
@ -24,21 +24,21 @@ class ControllerBase : public HasModesIF,
|
|||||||
static const Mode_t MODE_NORMAL = 2;
|
static const Mode_t MODE_NORMAL = 2;
|
||||||
|
|
||||||
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||||
virtual ~ControllerBase();
|
~ControllerBase() override;
|
||||||
|
|
||||||
/** SystemObject override */
|
/** SystemObject override */
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
/** HasHealthIF overrides */
|
/** HasHealthIF overrides */
|
||||||
virtual ReturnValue_t setHealth(HealthState health) override;
|
ReturnValue_t setHealth(HealthState health) override;
|
||||||
virtual HasHealthIF::HealthState getHealth() override;
|
HasHealthIF::HealthState getHealth() override;
|
||||||
|
|
||||||
/** ExecutableObjectIF overrides */
|
/** ExecutableObjectIF overrides */
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
virtual void setTaskIF(PeriodicTaskIF *task) override;
|
void setTaskIF(PeriodicTaskIF *task) override;
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -54,8 +54,8 @@ class ControllerBase : public HasModesIF,
|
|||||||
*/
|
*/
|
||||||
virtual void performControlOperation() = 0;
|
virtual void performControlOperation() = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) override = 0;
|
uint32_t *msToReachTheMode) override = 0;
|
||||||
|
|
||||||
const object_id_t parentId;
|
const object_id_t parentId;
|
||||||
|
|
||||||
@ -80,10 +80,10 @@ class ControllerBase : public HasModesIF,
|
|||||||
|
|
||||||
/** Mode helpers */
|
/** Mode helpers */
|
||||||
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||||
virtual void setToExternalControl() override;
|
void setToExternalControl() override;
|
||||||
virtual void announceMode(bool recursive);
|
void announceMode(bool recursive) override;
|
||||||
/** HK helpers */
|
/** HK helpers */
|
||||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t
|
|||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
actionHelper(this, commandQueue) {}
|
actionHelper(this, commandQueue) {}
|
||||||
|
|
||||||
ExtendedControllerBase::~ExtendedControllerBase() {}
|
ExtendedControllerBase::~ExtendedControllerBase() = default;
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy,
|
MessageQueueId_t commandedBy,
|
||||||
@ -31,7 +31,7 @@ ReturnValue_t ExtendedControllerBase::handleCommandMessage(CommandMessage *messa
|
|||||||
|
|
||||||
void ExtendedControllerBase::handleQueue() {
|
void ExtendedControllerBase::handleQueue() {
|
||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result;
|
||||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||||
result = commandQueue->receiveMessage(&command)) {
|
result = commandQueue->receiveMessage(&command)) {
|
||||||
result = actionHelper.handleActionMessage(&command);
|
result = actionHelper.handleActionMessage(&command);
|
||||||
|
@ -18,16 +18,16 @@ class ExtendedControllerBase : public ControllerBase,
|
|||||||
public HasLocalDataPoolIF {
|
public HasLocalDataPoolIF {
|
||||||
public:
|
public:
|
||||||
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||||
virtual ~ExtendedControllerBase();
|
~ExtendedControllerBase() override;
|
||||||
|
|
||||||
/* SystemObjectIF overrides */
|
/* SystemObjectIF overrides */
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
/* ExecutableObjectIF overrides */
|
/* ExecutableObjectIF overrides */
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LocalDataPoolManager poolManager;
|
LocalDataPoolManager poolManager;
|
||||||
@ -39,32 +39,32 @@ class ExtendedControllerBase : public ControllerBase,
|
|||||||
* @param message
|
* @param message
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
|
ReturnValue_t handleCommandMessage(CommandMessage* message) override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Periodic helper from ControllerBase, implemented by child class.
|
* Periodic helper from ControllerBase, implemented by child class.
|
||||||
*/
|
*/
|
||||||
virtual void performControlOperation() = 0;
|
void performControlOperation() override = 0;
|
||||||
|
|
||||||
/* Handle the four messages mentioned above */
|
/* Handle the four messages mentioned above */
|
||||||
void handleQueue() override;
|
void handleQueue() override;
|
||||||
|
|
||||||
/* HasActionsIF overrides */
|
/* HasActionsIF overrides */
|
||||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) override;
|
const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
/* HasLocalDatapoolIF overrides */
|
/* HasLocalDatapoolIF overrides */
|
||||||
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
virtual object_id_t getObjectId() const override;
|
[[nodiscard]] object_id_t getObjectId() const override;
|
||||||
virtual uint32_t getPeriodicOperationFrequency() const override;
|
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
|
||||||
|
|
||||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override = 0;
|
LocalDataPoolManager& poolManager) override = 0;
|
||||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
||||||
|
|
||||||
// Mode abstract functions
|
// Mode abstract functions
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t* msToReachTheMode) override = 0;
|
uint32_t* msToReachTheMode) override = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ */
|
#endif /* FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "fsfw/datalinklayer/Clcw.h"
|
#include "fsfw/datalinklayer/Clcw.h"
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
Clcw::Clcw() {
|
Clcw::Clcw() {
|
||||||
content.raw = 0;
|
content.raw = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "fsfw/datalinklayer/DataLinkLayer.h"
|
#include "fsfw/datalinklayer/DataLinkLayer.h"
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw,
|
DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw,
|
||||||
uint8_t set_start_sequence_length, uint16_t set_scid)
|
uint8_t set_start_sequence_length, uint16_t set_scid)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/tmtcpacket/SpacePacketBase.h"
|
#include "fsfw/tmtcpacket/SpacePacketBase.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "fsfw/datalinklayer/TcTransferFrame.h"
|
#include "fsfw/datalinklayer/TcTransferFrame.h"
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
TcTransferFrame::TcTransferFrame() { frame = nullptr; }
|
TcTransferFrame::TcTransferFrame() { frame = nullptr; }
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid,
|
TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid,
|
||||||
uint8_t vcId, uint8_t sequenceNumber,
|
uint8_t vcId, uint8_t sequenceNumber,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "fsfw/datalinklayer/VirtualChannelReception.h"
|
#include "fsfw/datalinklayer/VirtualChannelReception.h"
|
||||||
|
|
||||||
#include "fsfw/datalinklayer/BCFrame.h"
|
#include "fsfw/datalinklayer/BCFrame.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
VirtualChannelReception::VirtualChannelReception(uint8_t setChannelId,
|
VirtualChannelReception::VirtualChannelReception(uint8_t setChannelId,
|
||||||
uint8_t setSlidingWindowWidth)
|
uint8_t setSlidingWindowWidth)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/datapool/ReadCommitIFAttorney.h"
|
#include "fsfw/datapool/ReadCommitIFAttorney.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxFillCount)
|
const size_t maxFillCount)
|
||||||
@ -17,27 +17,15 @@ ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF* variable) {
|
|||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (state != States::STATE_SET_UNINITIALISED) {
|
if (state != States::STATE_SET_UNINITIALISED) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "registerVariable: Call made in wrong position\n");
|
||||||
sif::error << "DataSet::registerVariable: Call made in wrong position." << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("DataSet::registerVariable: Call made in wrong position.");
|
|
||||||
#endif
|
|
||||||
return DataSetIF::DATA_SET_UNINITIALISED;
|
return DataSetIF::DATA_SET_UNINITIALISED;
|
||||||
}
|
}
|
||||||
if (variable == nullptr) {
|
if (variable == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "registerVariable: Pool variable is nullptr\n");
|
||||||
sif::error << "DataSet::registerVariable: Pool variable is nullptr." << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("DataSet::registerVariable: Pool variable is nullptr.\n");
|
|
||||||
#endif
|
|
||||||
return DataSetIF::POOL_VAR_NULL;
|
return DataSetIF::POOL_VAR_NULL;
|
||||||
}
|
}
|
||||||
if (fillCount >= maxFillCount) {
|
if (fillCount >= maxFillCount) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "registerVariable: DataSet is full\n");
|
||||||
sif::error << "DataSet::registerVariable: DataSet is full." << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("DataSet::registerVariable: DataSet is full.\n");
|
|
||||||
#endif
|
|
||||||
return DataSetIF::DATA_SET_FULL;
|
return DataSetIF::DATA_SET_FULL;
|
||||||
}
|
}
|
||||||
registeredVariables[fillCount] = variable;
|
registeredVariables[fillCount] = variable;
|
||||||
@ -59,15 +47,7 @@ ReturnValue_t PoolDataSetBase::read(MutexIF::TimeoutType timeoutType, uint32_t l
|
|||||||
state = States::STATE_SET_WAS_READ;
|
state = States::STATE_SET_WAS_READ;
|
||||||
unlockDataPool();
|
unlockDataPool();
|
||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{}", "read: Call made in wrong position. commit call might be missing\n");
|
||||||
sif::warning << "PoolDataSetBase::read: Call made in wrong position. Don't forget to "
|
|
||||||
"commit member datasets!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"PoolDataSetBase::read: Call made in wrong position. Don't forget to "
|
|
||||||
"commit member datasets!\n");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
result = SET_WAS_ALREADY_READ;
|
result = SET_WAS_ALREADY_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
PoolEntry<T>::PoolEntry(uint8_t len, bool setValid) : length(len), valid(setValid) {
|
PoolEntry<T>::PoolEntry(uint8_t len, bool setValid) : length(len), valid(setValid) {
|
||||||
@ -70,13 +70,7 @@ void PoolEntry<T>::print() {
|
|||||||
} else {
|
} else {
|
||||||
validString = "Invalid";
|
validString = "Invalid";
|
||||||
}
|
}
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGI("PoolEntry Info. Validity {}\n", validString);
|
||||||
sif::info << "PoolEntry information." << std::endl;
|
|
||||||
sif::info << "PoolEntry validity: " << validString << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printInfo("PoolEntry information.\n");
|
|
||||||
sif::printInfo("PoolEntry validity: %s\n", validString);
|
|
||||||
#endif
|
|
||||||
arrayprinter::print(reinterpret_cast<uint8_t*>(address), getByteSize());
|
arrayprinter::print(reinterpret_cast<uint8_t*>(address), getByteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#ifndef FSFW_DATAPOOL_POOLREADHELPER_H_
|
#ifndef FSFW_DATAPOOL_POOLREADHELPER_H_
|
||||||
#define FSFW_DATAPOOL_POOLREADHELPER_H_
|
#define FSFW_DATAPOOL_POOLREADHELPER_H_
|
||||||
|
|
||||||
#include <FSFWConfig.h>
|
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "ReadCommitIF.h"
|
#include "ReadCommitIF.h"
|
||||||
|
#include "fsfw/FSFW.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper class to read data sets or pool variables
|
* @brief Helper class to read data sets or pool variables
|
||||||
@ -18,13 +17,7 @@ class PoolReadGuard {
|
|||||||
if (readObject != nullptr) {
|
if (readObject != nullptr) {
|
||||||
readResult = readObject->read(timeoutType, mutexTimeout);
|
readResult = readObject->read(timeoutType, mutexTimeout);
|
||||||
if (readResult != HasReturnvaluesIF::RETURN_OK) {
|
if (readResult != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL == 1
|
FSFW_LOGW("{}", "ctor: Read failed\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "PoolReadHelper: Read failed!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("PoolReadHelper: Read failed!\n");
|
|
||||||
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include "../datapool/PoolEntryIF.h"
|
#include "../datapool/PoolEntryIF.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
#include "../housekeeping/HousekeepingMessage.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "LocalDataPoolManager.h"
|
#include "LocalDataPoolManager.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "localPoolDefinitions.h"
|
#include "localPoolDefinitions.h"
|
||||||
|
|
||||||
class AccessPoolManagerIF;
|
class AccessPoolManagerIF;
|
||||||
@ -166,15 +166,7 @@ class HasLocalDataPoolIF {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
|
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden. Returning nullptr\n");
|
||||||
sif::warning << "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden. "
|
|
||||||
"Returning nullptr!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"HasLocalDataPoolIF::getPoolObjectHandle: "
|
|
||||||
"Not overriden. Returning nullptr!\n");
|
|
||||||
#endif
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "fsfw/FSFW.h"
|
||||||
#include "fsfw/datapoollocal.h"
|
#include "fsfw/datapoollocal.h"
|
||||||
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||||
#include "fsfw/housekeeping/HousekeepingSetPacket.h"
|
#include "fsfw/housekeeping/HousekeepingSetPacket.h"
|
||||||
@ -21,15 +22,15 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQue
|
|||||||
bool appendValidityBuffer)
|
bool appendValidityBuffer)
|
||||||
: appendValidityBuffer(appendValidityBuffer) {
|
: appendValidityBuffer(appendValidityBuffer) {
|
||||||
if (owner == nullptr) {
|
if (owner == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "LocalDataPoolManager",
|
printWarningOrError(sif::LogLevel::WARNING, "ctor", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "Invalid supplied owner");
|
"Invalid supplied owner");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->owner = owner;
|
this->owner = owner;
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
if (mutex == nullptr) {
|
if (mutex == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "LocalDataPoolManager",
|
printWarningOrError(sif::LogLevel::ERROR, "ctor", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "Could not create mutex");
|
"Could not create mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
hkQueue = queueToUse;
|
hkQueue = queueToUse;
|
||||||
@ -44,25 +45,25 @@ LocalDataPoolManager::~LocalDataPoolManager() {
|
|||||||
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||||
if (queueToUse == nullptr) {
|
if (queueToUse == nullptr) {
|
||||||
/* Error, all destinations invalid */
|
/* Error, all destinations invalid */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
||||||
}
|
}
|
||||||
hkQueue = queueToUse;
|
hkQueue = queueToUse;
|
||||||
|
|
||||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if (ipcStore == nullptr) {
|
if (ipcStore == nullptr) {
|
||||||
/* Error, all destinations invalid */
|
/* Error, all destinations invalid */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", HasReturnvaluesIF::RETURN_FAILED,
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
"Could not set IPC store.");
|
"Could not set IPC store.");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultHkDestination != objects::NO_OBJECT) {
|
if (defaultHkDestination != objects::NO_OBJECT) {
|
||||||
AcceptsHkPacketsIF* hkPacketReceiver =
|
auto* hkPacketReceiver =
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
||||||
if (hkPacketReceiver != nullptr) {
|
if (hkPacketReceiver != nullptr) {
|
||||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||||
} else {
|
} else {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +85,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "initializeHousekeepingPoolEntriesOnce",
|
printWarningOrError(sif::LogLevel::WARNING, "initializeHousekeepingPoolEntriesOnce",
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "The map should only be initialized once");
|
HasReturnvaluesIF::RETURN_FAILED, "The map should only be initialized once");
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -150,8 +151,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receive
|
|||||||
LocalPoolObjectBase* poolObj =
|
LocalPoolObjectBase* poolObj =
|
||||||
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId);
|
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId);
|
||||||
if (poolObj == nullptr) {
|
if (poolObj == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationUpdate",
|
printWarningOrError(sif::LogLevel::WARNING, "handleNotificationUpdate", POOLOBJECT_NOT_FOUND);
|
||||||
POOLOBJECT_NOT_FOUND);
|
|
||||||
return POOLOBJECT_NOT_FOUND;
|
return POOLOBJECT_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if (poolObj->hasChanged()) {
|
if (poolObj->hasChanged()) {
|
||||||
@ -170,8 +170,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receive
|
|||||||
LocalPoolDataSetBase* dataSet =
|
LocalPoolDataSetBase* dataSet =
|
||||||
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationUpdate",
|
printWarningOrError(sif::LogLevel::WARNING, "handleNotificationUpdate", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if (dataSet->hasChanged()) {
|
if (dataSet->hasChanged()) {
|
||||||
@ -199,7 +198,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
|||||||
LocalPoolObjectBase* poolObj =
|
LocalPoolObjectBase* poolObj =
|
||||||
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId);
|
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId);
|
||||||
if (poolObj == nullptr) {
|
if (poolObj == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationSnapshot",
|
printWarningOrError(sif::LogLevel::WARNING, "handleNotificationSnapshot",
|
||||||
POOLOBJECT_NOT_FOUND);
|
POOLOBJECT_NOT_FOUND);
|
||||||
return POOLOBJECT_NOT_FOUND;
|
return POOLOBJECT_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -235,8 +234,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
|||||||
LocalPoolDataSetBase* dataSet =
|
LocalPoolDataSetBase* dataSet =
|
||||||
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationSnapshot",
|
printWarningOrError(sif::LogLevel::WARNING, "handleNotificationSnapshot", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,9 +243,9 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare and send update snapshot */
|
/* Prepare and send update snapshot */
|
||||||
timeval now;
|
timeval now{};
|
||||||
Clock::getClock_timeval(&now);
|
Clock::getClock_timeval(&now);
|
||||||
CCSDSTime::CDS_short cds;
|
CCSDSTime::CDS_short cds{};
|
||||||
CCSDSTime::convertToCcsds(&cds, &now);
|
CCSDSTime::convertToCcsds(&cds, &now);
|
||||||
HousekeepingSnapshot updatePacket(
|
HousekeepingSnapshot updatePacket(
|
||||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
||||||
@ -342,7 +340,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool e
|
|||||||
AcceptsHkPacketsIF* hkReceiverObject =
|
AcceptsHkPacketsIF* hkReceiverObject =
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||||
if (hkReceiverObject == nullptr) {
|
if (hkReceiverObject == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
printWarningOrError(sif::LogLevel::WARNING, "subscribeForPeriodicPacket",
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
@ -368,10 +366,9 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool e
|
|||||||
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, bool isDiagnostics,
|
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, bool isDiagnostics,
|
||||||
bool reportingEnabled,
|
bool reportingEnabled,
|
||||||
object_id_t packetDestination) {
|
object_id_t packetDestination) {
|
||||||
AcceptsHkPacketsIF* hkReceiverObject =
|
auto* hkReceiverObject = ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
|
||||||
if (hkReceiverObject == nullptr) {
|
if (hkReceiverObject == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
printWarningOrError(sif::LogLevel::WARNING, "subscribeForPeriodicPacket",
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
@ -524,8 +521,7 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
|||||||
case (HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
|
case (HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
printWarningOrError(sif::LogLevel::WARNING, "handleHousekeepingMessage", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if (command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT and
|
if (command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT and
|
||||||
@ -577,10 +573,6 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
|||||||
|
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if (result == WRONG_HK_PACKET_TYPE) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
|
||||||
WRONG_HK_PACKET_TYPE);
|
|
||||||
}
|
|
||||||
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
||||||
} else {
|
} else {
|
||||||
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||||
@ -592,8 +584,7 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
|||||||
ReturnValue_t LocalDataPoolManager::printPoolEntry(lp_id_t localPoolId) {
|
ReturnValue_t LocalDataPoolManager::printPoolEntry(lp_id_t localPoolId) {
|
||||||
auto poolIter = localPoolMap.find(localPoolId);
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
if (poolIter == localPoolMap.end()) {
|
if (poolIter == localPoolMap.end()) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "printPoolEntry",
|
printWarningOrError(sif::LogLevel::WARNING, "printPoolEntry", localpool::POOL_ENTRY_NOT_FOUND);
|
||||||
localpool::POOL_ENTRY_NOT_FOUND);
|
|
||||||
return localpool::POOL_ENTRY_NOT_FOUND;
|
return localpool::POOL_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
poolIter->second->print();
|
poolIter->second->print();
|
||||||
@ -610,8 +601,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
MessageQueueId_t destination) {
|
MessageQueueId_t destination) {
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
/* Configuration error. */
|
/* Configuration error. */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
printWarningOrError(sif::LogLevel::WARNING, "generateHousekeepingPacket", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,14 +624,14 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
|
|
||||||
if (hkQueue == nullptr) {
|
if (hkQueue == nullptr) {
|
||||||
/* Error, no queue available to send packet with. */
|
/* Error, no queue available to send packet with. */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
printWarningOrError(sif::LogLevel::WARNING, "generateHousekeepingPacket",
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
if (destination == MessageQueueIF::NO_QUEUE) {
|
if (destination == MessageQueueIF::NO_QUEUE) {
|
||||||
if (hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
if (hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
||||||
/* Error, all destinations invalid */
|
/* Error, all destinations invalid */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
printWarningOrError(sif::LogLevel::WARNING, "generateHousekeepingPacket",
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
}
|
}
|
||||||
destination = hkDestinationId;
|
destination = hkDestinationId;
|
||||||
@ -675,8 +665,7 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
|||||||
sid_t sid = receiver.dataId.sid;
|
sid_t sid = receiver.dataId.sid;
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration",
|
printWarningOrError(sif::LogLevel::WARNING, "performPeriodicHkGeneration", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,11 +688,7 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
|||||||
ReturnValue_t result = generateHousekeepingPacket(sid, dataSet, true);
|
ReturnValue_t result = generateHousekeepingPacket(sid, dataSet, true);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
/* Configuration error */
|
/* Configuration error */
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("performPeriodicHkOperation: HK generation failed\n");
|
||||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed." << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,8 +696,7 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool ena
|
|||||||
bool isDiagnostics) {
|
bool isDiagnostics) {
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
printWarningOrError(sif::LogLevel::WARNING, "togglePeriodicGeneration", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,8 +718,7 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float ne
|
|||||||
bool isDiagnostics) {
|
bool isDiagnostics) {
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval",
|
printWarningOrError(sif::LogLevel::WARNING, "changeCollectionInterval", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,8 +743,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
|||||||
/* Get and check dataset first. */
|
/* Get and check dataset first. */
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration",
|
printWarningOrError(sif::LogLevel::WARNING, "performPeriodicHkGeneration", DATASET_NOT_FOUND);
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +764,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
|||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, expectedSize, &storePtr);
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId, expectedSize, &storePtr);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "generateSetStructurePacket",
|
printWarningOrError(sif::LogLevel::ERROR, "generateSetStructurePacket",
|
||||||
HasReturnvaluesIF::RETURN_FAILED,
|
HasReturnvaluesIF::RETURN_FAILED,
|
||||||
"Could not get free element from IPC store.");
|
"Could not get free element from IPC store.");
|
||||||
return result;
|
return result;
|
||||||
@ -796,7 +778,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (expectedSize != size) {
|
if (expectedSize != size) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket",
|
printWarningOrError(sif::LogLevel::WARNING, "generateSetStructurePacket",
|
||||||
HasReturnvaluesIF::RETURN_FAILED,
|
HasReturnvaluesIF::RETURN_FAILED,
|
||||||
"Expected size is not equal to serialized size");
|
"Expected size is not equal to serialized size");
|
||||||
}
|
}
|
||||||
@ -829,19 +811,16 @@ MutexIF* LocalDataPoolManager::getLocalPoolMutex() { return this->mutex; }
|
|||||||
|
|
||||||
object_id_t LocalDataPoolManager::getCreatorObjectId() const { return owner->getObjectId(); }
|
object_id_t LocalDataPoolManager::getCreatorObjectId() const { return owner->getObjectId(); }
|
||||||
|
|
||||||
void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
void LocalDataPoolManager::printWarningOrError(sif::LogLevel outputType, const char* functionName,
|
||||||
const char* functionName, ReturnValue_t error,
|
ReturnValue_t error, const char* errorPrint) {
|
||||||
const char* errorPrint) {
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
if (errorPrint == nullptr) {
|
if (errorPrint == nullptr) {
|
||||||
if (error == DATASET_NOT_FOUND) {
|
if (error == DATASET_NOT_FOUND) {
|
||||||
errorPrint = "Dataset not found";
|
errorPrint = "Dataset not found";
|
||||||
} else if (error == POOLOBJECT_NOT_FOUND) {
|
} else if (error == POOLOBJECT_NOT_FOUND) {
|
||||||
errorPrint = "Pool Object not found";
|
errorPrint = "Pool Object not found";
|
||||||
} else if (error == WRONG_HK_PACKET_TYPE) {
|
|
||||||
errorPrint = "Wrong Packet Type";
|
|
||||||
} else if (error == HasReturnvaluesIF::RETURN_FAILED) {
|
} else if (error == HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
if (outputType == sif::LogLevel::WARNING) {
|
||||||
errorPrint = "Generic Warning";
|
errorPrint = "Generic Warning";
|
||||||
} else {
|
} else {
|
||||||
errorPrint = "Generic error";
|
errorPrint = "Generic error";
|
||||||
@ -861,24 +840,10 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
|||||||
objectId = owner->getObjectId();
|
objectId = owner->getObjectId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
if (outputType == sif::LogLevel::WARNING) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{} | Object ID {} | {}\n", functionName, objectId, errorPrint);
|
||||||
sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8)
|
} else if (outputType == sif::LogLevel::ERROR) {
|
||||||
<< std::setfill('0') << std::hex << objectId << " | " << errorPrint << std::dec
|
FSFW_LOGET("{} | Object ID {} | {}\n", functionName, objectId, errorPrint);
|
||||||
<< std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, objectId,
|
|
||||||
errorPrint);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
} else if (outputType == sif::OutputTypes::OUT_ERROR) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8)
|
|
||||||
<< std::setfill('0') << std::hex << objectId << " | " << errorPrint << std::dec
|
|
||||||
<< std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, objectId,
|
|
||||||
errorPrint);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
}
|
}
|
||||||
#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
void setStaticFrameworkObjectIds();
|
void setStaticFrameworkObjectIds();
|
||||||
@ -375,7 +375,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
ReturnValue_t handleNotificationSnapshot(HkReceiver& hkReceiver, ReturnValue_t& status);
|
ReturnValue_t handleNotificationSnapshot(HkReceiver& hkReceiver, ReturnValue_t& status);
|
||||||
ReturnValue_t addUpdateToStore(HousekeepingSnapshot& updatePacket, store_address_t& storeId);
|
ReturnValue_t addUpdateToStore(HousekeepingSnapshot& updatePacket, store_address_t& storeId);
|
||||||
|
|
||||||
void printWarningOrError(sif::OutputTypes outputType, const char* functionName,
|
void printWarningOrError(sif::LogLevel outputType, const char* functionName,
|
||||||
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
||||||
const char* errorPrint = nullptr);
|
const char* errorPrint = nullptr);
|
||||||
};
|
};
|
||||||
@ -389,14 +389,13 @@ inline ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
|||||||
|
|
||||||
auto poolIter = localPoolMap.find(localPoolId);
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
if (poolIter == localPoolMap.end()) {
|
if (poolIter == localPoolMap.end()) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "fetchPoolEntry",
|
printWarningOrError(sif::LogLevel::WARNING, "fetchPoolEntry", localpool::POOL_ENTRY_NOT_FOUND);
|
||||||
localpool::POOL_ENTRY_NOT_FOUND);
|
|
||||||
return localpool::POOL_ENTRY_NOT_FOUND;
|
return localpool::POOL_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
*poolEntry = dynamic_cast<PoolEntry<T>*>(poolIter->second);
|
*poolEntry = dynamic_cast<PoolEntry<T>*>(poolIter->second);
|
||||||
if (*poolEntry == nullptr) {
|
if (*poolEntry == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "fetchPoolEntry",
|
printWarningOrError(sif::LogLevel::WARNING, "fetchPoolEntry",
|
||||||
localpool::POOL_ENTRY_TYPE_CONFLICT);
|
localpool::POOL_ENTRY_TYPE_CONFLICT);
|
||||||
return localpool::POOL_ENTRY_TYPE_CONFLICT;
|
return localpool::POOL_ENTRY_TYPE_CONFLICT;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "internal/HasLocalDpIFUserAttorney.h"
|
#include "internal/HasLocalDpIFUserAttorney.h"
|
||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId,
|
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId,
|
||||||
@ -16,14 +16,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t
|
|||||||
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner invalid\n");
|
||||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
|
||||||
<< "invalid!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError(
|
|
||||||
"LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
|
||||||
"invalid!\n\r");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AccessPoolManagerIF *accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
AccessPoolManagerIF *accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
||||||
@ -186,14 +179,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t **buffer, size
|
|||||||
auto result =
|
auto result =
|
||||||
SerializeAdapter::serialize(¤tPoolId, buffer, size, maxSize, streamEndianness);
|
SerializeAdapter::serialize(¤tPoolId, buffer, size, maxSize, streamEndianness);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "serializeLocalPoolIds: Serialization error\n");
|
||||||
sif::warning << "LocalPoolDataSetBase::serializeLocalPoolIds: "
|
|
||||||
<< "Serialization error!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"LocalPoolDataSetBase::serializeLocalPoolIds: "
|
|
||||||
"Serialization error!\n\r");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
object_id_t getCreatorObjectId();
|
object_id_t getCreatorObjectId();
|
||||||
|
|
||||||
bool getReportingEnabled() const;
|
bool getReportingEnabled() const;
|
||||||
void setReportingEnabled(bool enabled);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current periodic HK generation interval this set
|
* Returns the current periodic HK generation interval this set
|
||||||
@ -190,6 +189,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* Used for periodic generation.
|
* Used for periodic generation.
|
||||||
*/
|
*/
|
||||||
bool reportingEnabled = false;
|
bool reportingEnabled = false;
|
||||||
|
void setReportingEnabled(bool enabled);
|
||||||
|
|
||||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||||
uint8_t nonDiagIntervalFactor = 5);
|
uint8_t nonDiagIntervalFactor = 5);
|
||||||
|
@ -4,22 +4,17 @@
|
|||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "internal/HasLocalDpIFUserAttorney.h"
|
#include "internal/HasLocalDpIFUserAttorney.h"
|
||||||
|
|
||||||
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
||||||
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
|
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
|
||||||
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{}", "ctor: Invalid pool ID, has NO_PARAMETER value\n");
|
||||||
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
|
||||||
<< "which is the NO_PARAMETER value!" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGET("{}", "ctor: Supplied pool owner is a invalid\n");
|
||||||
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
|
||||||
<< "owner is a invalid!" << std::endl;
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AccessPoolManagerIF* poolManAccessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
AccessPoolManagerIF* poolManAccessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
||||||
@ -34,28 +29,14 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
|||||||
pool_rwm_t setReadWriteMode)
|
pool_rwm_t setReadWriteMode)
|
||||||
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{}", "ctor: Invalid pool ID, has NO_PARAMETER value\n");
|
||||||
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
|
||||||
"which is the NO_PARAMETER value!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
|
||||||
"which is the NO_PARAMETER value!\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
|
auto* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
|
||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT(
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
|
"ctor: The supplied pool owner {:#010x} did not implement the correct interface "
|
||||||
<< std::dec << " did not implement the correct interface "
|
"HasLocalDataPoolIF\n",
|
||||||
<< "HasLocalDataPoolIF" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError(
|
|
||||||
"LocalPoolVariable: The supplied pool owner 0x%08x did not implement the correct "
|
|
||||||
"interface HasLocalDataPoolIF\n",
|
|
||||||
poolOwner);
|
poolOwner);
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +70,6 @@ void LocalPoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
|
|||||||
|
|
||||||
void LocalPoolObjectBase::reportReadCommitError(const char* variableType, ReturnValue_t error,
|
void LocalPoolObjectBase::reportReadCommitError(const char* variableType, ReturnValue_t error,
|
||||||
bool read, object_id_t objectId, lp_id_t lpId) {
|
bool read, object_id_t objectId, lp_id_t lpId) {
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
|
||||||
const char* variablePrintout = variableType;
|
const char* variablePrintout = variableType;
|
||||||
if (variablePrintout == nullptr) {
|
if (variablePrintout == nullptr) {
|
||||||
variablePrintout = "Unknown Type";
|
variablePrintout = "Unknown Type";
|
||||||
@ -114,13 +94,6 @@ void LocalPoolObjectBase::reportReadCommitError(const char* variableType, Return
|
|||||||
errMsg = "Unknown error code";
|
errMsg = "Unknown error code";
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}: {} call | {} | Owner: {:#010x} | LPID: \n", variablePrintout, type, errMsg,
|
||||||
sif::warning << variablePrintout << ": " << type << " call | " << errMsg << " | Owner: 0x"
|
objectId, lpId);
|
||||||
<< std::hex << std::setw(8) << std::setfill('0') << objectId << std::dec
|
|
||||||
<< " LPID: " << lpId << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("%s: %s call | %s | Owner: 0x%08x LPID: %lu\n", variablePrintout, type, errMsg,
|
|
||||||
objectId, lpId);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "AccessLocalPoolF.h"
|
#include "AccessLocalPoolF.h"
|
||||||
#include "HasLocalDataPoolIF.h"
|
#include "HasLocalDataPoolIF.h"
|
||||||
#include "LocalDataPoolManager.h"
|
#include "LocalDataPoolManager.h"
|
||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "internal/LocalDpManagerAttorney.h"
|
#include "internal/LocalDpManagerAttorney.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "../datapoollocal/LocalDataPoolManager.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "internal/LocalDpManagerAttorney.h"
|
#include "internal/LocalDpManagerAttorney.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,172 +5,162 @@
|
|||||||
#error Include LocalPoolVector.h before LocalPoolVector.tpp!
|
#error Include LocalPoolVector.h before LocalPoolVector.tpp!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
|
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(
|
||||||
DataSetIF* dataSet,
|
HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet,
|
||||||
pool_rwm_t setReadWriteMode)
|
pool_rwm_t setReadWriteMode):
|
||||||
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(object_id_t poolOwner, lp_id_t poolId,
|
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(object_id_t poolOwner,
|
||||||
DataSetIF* dataSet,
|
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||||
pool_rwm_t setReadWriteMode)
|
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
||||||
: LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId, DataSetIF* dataSet,
|
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId,
|
||||||
pool_rwm_t setReadWriteMode)
|
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||||
: LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet,
|
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
|
||||||
setReadWriteMode) {}
|
dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(MutexIF::TimeoutType timeoutType,
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(
|
||||||
uint32_t timeoutMs) {
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
||||||
return readWithoutLock();
|
return readWithoutLock();
|
||||||
}
|
}
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
||||||
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
|
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true,
|
reportReadCommitError("LocalPoolVector",
|
||||||
targetObjectId, localPoolId);
|
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
localPoolId);
|
||||||
}
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
ReturnValue_t result =
|
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
|
||||||
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
|
&poolEntry);
|
||||||
memset(this->value, 0, vectorSize * sizeof(T));
|
memset(this->value, 0, vectorSize * sizeof(T));
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if(result != RETURN_OK) {
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
reportReadCommitError("LocalPoolVector", result, true, targetObjectId, localPoolId);
|
reportReadCommitError("LocalPoolVector", result, true, targetObjectId,
|
||||||
return result;
|
localPoolId);
|
||||||
}
|
return result;
|
||||||
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
|
}
|
||||||
this->valid = poolEntry->getValid();
|
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
|
||||||
return RETURN_OK;
|
this->valid = poolEntry->getValid();
|
||||||
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(bool valid,
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(bool valid,
|
||||||
MutexIF::TimeoutType timeoutType,
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
uint32_t timeoutMs) {
|
this->setValid(valid);
|
||||||
this->setValid(valid);
|
return commit(timeoutType, timeoutMs);
|
||||||
return commit(timeoutType, timeoutMs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(MutexIF::TimeoutType timeoutType,
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
|
||||||
uint32_t timeoutMs) {
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
||||||
return commitWithoutLock();
|
return commitWithoutLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
||||||
if (readWriteMode == pool_rwm_t::VAR_READ) {
|
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false,
|
reportReadCommitError("LocalPoolVector",
|
||||||
targetObjectId, localPoolId);
|
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
localPoolId);
|
||||||
}
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
}
|
||||||
ReturnValue_t result =
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
|
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
|
||||||
if (result != RETURN_OK) {
|
&poolEntry);
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
if(result != RETURN_OK) {
|
||||||
reportReadCommitError("LocalPoolVector", result, false, targetObjectId, localPoolId);
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
|
reportReadCommitError("LocalPoolVector", result, false, targetObjectId,
|
||||||
|
localPoolId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
|
||||||
|
poolEntry->setValid(this->valid);
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, uint16_t vectorSize>
|
||||||
|
inline T& LocalPoolVector<T, vectorSize>::operator [](size_t i) {
|
||||||
|
if(i < vectorSize) {
|
||||||
|
return value[i];
|
||||||
|
}
|
||||||
|
// If this happens, I have to set some value. I consider this
|
||||||
|
// a configuration error, but I wont exit here.
|
||||||
|
FSFW_LOGW("LocalPoolVector: Invalid index. Setting or returning last value\n");
|
||||||
|
return value[vectorSize - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, uint16_t vectorSize>
|
||||||
|
inline const T& LocalPoolVector<T, vectorSize>::operator [](size_t i) const {
|
||||||
|
if(i < vectorSize) {
|
||||||
|
return value[i];
|
||||||
|
}
|
||||||
|
// If this happens, I have to set some value. I consider this
|
||||||
|
// a configuration error, but I wont exit here.
|
||||||
|
FSFW_LOGW("LocalPoolVector: Invalid index. Setting or returning last value\n");
|
||||||
|
return value[vectorSize - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, uint16_t vectorSize>
|
||||||
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::serialize(uint8_t** buffer,
|
||||||
|
size_t* size, size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
for (uint16_t i = 0; i < vectorSize; i++) {
|
||||||
|
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
|
||||||
|
maxSize, streamEndianness);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
|
|
||||||
poolEntry->setValid(this->valid);
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline T& LocalPoolVector<T, vectorSize>::operator[](size_t i) {
|
|
||||||
if (i < vectorSize) {
|
|
||||||
return value[i];
|
|
||||||
}
|
|
||||||
// If this happens, I have to set some value. I consider this
|
|
||||||
// a configuration error, but I wont exit here.
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!\n");
|
|
||||||
#endif
|
|
||||||
return value[vectorSize - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline const T& LocalPoolVector<T, vectorSize>::operator[](size_t i) const {
|
|
||||||
if (i < vectorSize) {
|
|
||||||
return value[i];
|
|
||||||
}
|
|
||||||
// If this happens, I have to set some value. I consider this
|
|
||||||
// a configuration error, but I wont exit here.
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!\n");
|
|
||||||
#endif
|
|
||||||
return value[vectorSize - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::serialize(
|
|
||||||
uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
for (uint16_t i = 0; i < vectorSize; i++) {
|
|
||||||
result = SerializeAdapter::serialize(&(value[i]), buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline size_t LocalPoolVector<T, vectorSize>::getSerializedSize() const {
|
inline size_t LocalPoolVector<T, vectorSize>::getSerializedSize() const {
|
||||||
return vectorSize * SerializeAdapter::getSerializedSize(value);
|
return vectorSize * SerializeAdapter::getSerializedSize(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::deSerialize(
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::deSerialize(
|
||||||
const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) {
|
const uint8_t** buffer, size_t* size,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
SerializeIF::Endianness streamEndianness) {
|
||||||
for (uint16_t i = 0; i < vectorSize; i++) {
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||||
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, streamEndianness);
|
for (uint16_t i = 0; i < vectorSize; i++) {
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
|
||||||
break;
|
streamEndianness);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return result;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
template <typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline std::ostream& operator<<(std::ostream& out, const LocalPoolVector<T, vectorSize>& var) {
|
inline std::ostream& operator<< (std::ostream &out,
|
||||||
out << "Vector: [";
|
const LocalPoolVector<T, vectorSize> &var) {
|
||||||
for (int i = 0; i < vectorSize; i++) {
|
out << "Vector: [";
|
||||||
out << var.value[i];
|
for(int i = 0;i < vectorSize; i++) {
|
||||||
if (i < vectorSize - 1) {
|
out << var.value[i];
|
||||||
out << ", ";
|
if(i < vectorSize - 1) {
|
||||||
|
out << ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
out << "]";
|
||||||
out << "]";
|
return out;
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -26,7 +26,11 @@ void AssemblyBase::performChildOperation() {
|
|||||||
|
|
||||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
doStartTransition(mode, submode);
|
doStartTransition(mode, submode);
|
||||||
triggerModeHelperEvents(mode, submode);
|
if (modeHelper.isForced()) {
|
||||||
|
triggerEvent(FORCING_MODE, mode, submode);
|
||||||
|
} else {
|
||||||
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||||
@ -73,10 +77,9 @@ bool AssemblyBase::handleChildrenChangedHealth() {
|
|||||||
}
|
}
|
||||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||||
triggerEvent(TRYING_RECOVERY, iter->first, 0);
|
triggerEvent(TRYING_RECOVERY);
|
||||||
recoveryState = RECOVERY_STARTED;
|
recoveryState = RECOVERY_STARTED;
|
||||||
recoveringDevice = iter;
|
recoveringDevice = iter;
|
||||||
// The user needs to take care of commanding the children off in commandChildren
|
|
||||||
doStartTransition(targetMode, targetSubmode);
|
doStartTransition(targetMode, targetSubmode);
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||||
@ -225,9 +228,6 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
|||||||
bool AssemblyBase::checkAndHandleRecovery() {
|
bool AssemblyBase::checkAndHandleRecovery() {
|
||||||
switch (recoveryState) {
|
switch (recoveryState) {
|
||||||
case RECOVERY_STARTED:
|
case RECOVERY_STARTED:
|
||||||
// The recovery was already start in #handleChildrenChangedHealth and we just need
|
|
||||||
// to wait for an off time period.
|
|
||||||
// TODO: make time period configurable
|
|
||||||
recoveryState = RECOVERY_WAIT;
|
recoveryState = RECOVERY_WAIT;
|
||||||
recoveryOffTimer.resetTimer();
|
recoveryOffTimer.resetTimer();
|
||||||
return true;
|
return true;
|
||||||
@ -266,11 +266,3 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
|
|||||||
modeHelper.setForced(true);
|
modeHelper.setForced(true);
|
||||||
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyBase::triggerModeHelperEvents(Mode_t mode, Submode_t submode) {
|
|
||||||
if (modeHelper.isForced()) {
|
|
||||||
triggerEvent(FORCING_MODE, mode, submode);
|
|
||||||
} else {
|
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
* Documentation: Dissertation Baetz p.156, 157.
|
* Documentation: Dissertation Baetz p.156, 157.
|
||||||
*
|
*
|
||||||
* This class reduces the complexity of controller components which would
|
* This class reduces the complexity of controller components which would
|
||||||
* otherwise be needed for the handling of redundant devices. However, it can also be used to
|
* otherwise be needed for the handling of redundant devices.
|
||||||
* manage the mode keeping and recovery of non-redundant devices
|
|
||||||
*
|
*
|
||||||
* The template class monitors mode and health state of its children
|
* The template class monitors mode and health state of its children
|
||||||
* and checks availability of devices on every detected change.
|
* and checks availability of devices on every detected change.
|
||||||
@ -27,9 +26,11 @@
|
|||||||
*
|
*
|
||||||
* Important:
|
* Important:
|
||||||
*
|
*
|
||||||
* The implementation must call #registerChild for all commanded children during initialization.
|
* The implementation must call registerChild(object_id_t child)
|
||||||
|
* for all commanded children during initialization.
|
||||||
* The implementation must call the initialization function of the base class.
|
* The implementation must call the initialization function of the base class.
|
||||||
* (This will call the function in SubsystemBase)
|
* (This will call the function in SubsystemBase)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class AssemblyBase : public SubsystemBase {
|
class AssemblyBase : public SubsystemBase {
|
||||||
public:
|
public:
|
||||||
@ -46,14 +47,13 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Command children to reach [mode,submode] combination. Can be done by setting
|
* Command children to reach [mode,submode] combination
|
||||||
* #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
|
* Can be done by setting #commandsOutstanding correctly,
|
||||||
* the user needs to ensure that the target devices are healthy. If a device is not healthy,
|
* or using executeTable()
|
||||||
* a recovery might be on-going and the device needs to be commanded to off first.
|
|
||||||
* @param mode
|
* @param mode
|
||||||
* @param submode
|
* @param submode
|
||||||
* @return
|
* @return
|
||||||
* - @c RETURN_OK if OK
|
* - @c RETURN_OK if ok
|
||||||
* - @c NEED_SECOND_STEP if children need to be commanded again
|
* - @c NEED_SECOND_STEP if children need to be commanded again
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
|
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
|
||||||
@ -120,19 +120,8 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
||||||
|
|
||||||
/**
|
virtual void performChildOperation();
|
||||||
* @brief Default periodic handler
|
|
||||||
* @details
|
|
||||||
* This is the default periodic handler which will be called by the SubsystemBase
|
|
||||||
* performOperation. It performs the child transitions or reacts to changed health/mode states
|
|
||||||
* of children objects
|
|
||||||
*/
|
|
||||||
virtual void performChildOperation() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function handles changed mode or health states of children
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool handleChildrenChanged();
|
bool handleChildrenChanged();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,37 +134,12 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
bool handleChildrenChangedHealth();
|
bool handleChildrenChangedHealth();
|
||||||
|
|
||||||
/**
|
|
||||||
* Core transition handler. The default implementation will only do something if
|
|
||||||
* #commandsOutstanding is smaller or equal to zero, which means that all mode commands
|
|
||||||
* from the #doPerformTransition call were executed successfully.
|
|
||||||
*
|
|
||||||
* Unless a second step was requested, the function will then use #checkChildrenState to
|
|
||||||
* determine whether the target mode was reached.
|
|
||||||
*
|
|
||||||
* There is some special handling for certain (internal) modes:
|
|
||||||
* - A second step is necessary. #commandChildren will be performed again
|
|
||||||
* - The device health was overwritten. #commandChildren will be called
|
|
||||||
* - A recovery is ongoing. #checkAndHandleRecovery will be called.
|
|
||||||
*/
|
|
||||||
virtual void handleChildrenTransition();
|
virtual void handleChildrenTransition();
|
||||||
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls #doStartTransition and triggers an informative event as well that the mode will
|
|
||||||
* change
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
*/
|
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||||
|
|
||||||
/**
|
|
||||||
* This function starts the transition by setting the internal #targetSubmode and #targetMode
|
|
||||||
* variables and then calling the #commandChildren function.
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
*/
|
|
||||||
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
||||||
|
|
||||||
virtual bool isInTransition();
|
virtual bool isInTransition();
|
||||||
@ -196,7 +160,7 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
* Manages recovery of a device
|
* Manages recovery of a device
|
||||||
* @return true if recovery is still ongoing, false else.
|
* @return true if recovery is still ongoing, false else.
|
||||||
*/
|
*/
|
||||||
virtual bool checkAndHandleRecovery();
|
bool checkAndHandleRecovery();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to overwrite health state of one of the children.
|
* Helper method to overwrite health state of one of the children.
|
||||||
@ -204,8 +168,6 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
* @param objectId Must be a registered child.
|
* @param objectId Must be a registered child.
|
||||||
*/
|
*/
|
||||||
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
||||||
|
|
||||||
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/subsystem/SubsystemBase.h"
|
#include "fsfw/subsystem/SubsystemBase.h"
|
||||||
#include "fsfw/thermal/ThermalComponentIF.h"
|
#include "fsfw/thermal/ThermalComponentIF.h"
|
||||||
@ -39,20 +39,22 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
childTransitionDelay(5000),
|
childTransitionDelay(5000),
|
||||||
transitionSourceMode(_MODE_POWER_DOWN),
|
transitionSourceMode(_MODE_POWER_DOWN),
|
||||||
transitionSourceSubMode(SUBMODE_NONE) {
|
transitionSourceSubMode(SUBMODE_NONE) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
insertInCommandMap(RAW_COMMAND_ID);
|
insertInCommandMap(RAW_COMMAND_ID);
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||||
if (comCookie == nullptr) {
|
if (comCookie == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
|
printWarningOrError(sif::LogLevel::ERROR, "DeviceHandlerBase", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
|
"Invalid cookie");
|
||||||
|
}
|
||||||
|
if (this->fdirInstance == nullptr) {
|
||||||
|
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination_) {
|
||||||
this->hkDestination = hkDestination;
|
this->hkDestination = hkDestination_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId,
|
void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId,
|
||||||
@ -63,7 +65,9 @@ void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||||
delete comCookie;
|
if (comCookie != nullptr) {
|
||||||
|
delete comCookie;
|
||||||
|
}
|
||||||
if (defaultFDIRUsed) {
|
if (defaultFDIRUsed) {
|
||||||
delete fdirInstance;
|
delete fdirInstance;
|
||||||
}
|
}
|
||||||
@ -124,58 +128,38 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (this->fdirInstance == nullptr) {
|
|
||||||
this->fdirInstance =
|
|
||||||
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->parent != objects::NO_OBJECT) {
|
|
||||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
|
||||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
|
||||||
if (modeIF != nullptr and healthIF != nullptr) {
|
|
||||||
setParentQueue(modeIF->getCommandQueue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
communicationInterface =
|
communicationInterface =
|
||||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||||
if (communicationInterface == nullptr) {
|
if (communicationInterface == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED, "Passed communication IF invalid");
|
"Passed communication IF invalid");
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = communicationInterface->initializeInterface(comCookie);
|
result = communicationInterface->initializeInterface(comCookie);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED, "ComIF initialization failed");
|
"ComIF initialization failed");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if (IPCStore == nullptr) {
|
if (IPCStore == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED, "IPC Store not set up");
|
"IPC Store not set up");
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawDataReceiverId != objects::NO_OBJECT) {
|
if (rawDataReceiverId != objects::NO_OBJECT) {
|
||||||
AcceptsDeviceResponsesIF* rawReceiver =
|
auto* rawReceiver = ObjectManager::instance()->get<AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
||||||
ObjectManager::instance()->get<AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
|
||||||
|
|
||||||
if (rawReceiver == nullptr) {
|
if (rawReceiver == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED,
|
|
||||||
"Raw receiver object ID set but no valid object found.");
|
"Raw receiver object ID set but no valid object found.");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}",
|
||||||
sif::error << "Make sure the raw receiver object is set up properly"
|
"Make sure the raw receiver object is set up properly "
|
||||||
" and implements AcceptsDeviceResponsesIF"
|
"and implements AcceptsDeviceResponsesIF");
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError(
|
|
||||||
"Make sure the raw receiver object is set up "
|
|
||||||
"properly and implements AcceptsDeviceResponsesIF\n");
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
||||||
@ -184,17 +168,11 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
if (powerSwitcherId != objects::NO_OBJECT) {
|
if (powerSwitcherId != objects::NO_OBJECT) {
|
||||||
powerSwitcher = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitcherId);
|
powerSwitcher = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitcherId);
|
||||||
if (powerSwitcher == nullptr) {
|
if (powerSwitcher == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
printWarningOrError(sif::LogLevel::ERROR, "initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED,
|
|
||||||
"Power switcher set but no valid object found.");
|
"Power switcher set but no valid object found.");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}",
|
||||||
sif::error << "Make sure the power switcher object is set up "
|
"Make sure the power switcher object is set up "
|
||||||
<< "properly and implements PowerSwitchIF" << std::endl;
|
"properly and implements PowerSwitchIF\n");
|
||||||
#else
|
|
||||||
sif::printError(
|
|
||||||
"Make sure the power switcher object is set up "
|
|
||||||
"properly and implements PowerSwitchIF\n");
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,15 +225,14 @@ void DeviceHandlerBase::decrementDeviceReplyMap() {
|
|||||||
for (std::pair<const DeviceCommandId_t, DeviceReplyInfo>& replyPair : deviceReplyMap) {
|
for (std::pair<const DeviceCommandId_t, DeviceReplyInfo>& replyPair : deviceReplyMap) {
|
||||||
if (replyPair.second.countdown != nullptr && replyPair.second.active) {
|
if (replyPair.second.countdown != nullptr && replyPair.second.active) {
|
||||||
if (replyPair.second.countdown->hasTimedOut()) {
|
if (replyPair.second.countdown->hasTimedOut()) {
|
||||||
|
resetTimeoutControlledReply(&replyPair.second);
|
||||||
timedOut = true;
|
timedOut = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (replyPair.second.delayCycles != 0 && replyPair.second.countdown == nullptr) {
|
if (replyPair.second.delayCycles != 0 && replyPair.second.countdown == nullptr) {
|
||||||
replyPair.second.delayCycles--;
|
replyPair.second.delayCycles--;
|
||||||
if (replyPair.second.delayCycles == 0) {
|
if (replyPair.second.delayCycles == 0) {
|
||||||
if (replyPair.second.periodic) {
|
resetDelayCyclesControlledReply(&replyPair.second);
|
||||||
replyPair.second.delayCycles = replyPair.second.maxDelayCycles;
|
|
||||||
}
|
|
||||||
timedOut = true;
|
timedOut = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +240,6 @@ void DeviceHandlerBase::decrementDeviceReplyMap() {
|
|||||||
replyToReply(replyPair.first, replyPair.second, TIMEOUT);
|
replyToReply(replyPair.first, replyPair.second, TIMEOUT);
|
||||||
missedReply(replyPair.first);
|
missedReply(replyPair.first);
|
||||||
timedOut = false;
|
timedOut = false;
|
||||||
replyPair.second.active = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,8 +314,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
sprintf(printout, "Transition timeout (%lu) occured !",
|
sprintf(printout, "Transition timeout (%lu) occured !",
|
||||||
static_cast<unsigned long>(childTransitionDelay));
|
static_cast<unsigned long>(childTransitionDelay));
|
||||||
/* Common configuration error for development, so print it */
|
/* Common configuration error for development, so print it */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "doStateMachine", RETURN_FAILED,
|
printWarningOrError(sif::LogLevel::WARNING, "doStateMachine", RETURN_FAILED, printout);
|
||||||
printout);
|
|
||||||
#endif
|
#endif
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, childTransitionFailure, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, childTransitionFailure, 0);
|
||||||
setMode(transitionSourceMode, transitionSourceSubMode);
|
setMode(transitionSourceMode, transitionSourceSubMode);
|
||||||
@ -373,12 +348,13 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case _MODE_WAIT_OFF: {
|
case _MODE_WAIT_OFF: {
|
||||||
|
uint32_t currentUptime;
|
||||||
|
Clock::getUptime(¤tUptime);
|
||||||
|
|
||||||
if (powerSwitcher == nullptr) {
|
if (powerSwitcher == nullptr) {
|
||||||
setMode(MODE_OFF);
|
setMode(MODE_OFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint32_t currentUptime;
|
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||||
setMode(MODE_ERROR_ON);
|
setMode(MODE_ERROR_ON);
|
||||||
@ -451,9 +427,6 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
|||||||
info.dataSet = dataSet;
|
info.dataSet = dataSet;
|
||||||
info.command = deviceCommandMap.end();
|
info.command = deviceCommandMap.end();
|
||||||
info.countdown = countdown;
|
info.countdown = countdown;
|
||||||
if (info.periodic) {
|
|
||||||
info.active = true;
|
|
||||||
}
|
|
||||||
auto resultPair = deviceReplyMap.emplace(replyId, info);
|
auto resultPair = deviceReplyMap.emplace(replyId, info);
|
||||||
if (resultPair.second) {
|
if (resultPair.second) {
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
@ -526,9 +499,19 @@ ReturnValue_t DeviceHandlerBase::updatePeriodicReply(bool enable, DeviceCommandI
|
|||||||
return COMMAND_NOT_SUPPORTED;
|
return COMMAND_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
if (enable) {
|
if (enable) {
|
||||||
info->delayCycles = info->maxDelayCycles;
|
info->active = true;
|
||||||
|
if (info->countdown != nullptr) {
|
||||||
|
info->delayCycles = info->maxDelayCycles;
|
||||||
|
} else {
|
||||||
|
info->countdown->resetTimer();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
info->delayCycles = 0;
|
info->active = false;
|
||||||
|
if (info->countdown != nullptr) {
|
||||||
|
info->delayCycles = 0;
|
||||||
|
} else {
|
||||||
|
info->countdown->timeOut();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -572,9 +555,6 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
|||||||
mode = newMode;
|
mode = newMode;
|
||||||
modeChanged();
|
modeChanged();
|
||||||
setNormalDatapoolEntriesInvalid();
|
setNormalDatapoolEntriesInvalid();
|
||||||
if (newMode == MODE_OFF) {
|
|
||||||
disableCommandsAndReplies();
|
|
||||||
}
|
|
||||||
if (!isTransitionalMode()) {
|
if (!isTransitionalMode()) {
|
||||||
modeHelper.modeChanged(newMode, newSubmode);
|
modeHelper.modeChanged(newMode, newSubmode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
@ -639,8 +619,8 @@ void DeviceHandlerBase::replyToReply(const DeviceCommandId_t command, DeviceRepl
|
|||||||
}
|
}
|
||||||
DeviceCommandInfo* info = &replyInfo.command->second;
|
DeviceCommandInfo* info = &replyInfo.command->second;
|
||||||
if (info == nullptr) {
|
if (info == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "replyToReply",
|
printWarningOrError(sif::LogLevel::ERROR, "replyToReply", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "Command pointer not found");
|
"Command pointer not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +761,7 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData, size_t receivedD
|
|||||||
case RETURN_OK:
|
case RETURN_OK:
|
||||||
handleReply(receivedData, foundId, foundLen);
|
handleReply(receivedData, foundId, foundLen);
|
||||||
if (foundLen == 0) {
|
if (foundLen == 0) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "parseReply",
|
printWarningOrError(sif::LogLevel::WARNING, "parseReply",
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED,
|
ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
"Found length is one, parsing might be stuck");
|
"Found length is one, parsing might be stuck");
|
||||||
}
|
}
|
||||||
@ -793,14 +773,12 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData, size_t receivedD
|
|||||||
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId);
|
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId);
|
||||||
}
|
}
|
||||||
if (foundLen == 0) {
|
if (foundLen == 0) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "parseReply",
|
printWarningOrError(sif::LogLevel::ERROR, "parseReply",
|
||||||
ObjectManagerIF::CHILD_INIT_FAILED,
|
ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
"Power switcher set but no valid object found.");
|
"Power switcher set but no valid object found.");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}",
|
||||||
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
|
"DeviceHandlerBase::parseReply: foundLen is 0! "
|
||||||
" Packet parsing will be stuck."
|
"Packet parsing will be stuck\n");
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -846,9 +824,9 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (info->active && info->countdown != nullptr) {
|
if (info->active && info->countdown != nullptr) {
|
||||||
disableTimeoutControlledReply(info);
|
resetTimeoutControlledReply(info);
|
||||||
} else if (info->delayCycles != 0) {
|
} else if (info->delayCycles != 0) {
|
||||||
disableDelayCyclesControlledReply(info);
|
resetDelayCyclesControlledReply(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
@ -867,7 +845,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::disableTimeoutControlledReply(DeviceReplyInfo* info) {
|
void DeviceHandlerBase::resetTimeoutControlledReply(DeviceReplyInfo* info) {
|
||||||
if (info->periodic) {
|
if (info->periodic) {
|
||||||
info->countdown->resetTimer();
|
info->countdown->resetTimer();
|
||||||
} else {
|
} else {
|
||||||
@ -876,7 +854,7 @@ void DeviceHandlerBase::disableTimeoutControlledReply(DeviceReplyInfo* info) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::disableDelayCyclesControlledReply(DeviceReplyInfo* info) {
|
void DeviceHandlerBase::resetDelayCyclesControlledReply(DeviceReplyInfo* info) {
|
||||||
if (info->periodic) {
|
if (info->periodic) {
|
||||||
info->delayCycles = info->maxDelayCycles;
|
info->delayCycles = info->maxDelayCycles;
|
||||||
} else {
|
} else {
|
||||||
@ -1007,6 +985,8 @@ ReturnValue_t DeviceHandlerBase::enableReplyInReplyMap(DeviceCommandMap::iterato
|
|||||||
}
|
}
|
||||||
if (iter != deviceReplyMap.end()) {
|
if (iter != deviceReplyMap.end()) {
|
||||||
DeviceReplyInfo* info = &(iter->second);
|
DeviceReplyInfo* info = &(iter->second);
|
||||||
|
// If a countdown has been set, the delay cycles will be ignored and the reply times out
|
||||||
|
// as soon as the countdown has expired
|
||||||
info->delayCycles = info->maxDelayCycles;
|
info->delayCycles = info->maxDelayCycles;
|
||||||
info->command = command;
|
info->command = command;
|
||||||
command->second.expectedReplies = expectedReplies;
|
command->second.expectedReplies = expectedReplies;
|
||||||
@ -1339,7 +1319,7 @@ ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, MessageQueue
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::buildInternalCommand(void) {
|
void DeviceHandlerBase::buildInternalCommand() {
|
||||||
/* Neither raw nor direct could build a command */
|
/* Neither raw nor direct could build a command */
|
||||||
ReturnValue_t result = NOTHING_TO_SEND;
|
ReturnValue_t result = NOTHING_TO_SEND;
|
||||||
DeviceCommandId_t deviceCommandId = NO_COMMAND_ID;
|
DeviceCommandId_t deviceCommandId = NO_COMMAND_ID;
|
||||||
@ -1347,7 +1327,7 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
result = buildNormalDeviceCommand(&deviceCommandId);
|
result = buildNormalDeviceCommand(&deviceCommandId);
|
||||||
if (result == BUSY) {
|
if (result == BUSY) {
|
||||||
/* So we can track misconfigurations */
|
/* So we can track misconfigurations */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "buildInternalCommand",
|
printWarningOrError(sif::LogLevel::WARNING, "buildInternalCommand",
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "Busy.");
|
HasReturnvaluesIF::RETURN_FAILED, "Busy.");
|
||||||
/* No need to report this */
|
/* No need to report this */
|
||||||
result = NOTHING_TO_SEND;
|
result = NOTHING_TO_SEND;
|
||||||
@ -1365,14 +1345,14 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(deviceCommandId);
|
auto iter = deviceCommandMap.find(deviceCommandId);
|
||||||
if (iter == deviceCommandMap.end()) {
|
if (iter == deviceCommandMap.end()) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
char output[36];
|
char output[36];
|
||||||
sprintf(output, "Command 0x%08x unknown", static_cast<unsigned int>(deviceCommandId));
|
sprintf(output, "Command 0x%08x unknown", static_cast<unsigned int>(deviceCommandId));
|
||||||
// so we can track misconfigurations
|
// so we can track misconfigurations
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "buildInternalCommand",
|
printWarningOrError(sif::LogLevel::WARNING, "buildInternalCommand", COMMAND_NOT_SUPPORTED,
|
||||||
COMMAND_NOT_SUPPORTED, output);
|
output);
|
||||||
#endif
|
#endif
|
||||||
result = COMMAND_NOT_SUPPORTED;
|
result = COMMAND_NOT_SUPPORTED;
|
||||||
} else if (iter->second.isExecuting) {
|
} else if (iter->second.isExecuting) {
|
||||||
@ -1380,7 +1360,7 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
char output[36];
|
char output[36];
|
||||||
sprintf(output, "Command 0x%08x is executing", static_cast<unsigned int>(deviceCommandId));
|
sprintf(output, "Command 0x%08x is executing", static_cast<unsigned int>(deviceCommandId));
|
||||||
// so we can track misconfigurations
|
// so we can track misconfigurations
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "buildInternalCommand",
|
printWarningOrError(sif::LogLevel::WARNING, "buildInternalCommand",
|
||||||
HasReturnvaluesIF::RETURN_FAILED, output);
|
HasReturnvaluesIF::RETURN_FAILED, output);
|
||||||
#endif
|
#endif
|
||||||
// this is an internal command, no need to report a failure here,
|
// this is an internal command, no need to report a failure here,
|
||||||
@ -1401,11 +1381,16 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
ReturnValue_t DeviceHandlerBase::buildChildRawCommand() { return NOTHING_TO_SEND; }
|
ReturnValue_t DeviceHandlerBase::buildChildRawCommand() { return NOTHING_TO_SEND; }
|
||||||
|
|
||||||
uint8_t DeviceHandlerBase::getReplyDelayCycles(DeviceCommandId_t deviceCommand) {
|
uint8_t DeviceHandlerBase::getReplyDelayCycles(DeviceCommandId_t deviceCommand) {
|
||||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(deviceCommand);
|
auto iter = deviceReplyMap.find(deviceCommand);
|
||||||
if (iter == deviceReplyMap.end()) {
|
if (iter == deviceReplyMap.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (iter->second.countdown != nullptr) {
|
} else if (iter->second.countdown != nullptr) {
|
||||||
return 0;
|
// fake a useful return value for legacy code
|
||||||
|
if (iter->second.active) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return iter->second.delayCycles;
|
return iter->second.delayCycles;
|
||||||
}
|
}
|
||||||
@ -1454,8 +1439,6 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
|
|||||||
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
||||||
uint32_t parameter) {}
|
uint32_t parameter) {}
|
||||||
|
|
||||||
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::performOperationHook() {}
|
void DeviceHandlerBase::performOperationHook() {}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
@ -1478,7 +1461,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
this->poolManager.initializeAfterTaskCreation();
|
this->poolManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
if (setStartupImmediately) {
|
if (setStartupImmediately) {
|
||||||
startTransition(MODE_ON, getInitialSubmode());
|
startTransition(MODE_ON, SUBMODE_NONE);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -1513,13 +1496,13 @@ void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const char* functionName,
|
void DeviceHandlerBase::printWarningOrError(sif::LogLevel errorType, const char* functionName,
|
||||||
ReturnValue_t errorCode, const char* errorPrint) {
|
ReturnValue_t errorCode, const char* errorPrint) {
|
||||||
if (errorPrint == nullptr) {
|
if (errorPrint == nullptr) {
|
||||||
if (errorCode == ObjectManagerIF::CHILD_INIT_FAILED) {
|
if (errorCode == ObjectManagerIF::CHILD_INIT_FAILED) {
|
||||||
errorPrint = "Initialization error";
|
errorPrint = "Initialization error";
|
||||||
} else if (errorCode == HasReturnvaluesIF::RETURN_FAILED) {
|
} else if (errorCode == HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
if (errorType == sif::OutputTypes::OUT_WARNING) {
|
if (errorType == sif::LogLevel::WARNING) {
|
||||||
errorPrint = "Generic Warning";
|
errorPrint = "Generic Warning";
|
||||||
} else {
|
} else {
|
||||||
errorPrint = "Generic Error";
|
errorPrint = "Generic Error";
|
||||||
@ -1532,24 +1515,12 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const ch
|
|||||||
functionName = "unknown function";
|
functionName = "unknown function";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorType == sif::OutputTypes::OUT_WARNING) {
|
if (errorType == sif::LogLevel::WARNING) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{} | Object ID {:#010x} | {}", functionName, SystemObject::getObjectId(),
|
||||||
sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID 0x" << std::hex
|
errorPrint);
|
||||||
<< std::setw(8) << std::setfill('0') << this->getObjectId() << " | " << errorPrint
|
} else if (errorType == sif::LogLevel::ERROR) {
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
FSFW_LOGET("{} | Object ID {:#010x} | {}", functionName, SystemObject::getObjectId(),
|
||||||
#else
|
errorPrint);
|
||||||
sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", functionName,
|
|
||||||
this->getObjectId(), errorPrint);
|
|
||||||
#endif
|
|
||||||
} else if (errorType == sif::OutputTypes::OUT_ERROR) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "DeviceHandlerBase::" << functionName << ": Object ID 0x" << std::hex
|
|
||||||
<< std::setw(8) << std::setfill('0') << this->getObjectId() << " | " << errorPrint
|
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", functionName,
|
|
||||||
this->getObjectId(), errorPrint);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1562,29 +1533,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
|||||||
}
|
}
|
||||||
return commandIter->second.sendReplyTo;
|
return commandIter->second.sendReplyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
|
||||||
this->powerSwitcher = switcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeviceHandlerBase::disableCommandsAndReplies() {
|
|
||||||
for (auto& command : deviceCommandMap) {
|
|
||||||
if (command.second.isExecuting) {
|
|
||||||
command.second.isExecuting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto& reply : deviceReplyMap) {
|
|
||||||
if (!reply.second.periodic) {
|
|
||||||
if (reply.second.countdown != nullptr) {
|
|
||||||
reply.second.countdown->timeOut();
|
|
||||||
} else {
|
|
||||||
reply.second.delayCycles = 0;
|
|
||||||
}
|
|
||||||
reply.second.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "DeviceHandlerFailureIsolation.h"
|
#include "DeviceHandlerFailureIsolation.h"
|
||||||
#include "DeviceHandlerIF.h"
|
#include "DeviceHandlerIF.h"
|
||||||
#include "DeviceHandlerThermalSet.h"
|
#include "DeviceHandlerThermalSet.h"
|
||||||
#include "DhbCfgHelpers.h"
|
|
||||||
#include "fsfw/action/ActionHelper.h"
|
#include "fsfw/action/ActionHelper.h"
|
||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
#include "fsfw/datapool/PoolVariableIF.h"
|
#include "fsfw/datapool/PoolVariableIF.h"
|
||||||
@ -20,8 +19,7 @@
|
|||||||
#include "fsfw/parameters/ParameterHelper.h"
|
#include "fsfw/parameters/ParameterHelper.h"
|
||||||
#include "fsfw/power/PowerSwitchIF.h"
|
#include "fsfw/power/PowerSwitchIF.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||||
|
|
||||||
@ -104,9 +102,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||||
|
|
||||||
void setCustomFdir(FailureIsolationBase *fdir);
|
|
||||||
void setParent(object_id_t parent);
|
|
||||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
|
||||||
void setHkDestination(object_id_t hkDestination);
|
void setHkDestination(object_id_t hkDestination);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -468,14 +463,14 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @brief This is a helper method to insert replies in the reply map.
|
* @brief This is a helper method to insert replies in the reply map.
|
||||||
* @param deviceCommand Identifier of the reply to add.
|
* @param deviceCommand Identifier of the reply to add.
|
||||||
* @param maxDelayCycles The maximum number of delay cycles the reply waits
|
* @param maxDelayCycles The maximum number of delay cycles the reply waits
|
||||||
* until it times out.
|
* until it times out.
|
||||||
* @param periodic Indicates if the command is periodic (i.e. it is sent
|
* @param periodic Indicates if the command is periodic (i.e. it is sent
|
||||||
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
||||||
* Please note that periodic replies are disabled by default. You can enable them with
|
* Please note that periodic replies are disabled by default. You can enable them with
|
||||||
* #updatePeriodicReply
|
* #updatePeriodicReply
|
||||||
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
||||||
* to provide a pointer to a Countdown object which will signal the timeout
|
* to provide a pointer to a Countdown object which will signal the timeout
|
||||||
* when expired
|
* when expired
|
||||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||||
* - @c RETURN_FAILED else.
|
* - @c RETURN_FAILED else.
|
||||||
*/
|
*/
|
||||||
@ -489,9 +484,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||||
* - @c RETURN_FAILED else.
|
* - @c RETURN_FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInCommandMap(
|
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand,
|
||||||
DeviceCommandId_t deviceCommand, bool useAlternativeReply = false,
|
bool useAlternativeReply = false,
|
||||||
DeviceCommandId_t alternativeReplyId = DeviceHandlerIF::NO_COMMAND_ID);
|
DeviceCommandId_t alternativeReplyId = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
||||||
@ -660,12 +655,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
||||||
uint32_t parameter = 0);
|
uint32_t parameter = 0);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Can be overwritten by a child to specify the initial submode when device has been set
|
|
||||||
* to startup immediately.
|
|
||||||
*/
|
|
||||||
virtual Submode_t getInitialSubmode();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||||
|
|
||||||
@ -784,18 +773,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* This is used to keep track of pending replies.
|
* This is used to keep track of pending replies.
|
||||||
*/
|
*/
|
||||||
struct DeviceReplyInfo {
|
struct DeviceReplyInfo {
|
||||||
//! For Command-Reply combinations:
|
|
||||||
//! The maximum number of cycles the handler should wait for a reply
|
//! The maximum number of cycles the handler should wait for a reply
|
||||||
//! to this command.
|
//! to this command.
|
||||||
//!
|
|
||||||
//! Reply Only:
|
|
||||||
//! For periodic replies, this variable will be the number of delay cycles between the replies.
|
|
||||||
//! For the non-periodic variant, this variable is not used as there is no meaningful
|
|
||||||
//! definition for delay
|
|
||||||
uint16_t maxDelayCycles;
|
uint16_t maxDelayCycles;
|
||||||
//! This variable will be set to #maxDelayCycles if a reply is expected.
|
//! The currently remaining cycles the handler should wait for a reply,
|
||||||
//! For non-periodic replies without a command, this variable is unused.
|
//! 0 means there is no reply expected
|
||||||
//! A runtime value of 0 means there is no reply is currently expected.
|
|
||||||
uint16_t delayCycles;
|
uint16_t delayCycles;
|
||||||
size_t replyLen = 0; //!< Expected size of the reply.
|
size_t replyLen = 0; //!< Expected size of the reply.
|
||||||
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
||||||
@ -851,7 +833,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
/** Pointer to the used FDIR instance. If not provided by child,
|
/** Pointer to the used FDIR instance. If not provided by child,
|
||||||
* default class is instantiated. */
|
* default class is instantiated. */
|
||||||
FailureIsolationBase *fdirInstance;
|
FailureIsolationBase *fdirInstance;
|
||||||
object_id_t parent = objects::NO_OBJECT;
|
|
||||||
|
|
||||||
//! To correctly delete the default instance.
|
//! To correctly delete the default instance.
|
||||||
bool defaultFDIRUsed;
|
bool defaultFDIRUsed;
|
||||||
@ -1275,15 +1256,15 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
void doGetRead(void);
|
void doGetRead(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles disabling of replies which use a timeout to detect missed replies.
|
* @brief Resets replies which use a timeout to detect missed replies.
|
||||||
*/
|
*/
|
||||||
void disableTimeoutControlledReply(DeviceReplyInfo *info);
|
void resetTimeoutControlledReply(DeviceReplyInfo *info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles disabling of replies which use a number of maximum delay cycles to detect
|
* @brief Resets replies which use a number of maximum delay cycles to detect
|
||||||
* missed replies.
|
* missed replies.
|
||||||
*/
|
*/
|
||||||
void disableDelayCyclesControlledReply(DeviceReplyInfo *info);
|
void resetDelayCyclesControlledReply(DeviceReplyInfo *info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrive data from the #IPCStore.
|
* Retrive data from the #IPCStore.
|
||||||
@ -1323,14 +1304,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @param errorCode
|
* @param errorCode
|
||||||
* @param errorPrint
|
* @param errorPrint
|
||||||
*/
|
*/
|
||||||
void printWarningOrError(sif::OutputTypes errorType, const char *functionName,
|
void printWarningOrError(sif::LogLevel errorType, const char *functionName,
|
||||||
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
||||||
const char *errorPrint = nullptr);
|
const char *errorPrint = nullptr);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Disables all commands and replies when device is set to MODE_OFF
|
|
||||||
*/
|
|
||||||
void disableCommandsAndReplies();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "fsfw/modes/HasModesIF.h"
|
#include "fsfw/modes/HasModesIF.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/power/Fuse.h"
|
#include "fsfw/power/Fuse.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/thermal/ThermalComponentIF.h"
|
#include "fsfw/thermal/ThermalComponentIF.h"
|
||||||
|
|
||||||
object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||||
@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
|||||||
switch (event->getEvent()) {
|
switch (event->getEvent()) {
|
||||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
|
||||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||||
// Might cause some AssemblyBase cycles, so keep number low.
|
// Might cause some AssemblyBase cycles, so keep number low.
|
||||||
handleRecovery(event->getEvent());
|
handleRecovery(event->getEvent());
|
||||||
@ -164,15 +163,10 @@ void DeviceHandlerFailureIsolation::clearFaultCounters() {
|
|||||||
ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
|
ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
|
||||||
ReturnValue_t result = FailureIsolationBase::initialize();
|
ReturnValue_t result = FailureIsolationBase::initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}", "initialize: Could not initialize FailureIsolationBase\n");
|
||||||
sif::error << "DeviceHandlerFailureIsolation::initialize: Could not"
|
|
||||||
" initialize FailureIsolationBase."
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
ConfirmsFailuresIF* power =
|
auto* power = ObjectManager::instance()->get<ConfirmsFailuresIF>(powerConfirmationId);
|
||||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(powerConfirmationId);
|
|
||||||
if (power != nullptr) {
|
if (power != nullptr) {
|
||||||
powerConfirmation = power->getEventReceptionQueue();
|
powerConfirmation = power->getEventReceptionQueue();
|
||||||
}
|
}
|
||||||
@ -245,10 +239,7 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(EventMessage* ev
|
|||||||
|
|
||||||
if (owner == nullptr) {
|
if (owner == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("isFdirInActionOrAreWeFaulty: Owner not set\n");
|
||||||
sif::error << "DeviceHandlerFailureIsolation::"
|
|
||||||
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,6 @@ class DeviceHandlerIF {
|
|||||||
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
||||||
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
||||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
||||||
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
|
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||||
|
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
#ifndef FSFW_SRC_FSFW_DEVICEHANDLERS_DHBCFGHELPERS_H_
|
|
||||||
#define FSFW_SRC_FSFW_DEVICEHANDLERS_DHBCFGHELPERS_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This is the base class for configuration related to both DHB commands, replies and their
|
|
||||||
* combination
|
|
||||||
*/
|
|
||||||
struct CfgBase {
|
|
||||||
public:
|
|
||||||
explicit CfgBase(DeviceCommandId_t cmdAndOrReplyId) : cmdAndOrReplyId(cmdAndOrReplyId){};
|
|
||||||
DeviceCommandId_t cmdAndOrReplyId;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configuration class for commands
|
|
||||||
*/
|
|
||||||
struct CmdCfg {
|
|
||||||
public:
|
|
||||||
explicit CmdCfg(DeviceCommandId_t cmdId) : baseCfg(cmdId){};
|
|
||||||
|
|
||||||
CfgBase baseCfg;
|
|
||||||
//! This can be used if a command can trigger multiple replies
|
|
||||||
std::pair<bool, DeviceCommandId_t> alternativeReply = {false, DeviceHandlerIF::NO_COMMAND_ID};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configuration class for replies
|
|
||||||
*/
|
|
||||||
struct ReplyCfg {
|
|
||||||
public:
|
|
||||||
ReplyCfg(DeviceCommandId_t replyId, uint16_t maxDelayCycles)
|
|
||||||
: baseCfg(replyId), maxDelayCycles(maxDelayCycles){};
|
|
||||||
ReplyCfg(DeviceCommandId_t replyId, uint16_t maxDelayCycles, LocalPoolDataSetBase* set)
|
|
||||||
: ReplyCfg(replyId, maxDelayCycles) {
|
|
||||||
dataSet = set;
|
|
||||||
};
|
|
||||||
|
|
||||||
CfgBase baseCfg;
|
|
||||||
//! A data set can be mapped to a reply ID. This allows to omit the #getDataSetHandle
|
|
||||||
//! override in a user device handler as this pointer will be passed as long as the device
|
|
||||||
//! command ID is equal to the set ID.
|
|
||||||
LocalPoolDataSetBase* dataSet = nullptr;
|
|
||||||
//! For Command-Reply combinations:
|
|
||||||
//! The maximum number of cycles the handler should wait for a reply
|
|
||||||
//! to this command.
|
|
||||||
//!
|
|
||||||
//! Reply Only:
|
|
||||||
//! For periodic replies, this variable will be the number of delay cycles between the replies.
|
|
||||||
//! For the non-periodic variant, this variable is not used as there is no meaningful
|
|
||||||
//! definition for delay
|
|
||||||
uint16_t maxDelayCycles = 0;
|
|
||||||
//! First parameter: Specify whether reply is arriving periodically
|
|
||||||
//! Second parameter: Specify whether periodic reply should be enabled immediately
|
|
||||||
std::pair<bool, bool> periodicCfg = {false, false};
|
|
||||||
//! If a reply needs to be requested with a specific length, the length can be specified here
|
|
||||||
size_t replyLen = 0;
|
|
||||||
//! It is also possible to use a time based instead of a cycle based mechanism to specify
|
|
||||||
//! how long a reply takes. For non-periodic replies without a command, this variable is not used.
|
|
||||||
Countdown* countdown = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configuration class for commands and replies
|
|
||||||
*/
|
|
||||||
struct CmdReplyCfg {
|
|
||||||
public:
|
|
||||||
CmdReplyCfg(CmdCfg cmdCfg, ReplyCfg replyCfg) : cmdCfg(cmdCfg), replyCfg(replyCfg) {}
|
|
||||||
CmdCfg cmdCfg;
|
|
||||||
ReplyCfg replyCfg;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_SRC_FSFW_DEVICEHANDLERS_DHBCFGHELPERS_H_ */
|
|
@ -8,9 +8,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
|||||||
parentQueue(parentQueue),
|
parentQueue(parentQueue),
|
||||||
commandQueue(),
|
commandQueue(),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -18,9 +18,8 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
|||||||
EventManager::EventManager(object_id_t setObjectId)
|
EventManager::EventManager(object_id_t setObjectId)
|
||||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
EventMessage::EVENT_MESSAGE_SIZE);
|
||||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager() {
|
EventManager::~EventManager() {
|
||||||
@ -47,20 +46,9 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
|||||||
|
|
||||||
void EventManager::notifyListeners(EventMessage* message) {
|
void EventManager::notifyListeners(EventMessage* message) {
|
||||||
lockMutex();
|
lockMutex();
|
||||||
for (auto& listener : listenerList) {
|
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||||
if (listener.second.match(message)) {
|
if (iter->second.match(message)) {
|
||||||
ReturnValue_t result =
|
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||||
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
|
||||||
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
|
||||||
<< result << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
|
||||||
listener.first, result);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlockMutex();
|
unlockMutex();
|
||||||
@ -100,6 +88,11 @@ ReturnValue_t EventManager::subscribeToEventRange(MessageQueueId_t listener, Eve
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t EventManager::unsubscribeFromAllEvents(MessageQueueId_t listener,
|
||||||
|
object_id_t object) {
|
||||||
|
return unsubscribeFromEventRange(listener, 0, 0, true, object);
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom,
|
ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom,
|
||||||
EventId_t idTo, bool idInverted,
|
EventId_t idTo, bool idInverted,
|
||||||
object_id_t reporterFrom,
|
object_id_t reporterFrom,
|
||||||
@ -131,17 +124,17 @@ void EventManager::printEvent(EventMessage* message) {
|
|||||||
switch (message->getSeverity()) {
|
switch (message->getSeverity()) {
|
||||||
case severity::INFO: {
|
case severity::INFO: {
|
||||||
#if FSFW_DEBUG_INFO == 1
|
#if FSFW_DEBUG_INFO == 1
|
||||||
printUtility(sif::OutputTypes::OUT_INFO, message);
|
printUtility(sif::LogLevel::INFO, message);
|
||||||
#endif /* DEBUG_INFO_EVENT == 1 */
|
#endif /* DEBUG_INFO_EVENT == 1 */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
printUtility(sif::OutputTypes::OUT_DEBUG, message);
|
printUtility(sif::LogLevel::DEBUG, message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::printUtility(sif::OutputTypes printType, EventMessage* message) {
|
void EventManager::printUtility(sif::LogLevel printType, EventMessage* message) {
|
||||||
const char* string = 0;
|
const char* string = 0;
|
||||||
if (printType == sif::OutputTypes::OUT_INFO) {
|
if (printType == sif::OutputTypes::OUT_INFO) {
|
||||||
string = translateObject(message->getReporter());
|
string = translateObject(message->getReporter());
|
||||||
@ -201,19 +194,4 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::printListeners() {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
|
||||||
for (auto& listener : listenerList) {
|
|
||||||
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
|
||||||
}
|
|
||||||
sif::info << std::dec << std::setfill(' ');
|
|
||||||
#else
|
|
||||||
sif::printInfo("Event manager listener MQ IDs:\n");
|
|
||||||
for (auto& listener : listenerList) {
|
|
||||||
sif::printInfo("0x%08x\n", listener.first);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "../storagemanager/LocalPool.h"
|
#include "../storagemanager/LocalPool.h"
|
||||||
#include "../tasks/ExecutableObjectIF.h"
|
#include "../tasks/ExecutableObjectIF.h"
|
||||||
#include "EventManagerIF.h"
|
#include "EventManagerIF.h"
|
||||||
#include "FSFWConfig.h"
|
#include "FSFWConfig.h"
|
||||||
#include "eventmatching/EventMatchTree.h"
|
#include "eventmatching/EventMatchTree.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||||
// forward declaration, should be implemented by mission
|
// forward declaration, should be implemented by mission
|
||||||
@ -37,12 +37,12 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
EventId_t idTo = 0, bool idInverted = false,
|
EventId_t idTo = 0, bool idInverted = false,
|
||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false);
|
||||||
|
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object);
|
||||||
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||||
EventId_t idTo = 0, bool idInverted = false,
|
EventId_t idTo = 0, bool idInverted = false,
|
||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false);
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode);
|
||||||
void printListeners();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* eventReportQueue = nullptr;
|
MessageQueueIF* eventReportQueue = nullptr;
|
||||||
@ -64,7 +64,7 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
|
|
||||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||||
void printEvent(EventMessage* message);
|
void printEvent(EventMessage* message);
|
||||||
void printUtility(sif::OutputTypes printType, EventMessage* message);
|
void printUtility(sif::LogLevel printType, EventMessage* message);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void lockMutex();
|
void lockMutex();
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
#include "../ipc/MessageQueueIF.h"
|
#include "../ipc/MessageQueueIF.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../objectmanager/ObjectManager.h"
|
#include "../objectmanager/ObjectManager.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "EventMessage.h"
|
#include "EventMessage.h"
|
||||||
#include "eventmatching/eventmatching.h"
|
#include "eventmatching/eventmatching.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
class EventManagerIF {
|
class EventManagerIF {
|
||||||
public:
|
public:
|
||||||
@ -20,6 +20,7 @@ class EventManagerIF {
|
|||||||
bool forwardAllButSelected = false) = 0;
|
bool forwardAllButSelected = false) = 0;
|
||||||
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
|
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
|
||||||
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0;
|
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0;
|
||||||
|
virtual ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) = 0;
|
||||||
virtual ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
virtual ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||||
EventId_t idTo = 0, bool idInverted = false,
|
EventId_t idTo = 0, bool idInverted = false,
|
||||||
object_id_t reporterFrom = 0,
|
object_id_t reporterFrom = 0,
|
||||||
@ -39,19 +40,9 @@ class EventManagerIF {
|
|||||||
|
|
||||||
static void triggerEvent(EventMessage* message, MessageQueueId_t sentFrom = 0) {
|
static void triggerEvent(EventMessage* message, MessageQueueId_t sentFrom = 0) {
|
||||||
if (eventmanagerQueue == MessageQueueIF::NO_QUEUE) {
|
if (eventmanagerQueue == MessageQueueIF::NO_QUEUE) {
|
||||||
EventManagerIF* eventmanager =
|
auto* eventmanager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||||
ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
|
||||||
if (eventmanager == nullptr) {
|
if (eventmanager == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGW("{}", "EventManagerIF::triggerEvent: EventManager invalid or not found\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "EventManagerIF::triggerEvent: EventManager invalid or not found!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"EventManagerIF::triggerEvent: "
|
|
||||||
"EventManager invalid or not found!");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eventmanagerQueue = eventmanager->getEventReportQueue();
|
eventmanagerQueue = eventmanager->getEventReportQueue();
|
||||||
|
@ -9,23 +9,28 @@
|
|||||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||||
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
eventQueue =
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
||||||
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FailureIsolationBase::~FailureIsolationBase() {
|
FailureIsolationBase::~FailureIsolationBase() {
|
||||||
|
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||||
|
if (manager == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "FailureIsolationBase::~FailureIsolationBase: Event Manager has not"
|
||||||
|
" been initialized!"
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
manager->unsubscribeFromAllEvents(eventQueue->getId(), ownerId);
|
||||||
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t FailureIsolationBase::initialize() {
|
ReturnValue_t FailureIsolationBase::initialize() {
|
||||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||||
if (manager == nullptr) {
|
if (manager == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}", "initialize: Event Manager has not been initialized\n");
|
||||||
sif::error << "FailureIsolationBase::initialize: Event Manager has not"
|
|
||||||
" been initialized!"
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = manager->registerListener(eventQueue->getId());
|
ReturnValue_t result = manager->registerListener(eventQueue->getId());
|
||||||
@ -39,28 +44,20 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
}
|
}
|
||||||
owner = ObjectManager::instance()->get<HasHealthIF>(ownerId);
|
owner = ObjectManager::instance()->get<HasHealthIF>(ownerId);
|
||||||
if (owner == nullptr) {
|
if (owner == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE(
|
||||||
sif::error << "FailureIsolationBase::intialize: Owner object "
|
"FailureIsolationBase::intialize: Owner object {:#010x} invalid. "
|
||||||
"invalid. Make sure it implements HasHealthIF"
|
"Does it implement HasHealthIF?\n",
|
||||||
<< std::endl;
|
ownerId);
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (faultTreeParent != objects::NO_OBJECT) {
|
if (faultTreeParent != objects::NO_OBJECT) {
|
||||||
ConfirmsFailuresIF* parentIF =
|
auto* parentIF = ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
||||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
|
||||||
if (parentIF == nullptr) {
|
if (parentIF == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW(
|
||||||
sif::error << "FailureIsolationBase::intialize: Parent object "
|
"intialize: Parent object {:#010x} invalid. Does it implement ConfirmsFailuresIF?\n",
|
||||||
<< "invalid" << std::endl;
|
faultTreeParent);
|
||||||
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
|
||||||
sif::printError("Make sure it implements ConfirmsFailuresIF\n");
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
}
|
||||||
eventQueue->setDefaultDestination(parentIF->getEventReceptionQueue());
|
eventQueue->setDefaultDestination(parentIF->getEventReceptionQueue());
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,13 @@ class FailureIsolationBase : public HasReturnvaluesIF,
|
|||||||
public HasParametersIF {
|
public HasParametersIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
||||||
//! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
|
static const Event FDIR_CHANGED_STATE =
|
||||||
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO);
|
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
//!< (oldState) to par1 (newState).
|
||||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||||
//! FDIR turns off device. Par1: event that caused recovery.
|
2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
|
||||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
|
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(
|
||||||
|
3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||||
|
|
||||||
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||||
|
@ -60,14 +60,14 @@ ReturnValue_t FaultCounter::getParameter(uint8_t domainId, uint8_t uniqueId,
|
|||||||
return INVALID_DOMAIN_ID;
|
return INVALID_DOMAIN_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (uniqueId) {
|
switch (static_cast<ParameterIds>(uniqueId)) {
|
||||||
case 0:
|
case ParameterIds::FAILURE_THRESHOLD:
|
||||||
parameterWrapper->set(failureThreshold);
|
parameterWrapper->set(failureThreshold);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case ParameterIds::FAULT_COUNT:
|
||||||
parameterWrapper->set(faultCount);
|
parameterWrapper->set(faultCount);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case ParameterIds::TIMEOUT:
|
||||||
parameterWrapper->set(timer.timeout);
|
parameterWrapper->set(timer.timeout);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
class FaultCounter : public HasParametersIF {
|
class FaultCounter : public HasParametersIF {
|
||||||
public:
|
public:
|
||||||
|
enum class ParameterIds { FAILURE_THRESHOLD, FAULT_COUNT, TIMEOUT };
|
||||||
|
|
||||||
FaultCounter();
|
FaultCounter();
|
||||||
FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs,
|
FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs,
|
||||||
uint8_t setParameterDomain = 0);
|
uint8_t setParameterDomain = 0);
|
||||||
@ -25,7 +27,8 @@ class FaultCounter : public HasParametersIF {
|
|||||||
|
|
||||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper,
|
||||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
const ParameterWrapper *newValues = nullptr,
|
||||||
|
uint16_t startAtIndex = 0);
|
||||||
|
|
||||||
void setParameterDomain(uint8_t domain);
|
void setParameterDomain(uint8_t domain);
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ target_sources(
|
|||||||
AsciiConverter.cpp
|
AsciiConverter.cpp
|
||||||
CRC.cpp
|
CRC.cpp
|
||||||
DleEncoder.cpp
|
DleEncoder.cpp
|
||||||
DleParser.cpp
|
|
||||||
PeriodicOperationDivider.cpp
|
PeriodicOperationDivider.cpp
|
||||||
timevalOperations.cpp
|
timevalOperations.cpp
|
||||||
Type.cpp
|
Type.cpp
|
||||||
|
@ -1,230 +0,0 @@
|
|||||||
#include "DleParser.h"
|
|
||||||
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
DleParser::DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
|
||||||
BufPair decodedBuf, UserHandler handler, void* args)
|
|
||||||
: decodeRingBuf(decodeRingBuf),
|
|
||||||
decoder(decoder),
|
|
||||||
encodedBuf(encodedBuf),
|
|
||||||
decodedBuf(decodedBuf),
|
|
||||||
handler(handler),
|
|
||||||
ctx(args) {
|
|
||||||
if (handler == nullptr) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "DleParser::DleParser: Invalid user handler" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("DleParser::DleParser: Invalid user handler\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t DleParser::passData(uint8_t* data, size_t len) {
|
|
||||||
if (data == nullptr or len == 0 or handler == nullptr) {
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
size_t copyIntoRingBufFromHere = 0;
|
|
||||||
size_t copyAmount = len;
|
|
||||||
size_t startIdx = 0;
|
|
||||||
ReturnValue_t result = RETURN_OK;
|
|
||||||
bool startFoundInThisPacket = false;
|
|
||||||
for (size_t idx = 0; idx < len; idx++) {
|
|
||||||
if (data[idx] == DleEncoder::STX_CHAR) {
|
|
||||||
if (not startFound and not startFoundInThisPacket) {
|
|
||||||
startIdx = idx;
|
|
||||||
copyIntoRingBufFromHere = idx;
|
|
||||||
copyAmount = len - idx;
|
|
||||||
} else {
|
|
||||||
// Maybe print warning, should not happen
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
ErrorInfo info;
|
|
||||||
info.len = idx;
|
|
||||||
prepareErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
|
||||||
handler(ctx);
|
|
||||||
copyIntoRingBufFromHere = idx;
|
|
||||||
copyAmount = len - idx;
|
|
||||||
}
|
|
||||||
startFound = true;
|
|
||||||
startFoundInThisPacket = true;
|
|
||||||
} else if (data[idx] == DleEncoder::ETX_CHAR) {
|
|
||||||
if (startFoundInThisPacket) {
|
|
||||||
size_t readLen = 0;
|
|
||||||
size_t decodedLen = 0;
|
|
||||||
result = decoder.decode(data + startIdx, idx + 1 - startIdx, &readLen, decodedBuf.first,
|
|
||||||
decodedBuf.second, &decodedLen);
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
ctx.setType(ContextType::PACKET_FOUND);
|
|
||||||
ctx.decodedPacket.first = decodedBuf.first;
|
|
||||||
ctx.decodedPacket.second = decodedLen;
|
|
||||||
this->handler(ctx);
|
|
||||||
} else if (result == DleEncoder::STREAM_TOO_SHORT) {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.res = result;
|
|
||||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
|
||||||
handler(ctx);
|
|
||||||
} else {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.res = result;
|
|
||||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
|
||||||
handler(ctx);
|
|
||||||
}
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
if ((idx + 1) < len) {
|
|
||||||
copyIntoRingBufFromHere = idx + 1;
|
|
||||||
copyAmount = len - idx - 1;
|
|
||||||
} else {
|
|
||||||
copyAmount = 0;
|
|
||||||
}
|
|
||||||
} else if (startFound) {
|
|
||||||
// ETX found but STX was found in another mini packet. Reconstruct the full packet
|
|
||||||
// to decode it
|
|
||||||
result = decodeRingBuf.writeData(data, idx + 1);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.res = result;
|
|
||||||
prepareErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
|
||||||
handler(ctx);
|
|
||||||
}
|
|
||||||
size_t fullEncodedLen = decodeRingBuf.getAvailableReadData();
|
|
||||||
if (fullEncodedLen > encodedBuf.second) {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.len = fullEncodedLen;
|
|
||||||
prepareErrorContext(ErrorTypes::ENCODED_BUF_TOO_SMALL, info);
|
|
||||||
handler(ctx);
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
} else {
|
|
||||||
size_t decodedLen = 0;
|
|
||||||
size_t readLen = 0;
|
|
||||||
decodeRingBuf.readData(encodedBuf.first, fullEncodedLen, true);
|
|
||||||
result = decoder.decode(encodedBuf.first, fullEncodedLen, &readLen, decodedBuf.first,
|
|
||||||
decodedBuf.second, &decodedLen);
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
if (this->handler != nullptr) {
|
|
||||||
ctx.setType(ContextType::PACKET_FOUND);
|
|
||||||
ctx.decodedPacket.first = decodedBuf.first;
|
|
||||||
ctx.decodedPacket.second = decodedLen;
|
|
||||||
this->handler(ctx);
|
|
||||||
}
|
|
||||||
} else if (result == DleEncoder::STREAM_TOO_SHORT) {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.res = result;
|
|
||||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
|
||||||
handler(ctx);
|
|
||||||
} else {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.res = result;
|
|
||||||
prepareErrorContext(ErrorTypes::DECODE_ERROR, info);
|
|
||||||
handler(ctx);
|
|
||||||
}
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
startFound = false;
|
|
||||||
startFoundInThisPacket = false;
|
|
||||||
if ((idx + 1) < len) {
|
|
||||||
copyIntoRingBufFromHere = idx + 1;
|
|
||||||
copyAmount = len - idx - 1;
|
|
||||||
} else {
|
|
||||||
copyAmount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// End data without preceeding STX
|
|
||||||
ErrorInfo info;
|
|
||||||
info.len = idx + 1;
|
|
||||||
prepareErrorContext(ErrorTypes::CONSECUTIVE_ETX_CHARS, info);
|
|
||||||
handler(ctx);
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
if ((idx + 1) < len) {
|
|
||||||
copyIntoRingBufFromHere = idx + 1;
|
|
||||||
copyAmount = len - idx - 1;
|
|
||||||
} else {
|
|
||||||
copyAmount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startFoundInThisPacket = false;
|
|
||||||
startFound = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (copyAmount > 0) {
|
|
||||||
result = decodeRingBuf.writeData(data + copyIntoRingBufFromHere, copyAmount);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
ErrorInfo info;
|
|
||||||
info.res = result;
|
|
||||||
prepareErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
|
||||||
handler(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DleParser::defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args) {
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::info << "DleParserBase::handleFoundPacket: Detected DLE packet with " << len << " bytes"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printInfo("DleParserBase::handleFoundPacket: Detected DLE packet with %d bytes\n", len);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void DleParser::defaultErrorHandler(ErrorTypes err, ErrorInfo ctx) {
|
|
||||||
switch (err) {
|
|
||||||
case (ErrorTypes::NONE): {
|
|
||||||
errorPrinter("No error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ErrorTypes::DECODE_ERROR): {
|
|
||||||
errorPrinter("Decode Error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ErrorTypes::RING_BUF_ERROR): {
|
|
||||||
errorPrinter("Ring Buffer Error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ErrorTypes::ENCODED_BUF_TOO_SMALL):
|
|
||||||
case (ErrorTypes::DECODING_BUF_TOO_SMALL): {
|
|
||||||
char opt[64];
|
|
||||||
snprintf(opt, sizeof(opt), ": Too small for packet with length %zu", ctx.len);
|
|
||||||
if (err == ErrorTypes::ENCODED_BUF_TOO_SMALL) {
|
|
||||||
errorPrinter("Encoded buf too small", opt);
|
|
||||||
} else {
|
|
||||||
errorPrinter("Decoding buf too small", opt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ErrorTypes::CONSECUTIVE_STX_CHARS): {
|
|
||||||
errorPrinter("Consecutive STX chars detected");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ErrorTypes::CONSECUTIVE_ETX_CHARS): {
|
|
||||||
errorPrinter("Consecutive ETX chars detected");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DleParser::errorPrinter(const char* str, const char* opt) {
|
|
||||||
if (opt == nullptr) {
|
|
||||||
opt = "";
|
|
||||||
}
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::info << "DleParserBase::handleParseError: " << str << opt << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printInfo("DleParserBase::handleParseError: %s%s\n", str, opt);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void DleParser::prepareErrorContext(ErrorTypes err, ErrorInfo info) {
|
|
||||||
ctx.setType(ContextType::ERROR);
|
|
||||||
ctx.error.first = err;
|
|
||||||
ctx.error.second = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DleParser::reset() {
|
|
||||||
startFound = false;
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
}
|
|
@ -1,124 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <fsfw/container/SimpleRingBuffer.h>
|
|
||||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This base helper class can be used to extract DLE encoded packets from a data stream
|
|
||||||
* @details
|
|
||||||
* The core API of the parser takes received packets which can contains DLE packets. The parser
|
|
||||||
* can deal with DLE packets split across multiple packets. It does so by using a dedicated
|
|
||||||
* decoding ring buffer. The user can process received packets and detect errors by
|
|
||||||
* overriding two provided virtual methods. This also allows detecting multiple DLE packets
|
|
||||||
* inside one passed packet.
|
|
||||||
*/
|
|
||||||
class DleParser : public HasReturnvaluesIF {
|
|
||||||
public:
|
|
||||||
using BufPair = std::pair<uint8_t*, size_t>;
|
|
||||||
|
|
||||||
enum class ContextType { PACKET_FOUND, ERROR };
|
|
||||||
|
|
||||||
enum class ErrorTypes {
|
|
||||||
NONE,
|
|
||||||
ENCODED_BUF_TOO_SMALL,
|
|
||||||
DECODING_BUF_TOO_SMALL,
|
|
||||||
DECODE_ERROR,
|
|
||||||
RING_BUF_ERROR,
|
|
||||||
CONSECUTIVE_STX_CHARS,
|
|
||||||
CONSECUTIVE_ETX_CHARS
|
|
||||||
};
|
|
||||||
|
|
||||||
union ErrorInfo {
|
|
||||||
size_t len;
|
|
||||||
ReturnValue_t res;
|
|
||||||
};
|
|
||||||
|
|
||||||
using ErrorPair = std::pair<ErrorTypes, ErrorInfo>;
|
|
||||||
|
|
||||||
struct Context {
|
|
||||||
public:
|
|
||||||
Context(void* args) : userArgs(args) { setType(ContextType::PACKET_FOUND); }
|
|
||||||
|
|
||||||
void setType(ContextType type) {
|
|
||||||
if (type == ContextType::PACKET_FOUND) {
|
|
||||||
error.first = ErrorTypes::NONE;
|
|
||||||
error.second.len = 0;
|
|
||||||
} else {
|
|
||||||
decodedPacket.first = nullptr;
|
|
||||||
decodedPacket.second = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextType getType() const { return type; }
|
|
||||||
|
|
||||||
BufPair decodedPacket = {};
|
|
||||||
ErrorPair error;
|
|
||||||
void* userArgs;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ContextType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
using UserHandler = void (*)(const Context& ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class constructor
|
|
||||||
* @param decodeRingBuf Ring buffer used to store multiple packets to allow detecting DLE packets
|
|
||||||
* split across multiple packets
|
|
||||||
* @param decoder Decoder instance
|
|
||||||
* @param encodedBuf Buffer used to store encoded packets. It has to be large enough to hold
|
|
||||||
* the largest expected encoded DLE packet size
|
|
||||||
* @param decodedBuf Buffer used to store decoded packets. It has to be large enough to hold the
|
|
||||||
* largest expected decoded DLE packet size
|
|
||||||
* @param handler Function which will be called on a found packet
|
|
||||||
* @param args Arbitrary user argument
|
|
||||||
*/
|
|
||||||
DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
|
||||||
BufPair decodedBuf, UserHandler handler, void* args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function allows to pass new data into the parser. It then scans for DLE packets
|
|
||||||
* automatically and inserts (part of) the packet into a ring buffer if necessary.
|
|
||||||
* @param data
|
|
||||||
* @param len
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t passData(uint8_t* data, size_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example found packet handler
|
|
||||||
* function call
|
|
||||||
* @param packet Decoded packet
|
|
||||||
* @param len Length of detected packet
|
|
||||||
*/
|
|
||||||
void defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args);
|
|
||||||
/**
|
|
||||||
* Will be called if an error occured in the #passData call
|
|
||||||
* @param err
|
|
||||||
* @param ctx Context information depending on the error type
|
|
||||||
* - For buffer length errors, will be set to the detected packet length which is too large
|
|
||||||
* - For decode or ring buffer errors, will be set to the result returned from the failed call
|
|
||||||
*/
|
|
||||||
static void defaultErrorHandler(ErrorTypes err, ErrorInfo ctx);
|
|
||||||
|
|
||||||
static void errorPrinter(const char* str, const char* opt = nullptr);
|
|
||||||
|
|
||||||
void prepareErrorContext(ErrorTypes err, ErrorInfo ctx);
|
|
||||||
/**
|
|
||||||
* Resets the parser by resetting the internal states and clearing the decoding ring buffer
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SimpleRingBuffer& decodeRingBuf;
|
|
||||||
DleEncoder& decoder;
|
|
||||||
BufPair encodedBuf;
|
|
||||||
BufPair decodedBuf;
|
|
||||||
UserHandler handler = nullptr;
|
|
||||||
Context ctx;
|
|
||||||
bool startFound = false;
|
|
||||||
};
|
|
@ -3,31 +3,16 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, bool printInfo,
|
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, bool printInfo,
|
||||||
size_t maxCharPerLine) {
|
size_t maxCharPerLine) {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGI("{}", "Size is zero, nothing to print\n");
|
||||||
sif::info << "Size is zero, nothing to print" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printInfo("Size is zero, nothing to print\n");
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGI("Printing data with size {}:\n", size);
|
||||||
if (printInfo) {
|
|
||||||
sif::info << "Printing data with size " << size << ": " << std::endl;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#if FSFW_NO_C99_IO == 1
|
|
||||||
sif::printInfo("Printing data with size %lu: \n", static_cast<unsigned long>(size));
|
|
||||||
#else
|
|
||||||
sif::printInfo("Printing data with size %zu: \n", size);
|
|
||||||
#endif /* FSFW_NO_C99_IO == 1 */
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
|
|
||||||
if (type == OutputType::HEX) {
|
if (type == OutputType::HEX) {
|
||||||
arrayprinter::printHex(data, size, maxCharPerLine);
|
arrayprinter::printHex(data, size, maxCharPerLine);
|
||||||
} else if (type == OutputType::DEC) {
|
} else if (type == OutputType::DEC) {
|
||||||
@ -38,99 +23,99 @@ void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerLine) {
|
void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerLine) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
//#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
if (sif::info.crAdditionEnabled()) {
|
// if (sif::info.crAdditionEnabled()) {
|
||||||
std::cout << "\r" << std::endl;
|
// std::cout << "\r" << std::endl;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::cout << "hex [" << std::setfill('0') << std::hex;
|
// std::cout << "hex [" << std::setfill('0') << std::hex;
|
||||||
for (size_t i = 0; i < size; i++) {
|
// for (size_t i = 0; i < size; i++) {
|
||||||
std::cout << std::setw(2) << static_cast<int>(data[i]);
|
// std::cout << std::setw(2) << static_cast<int>(data[i]);
|
||||||
if (i < size - 1) {
|
// if (i < size - 1) {
|
||||||
std::cout << ",";
|
// std::cout << ",";
|
||||||
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
// if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||||
std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
std::cout << std::dec << std::setfill(' ');
|
// std::cout << std::dec << std::setfill(' ');
|
||||||
std::cout << "]" << std::endl;
|
// std::cout << "]" << std::endl;
|
||||||
#else
|
//#else
|
||||||
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
// // General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
||||||
// plus line break plus small safety margin.
|
// // plus line break plus small safety margin.
|
||||||
char printBuffer[(size + 1) * 7 + 1] = {};
|
// char printBuffer[(size + 1) * 7 + 1] = {};
|
||||||
size_t currentPos = 0;
|
// size_t currentPos = 0;
|
||||||
for (size_t i = 0; i < size; i++) {
|
// for (size_t i = 0; i < size; i++) {
|
||||||
// To avoid buffer overflows.
|
// // To avoid buffer overflows.
|
||||||
if (sizeof(printBuffer) - currentPos <= 7) {
|
// if (sizeof(printBuffer) - currentPos <= 7) {
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
currentPos += snprintf(printBuffer + currentPos, 6, "%02x", data[i]);
|
// currentPos += snprintf(printBuffer + currentPos, 6, "%02x", data[i]);
|
||||||
if (i < size - 1) {
|
// if (i < size - 1) {
|
||||||
currentPos += sprintf(printBuffer + currentPos, ",");
|
// currentPos += sprintf(printBuffer + currentPos, ",");
|
||||||
if ((i + 1) % maxCharPerLine == 0) {
|
// if ((i + 1) % maxCharPerLine == 0) {
|
||||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
// currentPos += sprintf(printBuffer + currentPos, "\n");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
//#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
printf("hex [%s]\n", printBuffer);
|
// printf("hex [%s]\n", printBuffer);
|
||||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
//#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||||
#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerLine) {
|
void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerLine) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
//#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
if (sif::info.crAdditionEnabled()) {
|
// if (sif::info.crAdditionEnabled()) {
|
||||||
std::cout << "\r" << std::endl;
|
// std::cout << "\r" << std::endl;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::cout << "dec [" << std::dec;
|
// std::cout << "dec [" << std::dec;
|
||||||
for (size_t i = 0; i < size; i++) {
|
// for (size_t i = 0; i < size; i++) {
|
||||||
std::cout << static_cast<int>(data[i]);
|
// std::cout << static_cast<int>(data[i]);
|
||||||
if (i < size - 1) {
|
// if (i < size - 1) {
|
||||||
std::cout << ",";
|
// std::cout << ",";
|
||||||
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
// if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||||
std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
std::cout << "]" << std::endl;
|
// std::cout << "]" << std::endl;
|
||||||
#else
|
//#else
|
||||||
// General format: 32,243,-12 so it is number of chars times 4
|
// // General format: 32,243,-12 so it is number of chars times 4
|
||||||
// plus line break plus small safety margin.
|
// // plus line break plus small safety margin.
|
||||||
uint16_t expectedLines = ceil((double)size / maxCharPerLine);
|
// uint16_t expectedLines = ceil((double)size / maxCharPerLine);
|
||||||
char printBuffer[size * 4 + 1 + expectedLines] = {};
|
// char printBuffer[size * 4 + 1 + expectedLines] = {};
|
||||||
size_t currentPos = 0;
|
// size_t currentPos = 0;
|
||||||
for (size_t i = 0; i < size; i++) {
|
// for (size_t i = 0; i < size; i++) {
|
||||||
// To avoid buffer overflows.
|
// // To avoid buffer overflows.
|
||||||
if (sizeof(printBuffer) - currentPos <= 4) {
|
// if (sizeof(printBuffer) - currentPos <= 4) {
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
currentPos += snprintf(printBuffer + currentPos, 4, "%d", data[i]);
|
// currentPos += snprintf(printBuffer + currentPos, 4, "%d", data[i]);
|
||||||
if (i < size - 1) {
|
// if (i < size - 1) {
|
||||||
currentPos += sprintf(printBuffer + currentPos, ",");
|
// currentPos += sprintf(printBuffer + currentPos, ",");
|
||||||
if ((i + 1) % maxCharPerLine == 0) {
|
// if ((i + 1) % maxCharPerLine == 0) {
|
||||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
// currentPos += sprintf(printBuffer + currentPos, "\n");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
//#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
printf("dec [%s]\n", printBuffer);
|
// printf("dec [%s]\n", printBuffer);
|
||||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
//#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||||
#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrayprinter::printBin(const uint8_t *data, size_t size) {
|
void arrayprinter::printBin(const uint8_t *data, size_t size) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
//#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
for (size_t i = 0; i < size; i++) {
|
// for (size_t i = 0; i < size; i++) {
|
||||||
sif::info << "Byte " << i + 1 << ": 0b" << std::bitset<8>(data[i]) << std::endl;
|
// sif::info << "Byte " << i + 1 << ": 0b" << std::bitset<8>(data[i]) << std::endl;
|
||||||
}
|
// }
|
||||||
#else
|
//#else
|
||||||
for (size_t i = 0; i < size; i++) {
|
// for (size_t i = 0; i < size; i++) {
|
||||||
sif::printInfo("Byte %d: 0b" BYTE_TO_BINARY_PATTERN "\n", i + 1, BYTE_TO_BINARY(data[i]));
|
// sif::printInfo("Byte %d: 0b" BYTE_TO_BINARY_PATTERN "\n", i + 1, BYTE_TO_BINARY(data[i]));
|
||||||
}
|
// }
|
||||||
#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
@ -16,27 +16,26 @@ class HasHealthIF {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||||
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY =
|
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1);
|
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
|
||||||
static constexpr ReturnValue_t INVALID_HEALTH_STATE =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2);
|
|
||||||
static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3);
|
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
||||||
//! P1: New Health, P2: Old Health
|
|
||||||
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
||||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||||
//! Assembly overwrites health information of children to keep satellite alive.
|
static const Event OVERWRITING_HEALTH =
|
||||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
|
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
//!< satellite alive.
|
||||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
static const Event TRYING_RECOVERY =
|
||||||
//! Recovery is ongoing. Comes twice during recovery.
|
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
//!< power-cycle). No parameters.
|
||||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
static const Event RECOVERY_STEP =
|
||||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
//!< 0 for the first, 1 for the second event. P2: 0
|
||||||
|
static const Event RECOVERY_DONE = MAKE_EVENT(
|
||||||
|
12,
|
||||||
|
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||||
|
|
||||||
virtual ~HasHealthIF() {}
|
virtual ~HasHealthIF() {}
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "fsfw/health/HealthHelper.h"
|
#include "fsfw/health/HealthHelper.h"
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
||||||
: objectId(objectId), owner(owner) {}
|
: objectId(objectId), owner(owner) {}
|
||||||
|
|
||||||
HealthHelper::~HealthHelper() {}
|
HealthHelper::~HealthHelper() { healthTable->removeObject(objectId); }
|
||||||
|
|
||||||
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
@ -35,20 +35,12 @@ ReturnValue_t HealthHelper::initialize() {
|
|||||||
eventSender = ObjectManager::instance()->get<EventReportingProxyIF>(objectId);
|
eventSender = ObjectManager::instance()->get<EventReportingProxyIF>(objectId);
|
||||||
|
|
||||||
if (healthTable == nullptr) {
|
if (healthTable == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}", "initialize: Health table object needs to be created in factory\n");
|
||||||
sif::error << "HealthHelper::initialize: Health table object needs"
|
|
||||||
"to be created in factory."
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventSender == nullptr) {
|
if (eventSender == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}", "initialize: Owner has to implement ReportingProxyIF\n");
|
||||||
sif::error << "HealthHelper::initialize: Owner has to implement "
|
|
||||||
"ReportingProxyIF."
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +69,7 @@ void HealthHelper::informParent(HasHealthIF::HealthState health,
|
|||||||
HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, health, oldHealth);
|
HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, health, oldHealth);
|
||||||
if (MessageQueueSenderIF::sendMessage(parentQueue, &information, owner->getCommandQueue()) !=
|
if (MessageQueueSenderIF::sendMessage(parentQueue, &information, owner->getCommandQueue()) !=
|
||||||
HasReturnvaluesIF::RETURN_OK) {
|
HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("informParent: Object ID {:#010x} | Sending health reply failed\n", objectId);
|
||||||
sif::debug << "HealthHelper::informParent: sending health reply failed." << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,10 +86,7 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) {
|
|||||||
}
|
}
|
||||||
if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue()) !=
|
if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue()) !=
|
||||||
HasReturnvaluesIF::RETURN_OK) {
|
HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("handleSetHealthCommand: Object ID {:#010x} | Sending health reply failed\n",
|
||||||
sif::debug << "HealthHelper::handleHealthCommand: sending health "
|
objectId);
|
||||||
"reply failed."
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "fsfw/ipc/MutexFactory.h"
|
#include "fsfw/ipc/MutexFactory.h"
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
|
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
@ -27,6 +28,15 @@ ReturnValue_t HealthTable::registerObject(object_id_t object,
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t HealthTable::removeObject(object_id_t object) {
|
||||||
|
mapIterator = healthMap.find(object);
|
||||||
|
if (mapIterator == healthMap.end()) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
healthMap.erase(mapIterator);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) {
|
void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) {
|
||||||
MutexGuard(mutex, timeoutType, mutexTimeoutMs);
|
MutexGuard(mutex, timeoutType, mutexTimeoutMs);
|
||||||
HealthMap::iterator iter = healthMap.find(object);
|
HealthMap::iterator iter = healthMap.find(object);
|
||||||
@ -68,13 +78,7 @@ void HealthTable::printAll(uint8_t* pointer, size_t maxSize) {
|
|||||||
ReturnValue_t result =
|
ReturnValue_t result =
|
||||||
SerializeAdapter::serialize(&count, &pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
SerializeAdapter::serialize(&count, &pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGW("{}", "printAll: Serialization of health table failed\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "HealthTable::printAll: Serialization of health table failed" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("HealthTable::printAll: Serialization of health table failed\n");
|
|
||||||
#endif
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto& health : healthMap) {
|
for (const auto& health : healthMap) {
|
||||||
|
@ -17,6 +17,7 @@ class HealthTable : public HealthTableIF, public SystemObject {
|
|||||||
/** HealthTableIF overrides */
|
/** HealthTableIF overrides */
|
||||||
virtual ReturnValue_t registerObject(
|
virtual ReturnValue_t registerObject(
|
||||||
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) override;
|
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) override;
|
||||||
|
ReturnValue_t removeObject(object_id_t object) override;
|
||||||
virtual size_t getPrintSize() override;
|
virtual size_t getPrintSize() override;
|
||||||
virtual void printAll(uint8_t* pointer, size_t maxSize) override;
|
virtual void printAll(uint8_t* pointer, size_t maxSize) override;
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ class HealthTableIF : public ManagesHealthIF {
|
|||||||
virtual ReturnValue_t registerObject(
|
virtual ReturnValue_t registerObject(
|
||||||
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0;
|
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0;
|
||||||
|
|
||||||
|
virtual ReturnValue_t removeObject(object_id_t objectId) = 0;
|
||||||
|
|
||||||
virtual size_t getPrintSize() = 0;
|
virtual size_t getPrintSize() = 0;
|
||||||
virtual void printAll(uint8_t *pointer, size_t maxSize) = 0;
|
virtual void printAll(uint8_t *pointer, size_t maxSize) = 0;
|
||||||
|
|
||||||
|
@ -3,17 +3,15 @@
|
|||||||
#include "fsfw/datapool/PoolReadGuard.h"
|
#include "fsfw/datapool/PoolReadGuard.h"
|
||||||
#include "fsfw/ipc/MutexFactory.h"
|
#include "fsfw/ipc/MutexFactory.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
|
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(this) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
@ -36,17 +34,8 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
|||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
if (diagnosticPrintout) {
|
if (diagnosticPrintout) {
|
||||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("performOperation: Errors occured\nQueue {} | TM {} | Store {}\n", newQueueHits,
|
||||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
newTmHits, newStoreHits);
|
||||||
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
|
||||||
<< newStoreHits << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printDebug(
|
|
||||||
"InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
|
|
||||||
"| %lu\n",
|
|
||||||
static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
|
|
||||||
static_cast<unsigned int>(newStoreHits));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,7 +34,7 @@ class CommandMessageIF {
|
|||||||
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
||||||
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
||||||
//! Reply indicating that the current command was rejected,
|
//! Reply indicating that the current command was rejected,
|
||||||
//! Parameter 1 should contain the error code
|
//! par1 should contain the error code
|
||||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||||
|
|
||||||
virtual ~CommandMessageIF(){};
|
virtual ~CommandMessageIF(){};
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
MessageQueueMessage::MessageQueueMessage() : messageSize(getMinimumMessageSize()) {
|
MessageQueueMessage::MessageQueueMessage() : messageSize(getMinimumMessageSize()) {
|
||||||
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
||||||
@ -15,11 +15,7 @@ MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
|||||||
memcpy(this->getData(), data, size);
|
memcpy(this->getData(), data, size);
|
||||||
this->messageSize = this->HEADER_SIZE + size;
|
this->messageSize = this->HEADER_SIZE + size;
|
||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "ctor: Passed size larger than maximum allowed size! Setting content to 0\n");
|
||||||
sif::warning << "MessageQueueMessage: Passed size larger than maximum"
|
|
||||||
"allowed size! Setting content to 0"
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
||||||
this->messageSize = this->HEADER_SIZE;
|
this->messageSize = this->HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#ifndef FRAMEWORK_IPC_MUTEXGUARD_H_
|
#ifndef FRAMEWORK_IPC_MUTEXGUARD_H_
|
||||||
#define FRAMEWORK_IPC_MUTEXGUARD_H_
|
#define FRAMEWORK_IPC_MUTEXGUARD_H_
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
#include <fmt/core.h>
|
||||||
#include "MutexFactory.h"
|
|
||||||
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
class MutexGuard {
|
class MutexGuard {
|
||||||
public:
|
public:
|
||||||
@ -10,35 +12,17 @@ class MutexGuard {
|
|||||||
uint32_t timeoutMs = 0)
|
uint32_t timeoutMs = 0)
|
||||||
: internalMutex(mutex) {
|
: internalMutex(mutex) {
|
||||||
if (mutex == nullptr) {
|
if (mutex == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
// It's tricky to use the error functions defined in the service interface
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
// because those functions require the mutex guard themselves
|
||||||
sif::error << "MutexGuard: Passed mutex is invalid!" << std::endl;
|
fmt::print("ERROR | Passed mutex is invalid\n");
|
||||||
#else
|
|
||||||
sif::printError("MutexGuard: Passed mutex is invalid!\n");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
result = mutex->lockMutex(timeoutType, timeoutMs);
|
result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
if (result == MutexIF::MUTEX_TIMEOUT) {
|
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
fmt::print("ERROR | Lock of mutex failed with timeout of {} milliseconds\n", timeoutMs);
|
||||||
sif::error << "MutexGuard: Lock of mutex failed with timeout of " << timeoutMs
|
|
||||||
<< " milliseconds!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("MutexGuard: Lock of mutex failed with timeout of %lu milliseconds\n",
|
|
||||||
timeoutMs);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
|
|
||||||
} else if (result != HasReturnvaluesIF::RETURN_OK) {
|
} else if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
fmt::print("ERROR | Lock of Mutex failed with code {}\n", result);
|
||||||
sif::error << "MutexGuard: Lock of Mutex failed with code " << result << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("MutexGuard: Lock of Mutex failed with code %d\n", result);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t getLockResult() const { return result; }
|
ReturnValue_t getLockResult() const { return result; }
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "fsfw/memory/MemoryMessage.h"
|
#include "fsfw/memory/MemoryMessage.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serialize/EndianConverter.h"
|
#include "fsfw/serialize/EndianConverter.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue)
|
MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue)
|
||||||
: workOnThis(workOnThis),
|
: workOnThis(workOnThis),
|
||||||
@ -17,9 +17,7 @@ ReturnValue_t MemoryHelper::handleMemoryCommand(CommandMessage* message) {
|
|||||||
lastSender = message->getSender();
|
lastSender = message->getSender();
|
||||||
lastCommand = message->getCommand();
|
lastCommand = message->getCommand();
|
||||||
if (busy) {
|
if (busy) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("{}", "MemoryHelper: Busy\n");
|
||||||
sif::debug << "MemHelper: Busy!" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
switch (lastCommand) {
|
switch (lastCommand) {
|
||||||
case MemoryMessage::CMD_MEMORY_DUMP:
|
case MemoryMessage::CMD_MEMORY_DUMP:
|
||||||
|
@ -19,33 +19,32 @@ class HasModesIF {
|
|||||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
||||||
//! An object announces changing the mode. p1: target mode. p2: target submode
|
static const Event CHANGING_MODE =
|
||||||
static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO);
|
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
//!< p2: target submode
|
||||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
static const Event MODE_INFO = MAKE_EVENT(
|
||||||
|
1,
|
||||||
|
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||||
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||||
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||||
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
||||||
//! Indicates a bug or configuration failure: Object is in a mode it should never be in.
|
static const Event OBJECT_IN_INVALID_MODE =
|
||||||
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW);
|
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
//!< mode it should never be in.
|
||||||
//! p1: target mode. p2: target submode
|
static const Event FORCING_MODE = MAKE_EVENT(
|
||||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
static const Event MODE_CMD_REJECTED =
|
||||||
|
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
|
||||||
|
//!< called object id, Par2: return code.
|
||||||
|
|
||||||
//! The device is powered and ready to perform operations. In this mode, no commands are
|
static const Mode_t MODE_ON =
|
||||||
//! sent by the device handler itself, but direct commands van be commanded and will be
|
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||||
//! interpreted
|
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||||
static constexpr Mode_t MODE_ON = 1;
|
//!< interpreted
|
||||||
//! The device is powered off. The only command accepted in this mode is a mode change to on.
|
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||||
static constexpr Mode_t MODE_OFF = 0;
|
//!< this mode is a mode change to on.
|
||||||
|
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||||
static constexpr Mode_t MODE_INVALID = -1;
|
|
||||||
static constexpr Mode_t MODE_UNDEFINED = -2;
|
|
||||||
|
|
||||||
//! To avoid checks against magic number "0".
|
|
||||||
static const Submode_t SUBMODE_NONE = 0;
|
|
||||||
|
|
||||||
virtual ~HasModesIF() {}
|
virtual ~HasModesIF() {}
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
||||||
#include "fsfw/modes/HasModesIF.h"
|
#include "fsfw/modes/HasModesIF.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
ModeHelper::ModeHelper(HasModesIF* owner)
|
ModeHelper::ModeHelper(HasModesIF* owner)
|
||||||
: commandedMode(HasModesIF::MODE_OFF),
|
: commandedMode(HasModesIF::MODE_OFF),
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
#include "../serialize/SerialFixedArrayListAdapter.h"
|
#include "../serialize/SerialFixedArrayListAdapter.h"
|
||||||
#include "../serialize/SerialLinkedListAdapter.h"
|
#include "../serialize/SerialLinkedListAdapter.h"
|
||||||
#include "../serialize/SerializeElement.h"
|
#include "../serialize/SerializeElement.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "../timemanager/TimeStamperIF.h"
|
#include "../timemanager/TimeStamperIF.h"
|
||||||
#include "HasMonitorsIF.h"
|
#include "HasMonitorsIF.h"
|
||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "monitoringConf.h"
|
#include "monitoringConf.h"
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
@ -81,11 +81,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
timeStamper = ObjectManager::instance()->get<TimeStamperIF>(timeStamperId);
|
timeStamper = ObjectManager::instance()->get<TimeStamperIF>(timeStamperId);
|
||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGET("{}", "checkAndSetStamper: Stamper not found\n");
|
||||||
sif::error << "MonitoringReportContent::checkAndSetStamper: "
|
|
||||||
"Stamper not found!"
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "ObjectManager.h"
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -36,17 +36,10 @@ ReturnValue_t ObjectManager::insert(object_id_t id, SystemObjectIF* object) {
|
|||||||
// sif::debug << "ObjectManager::insert: Object " << std::hex
|
// sif::debug << "ObjectManager::insert: Object " << std::hex
|
||||||
// << (int)id << std::dec << " inserted." << std::endl;
|
// << (int)id << std::dec << " inserted." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return this->RETURN_OK;
|
return ObjectManager::RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGET("ObjectManager::insert: Object ID {:#010x} is already in use\nTerminating program\n",
|
||||||
sif::error << "ObjectManager::insert: Object ID " << std::hex << static_cast<uint32_t>(id)
|
static_cast<uint32_t>(id));
|
||||||
<< std::dec << " is already in use!" << std::endl;
|
|
||||||
sif::error << "Terminating program" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("ObjectManager::insert: Object ID 0x%08x is already in use!\n",
|
|
||||||
static_cast<unsigned int>(id));
|
|
||||||
sif::printError("Terminating program");
|
|
||||||
#endif
|
|
||||||
// This is very severe and difficult to handle in other places.
|
// This is very severe and difficult to handle in other places.
|
||||||
std::exit(INSERTION_FAILED);
|
std::exit(INSERTION_FAILED);
|
||||||
}
|
}
|
||||||
@ -61,10 +54,7 @@ ReturnValue_t ObjectManager::remove(object_id_t id) {
|
|||||||
#endif
|
#endif
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("removeObject: Requested object {:#010x} not found\n", id);
|
||||||
sif::error << "ObjectManager::removeObject: Requested object " << std::hex << (int)id
|
|
||||||
<< std::dec << " not found." << std::endl;
|
|
||||||
#endif
|
|
||||||
return NOT_FOUND;
|
return NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,67 +69,44 @@ SystemObjectIF* ObjectManager::getSystemObject(object_id_t id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::initialize() {
|
void ObjectManager::initialize() {
|
||||||
if (objectFactoryFunction == nullptr) {
|
if (objectFactoryFunction != nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
objectFactoryFunction(factoryArgs);
|
||||||
sif::error << "ObjectManager::initialize: Passed produceObjects "
|
|
||||||
"functions is nullptr!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("ObjectManager::initialize: Passed produceObjects functions is nullptr!\n");
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
objectFactoryFunction(factoryArgs);
|
|
||||||
ReturnValue_t result = RETURN_FAILED;
|
ReturnValue_t result = RETURN_FAILED;
|
||||||
uint32_t errorCount = 0;
|
uint32_t errorCount = 0;
|
||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
result = it.second->initialize();
|
result = it.second->initialize();
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
object_id_t var = it.first;
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("initialize: Object {:#010x} failed to initialize with code {:#06x}\n", var,
|
||||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
result);
|
||||||
<< std::setfill('0') << it.first << " failed to initialize with code 0x" << result
|
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError(
|
|
||||||
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var,
|
|
||||||
it.first);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("{}", "initialize: Counted failed initializations\n");
|
||||||
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
|
||||||
<< " failed initializations." << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// Init was successful. Now check successful interconnections.
|
// Init was successful. Now check successful interconnections.
|
||||||
errorCount = 0;
|
errorCount = 0;
|
||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
result = it.second->checkObjectConnections();
|
result = it.second->checkObjectConnections();
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("initialize: Object {:#010x} connection check failed with code {:#06x}\n", it.first,
|
||||||
sif::error << "ObjectManager::ObjectManager: Object 0x" << std::hex << (int)it.first
|
result);
|
||||||
<< " connection check failed with code 0x" << result << std::dec << std::endl;
|
|
||||||
#endif
|
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("{}", "ObjectManager::ObjectManager: Counted {} failed connection checks\n",
|
||||||
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
errorCount);
|
||||||
<< " failed connection checks." << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::printList() {
|
void ObjectManager::printList() {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "ObjectManager: Object List contains:" << std::endl;
|
sif::info("ObjectManager: Object List contains:\n");
|
||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
sif::debug << std::hex << it.first << " | " << it.second << std::endl;
|
sif::info("{:#010x} | {:#010x}\n", it.first, fmt::ptr(it.second));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#define FSFW_OBJECTMANAGER_OBJECTMANAGERIF_H_
|
#define FSFW_OBJECTMANAGER_OBJECTMANAGERIF_H_
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "SystemObjectIF.h"
|
#include "SystemObjectIF.h"
|
||||||
#include "frameworkObjects.h"
|
#include "frameworkObjects.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class provides an interface to the global object manager.
|
* @brief This class provides an interface to the global object manager.
|
||||||
|
@ -16,9 +16,7 @@ elseif(FSFW_OSAL MATCHES "host")
|
|||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
message(
|
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
||||||
WARNING
|
|
||||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
|
||||||
# Not set. Assumuing this is a host build, try to determine host OS
|
# Not set. Assumuing this is a host build, try to determine host OS
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/osal/common/TcpTmTcBridge.h"
|
#include "fsfw/osal/common/TcpTmTcBridge.h"
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
|
|
||||||
@ -21,17 +21,13 @@ TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, ob
|
|||||||
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
|
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
// Connection is always up, TM is requested by connecting to server and receiving packets
|
// Connection is always up, TM is requested by connecting to server and receiving packets
|
||||||
registerCommConnect();
|
TmTcBridge::registerCommConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t TcpTmTcBridge::initialize() {
|
ReturnValue_t TcpTmTcBridge::initialize() {
|
||||||
ReturnValue_t result = TmTcBridge::initialize();
|
ReturnValue_t result = TmTcBridge::initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("TcpTmTcBridge::initialize: TmTcBridge initialization failed\n");
|
||||||
sif::error << "TcpTmTcBridge::initialize: TmTcBridge initialization failed!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("TcpTmTcBridge::initialize: TmTcBridge initialization failed!\n");
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
#include "fsfw/tmtcservices/SpacePacketParser.h"
|
#include "fsfw/tmtcservices/SpacePacketParser.h"
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
@ -56,11 +56,7 @@ ReturnValue_t TcpTmTcServer::initialize() {
|
|||||||
}
|
}
|
||||||
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||||
if (tcStore == nullptr) {
|
if (tcStore == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("TcpTmTcServer::initialize: TC store uninitialized\n");
|
||||||
sif::error << "TcpTmTcServer::initialize: TC store uninitialized!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("TcpTmTcServer::initialize: TC store uninitialized!\n");
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,11 +201,7 @@ void TcpTmTcServer::handleServerOperation(socket_t& connSocket) {
|
|||||||
|
|
||||||
ReturnValue_t TcpTmTcServer::handleTcReception(uint8_t* spacePacket, size_t packetSize) {
|
ReturnValue_t TcpTmTcServer::handleTcReception(uint8_t* spacePacket, size_t packetSize) {
|
||||||
if (wiretappingEnabled) {
|
if (wiretappingEnabled) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGI("Received TC:\n");
|
||||||
sif::info << "Received TC:" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printInfo("Received TC:\n");
|
|
||||||
#endif
|
|
||||||
arrayprinter::print(spacePacket, packetSize);
|
arrayprinter::print(spacePacket, packetSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,17 +211,7 @@ ReturnValue_t TcpTmTcServer::handleTcReception(uint8_t* spacePacket, size_t pack
|
|||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
ReturnValue_t result = tcStore->addData(&storeId, spacePacket, packetSize);
|
ReturnValue_t result = tcStore->addData(&storeId, spacePacket, packetSize);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGWT("handleTcReception: Data storage with packet size {} failed\n", packetSize);
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "TcpTmTcServer::handleServerOperation: Data storage with packet size"
|
|
||||||
<< packetSize << " failed" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"TcpTmTcServer::handleServerOperation: Data storage with packet size %d "
|
|
||||||
"failed\n",
|
|
||||||
packetSize);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,17 +219,7 @@ ReturnValue_t TcpTmTcServer::handleTcReception(uint8_t* spacePacket, size_t pack
|
|||||||
|
|
||||||
result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
|
result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGWT("handleTcReception: Sending message to queue failed\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "TcpTmTcServer::handleServerOperation: "
|
|
||||||
" Sending message to queue failed"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"TcpTmTcServer::handleServerOperation: "
|
|
||||||
" Sending message to queue failed\n");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
tcStore->deleteData(storeId);
|
tcStore->deleteData(storeId);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -277,11 +249,7 @@ ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (wiretappingEnabled) {
|
if (wiretappingEnabled) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGI("Sending TM:");
|
||||||
sif::info << "Sending TM:" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printInfo("Sending TM:\n");
|
|
||||||
#endif
|
|
||||||
arrayprinter::print(storeAccessor.data(), storeAccessor.size());
|
arrayprinter::print(storeAccessor.data(), storeAccessor.size());
|
||||||
}
|
}
|
||||||
ssize_t retval = send(connSocket, reinterpret_cast<const char*>(storeAccessor.data()),
|
ssize_t retval = send(connSocket, reinterpret_cast<const char*>(storeAccessor.data()),
|
||||||
@ -306,31 +274,14 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) {
|
|||||||
size_t readAmount = availableReadData;
|
size_t readAmount = availableReadData;
|
||||||
lastRingBufferSize = availableReadData;
|
lastRingBufferSize = availableReadData;
|
||||||
if (readAmount >= ringBuffer.getMaxSize()) {
|
if (readAmount >= ringBuffer.getMaxSize()) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
// Possible configuration error, too much data or/and data coming in too fast,
|
// Possible configuration error, too much data or/and data coming in too fast,
|
||||||
// requiring larger buffers
|
// requiring larger buffers
|
||||||
sif::warning << "TcpTmTcServer::handleServerOperation: Ring buffer reached "
|
FSFW_LOGWT("handleTcRingBufferData: Ring buffer reached fill count\n");
|
||||||
<< "fill count" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"TcpTmTcServer::handleServerOperation: Ring buffer reached "
|
|
||||||
"fill count");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (readAmount >= receptionBuffer.size()) {
|
if (readAmount >= receptionBuffer.size()) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
// Possible configuration error, too much data or/and data coming in too fast,
|
// Possible configuration error, too much data or/and data coming in too fast,
|
||||||
// requiring larger buffers
|
// requiring larger buffers
|
||||||
sif::warning << "TcpTmTcServer::handleServerOperation: "
|
FSFW_LOGWT("handleTcRingBufferData: Reception buffer too small\n");
|
||||||
"Reception buffer too small "
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("TcpTmTcServer::handleServerOperation: Reception buffer too small\n");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
readAmount = receptionBuffer.size();
|
readAmount = receptionBuffer.size();
|
||||||
}
|
}
|
||||||
ringBuffer.readData(receptionBuffer.data(), readAmount, true);
|
ringBuffer.readData(receptionBuffer.data(), readAmount, true);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/osal/common/tcpipHelpers.h"
|
#include "fsfw/osal/common/tcpipHelpers.h"
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
@ -51,9 +51,7 @@ UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBrid
|
|||||||
receptionFlags, &senderAddress, &senderAddressSize);
|
receptionFlags, &senderAddress, &senderAddressSize);
|
||||||
if (bytesReceived == SOCKET_ERROR) {
|
if (bytesReceived == SOCKET_ERROR) {
|
||||||
/* Handle error */
|
/* Handle error */
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("performOperation: Reception error\n");
|
||||||
sif::error << "UdpTcPollingTask::performOperation: Reception error." << std::endl;
|
|
||||||
#endif
|
|
||||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000);
|
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -81,12 +79,7 @@ ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
|
|||||||
|
|
||||||
ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead);
|
ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGWT("handleSuccessfullTcRead: Data storage failed. Packet size {}\n", bytesRead);
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "UdpTcPollingTask::transferPusToSoftwareBus: Data storage failed." << std::endl;
|
|
||||||
sif::warning << "Packet size: " << bytesRead << std::endl;
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,13 +87,7 @@ ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
|
|||||||
|
|
||||||
result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
|
result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
FSFW_LOGWT("handleSuccessfullTcRead: Sending message to queue failed\n");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "UdpTcPollingTask::handleSuccessfullTcRead: "
|
|
||||||
" Sending message to queue failed"
|
|
||||||
<< std::endl;
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
tcStore->deleteData(storeId);
|
tcStore->deleteData(storeId);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -109,17 +96,13 @@ ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
|
|||||||
ReturnValue_t UdpTcPollingTask::initialize() {
|
ReturnValue_t UdpTcPollingTask::initialize() {
|
||||||
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||||
if (tcStore == nullptr) {
|
if (tcStore == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("initialize: TC store uninitialized\n");
|
||||||
sif::error << "UdpTcPollingTask::initialize: TC store uninitialized!" << std::endl;
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmtcBridge = ObjectManager::instance()->get<UdpTmTcBridge>(tmtcBridgeId);
|
tmtcBridge = ObjectManager::instance()->get<UdpTmTcBridge>(tmtcBridgeId);
|
||||||
if (tmtcBridge == nullptr) {
|
if (tmtcBridge == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("initialize: Invalid TMTC bridge object\n");
|
||||||
sif::error << "UdpTcPollingTask::initialize: Invalid TMTC bridge object!" << std::endl;
|
|
||||||
#endif
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,11 +141,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) {
|
|||||||
tval = timevalOperations::toTimeval(timeoutSeconds);
|
tval = timevalOperations::toTimeval(timeoutSeconds);
|
||||||
int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout));
|
int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout));
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGW("setTimeout: Setting receive timeout failed with {} | {}", errno, strerror(errno));
|
||||||
sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting "
|
|
||||||
"receive timeout failed with "
|
|
||||||
<< strerror(errno) << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/osal/common/tcpipHelpers.h"
|
#include "fsfw/osal/common/tcpipHelpers.h"
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
@ -36,13 +36,11 @@ UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
|||||||
ReturnValue_t UdpTmTcBridge::initialize() {
|
ReturnValue_t UdpTmTcBridge::initialize() {
|
||||||
ReturnValue_t result = TmTcBridge::initialize();
|
ReturnValue_t result = TmTcBridge::initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGE("initialize: TmTcBridge initialization failed\n");
|
||||||
sif::error << "UdpTmTcBridge::initialize: TmTcBridge initialization failed!" << std::endl;
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef PLATFORM_WIN
|
||||||
/* Initiates Winsock DLL. */
|
/* Initiates Winsock DLL. */
|
||||||
WSAData wsaData;
|
WSAData wsaData;
|
||||||
WORD wVersionRequested = MAKEWORD(2, 2);
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
@ -120,9 +118,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
|||||||
ssize_t bytesSent = sendto(serverSocket, reinterpret_cast<const char *>(data), dataLen, flags,
|
ssize_t bytesSent = sendto(serverSocket, reinterpret_cast<const char *>(data), dataLen, flags,
|
||||||
&clientAddress, clientAddressLen);
|
&clientAddress, clientAddressLen);
|
||||||
if (bytesSent == SOCKET_ERROR) {
|
if (bytesSent == SOCKET_ERROR) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
FSFW_LOGWT("sendTm: Send operation failed\n");
|
||||||
sif::warning << "TmTcUdpBridge::sendTm: Send operation failed." << std::endl;
|
|
||||||
#endif
|
|
||||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
|
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
|
||||||
}
|
}
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include "fsfw/osal/common/tcpipCommon.h"
|
#include "fsfw/osal/common/tcpipCommon.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
@ -48,28 +50,20 @@ void tcpip::printAddress(struct sockaddr *addr) {
|
|||||||
const char *stringPtr = NULL;
|
const char *stringPtr = NULL;
|
||||||
switch (addr->sa_family) {
|
switch (addr->sa_family) {
|
||||||
case AF_INET: {
|
case AF_INET: {
|
||||||
struct sockaddr_in *addrIn = reinterpret_cast<struct sockaddr_in *>(addr);
|
auto *addrIn = reinterpret_cast<struct sockaddr_in *>(addr);
|
||||||
stringPtr = inet_ntop(AF_INET, &(addrIn->sin_addr), ipAddress, INET_ADDRSTRLEN);
|
stringPtr = inet_ntop(AF_INET, &(addrIn->sin_addr), ipAddress, INET_ADDRSTRLEN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AF_INET6: {
|
case AF_INET6: {
|
||||||
struct sockaddr_in6 *addrIn = reinterpret_cast<struct sockaddr_in6 *>(addr);
|
auto *addrIn = reinterpret_cast<struct sockaddr_in6 *>(addr);
|
||||||
stringPtr = inet_ntop(AF_INET6, &(addrIn->sin6_addr), ipAddress, INET6_ADDRSTRLEN);
|
stringPtr = inet_ntop(AF_INET6, &(addrIn->sin6_addr), ipAddress, INET6_ADDRSTRLEN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
if (stringPtr == nullptr) {
|
||||||
if (stringPtr == NULL) {
|
FSFW_LOGDT("Could not convert IP address to text representation, error code {} | {}", errno,
|
||||||
sif::debug << "Could not convert IP address to text representation, error code " << errno
|
strerror(errno));
|
||||||
<< std::endl;
|
|
||||||
} else {
|
} else {
|
||||||
sif::debug << "IP Address Sender: " << ipAddress << std::endl;
|
FSFW_LOGDT("IP Address Sender {}\n", ipAddress);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (stringPtr == NULL) {
|
|
||||||
sif::printDebug("Could not convert IP address to text representation, error code %d\n", errno);
|
|
||||||
} else {
|
|
||||||
sif::printDebug("IP Address Sender: %s\n", ipAddress);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "fsfw/osal/freertos/BinSemaphUsingTask.h"
|
#include "fsfw/osal/freertos/BinSemaphUsingTask.h"
|
||||||
|
|
||||||
#include "fsfw/osal/freertos/TaskManagement.h"
|
#include "fsfw/osal/freertos/TaskManagement.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || tskKERNEL_VERSION_MAJOR > 8
|
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || tskKERNEL_VERSION_MAJOR > 8
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "fsfw/osal/freertos/BinarySemaphore.h"
|
#include "fsfw/osal/freertos/BinarySemaphore.h"
|
||||||
|
|
||||||
#include "fsfw/osal/freertos/TaskManagement.h"
|
#include "fsfw/osal/freertos/TaskManagement.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
BinarySemaphore::BinarySemaphore() {
|
BinarySemaphore::BinarySemaphore() {
|
||||||
handle = xSemaphoreCreateBinary();
|
handle = xSemaphoreCreateBinary();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "fsfw/osal/freertos/CountingSemaphUsingTask.h"
|
#include "fsfw/osal/freertos/CountingSemaphUsingTask.h"
|
||||||
|
|
||||||
#include "fsfw/osal/freertos/TaskManagement.h"
|
#include "fsfw/osal/freertos/TaskManagement.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || tskKERNEL_VERSION_MAJOR > 8
|
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || tskKERNEL_VERSION_MAJOR > 8
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "fsfw/osal/freertos/TaskManagement.h"
|
#include "fsfw/osal/freertos/TaskManagement.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "semphr.h"
|
#include "semphr.h"
|
||||||
|
|
||||||
// Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in
|
// Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user