Compare commits
54 Commits
cfdbe0f6cb
...
meier/upst
Author | SHA1 | Date | |
---|---|---|---|
b96f5a2552 | |||
9a2e68b37e | |||
91067cde98 | |||
428018e4f1 | |||
6e5239e9a0 | |||
78b09ed0c9 | |||
fdf35232ee | |||
8465670374 | |||
3b23fb77b4 | |||
6f7be281ef | |||
ec8e5cc123 | |||
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 | |||
![]() |
298f764298 | ||
![]() |
2e76250209 | ||
3e9ae62b28 | |||
21eb386f3c | |||
ade36e65c6 | |||
103661facc | |||
ae2f7219fd | |||
4fba2704aa | |||
161dbde0d7 | |||
2fa4fd61d0 | |||
bf673c56c6 | |||
![]() |
1611a4e1f0 | ||
![]() |
7afe30ea88 | ||
![]() |
0aee86442e | ||
![]() |
951c077abc | ||
![]() |
adfefdd93f |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,8 +10,5 @@
|
||||
.settings
|
||||
.metadata
|
||||
|
||||
# VSCode
|
||||
.vscode
|
||||
|
||||
/build*
|
||||
/cmake-build*
|
||||
|
23
CHANGELOG.md
23
CHANGELOG.md
@@ -19,12 +19,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Bump C++ required version to C++17. Every project which uses the FSFW and every modern
|
||||
compiler supports it
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/622
|
||||
- HAL Linux SPI: Set the Clock Default State when setting new SPI speed
|
||||
and mode
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/573
|
||||
- GPIO HAL: `Direction`, `GpioOperation` and `Levels` are enum classes now, which prevents
|
||||
name clashes with Windows defines.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||
- New CMake option `FSFW_HAL_LINUX_ADD_LIBGPIOD` to specifically exclude `gpiod` code.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
||||
@@ -46,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
|
||||
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
|
||||
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
|
||||
|
||||
@@ -120,6 +117,8 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||
|
||||
## 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
|
||||
whether it is running in CI/CD
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/623
|
||||
@@ -139,6 +138,7 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||
Easiest solution for now: Keep this option OFF by default.
|
||||
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
|
||||
inside `fsfw/version.h`
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||
@@ -153,17 +153,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||
- `Subsystem`: New API to add table and sequence entries
|
||||
|
||||
## HAL
|
||||
|
||||
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
||||
lot more sense because each ComIF should be responsible for one SPI bus.
|
||||
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
||||
it is not automatically called when calling the setter function for SPI speed and mode.
|
||||
The user should call this function after locking the CS mutex if multiple SPI devices with
|
||||
differing speeds and modes are attached to one bus.
|
||||
- SPI: Getter functions for SPI speed and mode.
|
||||
- I2C: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1.
|
||||
|
||||
## Fixed
|
||||
|
||||
- TCP TMTC Server: `MutexGuard` was not created properly in
|
||||
|
@@ -67,6 +67,7 @@ endif()
|
||||
set(FSFW_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw")
|
||||
|
||||
set(FSFW_ETL_LIB_NAME etl)
|
||||
set(FSFW_ETL_LINK_TARGET etl::etl)
|
||||
set(FSFW_ETL_LIB_MAJOR_VERSION
|
||||
20
|
||||
CACHE STRING "ETL library major version requirement")
|
||||
@@ -103,11 +104,11 @@ if(FSFW_GENERATE_SECTIONS)
|
||||
option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON)
|
||||
endif()
|
||||
|
||||
option(FSFW_BUILD_UNITTESTS
|
||||
option(FSFW_BUILD_TESTS
|
||||
"Build unittest binary in addition to static library" OFF)
|
||||
option(FSFW_CICD_BUILD "Build for CI/CD. This can disable problematic test" OFF)
|
||||
option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF)
|
||||
if(FSFW_BUILD_UNITTESTS)
|
||||
if(FSFW_BUILD_TESTS)
|
||||
option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON)
|
||||
endif()
|
||||
|
||||
@@ -139,7 +140,7 @@ if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||
TRUE)
|
||||
endif()
|
||||
|
||||
if(FSFW_BUILD_UNITTESTS)
|
||||
if(FSFW_BUILD_TESTS)
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||
@@ -162,10 +163,9 @@ if(FSFW_BUILD_UNITTESTS)
|
||||
list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2)
|
||||
endif()
|
||||
|
||||
set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg)
|
||||
configure_file(tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
||||
configure_file(tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in
|
||||
tests/TestsConfig.h)
|
||||
set(FSFW_CONFIG_PATH unittests/testcfg)
|
||||
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
||||
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
||||
|
||||
project(${FSFW_TEST_TGT} CXX C)
|
||||
add_executable(${FSFW_TEST_TGT})
|
||||
@@ -183,18 +183,15 @@ if(FSFW_BUILD_UNITTESTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} Finding and/or providing etl library with version ${FSFW_ETL_LIB_MAJOR_VERSION}"
|
||||
)
|
||||
message(STATUS "${MSG_PREFIX} Finding and/or providing ETL library")
|
||||
|
||||
# Check whether the user has already installed ETL first
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET)
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
# Not installed, so use FetchContent to download and provide etl
|
||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
message(
|
||||
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")
|
||||
include(FetchContent)
|
||||
|
||||
@@ -284,16 +281,15 @@ message(
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(tests)
|
||||
if(FSFW_ADD_HAL)
|
||||
add_subdirectory(hal)
|
||||
endif()
|
||||
add_subdirectory(contrib)
|
||||
if(FSFW_BUILD_TESTS)
|
||||
add_subdirectory(unittests)
|
||||
endif()
|
||||
if(FSFW_BUILD_DOCS)
|
||||
add_subdirectory(docs)
|
||||
endif()
|
||||
|
||||
if(FSFW_BUILD_UNITTESTS)
|
||||
if(FSFW_BUILD_TESTS)
|
||||
if(FSFW_TESTS_GEN_COV)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
include(CodeCoverage)
|
||||
@@ -450,8 +446,8 @@ target_include_directories(
|
||||
target_compile_options(${LIB_FSFW_NAME} PRIVATE ${FSFW_WARNING_FLAGS}
|
||||
${COMPILER_FLAGS})
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${FSFW_ETL_LINK_TARGET}
|
||||
${FSFW_ADDITIONAL_LINK_LIBS})
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${FSFW_ADDITIONAL_LINK_LIBS})
|
||||
target_link_libraries(${LIB_FSFW_NAME} PUBLIC ${FSFW_ETL_LINK_TARGET})
|
||||
|
||||
string(
|
||||
CONCAT
|
||||
|
@@ -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`
|
||||
[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
|
||||
|
||||
```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
|
||||
`.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
|
||||
|
||||
|
@@ -12,3 +12,9 @@ RUN git clone https://github.com/catchorg/Catch2.git && \
|
||||
git checkout v3.0.0-preview5 && \
|
||||
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||
cmake --build build/ --target install
|
||||
|
||||
RUN git clone https://github.com/ETLCPP/etl.git && \
|
||||
cd etl && \
|
||||
git checkout 20.28.0 && \
|
||||
cmake -B build . && \
|
||||
cmake --install build/
|
||||
|
4
automation/Jenkinsfile
vendored
4
automation/Jenkinsfile
vendored
@@ -3,7 +3,7 @@ pipeline {
|
||||
BUILDDIR = 'build-tests'
|
||||
}
|
||||
agent {
|
||||
docker { image 'fsfw-ci:d2'}
|
||||
docker { image 'fsfw-ci:d3'}
|
||||
}
|
||||
stages {
|
||||
stage('Clean') {
|
||||
@@ -14,7 +14,7 @@ pipeline {
|
||||
stage('Configure') {
|
||||
steps {
|
||||
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;
|
||||
};
|
@@ -3,12 +3,6 @@ if [[ ! -f README.md ]]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
folder_list=(
|
||||
"./src"
|
||||
"./hal"
|
||||
"./tests"
|
||||
)
|
||||
|
||||
cmake_fmt="cmake-format"
|
||||
file_selectors="-iname CMakeLists.txt"
|
||||
if command -v ${cmake_fmt} &> /dev/null; then
|
||||
@@ -21,10 +15,9 @@ fi
|
||||
cpp_format="clang-format"
|
||||
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
||||
if command -v ${cpp_format} &> /dev/null; then
|
||||
for dir in ${folder_list[@]}; do
|
||||
echo "Auto-formatting ${dir} recursively"
|
||||
find ${dir} ${file_selectors} | xargs clang-format --style=file -i
|
||||
done
|
||||
find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
find ./hal ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
find ./tests ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
else
|
||||
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
||||
fi
|
||||
|
@@ -48,6 +48,20 @@ def main():
|
||||
action="store_true",
|
||||
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()
|
||||
if args.all:
|
||||
@@ -115,14 +129,14 @@ def handle_tests_type(args, build_dir_list: list):
|
||||
if args.create:
|
||||
if os.path.exists(UNITTEST_FOLDER_NAME):
|
||||
shutil.rmtree(UNITTEST_FOLDER_NAME)
|
||||
create_tests_build_cfg()
|
||||
create_tests_build_cfg(args)
|
||||
build_directory = UNITTEST_FOLDER_NAME
|
||||
elif len(build_dir_list) == 0:
|
||||
print(
|
||||
"No valid CMake tests build directory found. "
|
||||
"Trying to set up test build system"
|
||||
)
|
||||
create_tests_build_cfg()
|
||||
create_tests_build_cfg(args)
|
||||
build_directory = UNITTEST_FOLDER_NAME
|
||||
elif len(build_dir_list) == 1:
|
||||
build_directory = build_dir_list[0]
|
||||
@@ -147,10 +161,15 @@ def handle_tests_type(args, build_dir_list: list):
|
||||
os.chdir("..")
|
||||
|
||||
|
||||
def create_tests_build_cfg():
|
||||
def create_tests_build_cfg(args):
|
||||
os.mkdir(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("..")
|
||||
|
||||
|
||||
|
@@ -4,3 +4,8 @@ target_include_directories(${LIB_FSFW_NAME}
|
||||
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_subdirectory(fsfw)
|
||||
if(FSFW_ADD_HAL)
|
||||
add_subdirectory(fsfw_hal)
|
||||
endif()
|
||||
|
||||
add_subdirectory(fsfw_tests)
|
||||
|
@@ -15,7 +15,6 @@ add_subdirectory(globalfunctions)
|
||||
add_subdirectory(health)
|
||||
add_subdirectory(housekeeping)
|
||||
add_subdirectory(internalerror)
|
||||
add_subdirectory(introspection)
|
||||
add_subdirectory(ipc)
|
||||
add_subdirectory(memory)
|
||||
add_subdirectory(modes)
|
||||
|
@@ -1,62 +0,0 @@
|
||||
#include "Action.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#undef Action
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
Action::Action() {}
|
||||
|
||||
void Action::setEnum(EnumIF *theEnum) {
|
||||
id = theEnum->getValue();
|
||||
name = theEnum->getDescription();
|
||||
}
|
||||
|
||||
const char *Action::getName() { return name; }
|
||||
#else
|
||||
Action::Action(ActionId_t id) : id(id) {}
|
||||
#endif
|
||||
ActionId_t Action::getId() { return id; }
|
||||
|
||||
void Action::registerParameter(ParameterIF *parameter) { parameterList.push_back(parameter); }
|
||||
|
||||
std::vector<ParameterIF *> const *Action::getParameters() const { return ¶meterList; }
|
||||
|
||||
size_t Action::getSerializedSize() const {
|
||||
size_t size = SerializeAdapter::getSerializedSize(&id);
|
||||
for (auto parameter : *getParameters()) {
|
||||
size += parameter->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
ReturnValue_t Action::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
for (auto parameter : *getParameters()) {
|
||||
result = parameter->serialize(buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Action::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;/* TODO not needed as must have been read before to find this action = SerializeAdapter::deSerialize(&id, buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}*/
|
||||
for (auto parameter : *getParameters()) {
|
||||
result = parameter->deSerialize(buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
#include "ActionMessage.h"
|
||||
#include "ParameterIF.h"
|
||||
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#include "../introspection/Enum.h"
|
||||
#endif
|
||||
|
||||
class Action: public SerializeIF {
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
Action();
|
||||
void setEnum(EnumIF* id);
|
||||
const char *getName();
|
||||
#else
|
||||
Action(ActionId_t id);
|
||||
#endif
|
||||
ActionId_t getId();
|
||||
|
||||
MessageQueueId_t commandedBy;
|
||||
|
||||
[[nodiscard]] virtual ReturnValue_t handle() = 0;
|
||||
|
||||
void registerParameter(ParameterIF *parameter);
|
||||
|
||||
std::vector<ParameterIF *> const *getParameters() const;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
private:
|
||||
ActionId_t id;
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
const char *name;
|
||||
#endif
|
||||
std::vector<ParameterIF *> parameterList;
|
||||
};
|
@@ -6,7 +6,7 @@
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||
: owner(setOwner), queueToUse(useThisQueue) {}
|
||||
|
||||
ActionHelper::~ActionHelper() {}
|
||||
ActionHelper::~ActionHelper() = default;
|
||||
|
||||
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||
@@ -57,40 +57,18 @@ void ActionHelper::finish(bool success, MessageQueueId_t reportTo, ActionId_t co
|
||||
|
||||
void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = NULL;
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
auto actionIter = actionMap.find(actionId);
|
||||
if (actionIter == actionMap.end()){
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_ACTION_ID);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
Action* action = actionIter->second;
|
||||
result = action->deSerialize(&dataPtr, &size, SerializeIF::Endianness::NETWORK);
|
||||
if ((result != HasReturnvaluesIF::RETURN_OK) || (size != 0)){ //TODO write unittest for second condition
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_PARAMETERS);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
//TODO call action->check()
|
||||
action->commandedBy = commandedBy;
|
||||
result = owner->executeAction(action);
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
if (result == HasActionsIF::EXECUTION_FINISHED) {
|
||||
CommandMessage reply;
|
||||
@@ -185,11 +163,3 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ActionHelper::registerAction(Action* action) {
|
||||
//TODO error handling
|
||||
ActionId_t id = action->getId();
|
||||
actionMap.emplace(id, action);
|
||||
}
|
||||
|
||||
std::map<ActionId_t, Action*> const* ActionHelper::getActionMap() { return &actionMap; }
|
@@ -1,11 +1,9 @@
|
||||
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||
|
||||
#include <map>
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "Action.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
/**
|
||||
* @brief Action Helper is a helper class which handles action messages
|
||||
*
|
||||
@@ -100,10 +98,6 @@ class ActionHelper {
|
||||
*/
|
||||
void setQueueToUse(MessageQueueIF* queue);
|
||||
|
||||
void registerAction(Action* action);
|
||||
|
||||
std::map<ActionId_t, Action*> const* getActionMap();
|
||||
|
||||
protected:
|
||||
//! Increase of value of this per step
|
||||
static const uint8_t STEP_OFFSET = 1;
|
||||
@@ -114,8 +108,6 @@ class ActionHelper {
|
||||
MessageQueueIF* queueToUse;
|
||||
//! Pointer to an IPC Store, initialized during construction or
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
//! Map of all implemented Actions
|
||||
std::map<ActionId_t, Action*> actionMap;
|
||||
|
||||
/**
|
||||
* Internal function called by handleActionMessage
|
||||
|
@@ -2,9 +2,9 @@
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
ActionMessage::ActionMessage() {}
|
||||
ActionMessage::ActionMessage() = default;
|
||||
|
||||
ActionMessage::~ActionMessage() {}
|
||||
ActionMessage::~ActionMessage() = default;
|
||||
|
||||
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
||||
store_address_t parameters) {
|
||||
@@ -64,9 +64,8 @@ void ActionMessage::clear(CommandMessage* message) {
|
||||
switch (message->getCommand()) {
|
||||
case EXECUTE_ACTION:
|
||||
case DATA_REPLY: {
|
||||
StorageManagerIF* ipcStore =
|
||||
ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore != NULL) {
|
||||
auto* ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore != nullptr) {
|
||||
ipcStore->deleteData(getStoreId(message));
|
||||
}
|
||||
break;
|
||||
|
@@ -1,3 +1,3 @@
|
||||
target_sources(
|
||||
${LIB_FSFW_NAME} PRIVATE Action.cpp ActionHelper.cpp ActionMessage.cpp
|
||||
${LIB_FSFW_NAME} PRIVATE ActionHelper.cpp ActionMessage.cpp
|
||||
CommandActionHelper.cpp SimpleActionHelper.cpp)
|
||||
|
@@ -2,14 +2,14 @@
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
|
||||
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,
|
||||
SerializeIF *data) {
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == nullptr) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
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,
|
||||
const uint8_t *data, uint32_t size) {
|
||||
// if (commandCount != 0) {
|
||||
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
||||
// }
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == nullptr) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
@@ -59,12 +56,12 @@ ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionI
|
||||
|
||||
ReturnValue_t CommandActionHelper::initialize() {
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == NULL) {
|
||||
if (ipcStore == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
queueToUse = owner->getCommandQueuePtr();
|
||||
if (queueToUse == NULL) {
|
||||
if (queueToUse == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
@@ -104,7 +101,7 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
||||
uint8_t CommandActionHelper::getCommandCount() const { return commandCount; }
|
||||
|
||||
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
||||
const uint8_t *data = NULL;
|
||||
const uint8_t *data = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@@ -14,14 +14,14 @@ class CommandActionHelper {
|
||||
friend class CommandsActionsIF;
|
||||
|
||||
public:
|
||||
CommandActionHelper(CommandsActionsIF* owner);
|
||||
explicit CommandActionHelper(CommandsActionsIF* owner);
|
||||
virtual ~CommandActionHelper();
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
const uint8_t* data = nullptr, uint32_t size = 0);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
||||
uint32_t size);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||
ReturnValue_t initialize();
|
||||
ReturnValue_t handleReply(CommandMessage* reply);
|
||||
uint8_t getCommandCount() const;
|
||||
[[nodiscard]] uint8_t getCommandCount() const;
|
||||
|
||||
private:
|
||||
CommandsActionsIF* owner;
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#ifndef FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||
#define FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "CommandActionHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* 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 ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||
virtual ~CommandsActionsIF() {}
|
||||
virtual ~CommandsActionsIF() = default;
|
||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||
|
||||
protected:
|
||||
|
@@ -1,11 +1,11 @@
|
||||
#ifndef FSFW_ACTION_HASACTIONSIF_H_
|
||||
#define FSFW_ACTION_HASACTIONSIF_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "ActionHelper.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
@@ -40,15 +40,12 @@ class HasActionsIF {
|
||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||
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
|
||||
* @return MessageQueueId_t of the object
|
||||
*
|
||||
*/
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
virtual ActionHelper* getActionHelper() = 0;
|
||||
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
/**
|
||||
* Execute or initialize the execution of a certain function.
|
||||
* The ActionHelpers will execute this function and behave differently
|
||||
@@ -58,7 +55,8 @@ class HasActionsIF {
|
||||
* -@c EXECUTION_FINISHED Finish reply will be generated
|
||||
* -@c Not RETURN_OK Step failure reply will be generated
|
||||
*/
|
||||
virtual ReturnValue_t executeAction(Action* action) = 0;
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_ACTION_HASACTIONSIF_H_ */
|
||||
|
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parameter.h"
|
||||
|
||||
template <typename T>
|
||||
class MinMaxParameter : public Parameter<T> {
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
private:
|
||||
MinMaxParameter(Action *owner, const char *name, T min, T max)
|
||||
: Parameter<T>(owner, name), min(min), max(max) {}
|
||||
|
||||
public:
|
||||
static MinMaxParameter createMinMaxParameter(Action *owner, const char *name, T min, T max) {
|
||||
return MinMaxParameter(owner, name, min, max);
|
||||
}
|
||||
virtual double getMinFloating() override { return static_cast<double>(min); }
|
||||
virtual int64_t getMinSigned() override { return static_cast<int64_t>(min); }
|
||||
|
||||
virtual double getMaxFloating() override { return static_cast<double>(max); }
|
||||
virtual int64_t getMaxSigned() override { return static_cast<int64_t>(max); }
|
||||
|
||||
#else
|
||||
private:
|
||||
MinMaxParameter(Action *owner, T min, T max) : Parameter<T>(owner), min(min), max(max) {}
|
||||
|
||||
public:
|
||||
static MinMaxParameter createMinMaxParameter(Action *owner, T min, T max) {
|
||||
return MinMaxParameter(owner, min, max);
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
T min;
|
||||
T max;
|
||||
};
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define createMinMaxParameter(p1, p2, p3, p4) createMinMaxParameter(p1, p2, p3, p4)
|
||||
#else
|
||||
#define createMinMaxParameter(p1, p2, p3, p4) createMinMaxParameter(p1, p3, p4)
|
||||
#endif
|
@@ -1,117 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Action.h"
|
||||
#include <fsfw/introspection/Types.h>
|
||||
#include <fsfw/introspection/TypesHelper.h>
|
||||
#include "ParameterIF.h"
|
||||
// TODO: ifdef introspection stuff
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Parameter : public ParameterIF {
|
||||
protected:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
Parameter(Action *owner, const char *name)
|
||||
: name(name)
|
||||
#else
|
||||
Parameter(Action *owner)
|
||||
#endif
|
||||
{
|
||||
owner->registerParameter(this);
|
||||
}
|
||||
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
static Parameter createParameter(Action *owner, const char *name) {
|
||||
return Parameter(owner, name);
|
||||
}
|
||||
#else
|
||||
static Parameter createParameter(Action *owner) { return Parameter(owner); }
|
||||
#endif
|
||||
|
||||
bool isValid() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::isValid(&value);
|
||||
}
|
||||
|
||||
operator T(){
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
Types::ParameterType getType() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getType<T>();
|
||||
}
|
||||
#endif
|
||||
|
||||
T value;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
return SerializeAdapter::serialize(&value, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const override { return SerializeAdapter::getSerializedSize(&value); }
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override {
|
||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
double getFloating() override { return (double)value; }
|
||||
int64_t getSigned() override { return (int64_t)value; }
|
||||
|
||||
bool setFloating(double value) override {
|
||||
if (getType() != Types::FLOATING) {
|
||||
puts("fups");
|
||||
return false;
|
||||
}
|
||||
this->value = T(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setSigned(int64_t value) override {
|
||||
if ((getType() != Types::SIGNED) && (getType() != Types::ENUM)) {
|
||||
puts("sups");
|
||||
return false;
|
||||
}
|
||||
this->value = T(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
double getMinFloating() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMin<T>();
|
||||
}
|
||||
int64_t getMinSigned() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMin<T>();
|
||||
}
|
||||
|
||||
double getMaxFloating() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMax<T>();
|
||||
}
|
||||
int64_t getMaxSigned() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::template getMax<T>();
|
||||
}
|
||||
|
||||
std::vector<int64_t> getEnumValues() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::getEnumValues(&value);
|
||||
}
|
||||
const char *const *getEnumDescriptions() override {
|
||||
return enumHelper<std::is_base_of<EnumIF, T>::value>::getEnumDescriptions(&value);
|
||||
}
|
||||
|
||||
const char *getName() override { return name; }
|
||||
|
||||
private:
|
||||
const char *name;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define createParameter(p1, p2) createParameter(p1, p2)
|
||||
#else
|
||||
#define createParameter(p1, p2) createParameter(p1)
|
||||
#endif
|
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
#include <fsfw/introspection/Types.h>
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
class ParameterIF : public SerializeIF {
|
||||
public:
|
||||
virtual bool isValid() = 0;
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
|
||||
|
||||
virtual const char *getName() = 0;
|
||||
|
||||
virtual Types::ParameterType getType() = 0;
|
||||
|
||||
virtual double getFloating() = 0;
|
||||
virtual int64_t getSigned() = 0;
|
||||
|
||||
virtual bool setFloating(double value) = 0;
|
||||
virtual bool setSigned(int64_t value) = 0;
|
||||
|
||||
virtual double getMinFloating() = 0;
|
||||
virtual int64_t getMinSigned() = 0;
|
||||
|
||||
virtual double getMaxFloating() = 0;
|
||||
virtual int64_t getMaxSigned() = 0;
|
||||
|
||||
virtual std::vector<int64_t> getEnumValues() = 0;
|
||||
virtual const char *const * getEnumDescriptions() = 0;
|
||||
|
||||
// ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
// Endianness streamEndianness) const override = 0;
|
||||
|
||||
// size_t getSerializedSize() const override = 0;
|
||||
|
||||
// ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
// Endianness streamEndianness) override = 0;
|
||||
|
||||
#endif
|
||||
};
|
@@ -3,7 +3,7 @@
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||
: ActionHelper(setOwner, useThisQueue), isExecuting(false) {}
|
||||
|
||||
SimpleActionHelper::~SimpleActionHelper() {}
|
||||
SimpleActionHelper::~SimpleActionHelper() = default;
|
||||
|
||||
void SimpleActionHelper::step(ReturnValue_t result) {
|
||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||
@@ -38,33 +38,17 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::IS_BUSY);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
const uint8_t* dataPtr = NULL;
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
auto actionIter = actionMap.find(actionId);
|
||||
if (actionIter == actionMap.end()){
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_ACTION_ID);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
Action* action = actionIter->second;
|
||||
result = action->deSerialize(&dataPtr, &size, SerializeIF::Endianness::NETWORK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK){
|
||||
CommandMessage reply;
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::INVALID_PARAMETERS);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
return;
|
||||
}
|
||||
result = action->handle();
|
||||
lastCommander = commandedBy;
|
||||
lastAction = actionId;
|
||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||
ipcStore->deleteData(dataAddress);
|
||||
switch (result) {
|
||||
case HasReturnvaluesIF::RETURN_OK:
|
||||
|
@@ -11,15 +11,15 @@
|
||||
class SimpleActionHelper : public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
virtual ~SimpleActionHelper();
|
||||
~SimpleActionHelper() override;
|
||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
|
||||
protected:
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress);
|
||||
virtual void resetHelper();
|
||||
store_address_t dataAddress) override;
|
||||
void resetHelper() override;
|
||||
|
||||
private:
|
||||
bool isExecuting;
|
||||
@@ -28,4 +28,4 @@ class SimpleActionHelper : public ActionHelper {
|
||||
uint8_t stepCount = 0;
|
||||
};
|
||||
|
||||
#endif /* SIMPLEACTIONHELPER_H_ */
|
||||
#endif /* FSFW_ACTION_SIMPLEACTIONHELPER_H_ */
|
||||
|
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
template <class owner, class action, class ActionEnum>
|
||||
class TemplateAction : public Action {
|
||||
public:
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
TemplateAction(owner *myOwner, ActionEnum id) : Action(), myOwner(myOwner) {
|
||||
Action::setEnum(&id);
|
||||
myOwner->getActionHelper()->registerAction(this);
|
||||
}
|
||||
#else
|
||||
TemplateAction(owner *myOwner, ActionEnum id) : Action((uint32_t) id), myOwner(myOwner) {
|
||||
myOwner->getActionHelper()->registerAction(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
ReturnValue_t handle() override { return myOwner->handleAction(dynamic_cast<action *>(this)); }
|
||||
|
||||
private:
|
||||
owner *myOwner;
|
||||
};
|
@@ -12,9 +12,7 @@ object_id_t CFDPHandler::packetDestination = 0;
|
||||
|
||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||
: SystemObject(setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(
|
||||
CFDP_HANDLER_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
distributor = dist;
|
||||
}
|
||||
|
||||
|
@@ -13,9 +13,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||
submode(SUBMODE_NONE),
|
||||
modeHelper(this),
|
||||
healthHelper(this, setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
||||
}
|
||||
|
||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
@@ -28,7 +26,7 @@ ReturnValue_t ControllerBase::initialize() {
|
||||
|
||||
MessageQueueId_t parentQueue = 0;
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
auto* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == nullptr) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
@@ -54,7 +52,7 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->
|
||||
|
||||
void ControllerBase::handleQueue() {
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result;
|
||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&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);
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
this->mode = mode;
|
||||
this->submode = submode;
|
||||
mode = mode_;
|
||||
submode = submode_;
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
changeHK(this->mode, this->submode, true);
|
||||
}
|
||||
|
||||
void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) {
|
||||
*mode = this->mode;
|
||||
*submode = this->submode;
|
||||
void ControllerBase::getMode(Mode_t* mode_, Submode_t* submode_) {
|
||||
*mode_ = this->mode;
|
||||
*submode_ = this->submode;
|
||||
}
|
||||
|
||||
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
|
||||
@@ -101,7 +99,7 @@ ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
||||
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) {
|
||||
switch (health) {
|
||||
@@ -117,6 +115,6 @@ ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||
HasHealthIF::HealthState ControllerBase::getHealth() { return healthHelper.getHealth(); }
|
||||
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; }
|
||||
|
@@ -24,21 +24,21 @@ class ControllerBase : public HasModesIF,
|
||||
static const Mode_t MODE_NORMAL = 2;
|
||||
|
||||
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
virtual ~ControllerBase();
|
||||
~ControllerBase() 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 */
|
||||
virtual ReturnValue_t setHealth(HealthState health) override;
|
||||
virtual HasHealthIF::HealthState getHealth() override;
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
/** ExecutableObjectIF overrides */
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
virtual void setTaskIF(PeriodicTaskIF *task) override;
|
||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
void setTaskIF(PeriodicTaskIF *task) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -54,8 +54,8 @@ class ControllerBase : public HasModesIF,
|
||||
*/
|
||||
virtual void performControlOperation() = 0;
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override = 0;
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override = 0;
|
||||
|
||||
const object_id_t parentId;
|
||||
|
||||
@@ -80,10 +80,10 @@ class ControllerBase : public HasModesIF,
|
||||
|
||||
/** Mode helpers */
|
||||
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
||||
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
virtual void setToExternalControl() override;
|
||||
virtual void announceMode(bool recursive);
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
void setToExternalControl() override;
|
||||
void announceMode(bool recursive) override;
|
||||
/** HK helpers */
|
||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||
};
|
||||
|
@@ -6,14 +6,13 @@ ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t
|
||||
poolManager(this, commandQueue),
|
||||
actionHelper(this, commandQueue) {}
|
||||
|
||||
ExtendedControllerBase::~ExtendedControllerBase() {}
|
||||
ExtendedControllerBase::~ExtendedControllerBase() = default;
|
||||
|
||||
ActionHelper *ExtendedControllerBase::getActionHelper() {
|
||||
return &actionHelper;
|
||||
}
|
||||
|
||||
ReturnValue_t ExtendedControllerBase::executeAction(Action *action) {
|
||||
return action->handle();
|
||||
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
/* Needs to be overriden and implemented by child class. */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
object_id_t ExtendedControllerBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
@@ -32,7 +31,7 @@ ReturnValue_t ExtendedControllerBase::handleCommandMessage(CommandMessage *messa
|
||||
|
||||
void ExtendedControllerBase::handleQueue() {
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result;
|
||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&command)) {
|
||||
result = actionHelper.handleActionMessage(&command);
|
||||
|
@@ -18,20 +18,16 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
public HasLocalDataPoolIF {
|
||||
public:
|
||||
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
virtual ~ExtendedControllerBase();
|
||||
~ExtendedControllerBase() override;
|
||||
|
||||
/* 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 */
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
/* HasActionsIF overrides */
|
||||
ActionHelper* getActionHelper() override;
|
||||
ReturnValue_t executeAction(Action* actionId) override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
protected:
|
||||
LocalDataPoolManager poolManager;
|
||||
@@ -43,28 +39,32 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override = 0;
|
||||
|
||||
/**
|
||||
* Periodic helper from ControllerBase, implemented by child class.
|
||||
*/
|
||||
virtual void performControlOperation() = 0;
|
||||
void performControlOperation() override = 0;
|
||||
|
||||
/* Handle the four messages mentioned above */
|
||||
void handleQueue() override;
|
||||
|
||||
/* HasLocalDatapoolIF overrides */
|
||||
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
||||
virtual object_id_t getObjectId() const override;
|
||||
virtual uint32_t getPeriodicOperationFrequency() const override;
|
||||
/* HasActionsIF overrides */
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
|
||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override = 0;
|
||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
||||
/* HasLocalDatapoolIF overrides */
|
||||
LocalDataPoolManager* getHkManagerHandle() override;
|
||||
[[nodiscard]] object_id_t getObjectId() const override;
|
||||
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
|
||||
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override = 0;
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
||||
|
||||
// Mode abstract functions
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override = 0;
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_ */
|
||||
|
@@ -577,10 +577,6 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
||||
|
||||
CommandMessage reply;
|
||||
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);
|
||||
} else {
|
||||
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||
@@ -700,7 +696,8 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
/* Configuration error */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed." << std::endl;
|
||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed."
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
|
||||
#endif
|
||||
@@ -838,8 +835,6 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
||||
errorPrint = "Dataset not found";
|
||||
} else if (error == POOLOBJECT_NOT_FOUND) {
|
||||
errorPrint = "Pool Object not found";
|
||||
} else if (error == WRONG_HK_PACKET_TYPE) {
|
||||
errorPrint = "Wrong Packet Type";
|
||||
} else if (error == HasReturnvaluesIF::RETURN_FAILED) {
|
||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
||||
errorPrint = "Generic Warning";
|
||||
|
@@ -162,7 +162,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
object_id_t getCreatorObjectId();
|
||||
|
||||
bool getReportingEnabled() const;
|
||||
void setReportingEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Returns the current periodic HK generation interval this set
|
||||
@@ -190,6 +189,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
* Used for periodic generation.
|
||||
*/
|
||||
bool reportingEnabled = false;
|
||||
void setReportingEnabled(bool enabled);
|
||||
|
||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor = 5);
|
||||
|
@@ -26,7 +26,11 @@ void AssemblyBase::performChildOperation() {
|
||||
|
||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t 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) {
|
||||
@@ -73,10 +77,9 @@ bool AssemblyBase::handleChildrenChangedHealth() {
|
||||
}
|
||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||
triggerEvent(TRYING_RECOVERY, iter->first, 0);
|
||||
triggerEvent(TRYING_RECOVERY);
|
||||
recoveryState = RECOVERY_STARTED;
|
||||
recoveringDevice = iter;
|
||||
// The user needs to take care of commanding the children off in commandChildren
|
||||
doStartTransition(targetMode, targetSubmode);
|
||||
} else {
|
||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||
@@ -225,9 +228,6 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
||||
bool AssemblyBase::checkAndHandleRecovery() {
|
||||
switch (recoveryState) {
|
||||
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;
|
||||
recoveryOffTimer.resetTimer();
|
||||
return true;
|
||||
@@ -266,11 +266,3 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
|
||||
modeHelper.setForced(true);
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* manage the mode keeping and recovery of non-redundant devices
|
||||
* otherwise be needed for the handling of redundant devices.
|
||||
*
|
||||
* The template class monitors mode and health state of its children
|
||||
* and checks availability of devices on every detected change.
|
||||
@@ -27,9 +26,11 @@
|
||||
*
|
||||
* 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.
|
||||
* (This will call the function in SubsystemBase)
|
||||
*
|
||||
*/
|
||||
class AssemblyBase : public SubsystemBase {
|
||||
public:
|
||||
@@ -46,14 +47,13 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Command children to reach [mode,submode] combination. Can be done by setting
|
||||
* #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
|
||||
* the user needs to ensure that the target devices are healthy. If a device is not healthy,
|
||||
* a recovery might be on-going and the device needs to be commanded to off first.
|
||||
* Command children to reach [mode,submode] combination
|
||||
* Can be done by setting #commandsOutstanding correctly,
|
||||
* or using executeTable()
|
||||
* @param mode
|
||||
* @param submode
|
||||
* @return
|
||||
* - @c RETURN_OK if OK
|
||||
* - @c RETURN_OK if ok
|
||||
* - @c NEED_SECOND_STEP if children need to be commanded again
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @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;
|
||||
virtual void performChildOperation();
|
||||
|
||||
/**
|
||||
* This function handles changed mode or health states of children
|
||||
* @return
|
||||
*/
|
||||
bool handleChildrenChanged();
|
||||
|
||||
/**
|
||||
@@ -145,37 +134,12 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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 bool isInTransition();
|
||||
@@ -196,7 +160,7 @@ class AssemblyBase : public SubsystemBase {
|
||||
* Manages recovery of a device
|
||||
* @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.
|
||||
@@ -204,8 +168,6 @@ class AssemblyBase : public SubsystemBase {
|
||||
* @param objectId Must be a registered child.
|
||||
*/
|
||||
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
||||
|
||||
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
||||
|
@@ -39,9 +39,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
childTransitionDelay(5000),
|
||||
transitionSourceMode(_MODE_POWER_DOWN),
|
||||
transitionSourceSubMode(SUBMODE_NONE) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
insertInCommandMap(RAW_COMMAND_ID);
|
||||
cookieInfo.state = COOKIE_UNUSED;
|
||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||
@@ -49,6 +48,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
|
||||
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
|
||||
}
|
||||
if (this->fdirInstance == nullptr) {
|
||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||
@@ -63,7 +65,9 @@ void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId
|
||||
}
|
||||
|
||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||
delete comCookie;
|
||||
if (comCookie != nullptr) {
|
||||
delete comCookie;
|
||||
}
|
||||
if (defaultFDIRUsed) {
|
||||
delete fdirInstance;
|
||||
}
|
||||
@@ -124,18 +128,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
if (result != RETURN_OK) {
|
||||
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 =
|
||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||
@@ -247,15 +239,14 @@ void DeviceHandlerBase::decrementDeviceReplyMap() {
|
||||
for (std::pair<const DeviceCommandId_t, DeviceReplyInfo>& replyPair : deviceReplyMap) {
|
||||
if (replyPair.second.countdown != nullptr && replyPair.second.active) {
|
||||
if (replyPair.second.countdown->hasTimedOut()) {
|
||||
resetTimeoutControlledReply(&replyPair.second);
|
||||
timedOut = true;
|
||||
}
|
||||
}
|
||||
if (replyPair.second.delayCycles != 0 && replyPair.second.countdown == nullptr) {
|
||||
replyPair.second.delayCycles--;
|
||||
if (replyPair.second.delayCycles == 0) {
|
||||
if (replyPair.second.periodic) {
|
||||
replyPair.second.delayCycles = replyPair.second.maxDelayCycles;
|
||||
}
|
||||
resetDelayCyclesControlledReply(&replyPair.second);
|
||||
timedOut = true;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +254,6 @@ void DeviceHandlerBase::decrementDeviceReplyMap() {
|
||||
replyToReply(replyPair.first, replyPair.second, TIMEOUT);
|
||||
missedReply(replyPair.first);
|
||||
timedOut = false;
|
||||
replyPair.second.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,12 +363,13 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
}
|
||||
} break;
|
||||
case _MODE_WAIT_OFF: {
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
|
||||
if (powerSwitcher == nullptr) {
|
||||
setMode(MODE_OFF);
|
||||
break;
|
||||
}
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||
setMode(MODE_ERROR_ON);
|
||||
@@ -451,9 +442,6 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
||||
info.dataSet = dataSet;
|
||||
info.command = deviceCommandMap.end();
|
||||
info.countdown = countdown;
|
||||
if (info.periodic) {
|
||||
info.active = true;
|
||||
}
|
||||
auto resultPair = deviceReplyMap.emplace(replyId, info);
|
||||
if (resultPair.second) {
|
||||
return RETURN_OK;
|
||||
@@ -526,9 +514,19 @@ ReturnValue_t DeviceHandlerBase::updatePeriodicReply(bool enable, DeviceCommandI
|
||||
return COMMAND_NOT_SUPPORTED;
|
||||
}
|
||||
if (enable) {
|
||||
info->delayCycles = info->maxDelayCycles;
|
||||
info->active = true;
|
||||
if (info->countdown != nullptr) {
|
||||
info->delayCycles = info->maxDelayCycles;
|
||||
} else {
|
||||
info->countdown->resetTimer();
|
||||
}
|
||||
} else {
|
||||
info->delayCycles = 0;
|
||||
info->active = false;
|
||||
if (info->countdown != nullptr) {
|
||||
info->delayCycles = 0;
|
||||
} else {
|
||||
info->countdown->timeOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
@@ -572,9 +570,6 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
mode = newMode;
|
||||
modeChanged();
|
||||
setNormalDatapoolEntriesInvalid();
|
||||
if (newMode == MODE_OFF) {
|
||||
disableCommandsAndReplies();
|
||||
}
|
||||
if (!isTransitionalMode()) {
|
||||
modeHelper.modeChanged(newMode, newSubmode);
|
||||
announceMode(false);
|
||||
@@ -846,9 +841,9 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId
|
||||
}
|
||||
|
||||
if (info->active && info->countdown != nullptr) {
|
||||
disableTimeoutControlledReply(info);
|
||||
resetTimeoutControlledReply(info);
|
||||
} else if (info->delayCycles != 0) {
|
||||
disableDelayCyclesControlledReply(info);
|
||||
resetDelayCyclesControlledReply(info);
|
||||
}
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
@@ -867,7 +862,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::disableTimeoutControlledReply(DeviceReplyInfo* info) {
|
||||
void DeviceHandlerBase::resetTimeoutControlledReply(DeviceReplyInfo* info) {
|
||||
if (info->periodic) {
|
||||
info->countdown->resetTimer();
|
||||
} else {
|
||||
@@ -876,7 +871,7 @@ void DeviceHandlerBase::disableTimeoutControlledReply(DeviceReplyInfo* info) {
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::disableDelayCyclesControlledReply(DeviceReplyInfo* info) {
|
||||
void DeviceHandlerBase::resetDelayCyclesControlledReply(DeviceReplyInfo* info) {
|
||||
if (info->periodic) {
|
||||
info->delayCycles = info->maxDelayCycles;
|
||||
} else {
|
||||
@@ -1007,6 +1002,8 @@ ReturnValue_t DeviceHandlerBase::enableReplyInReplyMap(DeviceCommandMap::iterato
|
||||
}
|
||||
if (iter != deviceReplyMap.end()) {
|
||||
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->command = command;
|
||||
command->second.expectedReplies = expectedReplies;
|
||||
@@ -1316,25 +1313,22 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* dataSet, DeviceCommandId_t r
|
||||
}
|
||||
}
|
||||
|
||||
ActionHelper *DeviceHandlerBase::getActionHelper() {
|
||||
return &actionHelper;
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::executeAction(Action *action) {
|
||||
ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = acceptExternalDeviceCommands();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(action->getId());
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(actionId);
|
||||
if (iter == deviceCommandMap.end()) {
|
||||
result = COMMAND_NOT_SUPPORTED;
|
||||
} else if (iter->second.isExecuting) {
|
||||
result = COMMAND_ALREADY_SENT;
|
||||
} else {
|
||||
result = action->handle();
|
||||
result = buildCommandFromCommand(actionId, data, size);
|
||||
}
|
||||
if (result == RETURN_OK) {
|
||||
iter->second.sendReplyTo = action->commandedBy;
|
||||
iter->second.sendReplyTo = commandedBy;
|
||||
iter->second.isExecuting = true;
|
||||
cookieInfo.pendingCommand = iter;
|
||||
cookieInfo.state = COOKIE_WRITE_READY;
|
||||
@@ -1408,7 +1402,12 @@ uint8_t DeviceHandlerBase::getReplyDelayCycles(DeviceCommandId_t deviceCommand)
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
return 0;
|
||||
} 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;
|
||||
}
|
||||
@@ -1457,8 +1456,6 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
|
||||
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
||||
uint32_t parameter) {}
|
||||
|
||||
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
||||
|
||||
void DeviceHandlerBase::performOperationHook() {}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
@@ -1481,7 +1478,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
||||
this->poolManager.initializeAfterTaskCreation();
|
||||
|
||||
if (setStartupImmediately) {
|
||||
startTransition(MODE_ON, getInitialSubmode());
|
||||
startTransition(MODE_ON, SUBMODE_NONE);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
@@ -1565,29 +1562,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -103,9 +103,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||
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);
|
||||
|
||||
/**
|
||||
@@ -204,9 +201,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
virtual void setParentQueue(MessageQueueId_t parentQueueId);
|
||||
|
||||
/** @brief Implementations required for HasActionIF */
|
||||
ActionHelper* getActionHelper() override;
|
||||
ReturnValue_t executeAction(Action *action) override;
|
||||
/** @brief Implementation required for HasActionIF */
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) override;
|
||||
|
||||
Mode_t getTransitionSourceMode() const;
|
||||
Submode_t getTransitionSourceSubMode() const;
|
||||
@@ -314,8 +311,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* - Anything else triggers an even with the returnvalue as a parameter
|
||||
*/
|
||||
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) = 0;
|
||||
|
||||
//TODO Remove and update documentation
|
||||
/**
|
||||
* @brief Build a device command packet from data supplied by a direct
|
||||
* command (PUS Service 8)
|
||||
@@ -469,14 +464,14 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* @brief This is a helper method to insert replies in the reply map.
|
||||
* @param deviceCommand Identifier of the reply to add.
|
||||
* @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
|
||||
* 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
|
||||
* #updatePeriodicReply
|
||||
* 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
|
||||
* #updatePeriodicReply
|
||||
* @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
|
||||
* when expired
|
||||
* to provide a pointer to a Countdown object which will signal the timeout
|
||||
* when expired
|
||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
@@ -661,12 +656,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 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:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||
|
||||
@@ -785,18 +774,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* This is used to keep track of pending replies.
|
||||
*/
|
||||
struct DeviceReplyInfo {
|
||||
//! 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;
|
||||
//! This variable will be set to #maxDelayCycles if a reply is expected.
|
||||
//! For non-periodic replies without a command, this variable is unused.
|
||||
//! A runtime value of 0 means there is no reply is currently expected.
|
||||
//! The currently remaining cycles the handler should wait for a reply,
|
||||
//! 0 means there is no reply expected
|
||||
uint16_t delayCycles;
|
||||
size_t replyLen = 0; //!< Expected size of the reply.
|
||||
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
||||
@@ -852,7 +834,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
/** Pointer to the used FDIR instance. If not provided by child,
|
||||
* default class is instantiated. */
|
||||
FailureIsolationBase *fdirInstance;
|
||||
object_id_t parent = objects::NO_OBJECT;
|
||||
|
||||
//! To correctly delete the default instance.
|
||||
bool defaultFDIRUsed;
|
||||
@@ -1276,15 +1257,15 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
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.
|
||||
*/
|
||||
void disableDelayCyclesControlledReply(DeviceReplyInfo *info);
|
||||
void resetDelayCyclesControlledReply(DeviceReplyInfo *info);
|
||||
|
||||
/**
|
||||
* Retrive data from the #IPCStore.
|
||||
@@ -1327,11 +1308,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
void printWarningOrError(sif::OutputTypes errorType, const char *functionName,
|
||||
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
||||
const char *errorPrint = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Disables all commands and replies when device is set to MODE_OFF
|
||||
*/
|
||||
void disableCommandsAndReplies();
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||
|
@@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
||||
switch (event->getEvent()) {
|
||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||
// Might cause some AssemblyBase cycles, so keep number low.
|
||||
handleRecovery(event->getEvent());
|
||||
|
@@ -109,7 +109,6 @@ class DeviceHandlerIF {
|
||||
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_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;
|
||||
|
||||
|
@@ -8,9 +8,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
||||
parentQueue(parentQueue),
|
||||
commandQueue(),
|
||||
healthHelper(this, setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||
}
|
||||
|
||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
|
@@ -18,9 +18,8 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
||||
EventManager::EventManager(object_id_t setObjectId)
|
||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||
EventMessage::EVENT_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
EventManager::~EventManager() {
|
||||
@@ -47,20 +46,9 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
||||
|
||||
void EventManager::notifyListeners(EventMessage* message) {
|
||||
lockMutex();
|
||||
for (auto& listener : listenerList) {
|
||||
if (listener.second.match(message)) {
|
||||
ReturnValue_t result =
|
||||
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
|
||||
}
|
||||
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||
if (iter->second.match(message)) {
|
||||
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||
}
|
||||
}
|
||||
unlockMutex();
|
||||
@@ -100,6 +88,11 @@ ReturnValue_t EventManager::subscribeToEventRange(MessageQueueId_t listener, Eve
|
||||
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,
|
||||
EventId_t idTo, bool idInverted,
|
||||
object_id_t reporterFrom,
|
||||
@@ -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 */
|
||||
|
@@ -37,12 +37,12 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
||||
EventId_t idTo = 0, bool idInverted = false,
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object);
|
||||
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||
EventId_t idTo = 0, bool idInverted = false,
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
void printListeners();
|
||||
|
||||
protected:
|
||||
MessageQueueIF* eventReportQueue = nullptr;
|
||||
|
@@ -20,6 +20,7 @@ class EventManagerIF {
|
||||
bool forwardAllButSelected = false) = 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 unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) = 0;
|
||||
virtual ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||
EventId_t idTo = 0, bool idInverted = false,
|
||||
object_id_t reporterFrom = 0,
|
||||
|
@@ -9,12 +9,21 @@
|
||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -52,12 +61,11 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
||||
if (parentIF == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "FailureIsolationBase::intialize: Parent object "
|
||||
<< "invalid" << std::endl;
|
||||
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");
|
||||
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||
<< "invalid." << std::endl;
|
||||
#endif
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Make sure it implements ConfirmsFailuresIF." << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
return RETURN_FAILED;
|
||||
|
@@ -14,12 +14,13 @@ class FailureIsolationBase : public HasReturnvaluesIF,
|
||||
public HasParametersIF {
|
||||
public:
|
||||
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 = MAKE_EVENT(1, severity::INFO);
|
||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
||||
//! FDIR turns off device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
|
||||
static const Event FDIR_CHANGED_STATE =
|
||||
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||
//!< (oldState) to par1 (newState).
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||
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); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||
|
||||
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||
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;
|
||||
}
|
||||
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
switch (static_cast<ParameterIds>(uniqueId)) {
|
||||
case ParameterIds::FAILURE_THRESHOLD:
|
||||
parameterWrapper->set(failureThreshold);
|
||||
break;
|
||||
case 1:
|
||||
case ParameterIds::FAULT_COUNT:
|
||||
parameterWrapper->set(faultCount);
|
||||
break;
|
||||
case 2:
|
||||
case ParameterIds::TIMEOUT:
|
||||
parameterWrapper->set(timer.timeout);
|
||||
break;
|
||||
default:
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
class FaultCounter : public HasParametersIF {
|
||||
public:
|
||||
enum class ParameterIds { FAILURE_THRESHOLD, FAULT_COUNT, TIMEOUT };
|
||||
|
||||
FaultCounter();
|
||||
FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs,
|
||||
uint8_t setParameterDomain = 0);
|
||||
@@ -25,7 +27,8 @@ class FaultCounter : public HasParametersIF {
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
const ParameterWrapper *newValues = nullptr,
|
||||
uint16_t startAtIndex = 0);
|
||||
|
||||
void setParameterDomain(uint8_t domain);
|
||||
|
||||
|
@@ -4,7 +4,6 @@ target_sources(
|
||||
AsciiConverter.cpp
|
||||
CRC.cpp
|
||||
DleEncoder.cpp
|
||||
DleParser.cpp
|
||||
PeriodicOperationDivider.cpp
|
||||
timevalOperations.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;
|
||||
};
|
@@ -16,27 +16,26 @@ class HasHealthIF {
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY =
|
||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1);
|
||||
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 ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
|
||||
|
||||
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 CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||
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 = MAKE_EVENT(9, severity::LOW);
|
||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
||||
//! Recovery is ongoing. Comes twice during recovery.
|
||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
||||
static const Event OVERWRITING_HEALTH =
|
||||
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||
//!< satellite alive.
|
||||
static const Event TRYING_RECOVERY =
|
||||
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||
//!< power-cycle). No parameters.
|
||||
static const Event RECOVERY_STEP =
|
||||
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||
//!< 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 MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
||||
: objectId(objectId), owner(owner) {}
|
||||
|
||||
HealthHelper::~HealthHelper() {}
|
||||
HealthHelper::~HealthHelper() { healthTable->removeObject(objectId); }
|
||||
|
||||
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
||||
switch (message->getCommand()) {
|
||||
|
@@ -27,6 +27,15 @@ ReturnValue_t HealthTable::registerObject(object_id_t object,
|
||||
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) {
|
||||
MutexGuard(mutex, timeoutType, mutexTimeoutMs);
|
||||
HealthMap::iterator iter = healthMap.find(object);
|
||||
|
@@ -17,6 +17,7 @@ class HealthTable : public HealthTableIF, public SystemObject {
|
||||
/** HealthTableIF overrides */
|
||||
virtual ReturnValue_t registerObject(
|
||||
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) override;
|
||||
ReturnValue_t removeObject(object_id_t object) override;
|
||||
virtual size_t getPrintSize() override;
|
||||
virtual void printAll(uint8_t* pointer, size_t maxSize) override;
|
||||
|
||||
|
@@ -14,6 +14,8 @@ class HealthTableIF : public ManagesHealthIF {
|
||||
virtual ReturnValue_t registerObject(
|
||||
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 void printAll(uint8_t *pointer, size_t maxSize) = 0;
|
||||
|
||||
|
@@ -7,13 +7,11 @@
|
||||
|
||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||
poolManager(this, commandQueue),
|
||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||
internalErrorDataset(this) {
|
||||
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); }
|
||||
@@ -38,14 +36,15 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
||||
<< newStoreHits << std::endl;
|
||||
<< "occured!" << std::endl;
|
||||
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
||||
sif::debug << "TM errors: " << newTmHits << std::endl;
|
||||
sif::debug << "Store errors: " << 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));
|
||||
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
||||
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
||||
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
||||
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -1 +0,0 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE ParameterTypeSelector.cpp)
|
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
// TODO ifdef EnumIF, consistent naming of functions arrays and macros (probably enum values and
|
||||
// descriptions)
|
||||
|
||||
#include "EnumIF.h"
|
||||
#include "EnumCommon.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
#define FSFW_CLASSLESS_ENUM(name, type, elements) \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
\
|
||||
class name : public EnumIF { \
|
||||
public: \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
name(type value) : value(value) {} \
|
||||
name() : value(-1) {} \
|
||||
name(const name &other) : value(other.value) {} \
|
||||
int64_t getValue() const override { return value; } \
|
||||
operator type() { return value; } \
|
||||
name &operator=(name other) { \
|
||||
value = other.value; \
|
||||
return *this; \
|
||||
} \
|
||||
name &operator=(type value) { \
|
||||
this->value = value; \
|
||||
return *this; \
|
||||
} \
|
||||
CREATE_KEY_ARRAY(elements, type) \
|
||||
VALUE_CHECK(type) \
|
||||
GET_INDEX() \
|
||||
CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
GET_DESCRIPTION_FUNC() \
|
||||
private: \
|
||||
type value; \
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define FSFW_CLASSLESS_ENUM(name, type, elements) \
|
||||
enum name : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) };
|
||||
|
||||
#endif
|
@@ -1,64 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
// TODO ifdef EnumIF, consistent naming of functions arrays and macros (probably enum values and
|
||||
// descriptions)
|
||||
|
||||
#include "EnumIF.h"
|
||||
#include "EnumCommon.h"
|
||||
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
#define FSFW_ENUM(name, type, elements) \
|
||||
class name : public EnumIF, public SerializeIF { \
|
||||
public: \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
name(type value) : value(value) {} \
|
||||
name() : value(-1) {} \
|
||||
name(const name &other) : value(other.value) {} \
|
||||
int64_t getValue() const override { return value; } \
|
||||
operator type() { return value; } \
|
||||
name &operator=(name other) { \
|
||||
value = other.value; \
|
||||
return *this; \
|
||||
} \
|
||||
name &operator=(type value) { \
|
||||
this->value = value; \
|
||||
return *this; \
|
||||
} \
|
||||
CREATE_KEY_ARRAY(elements, type) \
|
||||
VALUE_CHECK(type) \
|
||||
GET_INDEX() \
|
||||
CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
GET_DESCRIPTION_FUNC() \
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, \
|
||||
Endianness streamEndianness) const override { \
|
||||
return SerializeAdapter::serialize<>(&value, buffer, size, maxSize, streamEndianness); \
|
||||
} \
|
||||
virtual size_t getSerializedSize() const override { \
|
||||
return SerializeAdapter::getSerializedSize<>(&value); \
|
||||
} \
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, \
|
||||
Endianness streamEndianness) override { \
|
||||
return SerializeAdapter::deSerialize<>(&value, buffer, size, streamEndianness); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
type value; \
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define FSFW_ENUM(name, type, elements) \
|
||||
enum class name : type { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) \
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@@ -1,62 +0,0 @@
|
||||
#define CLEAN_ENUM_ITEM(r, data, element) \
|
||||
BOOST_PP_IF(BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(element), 2), \
|
||||
(BOOST_PP_TUPLE_ELEM(0, element) = BOOST_PP_TUPLE_ELEM(1, element)), \
|
||||
(BOOST_PP_TUPLE_ELEM(0, element)))
|
||||
|
||||
#if defined FSFW_ENUM_VALUE_CHECKS || defined FSFW_INTROSPECTION
|
||||
|
||||
|
||||
#define GET_KEY(r, data, element) (BOOST_PP_TUPLE_ELEM(0, element))
|
||||
#define GET_DESCRIPTION(r, data, element) \
|
||||
BOOST_PP_IF(BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(element), 2), (BOOST_PP_TUPLE_ELEM(2, element)), \
|
||||
(BOOST_PP_TUPLE_ELEM(1, element)))
|
||||
|
||||
#define CREATE_KEY_ARRAY(enum_elements, type) \
|
||||
/*was static constexpr, but clang won't compile that*/ \
|
||||
int64_t elements[BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements))] = { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements))}; \
|
||||
const int64_t *getElements() const override { return elements; } \
|
||||
size_t getSize() const override { \
|
||||
return BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements)); \
|
||||
}
|
||||
#define VALUE_CHECK(type) \
|
||||
bool isValid() const override { \
|
||||
for (size_t i = 0; i < sizeof(elements) / sizeof(elements[0]); i++) { \
|
||||
if (value == elements[i]) { \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
/*was static constexpr, but clang won't compile that*/ \
|
||||
const char \
|
||||
*descriptions[BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_DESCRIPTION, "", elements))] = { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(GET_DESCRIPTION, "", elements))}; \
|
||||
const char *const *getDescriptions() const override { return descriptions; }
|
||||
#define GET_INDEX() \
|
||||
size_t getIndex(int64_t value) const override { \
|
||||
for (size_t i = 0; i < sizeof(elements) / sizeof(elements[0]); i++) { \
|
||||
if (value == elements[i]) { \
|
||||
return i; \
|
||||
} \
|
||||
} \
|
||||
return -1; \
|
||||
}
|
||||
#define GET_DESCRIPTION_FUNC() \
|
||||
const char *getDescription() const override { \
|
||||
if (getIndex(value) == static_cast<size_t>(-1)) { \
|
||||
return nullptr; \
|
||||
} else { \
|
||||
return descriptions[getIndex(value)]; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define GET_INDEX()
|
||||
#define CREATE_DESCRIPTION_ARRAY(elements)
|
||||
#define GET_DESCRIPTION_FUNC()
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
class EnumIF {
|
||||
public:
|
||||
virtual int64_t getValue() const = 0;
|
||||
virtual bool isValid() const = 0;
|
||||
virtual size_t getSize() const = 0;
|
||||
virtual size_t getIndex(int64_t value) const = 0;
|
||||
virtual const int64_t *getElements() const = 0;
|
||||
virtual const char *const *getDescriptions() const = 0;
|
||||
virtual const char *getDescription() const = 0;
|
||||
};
|
@@ -1,56 +0,0 @@
|
||||
#include "ParameterTypeSelector.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
template <typename T>
|
||||
Types::ParameterType ParameterTypeSelector::getType() {
|
||||
return Types::UNSUPPORTED;
|
||||
}
|
||||
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint8_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int8_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint16_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int16_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint32_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int32_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
// template <>
|
||||
// Types::ParameterType ParameterTypeSelector::getType<uint64_t>() {
|
||||
// return Types::UNSIGNED;
|
||||
// }
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int64_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<float>() {
|
||||
return Types::FLOATING;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<double>() {
|
||||
return Types::FLOATING;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
class ParameterTypeSelector {
|
||||
public:
|
||||
template <typename T>
|
||||
static Types::ParameterType getType();
|
||||
};
|
||||
|
||||
#endif
|
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
//maybe call them MIB types as these are the ones exposed to the MIB?
|
||||
// Note: some DBs (Postgress, Mongo) only support signed 64bit integers. To have a common denominator, all integers are int64_t.
|
||||
// As such, ther is no unsigned Type, as there can not be a uint64_t and uint32_t completely fits into int64_t
|
||||
namespace Types {
|
||||
enum ParameterType { SIGNED, FLOATING, ENUM, UNSUPPORTED };
|
||||
} // namespace Types
|
@@ -1,74 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "Enum.h"
|
||||
#include "Types.h"
|
||||
#include "ParameterTypeSelector.h"
|
||||
|
||||
template <bool>
|
||||
class enumHelper;
|
||||
|
||||
template <>
|
||||
class enumHelper<true> {
|
||||
public:
|
||||
static bool isValid(EnumIF *anEnum) { return anEnum->isValid(); }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
template <typename T>
|
||||
static Types::ParameterType getType() {
|
||||
return Types::ENUM;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMin() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMax() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::vector<int64_t> getEnumValues() { return std::vector<int64_t>(); }
|
||||
|
||||
static std::vector<int64_t> getEnumValues(EnumIF *anEnum) {
|
||||
std::vector<int64_t> vector;
|
||||
for (size_t i = 0; i < anEnum->getSize(); i++) {
|
||||
vector.push_back(anEnum->getElements()[i]);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
static const char *const *getEnumDescriptions(EnumIF *anEnum) {
|
||||
return anEnum->getDescriptions();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
class enumHelper<false> {
|
||||
public:
|
||||
static bool isValid(void *) { return true; }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
template <typename T>
|
||||
static Types::ParameterType getType() {
|
||||
return ParameterTypeSelector::getType<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMin() {
|
||||
return std::numeric_limits<T>::lowest();
|
||||
}
|
||||
template <typename T>
|
||||
static T getMax() {
|
||||
return std::numeric_limits<T>::max();
|
||||
}
|
||||
|
||||
static std::vector<int64_t> getEnumValues(void *) { return std::vector<int64_t>(); }
|
||||
|
||||
static const char *const *getEnumDescriptions(void *) { return nullptr; }
|
||||
#endif
|
||||
};
|
@@ -34,7 +34,7 @@ class CommandMessageIF {
|
||||
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
||||
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
||||
//! 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);
|
||||
|
||||
virtual ~CommandMessageIF(){};
|
||||
|
@@ -19,33 +19,32 @@ class HasModesIF {
|
||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||
|
||||
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 = MAKE_EVENT(0, severity::INFO);
|
||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
||||
static const Event CHANGING_MODE =
|
||||
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||
//!< p2: target submode
|
||||
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 MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
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 = MAKE_EVENT(5, severity::LOW);
|
||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
||||
//! p1: target mode. p2: target submode
|
||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
||||
static const Event OBJECT_IN_INVALID_MODE =
|
||||
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||
//!< mode it should never be in.
|
||||
static const Event FORCING_MODE = MAKE_EVENT(
|
||||
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||
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
|
||||
//! sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//! interpreted
|
||||
static constexpr Mode_t MODE_ON = 1;
|
||||
//! The device is powered off. The only command accepted in this mode is a mode change to on.
|
||||
static constexpr Mode_t MODE_OFF = 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;
|
||||
static const Mode_t MODE_ON =
|
||||
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//!< interpreted
|
||||
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||
//!< this mode is a mode change to on.
|
||||
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||
|
||||
virtual ~HasModesIF() {}
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
@@ -95,16 +95,13 @@ void ObjectManager::initialize() {
|
||||
for (auto const& it : objectList) {
|
||||
result = it.second->initialize();
|
||||
if (result != RETURN_OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
object_id_t var = it.first;
|
||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
||||
<< 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
|
||||
<< std::setfill('0') << var
|
||||
<< " failed to "
|
||||
"initialize with code 0x"
|
||||
<< result << std::dec << std::setfill(' ') << std::endl;
|
||||
#endif
|
||||
errorCount++;
|
||||
}
|
||||
|
@@ -16,9 +16,7 @@ elseif(FSFW_OSAL MATCHES "host")
|
||||
|
||||
else()
|
||||
|
||||
message(
|
||||
WARNING
|
||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
||||
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
||||
# Not set. Assumuing this is a host build, try to determine host OS
|
||||
if(WIN32)
|
||||
add_subdirectory(host)
|
||||
|
@@ -54,7 +54,7 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
|
||||
// If the deadline was missed, the deadlineMissedFunc is called.
|
||||
if (!PosixThread::delayUntil(&lastWakeTime, interval)) {
|
||||
// No time left on timer -> we missed the deadline
|
||||
if(dlmFunc != nullptr){
|
||||
if (dlmFunc != nullptr) {
|
||||
dlmFunc();
|
||||
}
|
||||
}
|
||||
|
@@ -290,10 +290,9 @@ ReturnValue_t MessageQueue::handleOpenError(mq_attr* attributes, uint32_t messag
|
||||
*/
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg
|
||||
<< " is too small for requested size " << messageDepth << std::endl;
|
||||
<< " is too small for requested message depth " << messageDepth << std::endl;
|
||||
sif::error << "This error can be fixed by setting the maximum "
|
||||
"allowed message size higher!"
|
||||
<< std::endl;
|
||||
"allowed message depth higher" << std::endl;
|
||||
#else
|
||||
sif::printError(
|
||||
"MessageQueue::MessageQueue: Default MQ size %d is too small for"
|
||||
|
@@ -66,7 +66,7 @@ class HasParametersIF {
|
||||
* @param newValues
|
||||
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
||||
* matrix indexes.
|
||||
* @return RETURN_OK if parameter is valid and a set function of the parameter wrapper was called.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
|
@@ -211,13 +211,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (data == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable or "
|
||||
"data pointer not set"
|
||||
<< std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable!" << std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"ParameterWrapper::copyFrom: Called on read-only variable "
|
||||
"or data pointer not set\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Called on read-only variable!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return READONLY;
|
||||
@@ -226,9 +222,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (from->readonlyData == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Source not set" << std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Source not set!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return SOURCE_NOT_SET;
|
||||
@@ -237,9 +233,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (type != from->type) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch" << std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return DATATYPE_MISSMATCH;
|
||||
@@ -249,9 +245,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (rows == 0 or columns == 0) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero" << std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return COLUMN_OR_ROWS_ZERO;
|
||||
|
@@ -29,9 +29,9 @@ class PowerSwitchIF : public HasReturnvaluesIF {
|
||||
static const ReturnValue_t FUSE_ON = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t FUSE_OFF = MAKE_RETURN_CODE(4);
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_2;
|
||||
//!< Someone detected that a switch went off which shouldn't. Severity:
|
||||
//!< Low, Parameter1: switchId1, Parameter2: switchId2
|
||||
static const Event SWITCH_WENT_OFF = MAKE_EVENT(0, severity::LOW);
|
||||
static const Event SWITCH_WENT_OFF = MAKE_EVENT(
|
||||
0, severity::LOW); //!< Someone detected that a switch went off which shouldn't. Severity:
|
||||
//!< Low, Parameter1: switchId1, Parameter2: switchId2
|
||||
/**
|
||||
* send a direct command to the Power Unit to enable/disable the specified switch.
|
||||
*
|
||||
|
@@ -78,7 +78,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
|
||||
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
|
||||
// does not work in this case as we are deleting the current element here.
|
||||
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
|
||||
if (it->first <= static_cast<uint32_t>(tNow.tv_sec)) {
|
||||
if (it->first <= tNow.tv_sec) {
|
||||
if (schedulingEnabled) {
|
||||
// release tc
|
||||
TmTcMessage releaseMsg(it->second.storeAddr);
|
||||
|
@@ -16,9 +16,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
||||
apid(apid),
|
||||
serviceId(serviceId),
|
||||
targetDestination(targetDestination) {
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||
}
|
||||
|
||||
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
||||
|
@@ -208,17 +208,17 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
|
||||
ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED;
|
||||
HousekeepingMessage::getHkRequestFailureReply(reply, &error);
|
||||
failureParameter2 = error;
|
||||
return RETURN_FAILED;
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
||||
<< "reply command " << command << std::endl;
|
||||
<< "reply command " << command << "!" << std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"Service3Housekeeping::handleReply: Invalid reply with "
|
||||
"reply command %hu\n",
|
||||
"reply command %hu!\n",
|
||||
command);
|
||||
#endif
|
||||
return CommandingServiceBase::INVALID_REPLY;
|
||||
@@ -248,25 +248,19 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) {
|
||||
case (HousekeepingMessage::HK_REQUEST_FAILURE): {
|
||||
break;
|
||||
}
|
||||
case (CommandMessage::REPLY_REJECTED): {
|
||||
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Unexpected reply "
|
||||
"rejected with error code"
|
||||
<< reply->getParameter() << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Invalid reply with reply "
|
||||
"command "
|
||||
<< command << "" << std::endl;
|
||||
<< command << "!" << std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"Service3Housekeeping::handleUnrequestedReply: Invalid reply with "
|
||||
"reply command %hu\n",
|
||||
"reply command %hu!\n",
|
||||
command);
|
||||
#endif
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +275,6 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) {
|
||||
"Could not generate reply!\n");
|
||||
#endif
|
||||
}
|
||||
CommandingServiceBase::handleUnrequestedReply(reply);
|
||||
}
|
||||
|
||||
MessageQueueId_t Service3Housekeeping::getHkQueue() const { return commandQueue->getId(); }
|
||||
|
@@ -12,9 +12,7 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, uint16_t ap
|
||||
uint32_t messageQueueDepth)
|
||||
: PusServiceBase(objectId, apid, serviceId),
|
||||
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||
}
|
||||
|
||||
Service5EventReporting::~Service5EventReporting() {
|
||||
@@ -38,6 +36,9 @@ ReturnValue_t Service5EventReporting::performService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service5EventReporting::generateEventReport: Too many events" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,7 @@
|
||||
class Service5EventReporting : public PusServiceBase {
|
||||
public:
|
||||
Service5EventReporting(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||
size_t maxNumberReportsPerCycle, uint32_t messageQueueDepth);
|
||||
size_t maxNumberReportsPerCycle = 10, uint32_t messageQueueDepth = 10);
|
||||
virtual ~Service5EventReporting();
|
||||
|
||||
/***
|
||||
|
@@ -6,10 +6,10 @@
|
||||
class Service9TimeManagement : public PusServiceBase {
|
||||
public:
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
||||
//!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
||||
//!< Clock could not be set. P1: Returncode.
|
||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
static constexpr Event CLOCK_SET =
|
||||
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||
static constexpr Event CLOCK_SET_FAILURE =
|
||||
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
|
||||
|
||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||
|
||||
|
@@ -33,12 +33,8 @@ struct SequenceEntry : public TableSequenceBase {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class extends the SubsystemBase to perform the management of mode tables
|
||||
* and mode sequences
|
||||
* @brief TODO: documentation missing
|
||||
* @details
|
||||
* This class is able to use mode tables and sequences to command all its children into the
|
||||
* right mode. Fallback sequences can be used to handle failed transitions or have a fallback
|
||||
* in case a component can't keep its current mode.
|
||||
*/
|
||||
class Subsystem : public SubsystemBase, public HasModeSequenceIF {
|
||||
public:
|
||||
|
@@ -8,13 +8,11 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
|
||||
uint16_t commandQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
mode(initialMode),
|
||||
commandQueue(QueueFactory::instance()->createMessageQueue(commandQueueDepth,
|
||||
CommandMessage::MAX_MESSAGE_SIZE)),
|
||||
healthHelper(this, setObjectId),
|
||||
modeHelper(this),
|
||||
parentId(parent) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
parentId(parent) {}
|
||||
|
||||
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
|
||||
@@ -33,9 +31,8 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
|
||||
info.mode = MODE_OFF;
|
||||
}
|
||||
} else {
|
||||
// intentional to force an initial command during system startup
|
||||
info.commandQueue = child->getCommandQueue();
|
||||
info.mode = HasModesIF::MODE_UNDEFINED;
|
||||
info.mode = -1; // intentional to force an initial command during system startup
|
||||
}
|
||||
|
||||
info.submode = SUBMODE_NONE;
|
||||
|
@@ -15,14 +15,7 @@
|
||||
|
||||
/**
|
||||
* @defgroup subsystems Subsystem Objects
|
||||
* All Subsystem and Assemblies can derive from this class. It contains helper classes to
|
||||
* perform mode and health handling, which allows OBSW developers to build a mode tree for
|
||||
* the whole satellite.
|
||||
*
|
||||
* Aside from setting up a mode tree and being able to executing mode tables, this class does not
|
||||
* provide an implementation on what to do with the features. To build a mode tree, helper classes
|
||||
* like the #AssemblyBase or the #Subsystem class extend and use the functionality of the base
|
||||
* class.
|
||||
* Contains all Subsystem and Assemblies
|
||||
*/
|
||||
class SubsystemBase : public SystemObject,
|
||||
public HasModesIF,
|
||||
@@ -103,7 +96,6 @@ class SubsystemBase : public SystemObject,
|
||||
Submode_t targetSubmode);
|
||||
|
||||
/**
|
||||
* This function takes care of sending all according mode commands specified inside a mode table.
|
||||
* We need to know the target Submode, as children are able to inherit the submode
|
||||
* Still, we have a default for all child implementations which do not use submode inheritance
|
||||
*/
|
||||
|
@@ -33,7 +33,11 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() {
|
||||
if (this->currentPacket == nullptr) {
|
||||
return queueMapIt;
|
||||
}
|
||||
this->currentPacket->setStoreAddress(this->currentMessage.getStorageId());
|
||||
ReturnValue_t result = this->currentPacket->setStoreAddress(this->currentMessage.getStorageId());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
tcStatus = PACKET_TOO_SHORT;
|
||||
return this->queueMap.end();
|
||||
}
|
||||
if (currentPacket->getWholeData() != nullptr) {
|
||||
tcStatus = checker.checkPacket(currentPacket);
|
||||
if (tcStatus != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@@ -27,7 +27,12 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
|
||||
if (this->currentPacket == nullptr) {
|
||||
return queueMapIt;
|
||||
}
|
||||
this->currentPacket->setStoreAddress(this->currentMessage.getStorageId(), currentPacket);
|
||||
ReturnValue_t result =
|
||||
this->currentPacket->setStoreAddress(this->currentMessage.getStorageId(), currentPacket);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
tcStatus = PACKET_TOO_SHORT;
|
||||
return this->queueMap.end();
|
||||
}
|
||||
if (currentPacket->getWholeData() != nullptr) {
|
||||
tcStatus = checker.checkPacket(currentPacket);
|
||||
if (tcStatus != HasReturnvaluesIF::RETURN_OK) {
|
||||
@@ -106,6 +111,14 @@ ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) {
|
||||
MessageQueueId_t PUSDistributor::getRequestQueue() { return tcQueue->getId(); }
|
||||
|
||||
ReturnValue_t PUSDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
||||
if (tcStatus == PACKET_LOST or tcStatus == PACKET_TOO_SHORT) {
|
||||
// The ack flags, packet id and sequence control are unknown for a packet which is too short or
|
||||
// has been lost
|
||||
this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, UNKNOWN_ACK_FLAGS,
|
||||
UNKNOWN_PACKET_ID, UNKNOWN_SEQUENCE_CONTROL, tcStatus);
|
||||
currentPacket->deletePacket();
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (queueStatus != RETURN_OK) {
|
||||
tcStatus = queueStatus;
|
||||
}
|
||||
|
@@ -72,6 +72,11 @@ class PUSDistributor : public TcDistributor, public PUSDistributorIF, public Acc
|
||||
* success/failure messages.
|
||||
*/
|
||||
ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override;
|
||||
|
||||
private:
|
||||
static const uint8_t UNKNOWN_ACK_FLAGS = 0;
|
||||
static const uint8_t UNKNOWN_PACKET_ID = 0;
|
||||
static const uint8_t UNKNOWN_SEQUENCE_CONTROL = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ */
|
||||
|
@@ -5,9 +5,7 @@
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
|
||||
TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) {
|
||||
auto mqArgs = MqArgs(objectId);
|
||||
tcQueue = QueueFactory::instance()->createMessageQueue(
|
||||
DISTRIBUTER_MAX_PACKETS, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS);
|
||||
}
|
||||
|
||||
TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }
|
||||
|
@@ -36,6 +36,7 @@ class TcDistributor : public SystemObject, public ExecutableObjectIF, public Has
|
||||
static constexpr ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE(1);
|
||||
static constexpr ReturnValue_t DESTINATION_NOT_FOUND = MAKE_RETURN_CODE(2);
|
||||
static constexpr ReturnValue_t SERVICE_ID_ALREADY_EXISTS = MAKE_RETURN_CODE(3);
|
||||
static constexpr ReturnValue_t PACKET_TOO_SHORT = MAKE_RETURN_CODE(4);
|
||||
/**
|
||||
* Within the default constructor, the SystemObject id is set and the
|
||||
* message queue is initialized.
|
||||
|
@@ -4,13 +4,14 @@
|
||||
|
||||
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
||||
ThermalModuleIF *thermalModule)
|
||||
: SystemObject(setObjectid), healthHelper(this, setObjectid), parameterHelper(this) {
|
||||
if (thermalModule != nullptr) {
|
||||
: SystemObject(setObjectid),
|
||||
commandQueue(NULL),
|
||||
healthHelper(this, setObjectid),
|
||||
parameterHelper(this) {
|
||||
if (thermalModule != NULL) {
|
||||
thermalModule->registerSensor(this);
|
||||
}
|
||||
auto mqArgs = MqArgs(setObjectid, static_cast<void *>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue();
|
||||
}
|
||||
|
||||
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
||||
|
@@ -51,7 +51,7 @@ class AbstractTemperatureSensor : public HasHealthIF,
|
||||
HasHealthIF::HealthState getHealth();
|
||||
|
||||
protected:
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
MessageQueueIF* commandQueue;
|
||||
HealthHelper healthHelper;
|
||||
ParameterHelper parameterHelper;
|
||||
|
||||
|
@@ -12,9 +12,7 @@ Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1)
|
||||
switch1(switch1),
|
||||
heaterOnCountdown(10800000) /*about two orbits*/,
|
||||
parameterHelper(this) {
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue();
|
||||
}
|
||||
|
||||
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
||||
|
@@ -13,9 +13,9 @@ class ThermalComponentIF : public HasParametersIF {
|
||||
static const Event COMPONENT_TEMP_HIGH = MAKE_EVENT(2, severity::LOW);
|
||||
static const Event COMPONENT_TEMP_OOL_LOW = MAKE_EVENT(3, severity::LOW);
|
||||
static const Event COMPONENT_TEMP_OOL_HIGH = MAKE_EVENT(4, severity::LOW);
|
||||
//!< Is thrown when a device should start-up, but the temperature is out
|
||||
//!< of OP range. P1: thermalState of the component, P2: 0
|
||||
static const Event TEMP_NOT_IN_OP_RANGE = MAKE_EVENT(5, severity::LOW);
|
||||
static const Event TEMP_NOT_IN_OP_RANGE = MAKE_EVENT(
|
||||
5, severity::LOW); //!< Is thrown when a device should start-up, but the temperature is out
|
||||
//!< of OP range. P1: thermalState of the component, P2: 0
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::THERMAL_COMPONENT_IF;
|
||||
static const ReturnValue_t INVALID_TARGET_STATE = MAKE_RETURN_CODE(1);
|
||||
|
@@ -1,11 +1,7 @@
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
|
||||
Countdown::Countdown(uint32_t initialTimeout, bool startImmediately) : timeout(initialTimeout) {
|
||||
if (startImmediately) {
|
||||
setTimeout(initialTimeout);
|
||||
} else {
|
||||
timeout = initialTimeout;
|
||||
}
|
||||
Countdown::Countdown(uint32_t initialTimeout) : timeout(initialTimeout) {
|
||||
setTimeout(initialTimeout);
|
||||
}
|
||||
|
||||
Countdown::~Countdown() {}
|
||||
|
@@ -26,9 +26,8 @@ class Countdown {
|
||||
* Otherwise a call to hasTimedOut might return True.
|
||||
*
|
||||
* @param initialTimeout Countdown duration in milliseconds
|
||||
* @param startImmediately Set to false if countdown should not be started immediately
|
||||
*/
|
||||
Countdown(uint32_t initialTimeout = 0, bool startImmediately = true);
|
||||
Countdown(uint32_t initialTimeout = 0);
|
||||
~Countdown();
|
||||
/**
|
||||
* Call to set a new countdown duration.
|
||||
|
@@ -33,47 +33,50 @@ class TmStoreBackendIF : public HasParametersIF {
|
||||
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
|
||||
//! Initiating sending data to store failed. Low, par1:
|
||||
//! returnCode, par2: integer (debug info)
|
||||
static const Event STORE_SEND_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||
//! Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_WRITE_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||
//! Initiating reading data from store failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_SEND_READ_FAILED = MAKE_EVENT(2, severity::LOW);
|
||||
//! Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_READ_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
//! An unexpected TM packet or data message occurred. Low, par1: 0, par2: integer (debug info)
|
||||
static const Event UNEXPECTED_MSG = MAKE_EVENT(4, severity::LOW);
|
||||
//! Storing data failed. May simply be a full store. Low, par1: returnCode,
|
||||
//! par2: integer (sequence count of failed packet).
|
||||
static const Event STORING_FAILED = MAKE_EVENT(5, severity::LOW);
|
||||
//! Dumping retrieved data failed. Low, par1: returnCode,
|
||||
//! par2: integer (sequence count of failed packet).
|
||||
static const Event TM_DUMP_FAILED = MAKE_EVENT(6, severity::LOW);
|
||||
//! Corrupted init data or read error. Low, par1: returnCode, par2: integer (debug info)
|
||||
//! Store was not initialized. Starts empty. Info, parameters both zero.
|
||||
static const Event STORE_INIT_FAILED = MAKE_EVENT(7, severity::LOW);
|
||||
//! Data was read out, but it is inconsistent. Low par1:
|
||||
//! Memory address of corruption, par2: integer (debug info)
|
||||
static const Event STORE_INIT_EMPTY = MAKE_EVENT(8, severity::INFO);
|
||||
|
||||
static const Event STORE_CONTENT_CORRUPTED = MAKE_EVENT(9, severity::LOW);
|
||||
//! Info event indicating the store will be initialized, either at boot or after IOB switch.
|
||||
//! Info. pars: 0
|
||||
static const Event STORE_INITIALIZE = MAKE_EVENT(10, severity::INFO);
|
||||
//! Info event indicating the store was successfully initialized, either at boot or after
|
||||
//! IOB switch. Info. pars: 0
|
||||
static const Event INIT_DONE = MAKE_EVENT(11, severity::INFO);
|
||||
//! Info event indicating that dumping finished successfully.
|
||||
//! par1: Number of dumped packets. par2: APID/SSC (16bits each)
|
||||
static const Event DUMP_FINISHED = MAKE_EVENT(12, severity::INFO);
|
||||
//! Info event indicating that deletion finished successfully.
|
||||
//! par1:Number of deleted packets. par2: APID/SSC (16bits each)
|
||||
static const Event DELETION_FINISHED = MAKE_EVENT(13, severity::INFO);
|
||||
//! Info event indicating that something went wrong during deletion. pars: 0
|
||||
static const Event DELETION_FAILED = MAKE_EVENT(14, severity::LOW);
|
||||
//! Info that the a auto catalog report failed
|
||||
static const Event AUTO_CATALOGS_SENDING_FAILED = MAKE_EVENT(15, severity::INFO);
|
||||
static const Event STORE_SEND_WRITE_FAILED =
|
||||
MAKE_EVENT(0, severity::LOW); //!< Initiating sending data to store failed. Low, par1:
|
||||
//!< returnCode, par2: integer (debug info)
|
||||
static const Event STORE_WRITE_FAILED = MAKE_EVENT(
|
||||
1, severity::LOW); //!< Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_SEND_READ_FAILED =
|
||||
MAKE_EVENT(2, severity::LOW); //!< Initiating reading data from store failed. Low, par1:
|
||||
//!< returnCode, par2: 0
|
||||
static const Event STORE_READ_FAILED = MAKE_EVENT(
|
||||
3, severity::LOW); //!< Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
||||
static const Event UNEXPECTED_MSG =
|
||||
MAKE_EVENT(4, severity::LOW); //!< An unexpected TM packet or data message occurred. Low,
|
||||
//!< par1: 0, par2: integer (debug info)
|
||||
static const Event STORING_FAILED = MAKE_EVENT(
|
||||
5, severity::LOW); //!< Storing data failed. May simply be a full store. Low, par1:
|
||||
//!< returnCode, par2: integer (sequence count of failed packet).
|
||||
static const Event TM_DUMP_FAILED =
|
||||
MAKE_EVENT(6, severity::LOW); //!< Dumping retrieved data failed. Low, par1: returnCode,
|
||||
//!< par2: integer (sequence count of failed packet).
|
||||
static const Event STORE_INIT_FAILED =
|
||||
MAKE_EVENT(7, severity::LOW); //!< Corrupted init data or read error. Low, par1: returnCode,
|
||||
//!< par2: integer (debug info)
|
||||
static const Event STORE_INIT_EMPTY = MAKE_EVENT(
|
||||
8, severity::INFO); //!< Store was not initialized. Starts empty. Info, parameters both zero.
|
||||
static const Event STORE_CONTENT_CORRUPTED =
|
||||
MAKE_EVENT(9, severity::LOW); //!< Data was read out, but it is inconsistent. Low par1:
|
||||
//!< Memory address of corruption, par2: integer (debug info)
|
||||
static const Event STORE_INITIALIZE =
|
||||
MAKE_EVENT(10, severity::INFO); //!< Info event indicating the store will be initialized,
|
||||
//!< either at boot or after IOB switch. Info. pars: 0
|
||||
static const Event INIT_DONE = MAKE_EVENT(
|
||||
11, severity::INFO); //!< Info event indicating the store was successfully initialized,
|
||||
//!< either at boot or after IOB switch. Info. pars: 0
|
||||
static const Event DUMP_FINISHED = MAKE_EVENT(
|
||||
12, severity::INFO); //!< Info event indicating that dumping finished successfully. par1:
|
||||
//!< Number of dumped packets. par2: APID/SSC (16bits each)
|
||||
static const Event DELETION_FINISHED = MAKE_EVENT(
|
||||
13, severity::INFO); //!< Info event indicating that deletion finished successfully. par1:
|
||||
//!< Number of deleted packets. par2: APID/SSC (16bits each)
|
||||
static const Event DELETION_FAILED = MAKE_EVENT(
|
||||
14,
|
||||
severity::LOW); //!< Info event indicating that something went wrong during deletion. pars: 0
|
||||
static const Event AUTO_CATALOGS_SENDING_FAILED =
|
||||
MAKE_EVENT(15, severity::INFO); //!< Info that the a auto catalog report failed
|
||||
|
||||
virtual ~TmStoreBackendIF() {}
|
||||
|
||||
|
@@ -25,7 +25,7 @@ class SpacePacket : public SpacePacketBase {
|
||||
* @param apid Sets the packet's APID field. The default value describes an idle packet.
|
||||
* @param sequenceCount ets the packet's Source Sequence Count field.
|
||||
*/
|
||||
SpacePacket(uint16_t packetDataLength = 0, bool isTelecommand = false,
|
||||
SpacePacket(uint16_t packetDataLength, bool isTelecommand = false,
|
||||
uint16_t apid = APID_IDLE_PACKET, uint16_t sequenceCount = 0);
|
||||
/**
|
||||
* The class's default destructor.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user