Compare commits
88 Commits
bbe21e7e89
...
docker_d2
Author | SHA1 | Date | |
---|---|---|---|
70f0a72f1b | |||
b5d890eedd | |||
50b1b48678 | |||
0e0dbc74aa | |||
8c34051d8b | |||
b00d83cb1a | |||
17e609c3a5 | |||
64f0166b64 | |||
c80f06fbcb | |||
e796f82203 | |||
5b7ca8c13c | |||
031739ef51 | |||
b8516b15cb | |||
ac5a54b5da | |||
29015b340b | |||
64274acbeb | |||
ff98c42514 | |||
126ac52975 | |||
70d3197212 | |||
dd90980520 | |||
![]() |
352ab43c1f | ||
97e98eae24 | |||
5ac88f2b15 | |||
b03a6684f9 | |||
![]() |
7c2e50b665 | ||
c04ca704d2 | |||
![]() |
6aa54fe1d4 | ||
![]() |
c55925959b | ||
![]() |
4f0669c574 | ||
f0d996ffd2 | |||
f4d05c2c9c | |||
d1151ca707 | |||
82f46992f6 | |||
c0f80680ef | |||
7761b66fe2 | |||
acc4c8d975 | |||
fe739aa81a | |||
afe006e234 | |||
95f018a0b0 | |||
8c2105ae0a | |||
ed2c2af4a0 | |||
17771c0497 | |||
82df132e7d | |||
a02619e5a2 | |||
a011e70665 | |||
c05184e1c4 | |||
![]() |
b2252bdc0b | ||
7e61ce1ed2 | |||
fcb6437388 | |||
![]() |
6c1db8473b | ||
1a530633ca | |||
8037e8074b | |||
d07e0e5576 | |||
5525466b52 | |||
c2a89bf709 | |||
8dd0b2608d | |||
05495077ec | |||
8ff9eadf30 | |||
082c86ea18 | |||
2800d6f28c | |||
b4effe7a46 | |||
e6e71436c2 | |||
4be45adae6 | |||
a887f852c8 | |||
0d7d2203d2 | |||
cde184f428 | |||
0b3255e463 | |||
df3794dfd8 | |||
d02d5c351d | |||
631a531212 | |||
febecd4b30 | |||
964e311d8b | |||
d43caa8296 | |||
916ed3f56a | |||
665d8cd479 | |||
10398855a9 | |||
d0fec93dc3 | |||
59ab54b2fb | |||
7095999bd2 | |||
7ffb4107d2 | |||
d9d9a28ef8 | |||
![]() |
d95582b81b | ||
c60aa68d00 | |||
9ce59d3c75 | |||
a0dfdfab2c | |||
3e17011087 | |||
f441505476 | |||
7c64797f03 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -22,6 +22,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||||
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
||||||
- `oneShotAction` flag in the `TestTask` class is not static anymore
|
- `oneShotAction` flag in the `TestTask` class is not static anymore
|
||||||
|
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585
|
||||||
|
- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue
|
||||||
|
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
|
||||||
|
- Clock:
|
||||||
|
- `timeval` to `TimeOfDay_t`
|
||||||
|
- Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/)
|
||||||
|
- Moved the statics used by Clock in ClockCommon.cpp to this file
|
||||||
|
- Better check for leap seconds
|
||||||
|
- Added Unittests for Clock (only getter)
|
||||||
|
|
||||||
## Removed
|
## Removed
|
||||||
|
|
||||||
@@ -35,6 +47,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||||
inside `fsfw/version.h`
|
inside `fsfw/version.h`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||||
|
- Added ETL dependency and improved library dependency management
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Small bugfix in STM32 HAL for SPI
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599
|
||||||
|
- HAL GPIO: Improved error checking in `LinuxLibgpioIF::configureGpios(...)`. If a GPIO
|
||||||
|
configuration fails, the function will exit prematurely with a dedicated error code
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/602
|
||||||
|
|
||||||
# [v4.0.0]
|
# [v4.0.0]
|
||||||
|
|
||||||
|
@@ -7,6 +7,23 @@ set(FSFW_REVISION 0)
|
|||||||
# Add the cmake folder so the FindSphinx module is found
|
# Add the cmake folder so the FindSphinx module is found
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
|
set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING
|
||||||
|
"ETL library major version requirement"
|
||||||
|
)
|
||||||
|
set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING
|
||||||
|
"ETL library exact version requirement"
|
||||||
|
)
|
||||||
|
set(FSFW_ETL_LINK_TARGET etl::etl)
|
||||||
|
|
||||||
|
set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING
|
||||||
|
"Catch2 library major version requirement"
|
||||||
|
)
|
||||||
|
set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE STRING
|
||||||
|
"Catch2 library exact version requirement"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(FSFW_ETL_LIB_NAME etl)
|
||||||
|
|
||||||
option(FSFW_GENERATE_SECTIONS
|
option(FSFW_GENERATE_SECTIONS
|
||||||
"Generate function and data sections. Required to remove unused code" ON
|
"Generate function and data sections. Required to remove unused code" ON
|
||||||
)
|
)
|
||||||
@@ -48,19 +65,21 @@ add_library(${LIB_FSFW_NAME})
|
|||||||
if(FSFW_BUILD_UNITTESTS)
|
if(FSFW_BUILD_UNITTESTS)
|
||||||
message(STATUS "Building the FSFW unittests in addition to the static library")
|
message(STATUS "Building the FSFW unittests in addition to the static library")
|
||||||
# Check whether the user has already installed Catch2 first
|
# Check whether the user has already installed Catch2 first
|
||||||
find_package(Catch2 3)
|
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION})
|
||||||
# Not installed, so use FetchContent to download and provide Catch2
|
# Not installed, so use FetchContent to download and provide Catch2
|
||||||
if(NOT Catch2_FOUND)
|
if(NOT Catch2_FOUND)
|
||||||
|
message(STATUS "Catch2 installation not found. Downloading Catch2 library with FetchContent")
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
Catch2
|
Catch2
|
||||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||||
GIT_TAG v3.0.0-preview4
|
GIT_TAG ${FSFW_CATCH2_LIB_VERSION}
|
||||||
)
|
)
|
||||||
|
|
||||||
FetchContent_MakeAvailable(Catch2)
|
FetchContent_MakeAvailable(Catch2)
|
||||||
#fixes regression -preview4, to be confirmed in later releases
|
# fixes regression -preview4, to be confirmed in later releases
|
||||||
|
# Related GitHub issue: https://github.com/catchorg/Catch2/issues/2417
|
||||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -88,6 +107,28 @@ if(FSFW_BUILD_UNITTESTS)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "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} QUIET)
|
||||||
|
# Not installed, so use FetchContent to download and provide etl
|
||||||
|
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||||
|
message(STATUS
|
||||||
|
"No ETL installation was found with find_package. Installing and providing "
|
||||||
|
"etl with FindPackage"
|
||||||
|
)
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
${FSFW_ETL_LIB_NAME}
|
||||||
|
GIT_REPOSITORY https://github.com/ETLCPP/etl
|
||||||
|
GIT_TAG ${FSFW_ETL_LIB_VERSION}
|
||||||
|
)
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(${FSFW_ETL_LIB_NAME})
|
||||||
|
add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
set(FSFW_CORE_INC_PATH "inc")
|
set(FSFW_CORE_INC_PATH "inc")
|
||||||
|
|
||||||
set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos)
|
set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos)
|
||||||
@@ -349,6 +390,7 @@ target_compile_options(${LIB_FSFW_NAME} PRIVATE
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
||||||
|
${FSFW_ETL_LINK_TARGET}
|
||||||
${FSFW_ADDITIONAL_LINK_LIBS}
|
${FSFW_ADDITIONAL_LINK_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
45
README.md
45
README.md
@@ -11,9 +11,15 @@ with Airbus Defence and Space GmbH.
|
|||||||
|
|
||||||
## Quick facts
|
## Quick facts
|
||||||
|
|
||||||
The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability. Therefore, a mode and health system provides control over the states of the software and the controlled devices. In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
|
The framework is designed for systems, which communicate with external devices, perform control loops,
|
||||||
|
receive telecommands and send telemetry, and need to maintain a high level of availability. Therefore,
|
||||||
|
a mode and health system provides control over the states of the software and the controlled devices.
|
||||||
|
In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
|
||||||
|
|
||||||
The FSFW provides abstraction layers for operating systems to provide a uniform operating system abstraction layer (OSAL). Some components of this OSAL are required internally by the FSFW but is also very useful for developers to implement the same application logic on different operating systems with a uniform interface.
|
The FSFW provides abstraction layers for operating systems to provide a uniform operating system
|
||||||
|
abstraction layer (OSAL). Some components of this OSAL are required internally by the FSFW but is
|
||||||
|
also very useful for developers to implement the same application logic on different operating
|
||||||
|
systems with a uniform interface.
|
||||||
|
|
||||||
Currently, the FSFW provides the following OSALs:
|
Currently, the FSFW provides the following OSALs:
|
||||||
|
|
||||||
@@ -45,6 +51,28 @@ A template configuration folder was provided and can be copied into the project
|
|||||||
a starting point. The [configuration section](docs/README-config.md#top) provides more specific
|
a starting point. The [configuration section](docs/README-config.md#top) provides more specific
|
||||||
information about the possible options.
|
information about the possible options.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
The Embedded Template Library (etl) is a dependency of the FSFW which is automatically
|
||||||
|
installed and provided by the build system unless the correction version was installed.
|
||||||
|
The current recommended version can be found inside the fsfw `CMakeLists.txt` file or by using
|
||||||
|
`ccmake` and looking up the `FSFW_ETL_LIB_MAJOR_VERSION` variable.
|
||||||
|
|
||||||
|
You can install the ETL library like this. On Linux, it might be necessary to add `sudo` before
|
||||||
|
the install call:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
git clone https://github.com/ETLCPP/etl
|
||||||
|
cd etl
|
||||||
|
git checkout <currentRecommendedVersion>
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
cmake --install .
|
||||||
|
```
|
||||||
|
|
||||||
|
It is recommended to install `20.27.2` or newer for the package version handling of
|
||||||
|
ETL to work.
|
||||||
|
|
||||||
## Adding the library
|
## Adding the library
|
||||||
|
|
||||||
The following steps show how to add and use FSFW components. It is still recommended to
|
The following steps show how to add and use FSFW components. It is still recommended to
|
||||||
@@ -83,6 +111,19 @@ The FSFW also has unittests which use the [Catch2 library](https://github.com/ca
|
|||||||
These are built by setting the CMake option `FSFW_BUILD_UNITTESTS` to `ON` or `TRUE`
|
These are built by setting the CMake option `FSFW_BUILD_UNITTESTS` to `ON` or `TRUE`
|
||||||
from your project `CMakeLists.txt` file or from the command line.
|
from your project `CMakeLists.txt` file or from the command line.
|
||||||
|
|
||||||
|
You can install the Catch2 library, which prevents the build system to avoid re-downloading
|
||||||
|
the dependency if the unit tests are completely rebuilt. The current recommended version
|
||||||
|
can be found inside the fsfw `CMakeLists.txt` file or by using `ccmake` and looking up
|
||||||
|
the `FSFW_CATCH2_LIB_VERSION` variable.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/catchorg/Catch2.git
|
||||||
|
cd Catch2
|
||||||
|
git checkout <currentRecommendedVersion>
|
||||||
|
cmake -Bbuild -H. -DBUILD_TESTING=OFF
|
||||||
|
sudo cmake --build build/ --target install
|
||||||
|
```
|
||||||
|
|
||||||
The fsfw-tests binary will be built as part of the static library and dropped alongside it.
|
The fsfw-tests binary will be built as part of the static library and dropped alongside it.
|
||||||
If the unittests are built, the library and the tests will be built with coverage information by
|
If the unittests are built, the library and the tests will be built with coverage information by
|
||||||
default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF` or `FALSE`.
|
default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF` or `FALSE`.
|
||||||
|
@@ -6,3 +6,9 @@ RUN apt-get --yes upgrade
|
|||||||
#tzdata is a dependency, won't install otherwise
|
#tzdata is a dependency, won't install otherwise
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping
|
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping
|
||||||
|
|
||||||
|
RUN git clone https://github.com/catchorg/Catch2.git && \
|
||||||
|
cd Catch2 && \
|
||||||
|
git checkout v3.0.0-preview5 && \
|
||||||
|
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||||
|
cmake --build build/ --target install
|
||||||
|
2
automation/Jenkinsfile
vendored
2
automation/Jenkinsfile
vendored
@@ -3,7 +3,7 @@ pipeline {
|
|||||||
BUILDDIR = 'build-tests'
|
BUILDDIR = 'build-tests'
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker { image 'fsfw-ci:d1'}
|
docker { image 'fsfw-ci:d2'}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('Clean') {
|
stage('Clean') {
|
||||||
|
@@ -19,6 +19,29 @@ A template configuration folder was provided and can be copied into the project
|
|||||||
a starting point. The [configuration section](docs/README-config.md#top) provides more specific
|
a starting point. The [configuration section](docs/README-config.md#top) provides more specific
|
||||||
information about the possible options.
|
information about the possible options.
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The Embedded Template Library (etl) is a dependency of the FSFW which is automatically
|
||||||
|
installed and provided by the build system unless the correction version was installed.
|
||||||
|
The current recommended version can be found inside the fsfw ``CMakeLists.txt`` file or by using
|
||||||
|
``ccmake`` and looking up the ``FSFW_ETL_LIB_MAJOR_VERSION`` variable.
|
||||||
|
|
||||||
|
You can install the ETL library like this. On Linux, it might be necessary to add ``sudo`` before
|
||||||
|
the install call:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
git clone https://github.com/ETLCPP/etl
|
||||||
|
cd etl
|
||||||
|
git checkout <currentRecommendedVersion>
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
cmake --install .
|
||||||
|
|
||||||
|
It is recommended to install ``20.27.2`` or newer for the package version handling of
|
||||||
|
ETL to work.
|
||||||
|
|
||||||
Adding the library
|
Adding the library
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
@@ -60,6 +83,20 @@ The FSFW also has unittests which use the `Catch2 library`_.
|
|||||||
These are built by setting the CMake option ``FSFW_BUILD_UNITTESTS`` to ``ON`` or `TRUE`
|
These are built by setting the CMake option ``FSFW_BUILD_UNITTESTS`` to ``ON`` or `TRUE`
|
||||||
from your project `CMakeLists.txt` file or from the command line.
|
from your project `CMakeLists.txt` file or from the command line.
|
||||||
|
|
||||||
|
You can install the Catch2 library, which prevents the build system to avoid re-downloading
|
||||||
|
the dependency if the unit tests are completely rebuilt. The current recommended version
|
||||||
|
can be found inside the fsfw ``CMakeLists.txt`` file or by using ``ccmake`` and looking up
|
||||||
|
the ``FSFW_CATCH2_LIB_VERSION`` variable.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
git clone https://github.com/catchorg/Catch2.git
|
||||||
|
cd Catch2
|
||||||
|
git checkout <currentRecommendedVersion>
|
||||||
|
cmake -Bbuild -H. -DBUILD_TESTING=OFF
|
||||||
|
sudo cmake --build build/ --target install
|
||||||
|
|
||||||
|
|
||||||
The fsfw-tests binary will be built as part of the static library and dropped alongside it.
|
The fsfw-tests binary will be built as part of the static library and dropped alongside it.
|
||||||
If the unittests are built, the library and the tests will be built with coverage information by
|
If the unittests are built, the library and the tests will be built with coverage information by
|
||||||
default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF` or `FALSE`.
|
default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF` or `FALSE`.
|
||||||
|
@@ -1,12 +1,9 @@
|
|||||||
#include "MgmLIS3MDLHandler.h"
|
#include "MgmLIS3MDLHandler.h"
|
||||||
|
|
||||||
#include "fsfw/datapool/PoolReadGuard.h"
|
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
|
||||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "fsfw/datapool/PoolReadGuard.h"
|
||||||
|
|
||||||
MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication,
|
MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication,
|
||||||
CookieIF *comCookie, uint32_t transitionDelay)
|
CookieIF *comCookie, uint32_t transitionDelay)
|
||||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
|
@@ -44,6 +44,7 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
for (auto& gpioConfig : mapToAdd) {
|
for (auto& gpioConfig : mapToAdd) {
|
||||||
auto& gpioType = gpioConfig.second->gpioType;
|
auto& gpioType = gpioConfig.second->gpioType;
|
||||||
switch (gpioType) {
|
switch (gpioType) {
|
||||||
@@ -55,7 +56,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
|||||||
if (regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
configureGpioByChip(gpioConfig.first, *regularGpio);
|
result = configureGpioByChip(gpioConfig.first, *regularGpio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): {
|
case (gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): {
|
||||||
@@ -63,7 +64,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
|||||||
if (regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
configureGpioByLabel(gpioConfig.first, *regularGpio);
|
result = configureGpioByLabel(gpioConfig.first, *regularGpio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): {
|
case (gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): {
|
||||||
@@ -71,7 +72,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
|||||||
if (regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
configureGpioByLineName(gpioConfig.first, *regularGpio);
|
result = configureGpioByLineName(gpioConfig.first, *regularGpio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (gpio::GpioTypes::CALLBACK): {
|
case (gpio::GpioTypes::CALLBACK): {
|
||||||
@@ -83,8 +84,11 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
|||||||
gpioCallback->initValue, gpioCallback->callbackArgs);
|
gpioCallback->initValue, gpioCallback->callbackArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return GPIO_INIT_FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId,
|
ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId,
|
||||||
|
@@ -29,6 +29,8 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
|||||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
||||||
static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED =
|
static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED =
|
||||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5);
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5);
|
||||||
|
static constexpr ReturnValue_t GPIO_INIT_FAILED =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 6);
|
||||||
|
|
||||||
LinuxLibgpioIF(object_id_t objectId);
|
LinuxLibgpioIF(object_id_t objectId);
|
||||||
virtual ~LinuxLibgpioIF();
|
virtual ~LinuxLibgpioIF();
|
||||||
|
@@ -148,16 +148,16 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook
|
|||||||
/* Clear size bits */
|
/* Clear size bits */
|
||||||
options->c_cflag &= ~CSIZE;
|
options->c_cflag &= ~CSIZE;
|
||||||
switch (uartCookie->getBitsPerWord()) {
|
switch (uartCookie->getBitsPerWord()) {
|
||||||
case 5:
|
case BitsPerWord::BITS_5:
|
||||||
options->c_cflag |= CS5;
|
options->c_cflag |= CS5;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case BitsPerWord::BITS_6:
|
||||||
options->c_cflag |= CS6;
|
options->c_cflag |= CS6;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case BitsPerWord::BITS_7:
|
||||||
options->c_cflag |= CS7;
|
options->c_cflag |= CS7;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case BitsPerWord::BITS_8:
|
||||||
options->c_cflag |= CS8;
|
options->c_cflag |= CS8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -193,123 +193,123 @@ void UartComIF::setFixedOptions(struct termios* options) {
|
|||||||
|
|
||||||
void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCookie) {
|
void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCookie) {
|
||||||
switch (uartCookie->getBaudrate()) {
|
switch (uartCookie->getBaudrate()) {
|
||||||
case 50:
|
case UartBaudRate::RATE_50:
|
||||||
cfsetispeed(options, B50);
|
cfsetispeed(options, B50);
|
||||||
cfsetospeed(options, B50);
|
cfsetospeed(options, B50);
|
||||||
break;
|
break;
|
||||||
case 75:
|
case UartBaudRate::RATE_75:
|
||||||
cfsetispeed(options, B75);
|
cfsetispeed(options, B75);
|
||||||
cfsetospeed(options, B75);
|
cfsetospeed(options, B75);
|
||||||
break;
|
break;
|
||||||
case 110:
|
case UartBaudRate::RATE_110:
|
||||||
cfsetispeed(options, B110);
|
cfsetispeed(options, B110);
|
||||||
cfsetospeed(options, B110);
|
cfsetospeed(options, B110);
|
||||||
break;
|
break;
|
||||||
case 134:
|
case UartBaudRate::RATE_134:
|
||||||
cfsetispeed(options, B134);
|
cfsetispeed(options, B134);
|
||||||
cfsetospeed(options, B134);
|
cfsetospeed(options, B134);
|
||||||
break;
|
break;
|
||||||
case 150:
|
case UartBaudRate::RATE_150:
|
||||||
cfsetispeed(options, B150);
|
cfsetispeed(options, B150);
|
||||||
cfsetospeed(options, B150);
|
cfsetospeed(options, B150);
|
||||||
break;
|
break;
|
||||||
case 200:
|
case UartBaudRate::RATE_200:
|
||||||
cfsetispeed(options, B200);
|
cfsetispeed(options, B200);
|
||||||
cfsetospeed(options, B200);
|
cfsetospeed(options, B200);
|
||||||
break;
|
break;
|
||||||
case 300:
|
case UartBaudRate::RATE_300:
|
||||||
cfsetispeed(options, B300);
|
cfsetispeed(options, B300);
|
||||||
cfsetospeed(options, B300);
|
cfsetospeed(options, B300);
|
||||||
break;
|
break;
|
||||||
case 600:
|
case UartBaudRate::RATE_600:
|
||||||
cfsetispeed(options, B600);
|
cfsetispeed(options, B600);
|
||||||
cfsetospeed(options, B600);
|
cfsetospeed(options, B600);
|
||||||
break;
|
break;
|
||||||
case 1200:
|
case UartBaudRate::RATE_1200:
|
||||||
cfsetispeed(options, B1200);
|
cfsetispeed(options, B1200);
|
||||||
cfsetospeed(options, B1200);
|
cfsetospeed(options, B1200);
|
||||||
break;
|
break;
|
||||||
case 1800:
|
case UartBaudRate::RATE_1800:
|
||||||
cfsetispeed(options, B1800);
|
cfsetispeed(options, B1800);
|
||||||
cfsetospeed(options, B1800);
|
cfsetospeed(options, B1800);
|
||||||
break;
|
break;
|
||||||
case 2400:
|
case UartBaudRate::RATE_2400:
|
||||||
cfsetispeed(options, B2400);
|
cfsetispeed(options, B2400);
|
||||||
cfsetospeed(options, B2400);
|
cfsetospeed(options, B2400);
|
||||||
break;
|
break;
|
||||||
case 4800:
|
case UartBaudRate::RATE_4800:
|
||||||
cfsetispeed(options, B4800);
|
cfsetispeed(options, B4800);
|
||||||
cfsetospeed(options, B4800);
|
cfsetospeed(options, B4800);
|
||||||
break;
|
break;
|
||||||
case 9600:
|
case UartBaudRate::RATE_9600:
|
||||||
cfsetispeed(options, B9600);
|
cfsetispeed(options, B9600);
|
||||||
cfsetospeed(options, B9600);
|
cfsetospeed(options, B9600);
|
||||||
break;
|
break;
|
||||||
case 19200:
|
case UartBaudRate::RATE_19200:
|
||||||
cfsetispeed(options, B19200);
|
cfsetispeed(options, B19200);
|
||||||
cfsetospeed(options, B19200);
|
cfsetospeed(options, B19200);
|
||||||
break;
|
break;
|
||||||
case 38400:
|
case UartBaudRate::RATE_38400:
|
||||||
cfsetispeed(options, B38400);
|
cfsetispeed(options, B38400);
|
||||||
cfsetospeed(options, B38400);
|
cfsetospeed(options, B38400);
|
||||||
break;
|
break;
|
||||||
case 57600:
|
case UartBaudRate::RATE_57600:
|
||||||
cfsetispeed(options, B57600);
|
cfsetispeed(options, B57600);
|
||||||
cfsetospeed(options, B57600);
|
cfsetospeed(options, B57600);
|
||||||
break;
|
break;
|
||||||
case 115200:
|
case UartBaudRate::RATE_115200:
|
||||||
cfsetispeed(options, B115200);
|
cfsetispeed(options, B115200);
|
||||||
cfsetospeed(options, B115200);
|
cfsetospeed(options, B115200);
|
||||||
break;
|
break;
|
||||||
case 230400:
|
case UartBaudRate::RATE_230400:
|
||||||
cfsetispeed(options, B230400);
|
cfsetispeed(options, B230400);
|
||||||
cfsetospeed(options, B230400);
|
cfsetospeed(options, B230400);
|
||||||
break;
|
break;
|
||||||
case 460800:
|
case UartBaudRate::RATE_460800:
|
||||||
cfsetispeed(options, B460800);
|
cfsetispeed(options, B460800);
|
||||||
cfsetospeed(options, B460800);
|
cfsetospeed(options, B460800);
|
||||||
break;
|
break;
|
||||||
case 500000:
|
case UartBaudRate::RATE_500000:
|
||||||
cfsetispeed(options, B500000);
|
cfsetispeed(options, B500000);
|
||||||
cfsetospeed(options, B500000);
|
cfsetospeed(options, B500000);
|
||||||
break;
|
break;
|
||||||
case 576000:
|
case UartBaudRate::RATE_576000:
|
||||||
cfsetispeed(options, B576000);
|
cfsetispeed(options, B576000);
|
||||||
cfsetospeed(options, B576000);
|
cfsetospeed(options, B576000);
|
||||||
break;
|
break;
|
||||||
case 921600:
|
case UartBaudRate::RATE_921600:
|
||||||
cfsetispeed(options, B921600);
|
cfsetispeed(options, B921600);
|
||||||
cfsetospeed(options, B921600);
|
cfsetospeed(options, B921600);
|
||||||
break;
|
break;
|
||||||
case 1000000:
|
case UartBaudRate::RATE_1000000:
|
||||||
cfsetispeed(options, B1000000);
|
cfsetispeed(options, B1000000);
|
||||||
cfsetospeed(options, B1000000);
|
cfsetospeed(options, B1000000);
|
||||||
break;
|
break;
|
||||||
case 1152000:
|
case UartBaudRate::RATE_1152000:
|
||||||
cfsetispeed(options, B1152000);
|
cfsetispeed(options, B1152000);
|
||||||
cfsetospeed(options, B1152000);
|
cfsetospeed(options, B1152000);
|
||||||
break;
|
break;
|
||||||
case 1500000:
|
case UartBaudRate::RATE_1500000:
|
||||||
cfsetispeed(options, B1500000);
|
cfsetispeed(options, B1500000);
|
||||||
cfsetospeed(options, B1500000);
|
cfsetospeed(options, B1500000);
|
||||||
break;
|
break;
|
||||||
case 2000000:
|
case UartBaudRate::RATE_2000000:
|
||||||
cfsetispeed(options, B2000000);
|
cfsetispeed(options, B2000000);
|
||||||
cfsetospeed(options, B2000000);
|
cfsetospeed(options, B2000000);
|
||||||
break;
|
break;
|
||||||
case 2500000:
|
case UartBaudRate::RATE_2500000:
|
||||||
cfsetispeed(options, B2500000);
|
cfsetispeed(options, B2500000);
|
||||||
cfsetospeed(options, B2500000);
|
cfsetospeed(options, B2500000);
|
||||||
break;
|
break;
|
||||||
case 3000000:
|
case UartBaudRate::RATE_3000000:
|
||||||
cfsetispeed(options, B3000000);
|
cfsetispeed(options, B3000000);
|
||||||
cfsetospeed(options, B3000000);
|
cfsetospeed(options, B3000000);
|
||||||
break;
|
break;
|
||||||
case 3500000:
|
case UartBaudRate::RATE_3500000:
|
||||||
cfsetispeed(options, B3500000);
|
cfsetispeed(options, B3500000);
|
||||||
cfsetospeed(options, B3500000);
|
cfsetospeed(options, B3500000);
|
||||||
break;
|
break;
|
||||||
case 4000000:
|
case UartBaudRate::RATE_4000000:
|
||||||
cfsetispeed(options, B4000000);
|
cfsetispeed(options, B4000000);
|
||||||
cfsetospeed(options, B4000000);
|
cfsetospeed(options, B4000000);
|
||||||
break;
|
break;
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
#include <fsfw/serviceinterface.h>
|
#include <fsfw/serviceinterface.h>
|
||||||
|
|
||||||
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
|
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
|
||||||
uint32_t baudrate, size_t maxReplyLen)
|
UartBaudRate baudrate, size_t maxReplyLen)
|
||||||
: handlerId(handlerId),
|
: handlerId(handlerId),
|
||||||
deviceFile(deviceFile),
|
deviceFile(deviceFile),
|
||||||
uartMode(uartMode),
|
uartMode(uartMode),
|
||||||
@@ -12,7 +12,7 @@ UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes
|
|||||||
|
|
||||||
UartCookie::~UartCookie() {}
|
UartCookie::~UartCookie() {}
|
||||||
|
|
||||||
uint32_t UartCookie::getBaudrate() const { return baudrate; }
|
UartBaudRate UartCookie::getBaudrate() const { return baudrate; }
|
||||||
|
|
||||||
size_t UartCookie::getMaxReplyLen() const { return maxReplyLen; }
|
size_t UartCookie::getMaxReplyLen() const { return maxReplyLen; }
|
||||||
|
|
||||||
@@ -24,23 +24,9 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; }
|
|||||||
|
|
||||||
Parity UartCookie::getParity() const { return parity; }
|
Parity UartCookie::getParity() const { return parity; }
|
||||||
|
|
||||||
void UartCookie::setBitsPerWord(uint8_t bitsPerWord_) {
|
void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
|
||||||
switch (bitsPerWord_) {
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::debug << "UartCookie::setBitsPerWord: Invalid bits per word specified" << std::endl;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bitsPerWord = bitsPerWord_;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t UartCookie::getBitsPerWord() const { return bitsPerWord; }
|
BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; }
|
||||||
|
|
||||||
StopBits UartCookie::getStopBits() const { return stopBits; }
|
StopBits UartCookie::getStopBits() const { return stopBits; }
|
||||||
|
|
||||||
|
@@ -12,6 +12,41 @@ enum class StopBits { ONE_STOP_BIT, TWO_STOP_BITS };
|
|||||||
|
|
||||||
enum class UartModes { CANONICAL, NON_CANONICAL };
|
enum class UartModes { CANONICAL, NON_CANONICAL };
|
||||||
|
|
||||||
|
enum class BitsPerWord { BITS_5, BITS_6, BITS_7, BITS_8 };
|
||||||
|
|
||||||
|
enum class UartBaudRate {
|
||||||
|
RATE_50,
|
||||||
|
RATE_75,
|
||||||
|
RATE_110,
|
||||||
|
RATE_134,
|
||||||
|
RATE_150,
|
||||||
|
RATE_200,
|
||||||
|
RATE_300,
|
||||||
|
RATE_600,
|
||||||
|
RATE_1200,
|
||||||
|
RATE_1800,
|
||||||
|
RATE_2400,
|
||||||
|
RATE_4800,
|
||||||
|
RATE_9600,
|
||||||
|
RATE_19200,
|
||||||
|
RATE_38400,
|
||||||
|
RATE_57600,
|
||||||
|
RATE_115200,
|
||||||
|
RATE_230400,
|
||||||
|
RATE_460800,
|
||||||
|
RATE_500000,
|
||||||
|
RATE_576000,
|
||||||
|
RATE_921600,
|
||||||
|
RATE_1000000,
|
||||||
|
RATE_1152000,
|
||||||
|
RATE_1500000,
|
||||||
|
RATE_2000000,
|
||||||
|
RATE_2500000,
|
||||||
|
RATE_3000000,
|
||||||
|
RATE_3500000,
|
||||||
|
RATE_4000000
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
|
* @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
|
||||||
* The constructor only requests for common options like the baudrate. Other options can
|
* The constructor only requests for common options like the baudrate. Other options can
|
||||||
@@ -27,25 +62,23 @@ class UartCookie : public CookieIF {
|
|||||||
* @param uartMode Specify the UART mode. The canonical mode should be used if the
|
* @param uartMode Specify the UART mode. The canonical mode should be used if the
|
||||||
* messages are separated by a delimited character like '\n'. See the
|
* messages are separated by a delimited character like '\n'. See the
|
||||||
* termios documentation for more information
|
* termios documentation for more information
|
||||||
* @param baudrate The baudrate to use for input and output. Possible Baudrates are: 50,
|
* @param baudrate The baudrate to use for input and output.
|
||||||
* 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, B19200,
|
|
||||||
* 38400, 57600, 115200, 230400, 460800
|
|
||||||
* @param maxReplyLen The maximum size an object using this cookie expects
|
* @param maxReplyLen The maximum size an object using this cookie expects
|
||||||
* @details
|
* @details
|
||||||
* Default configuration: No parity
|
* Default configuration: No parity
|
||||||
* 8 databits (number of bits transfered with one uart frame)
|
* 8 databits (number of bits transfered with one uart frame)
|
||||||
* One stop bit
|
* One stop bit
|
||||||
*/
|
*/
|
||||||
UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, uint32_t baudrate,
|
UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
|
||||||
size_t maxReplyLen);
|
UartBaudRate baudrate, size_t maxReplyLen);
|
||||||
|
|
||||||
virtual ~UartCookie();
|
virtual ~UartCookie();
|
||||||
|
|
||||||
uint32_t getBaudrate() const;
|
UartBaudRate getBaudrate() const;
|
||||||
size_t getMaxReplyLen() const;
|
size_t getMaxReplyLen() const;
|
||||||
std::string getDeviceFile() const;
|
std::string getDeviceFile() const;
|
||||||
Parity getParity() const;
|
Parity getParity() const;
|
||||||
uint8_t getBitsPerWord() const;
|
BitsPerWord getBitsPerWord() const;
|
||||||
StopBits getStopBits() const;
|
StopBits getStopBits() const;
|
||||||
UartModes getUartMode() const;
|
UartModes getUartMode() const;
|
||||||
object_id_t getHandlerId() const;
|
object_id_t getHandlerId() const;
|
||||||
@@ -76,7 +109,7 @@ class UartCookie : public CookieIF {
|
|||||||
/**
|
/**
|
||||||
* Function two set number of bits per UART frame.
|
* Function two set number of bits per UART frame.
|
||||||
*/
|
*/
|
||||||
void setBitsPerWord(uint8_t bitsPerWord_);
|
void setBitsPerWord(BitsPerWord bitsPerWord_);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to specify the number of stopbits.
|
* Function to specify the number of stopbits.
|
||||||
@@ -97,10 +130,10 @@ class UartCookie : public CookieIF {
|
|||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
const UartModes uartMode;
|
const UartModes uartMode;
|
||||||
bool flushInput = false;
|
bool flushInput = false;
|
||||||
uint32_t baudrate;
|
UartBaudRate baudrate;
|
||||||
size_t maxReplyLen = 0;
|
size_t maxReplyLen = 0;
|
||||||
Parity parity = Parity::NONE;
|
Parity parity = Parity::NONE;
|
||||||
uint8_t bitsPerWord = 8;
|
BitsPerWord bitsPerWord = BitsPerWord::BITS_8;
|
||||||
uint8_t readCycles = 1;
|
uint8_t readCycles = 1;
|
||||||
StopBits stopBits = StopBits::ONE_STOP_BIT;
|
StopBits stopBits = StopBits::ONE_STOP_BIT;
|
||||||
bool replySizeFixed = true;
|
bool replySizeFixed = true;
|
||||||
|
@@ -21,7 +21,7 @@ using mspCb = void (*)(void);
|
|||||||
namespace spi {
|
namespace spi {
|
||||||
|
|
||||||
struct MspCfgBase {
|
struct MspCfgBase {
|
||||||
MspCfgBase();
|
MspCfgBase() {}
|
||||||
MspCfgBase(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
MspCfgBase(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso,
|
||||||
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
mspCb cleanupCb = nullptr, mspCb setupCb = nullptr)
|
||||||
: sck(sck), mosi(mosi), miso(miso), cleanupCb(cleanupCb), setupCb(setupCb) {}
|
: sck(sck), mosi(mosi), miso(miso), cleanupCb(cleanupCb), setupCb(setupCb) {}
|
||||||
|
@@ -12,9 +12,7 @@ object_id_t CFDPHandler::packetDestination = 0;
|
|||||||
|
|
||||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||||
: SystemObject(setObjectId) {
|
: SystemObject(setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
CFDP_HANDLER_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
distributor = dist;
|
distributor = dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,9 +13,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
|||||||
submode(SUBMODE_NONE),
|
submode(SUBMODE_NONE),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||||
PoolDataSetBase.cpp
|
PoolDataSetBase.cpp
|
||||||
PoolEntry.cpp
|
PoolEntry.cpp
|
||||||
)
|
)
|
@@ -787,6 +787,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
|||||||
// Serialize set packet into store.
|
// Serialize set packet into store.
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG);
|
result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
ipcStore->deleteData(storeId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (expectedSize != size) {
|
if (expectedSize != size) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket",
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket",
|
||||||
HasReturnvaluesIF::RETURN_FAILED,
|
HasReturnvaluesIF::RETURN_FAILED,
|
||||||
@@ -801,7 +805,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
|||||||
HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId);
|
HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
hkQueue->reply(&reply);
|
result = hkQueue->reply(&reply);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
ipcStore->deleteData(storeId);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,7 +26,11 @@ void AssemblyBase::performChildOperation() {
|
|||||||
|
|
||||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
doStartTransition(mode, submode);
|
doStartTransition(mode, submode);
|
||||||
triggerModeHelperEvents(mode, submode);
|
if (modeHelper.isForced()) {
|
||||||
|
triggerEvent(FORCING_MODE, mode, submode);
|
||||||
|
} else {
|
||||||
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||||
@@ -73,10 +77,9 @@ bool AssemblyBase::handleChildrenChangedHealth() {
|
|||||||
}
|
}
|
||||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||||
triggerEvent(TRYING_RECOVERY, iter->first, 0);
|
triggerEvent(TRYING_RECOVERY);
|
||||||
recoveryState = RECOVERY_STARTED;
|
recoveryState = RECOVERY_STARTED;
|
||||||
recoveringDevice = iter;
|
recoveringDevice = iter;
|
||||||
// The user needs to take care of commanding the children off in commandChildren
|
|
||||||
doStartTransition(targetMode, targetSubmode);
|
doStartTransition(targetMode, targetSubmode);
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||||
@@ -225,9 +228,6 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
|||||||
bool AssemblyBase::checkAndHandleRecovery() {
|
bool AssemblyBase::checkAndHandleRecovery() {
|
||||||
switch (recoveryState) {
|
switch (recoveryState) {
|
||||||
case RECOVERY_STARTED:
|
case RECOVERY_STARTED:
|
||||||
// The recovery was already start in #handleChildrenChangedHealth and we just need
|
|
||||||
// to wait for an off time period.
|
|
||||||
// TODO: make time period configurable
|
|
||||||
recoveryState = RECOVERY_WAIT;
|
recoveryState = RECOVERY_WAIT;
|
||||||
recoveryOffTimer.resetTimer();
|
recoveryOffTimer.resetTimer();
|
||||||
return true;
|
return true;
|
||||||
@@ -266,11 +266,3 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
|
|||||||
modeHelper.setForced(true);
|
modeHelper.setForced(true);
|
||||||
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyBase::triggerModeHelperEvents(Mode_t mode, Submode_t submode) {
|
|
||||||
if (modeHelper.isForced()) {
|
|
||||||
triggerEvent(FORCING_MODE, mode, submode);
|
|
||||||
} else {
|
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -12,8 +12,7 @@
|
|||||||
* Documentation: Dissertation Baetz p.156, 157.
|
* Documentation: Dissertation Baetz p.156, 157.
|
||||||
*
|
*
|
||||||
* This class reduces the complexity of controller components which would
|
* This class reduces the complexity of controller components which would
|
||||||
* otherwise be needed for the handling of redundant devices. However, it can also be used to
|
* otherwise be needed for the handling of redundant devices.
|
||||||
* manage the mode keeping and recovery of non-redundant devices
|
|
||||||
*
|
*
|
||||||
* The template class monitors mode and health state of its children
|
* The template class monitors mode and health state of its children
|
||||||
* and checks availability of devices on every detected change.
|
* and checks availability of devices on every detected change.
|
||||||
@@ -27,9 +26,11 @@
|
|||||||
*
|
*
|
||||||
* Important:
|
* Important:
|
||||||
*
|
*
|
||||||
* The implementation must call #registerChild for all commanded children during initialization.
|
* The implementation must call registerChild(object_id_t child)
|
||||||
|
* for all commanded children during initialization.
|
||||||
* The implementation must call the initialization function of the base class.
|
* The implementation must call the initialization function of the base class.
|
||||||
* (This will call the function in SubsystemBase)
|
* (This will call the function in SubsystemBase)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class AssemblyBase : public SubsystemBase {
|
class AssemblyBase : public SubsystemBase {
|
||||||
public:
|
public:
|
||||||
@@ -46,14 +47,13 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Command children to reach [mode,submode] combination. Can be done by setting
|
* Command children to reach [mode,submode] combination
|
||||||
* #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
|
* Can be done by setting #commandsOutstanding correctly,
|
||||||
* the user needs to ensure that the target devices are healthy. If a device is not healthy,
|
* or using executeTable()
|
||||||
* a recovery might be on-going and the device needs to be commanded to off first.
|
|
||||||
* @param mode
|
* @param mode
|
||||||
* @param submode
|
* @param submode
|
||||||
* @return
|
* @return
|
||||||
* - @c RETURN_OK if OK
|
* - @c RETURN_OK if ok
|
||||||
* - @c NEED_SECOND_STEP if children need to be commanded again
|
* - @c NEED_SECOND_STEP if children need to be commanded again
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
|
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
|
||||||
@@ -120,19 +120,8 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
||||||
|
|
||||||
/**
|
virtual void performChildOperation();
|
||||||
* @brief Default periodic handler
|
|
||||||
* @details
|
|
||||||
* This is the default periodic handler which will be called by the SubsystemBase
|
|
||||||
* performOperation. It performs the child transitions or reacts to changed health/mode states
|
|
||||||
* of children objects
|
|
||||||
*/
|
|
||||||
virtual void performChildOperation() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function handles changed mode or health states of children
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool handleChildrenChanged();
|
bool handleChildrenChanged();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,37 +134,12 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
bool handleChildrenChangedHealth();
|
bool handleChildrenChangedHealth();
|
||||||
|
|
||||||
/**
|
|
||||||
* Core transition handler. The default implementation will only do something if
|
|
||||||
* #commandsOutstanding is smaller or equal to zero, which means that all mode commands
|
|
||||||
* from the #doPerformTransition call were executed successfully.
|
|
||||||
*
|
|
||||||
* Unless a second step was requested, the function will then use #checkChildrenState to
|
|
||||||
* determine whether the target mode was reached.
|
|
||||||
*
|
|
||||||
* There is some special handling for certain (internal) modes:
|
|
||||||
* - A second step is necessary. #commandChildren will be performed again
|
|
||||||
* - The device health was overwritten. #commandChildren will be called
|
|
||||||
* - A recovery is ongoing. #checkAndHandleRecovery will be called.
|
|
||||||
*/
|
|
||||||
virtual void handleChildrenTransition();
|
virtual void handleChildrenTransition();
|
||||||
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls #doStartTransition and triggers an informative event as well that the mode will
|
|
||||||
* change
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
*/
|
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||||
|
|
||||||
/**
|
|
||||||
* This function starts the transition by setting the internal #targetSubmode and #targetMode
|
|
||||||
* variables and then calling the #commandChildren function.
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
*/
|
|
||||||
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
||||||
|
|
||||||
virtual bool isInTransition();
|
virtual bool isInTransition();
|
||||||
@@ -196,7 +160,7 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
* Manages recovery of a device
|
* Manages recovery of a device
|
||||||
* @return true if recovery is still ongoing, false else.
|
* @return true if recovery is still ongoing, false else.
|
||||||
*/
|
*/
|
||||||
virtual bool checkAndHandleRecovery();
|
bool checkAndHandleRecovery();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to overwrite health state of one of the children.
|
* Helper method to overwrite health state of one of the children.
|
||||||
@@ -204,8 +168,6 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
* @param objectId Must be a registered child.
|
* @param objectId Must be a registered child.
|
||||||
*/
|
*/
|
||||||
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
||||||
|
|
||||||
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
||||||
|
@@ -39,9 +39,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
childTransitionDelay(5000),
|
childTransitionDelay(5000),
|
||||||
transitionSourceMode(_MODE_POWER_DOWN),
|
transitionSourceMode(_MODE_POWER_DOWN),
|
||||||
transitionSourceSubMode(SUBMODE_NONE) {
|
transitionSourceSubMode(SUBMODE_NONE) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
insertInCommandMap(RAW_COMMAND_ID);
|
insertInCommandMap(RAW_COMMAND_ID);
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||||
@@ -49,6 +48,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
|
||||||
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
|
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
|
||||||
}
|
}
|
||||||
|
if (this->fdirInstance == nullptr) {
|
||||||
|
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||||
@@ -124,17 +126,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (this->fdirInstance == nullptr) {
|
|
||||||
this->fdirInstance = new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this->parent != objects::NO_OBJECT) {
|
|
||||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
|
||||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
|
||||||
if(modeIF != nullptr and healthIF != nullptr) {
|
|
||||||
setParentQueue(modeIF->getCommandQueue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
communicationInterface =
|
communicationInterface =
|
||||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||||
@@ -419,7 +410,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
|||||||
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet,
|
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet,
|
||||||
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
||||||
// No need to check, as we may try to insert multiple times.
|
// No need to check, as we may try to insert multiple times.
|
||||||
insertInCommandMap(deviceCommand);
|
insertInCommandMap(deviceCommand, hasDifferentReplyId, replyId);
|
||||||
if (hasDifferentReplyId) {
|
if (hasDifferentReplyId) {
|
||||||
return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic);
|
return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic);
|
||||||
} else {
|
} else {
|
||||||
@@ -446,11 +437,15 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
|
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand,
|
||||||
|
bool useAlternativeReply,
|
||||||
|
DeviceCommandId_t alternativeReplyId) {
|
||||||
DeviceCommandInfo info;
|
DeviceCommandInfo info;
|
||||||
info.expectedReplies = 0;
|
info.expectedReplies = 0;
|
||||||
info.isExecuting = false;
|
info.isExecuting = false;
|
||||||
info.sendReplyTo = NO_COMMANDER;
|
info.sendReplyTo = NO_COMMANDER;
|
||||||
|
info.useAlternativeReplyId = alternativeReplyId;
|
||||||
|
info.alternativeReplyId = alternativeReplyId;
|
||||||
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
||||||
if (resultPair.second) {
|
if (resultPair.second) {
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
@@ -460,12 +455,20 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) {
|
size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) {
|
||||||
DeviceReplyIter iter = deviceReplyMap.find(commandId);
|
DeviceCommandId_t replyId = NO_COMMAND_ID;
|
||||||
if (iter != deviceReplyMap.end()) {
|
DeviceCommandMap::iterator command = cookieInfo.pendingCommand;
|
||||||
return iter->second.replyLen;
|
if (command->second.useAlternativeReplyId) {
|
||||||
|
replyId = command->second.alternativeReplyId;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
replyId = commandId;
|
||||||
}
|
}
|
||||||
|
DeviceReplyIter iter = deviceReplyMap.find(replyId);
|
||||||
|
if (iter != deviceReplyMap.end()) {
|
||||||
|
if (iter->second.delayCycles != 0) {
|
||||||
|
return iter->second.replyLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
|
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
|
||||||
@@ -660,7 +663,9 @@ void DeviceHandlerBase::doGetWrite() {
|
|||||||
|
|
||||||
// We need to distinguish here, because a raw command never expects a reply.
|
// We need to distinguish here, because a raw command never expects a reply.
|
||||||
//(Could be done in eRIRM, but then child implementations need to be careful.
|
//(Could be done in eRIRM, but then child implementations need to be careful.
|
||||||
result = enableReplyInReplyMap(cookieInfo.pendingCommand);
|
DeviceCommandMap::iterator command = cookieInfo.pendingCommand;
|
||||||
|
result = enableReplyInReplyMap(command, 1, command->second.useAlternativeReplyId,
|
||||||
|
command->second.alternativeReplyId);
|
||||||
} else {
|
} else {
|
||||||
// always generate a failure event, so that FDIR knows what's up
|
// always generate a failure event, so that FDIR knows what's up
|
||||||
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first);
|
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first);
|
||||||
@@ -1394,8 +1399,6 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
|
|||||||
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
||||||
uint32_t parameter) {}
|
uint32_t parameter) {}
|
||||||
|
|
||||||
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::performOperationHook() {}
|
void DeviceHandlerBase::performOperationHook() {}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
@@ -1418,7 +1421,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
this->poolManager.initializeAfterTaskCreation();
|
this->poolManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
if (setStartupImmediately) {
|
if (setStartupImmediately) {
|
||||||
startTransition(MODE_ON, getInitialSubmode());
|
startTransition(MODE_ON, SUBMODE_NONE);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@@ -1502,9 +1505,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
|||||||
}
|
}
|
||||||
return commandIter->second.sendReplyTo;
|
return commandIter->second.sendReplyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) { this->powerSwitcher = switcher; }
|
|
||||||
|
@@ -103,9 +103,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||||
|
|
||||||
void setCustomFdir(FailureIsolationBase* fdir);
|
|
||||||
void setParent(object_id_t parent);
|
|
||||||
void setPowerSwitcher(PowerSwitchIF* switcher);
|
|
||||||
void setHkDestination(object_id_t hkDestination);
|
void setHkDestination(object_id_t hkDestination);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -481,7 +478,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||||
* - @c RETURN_FAILED else.
|
* - @c RETURN_FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand);
|
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand,
|
||||||
|
bool useAlternativeReply = false,
|
||||||
|
DeviceCommandId_t alternativeReplyId = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
||||||
@@ -650,12 +649,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
||||||
uint32_t parameter = 0);
|
uint32_t parameter = 0);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Can be overwritten by a child to specify the initial submode when device has been set
|
|
||||||
* to startup immediately.
|
|
||||||
*/
|
|
||||||
virtual Submode_t getInitialSubmode();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||||
|
|
||||||
@@ -760,6 +753,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
//! if this is != NO_COMMANDER, DHB was commanded externally and shall
|
//! if this is != NO_COMMANDER, DHB was commanded externally and shall
|
||||||
//! report everything to commander.
|
//! report everything to commander.
|
||||||
MessageQueueId_t sendReplyTo;
|
MessageQueueId_t sendReplyTo;
|
||||||
|
bool useAlternativeReplyId;
|
||||||
|
DeviceCommandId_t alternativeReplyId;
|
||||||
};
|
};
|
||||||
using DeviceCommandMap = std::map<DeviceCommandId_t, DeviceCommandInfo>;
|
using DeviceCommandMap = std::map<DeviceCommandId_t, DeviceCommandInfo>;
|
||||||
/**
|
/**
|
||||||
@@ -827,7 +822,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
/** Pointer to the used FDIR instance. If not provided by child,
|
/** Pointer to the used FDIR instance. If not provided by child,
|
||||||
* default class is instantiated. */
|
* default class is instantiated. */
|
||||||
FailureIsolationBase *fdirInstance;
|
FailureIsolationBase *fdirInstance;
|
||||||
object_id_t parent = objects::NO_OBJECT;
|
|
||||||
|
|
||||||
//! To correctly delete the default instance.
|
//! To correctly delete the default instance.
|
||||||
bool defaultFDIRUsed;
|
bool defaultFDIRUsed;
|
||||||
|
@@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
|||||||
switch (event->getEvent()) {
|
switch (event->getEvent()) {
|
||||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
|
||||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||||
// Might cause some AssemblyBase cycles, so keep number low.
|
// Might cause some AssemblyBase cycles, so keep number low.
|
||||||
handleRecovery(event->getEvent());
|
handleRecovery(event->getEvent());
|
||||||
|
@@ -109,7 +109,6 @@ class DeviceHandlerIF {
|
|||||||
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
||||||
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
||||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
||||||
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
|
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||||
|
|
||||||
|
@@ -8,9 +8,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
|||||||
parentQueue(parentQueue),
|
parentQueue(parentQueue),
|
||||||
commandQueue(),
|
commandQueue(),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@@ -18,9 +18,8 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
|||||||
EventManager::EventManager(object_id_t setObjectId)
|
EventManager::EventManager(object_id_t setObjectId)
|
||||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
EventMessage::EVENT_MESSAGE_SIZE);
|
||||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager() {
|
EventManager::~EventManager() {
|
||||||
@@ -47,20 +46,9 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
|||||||
|
|
||||||
void EventManager::notifyListeners(EventMessage* message) {
|
void EventManager::notifyListeners(EventMessage* message) {
|
||||||
lockMutex();
|
lockMutex();
|
||||||
for (auto& listener : listenerList) {
|
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||||
if (listener.second.match(message)) {
|
if (iter->second.match(message)) {
|
||||||
ReturnValue_t result =
|
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||||
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
|
||||||
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
|
||||||
<< result << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
|
||||||
listener.first, result);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlockMutex();
|
unlockMutex();
|
||||||
@@ -201,19 +189,4 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::printListeners() {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
|
||||||
for (auto& listener : listenerList) {
|
|
||||||
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
|
||||||
}
|
|
||||||
sif::info << std::dec << std::setfill(' ');
|
|
||||||
#else
|
|
||||||
sif::printInfo("Event manager listener MQ IDs:\n");
|
|
||||||
for (auto& listener : listenerList) {
|
|
||||||
sif::printInfo("0x%08x\n", listener.first);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||||
|
@@ -42,7 +42,6 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false);
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode);
|
||||||
void printListeners();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* eventReportQueue = nullptr;
|
MessageQueueIF* eventReportQueue = nullptr;
|
||||||
|
@@ -9,9 +9,8 @@
|
|||||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||||
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
eventQueue =
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
||||||
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FailureIsolationBase::~FailureIsolationBase() {
|
FailureIsolationBase::~FailureIsolationBase() {
|
||||||
@@ -52,12 +51,11 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
||||||
if (parentIF == nullptr) {
|
if (parentIF == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FailureIsolationBase::intialize: Parent object "
|
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||||
<< "invalid" << std::endl;
|
<< "invalid." << std::endl;
|
||||||
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
#endif
|
||||||
#else
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
sif::error << "Make sure it implements ConfirmsFailuresIF." << std::endl;
|
||||||
sif::printError("Make sure it implements ConfirmsFailuresIF\n");
|
|
||||||
#endif
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
|
@@ -14,12 +14,13 @@ class FailureIsolationBase : public HasReturnvaluesIF,
|
|||||||
public HasParametersIF {
|
public HasParametersIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
||||||
//! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
|
static const Event FDIR_CHANGED_STATE =
|
||||||
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO);
|
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
//!< (oldState) to par1 (newState).
|
||||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||||
//! FDIR turns off device. Par1: event that caused recovery.
|
2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
|
||||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
|
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(
|
||||||
|
3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||||
|
|
||||||
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||||
|
@@ -23,15 +23,19 @@ class HasHealthIF {
|
|||||||
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
||||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||||
//! Assembly overwrites health information of children to keep satellite alive.
|
static const Event OVERWRITING_HEALTH =
|
||||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
|
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
//!< satellite alive.
|
||||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
static const Event TRYING_RECOVERY =
|
||||||
//! Recovery is ongoing. Comes twice during recovery.
|
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
//!< power-cycle). No parameters.
|
||||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
static const Event RECOVERY_STEP =
|
||||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
//!< 0 for the first, 1 for the second event. P2: 0
|
||||||
|
static const Event RECOVERY_DONE = MAKE_EVENT(
|
||||||
|
12,
|
||||||
|
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||||
|
|
||||||
virtual ~HasHealthIF() {}
|
virtual ~HasHealthIF() {}
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@@ -7,13 +7,11 @@
|
|||||||
|
|
||||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
|
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(this) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
@@ -38,14 +36,15 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
|||||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||||
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
<< "occured!" << std::endl;
|
||||||
<< newStoreHits << std::endl;
|
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
||||||
|
sif::debug << "TM errors: " << newTmHits << std::endl;
|
||||||
|
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printDebug(
|
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
||||||
"InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
|
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
||||||
"| %lu\n",
|
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
||||||
static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
|
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
||||||
static_cast<unsigned int>(newStoreHits));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
target_sources(${LIB_FSFW_NAME}
|
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||||
PRIVATE
|
CommandMessage.cpp
|
||||||
CommandMessage.cpp
|
CommandMessageCleaner.cpp
|
||||||
CommandMessageCleaner.cpp
|
MessageQueueMessage.cpp
|
||||||
MessageQueueMessage.cpp
|
MessageQueueBase.cpp
|
||||||
)
|
)
|
54
src/fsfw/ipc/MessageQueueBase.cpp
Normal file
54
src/fsfw/ipc/MessageQueueBase.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "MessageQueueBase.h"
|
||||||
|
|
||||||
|
MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* args)
|
||||||
|
: id(id) {
|
||||||
|
this->defaultDest = defaultDest;
|
||||||
|
if (args != nullptr) {
|
||||||
|
this->args = *args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueBase::~MessageQueueBase() {}
|
||||||
|
|
||||||
|
ReturnValue_t MessageQueueBase::sendToDefault(MessageQueueMessageIF* message) {
|
||||||
|
return sendToDefaultFrom(message, this->getId(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t MessageQueueBase::reply(MessageQueueMessageIF* message) {
|
||||||
|
if (this->last != MessageQueueIF::NO_QUEUE) {
|
||||||
|
return sendMessageFrom(this->last, message, this->getId());
|
||||||
|
} else {
|
||||||
|
return NO_REPLY_PARTNER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t MessageQueueBase::receiveMessage(MessageQueueMessageIF* message,
|
||||||
|
MessageQueueId_t* receivedFrom) {
|
||||||
|
ReturnValue_t status = this->receiveMessage(message);
|
||||||
|
*receivedFrom = this->last;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t MessageQueueBase::getLastPartner() const { return last; }
|
||||||
|
|
||||||
|
MessageQueueId_t MessageQueueBase::getId() const { return id; }
|
||||||
|
|
||||||
|
MqArgs& MessageQueueBase::getMqArgs() { return args; }
|
||||||
|
|
||||||
|
void MessageQueueBase::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||||
|
this->defaultDest = defaultDestination;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t MessageQueueBase::getDefaultDestination() const { return defaultDest; }
|
||||||
|
|
||||||
|
bool MessageQueueBase::isDefaultDestinationSet() const { return (defaultDest != NO_QUEUE); }
|
||||||
|
|
||||||
|
ReturnValue_t MessageQueueBase::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
|
bool ignoreFault) {
|
||||||
|
return sendMessageFrom(sendTo, message, this->getId(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t MessageQueueBase::sendToDefaultFrom(MessageQueueMessageIF* message,
|
||||||
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
|
return sendMessageFrom(defaultDest, message, sentFrom, ignoreFault);
|
||||||
|
}
|
40
src/fsfw/ipc/MessageQueueBase.h
Normal file
40
src/fsfw/ipc/MessageQueueBase.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_
|
||||||
|
#define FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/MessageQueueIF.h>
|
||||||
|
#include <fsfw/ipc/definitions.h>
|
||||||
|
|
||||||
|
class MessageQueueBase : public MessageQueueIF {
|
||||||
|
public:
|
||||||
|
MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* mqArgs);
|
||||||
|
virtual ~MessageQueueBase();
|
||||||
|
|
||||||
|
// Default implementations for MessageQueueIF where possible
|
||||||
|
virtual MessageQueueId_t getLastPartner() const override;
|
||||||
|
virtual MessageQueueId_t getId() const override;
|
||||||
|
virtual MqArgs& getMqArgs() override;
|
||||||
|
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
||||||
|
virtual MessageQueueId_t getDefaultDestination() const override;
|
||||||
|
virtual bool isDefaultDestinationSet() const override;
|
||||||
|
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
|
bool ignoreFault) override;
|
||||||
|
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||||
|
virtual ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||||
|
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||||
|
MessageQueueId_t* receivedFrom) override;
|
||||||
|
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||||
|
bool ignoreFault = false) override;
|
||||||
|
|
||||||
|
// OSAL specific, forward the abstract function
|
||||||
|
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) = 0;
|
||||||
|
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
|
MessageQueueId_t sentFrom, bool ignoreFault = false) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MessageQueueId_t id = MessageQueueIF::NO_QUEUE;
|
||||||
|
MessageQueueId_t last = MessageQueueIF::NO_QUEUE;
|
||||||
|
MessageQueueId_t defaultDest = MessageQueueIF::NO_QUEUE;
|
||||||
|
MqArgs args = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ */
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef FSFW_IPC_MESSAGEQUEUEIF_H_
|
#ifndef FSFW_IPC_MESSAGEQUEUEIF_H_
|
||||||
#define FSFW_IPC_MESSAGEQUEUEIF_H_
|
#define FSFW_IPC_MESSAGEQUEUEIF_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/definitions.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
@@ -44,8 +46,8 @@ class MessageQueueIF {
|
|||||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) = 0;
|
virtual ReturnValue_t reply(MessageQueueMessageIF* message) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function reads available messages from the message queue
|
* @brief This function reads available messages from the message queue and returns the
|
||||||
* and returns the sender.
|
* sender.
|
||||||
* @details
|
* @details
|
||||||
* It works identically to the other receiveMessage call, but in addition
|
* It works identically to the other receiveMessage call, but in addition
|
||||||
* returns the sender's queue id.
|
* returns the sender's queue id.
|
||||||
@@ -78,19 +80,16 @@ class MessageQueueIF {
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t flush(uint32_t* count) = 0;
|
virtual ReturnValue_t flush(uint32_t* count) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief This method returns the message queue
|
* @brief This method returns the message queue ID of the last communication partner.
|
||||||
* id of the last communication partner.
|
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getLastPartner() const = 0;
|
virtual MessageQueueId_t getLastPartner() const = 0;
|
||||||
/**
|
/**
|
||||||
* @brief This method returns the message queue
|
* @brief This method returns the message queue ID of this class's message queue.
|
||||||
* id of this class's message queue.
|
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getId() const = 0;
|
virtual MessageQueueId_t getId() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief With the sendMessage call, a queue message
|
* @brief With the sendMessage call, a queue message is sent to a receiving queue.
|
||||||
* is sent to a receiving queue.
|
|
||||||
* @details
|
* @details
|
||||||
* This method takes the message provided, adds the sentFrom information
|
* This method takes the message provided, adds the sentFrom information
|
||||||
* and passes it on to the destination provided with an operating system
|
* and passes it on to the destination provided with an operating system
|
||||||
@@ -129,8 +128,7 @@ class MessageQueueIF {
|
|||||||
bool ignoreFault = false) = 0;
|
bool ignoreFault = false) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The sendToDefaultFrom method sends a queue message
|
* @brief The sendToDefaultFrom method sends a queue message to the default destination.
|
||||||
* to the default destination.
|
|
||||||
* @details
|
* @details
|
||||||
* In all other aspects, it works identical to the sendMessage method.
|
* In all other aspects, it works identical to the sendMessage method.
|
||||||
* @param message
|
* @param message
|
||||||
@@ -164,6 +162,8 @@ class MessageQueueIF {
|
|||||||
virtual MessageQueueId_t getDefaultDestination() const = 0;
|
virtual MessageQueueId_t getDefaultDestination() const = 0;
|
||||||
|
|
||||||
virtual bool isDefaultDestinationSet() const = 0;
|
virtual bool isDefaultDestinationSet() const = 0;
|
||||||
|
|
||||||
|
virtual MqArgs& getMqArgs() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_IPC_MESSAGEQUEUEIF_H_ */
|
#endif /* FSFW_IPC_MESSAGEQUEUEIF_H_ */
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
#ifndef FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
|
#ifndef FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
|
||||||
#define FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
|
#define FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
|
||||||
|
|
||||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||||
|
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||||
|
|
||||||
struct MqArgs {
|
struct MqArgs {
|
||||||
MqArgs(){};
|
MqArgs(){};
|
||||||
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
||||||
object_id_t objectId = 0;
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
void* args = nullptr;
|
void* args = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,33 +19,32 @@ class HasModesIF {
|
|||||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
||||||
//! An object announces changing the mode. p1: target mode. p2: target submode
|
static const Event CHANGING_MODE =
|
||||||
static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO);
|
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
//!< p2: target submode
|
||||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
static const Event MODE_INFO = MAKE_EVENT(
|
||||||
|
1,
|
||||||
|
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||||
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||||
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||||
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
||||||
//! Indicates a bug or configuration failure: Object is in a mode it should never be in.
|
static const Event OBJECT_IN_INVALID_MODE =
|
||||||
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW);
|
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
//!< mode it should never be in.
|
||||||
//! p1: target mode. p2: target submode
|
static const Event FORCING_MODE = MAKE_EVENT(
|
||||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
static const Event MODE_CMD_REJECTED =
|
||||||
|
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
|
||||||
|
//!< called object id, Par2: return code.
|
||||||
|
|
||||||
//! The device is powered and ready to perform operations. In this mode, no commands are
|
static const Mode_t MODE_ON =
|
||||||
//! sent by the device handler itself, but direct commands van be commanded and will be
|
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||||
//! interpreted
|
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||||
static constexpr Mode_t MODE_ON = 1;
|
//!< interpreted
|
||||||
//! The device is powered off. The only command accepted in this mode is a mode change to on.
|
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||||
static constexpr Mode_t MODE_OFF = 0;
|
//!< this mode is a mode change to on.
|
||||||
|
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||||
static constexpr Mode_t MODE_INVALID = -1;
|
|
||||||
static constexpr Mode_t MODE_UNDEFINED = -2;
|
|
||||||
|
|
||||||
//! To avoid checks against magic number "0".
|
|
||||||
static const Submode_t SUBMODE_NONE = 0;
|
|
||||||
|
|
||||||
virtual ~HasModesIF() {}
|
virtual ~HasModesIF() {}
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@@ -95,16 +95,13 @@ void ObjectManager::initialize() {
|
|||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
result = it.second->initialize();
|
result = it.second->initialize();
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
object_id_t var = it.first;
|
||||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
||||||
<< std::setfill('0') << it.first << " failed to initialize with code 0x" << result
|
<< std::setfill('0') << var
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
<< " failed to "
|
||||||
#else
|
"initialize with code 0x"
|
||||||
sif::printError(
|
<< result << std::dec << std::setfill(' ') << std::endl;
|
||||||
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var,
|
|
||||||
it.first);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
|
@@ -11,9 +11,6 @@
|
|||||||
// TODO sanitize input?
|
// TODO sanitize input?
|
||||||
// TODO much of this code can be reused for tick-only systems
|
// TODO much of this code can be reused for tick-only systems
|
||||||
|
|
||||||
uint16_t Clock::leapSeconds = 0;
|
|
||||||
MutexIF* Clock::timeMutex = nullptr;
|
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void) { return 1000; }
|
uint32_t Clock::getTicksPerSecond(void) { return 1000; }
|
||||||
|
|
||||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||||
|
@@ -5,7 +5,8 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
||||||
: maxMessageSize(maxMessageSize) {
|
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args),
|
||||||
|
maxMessageSize(maxMessageSize) {
|
||||||
handle = xQueueCreate(messageDepth, maxMessageSize);
|
handle = xQueueCreate(messageDepth, maxMessageSize);
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@@ -15,10 +16,10 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* a
|
|||||||
#else
|
#else
|
||||||
sif::printError("MessageQueue::MessageQueue: Creation failed\n");
|
sif::printError("MessageQueue::MessageQueue: Creation failed\n");
|
||||||
sif::printError("Specified Message Depth: %d\n", messageDepth);
|
sif::printError("Specified Message Depth: %d\n", messageDepth);
|
||||||
sif::printError("Specified MAximum Message Size: %d\n", maxMessageSize);
|
sif::printError("Specified Maximum Message Size: %d\n", maxMessageSize);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
QueueMapManager::instance()->addMessageQueue(handle, &queueId);
|
QueueMapManager::instance()->addMessageQueue(handle, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue::~MessageQueue() {
|
MessageQueue::~MessageQueue() {
|
||||||
@@ -29,28 +30,6 @@ MessageQueue::~MessageQueue() {
|
|||||||
|
|
||||||
void MessageQueue::switchSystemContext(CallContext callContext) { this->callContext = callContext; }
|
void MessageQueue::switchSystemContext(CallContext callContext) { this->callContext = callContext; }
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault) {
|
|
||||||
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
|
|
||||||
return sendToDefaultFrom(message, this->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
|
||||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
|
|
||||||
if (this->lastPartner != MessageQueueIF::NO_QUEUE) {
|
|
||||||
return sendMessageFrom(this->lastPartner, message, this->getId());
|
|
||||||
} else {
|
|
||||||
return NO_REPLY_PARTNER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault, callContext);
|
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault, callContext);
|
||||||
@@ -72,27 +51,16 @@ ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) {
|
|
||||||
ReturnValue_t status = this->receiveMessage(message);
|
|
||||||
if (status == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
*receivedFrom = this->lastPartner;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
||||||
BaseType_t result = xQueueReceive(handle, reinterpret_cast<void*>(message->getBuffer()), 0);
|
BaseType_t result = xQueueReceive(handle, reinterpret_cast<void*>(message->getBuffer()), 0);
|
||||||
if (result == pdPASS) {
|
if (result == pdPASS) {
|
||||||
this->lastPartner = message->getSender();
|
this->last = message->getSender();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getLastPartner() const { return lastPartner; }
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
||||||
// TODO FreeRTOS does not support flushing partially
|
// TODO FreeRTOS does not support flushing partially
|
||||||
// Is always successful
|
// Is always successful
|
||||||
@@ -100,17 +68,6 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getId() const { return queueId; }
|
|
||||||
|
|
||||||
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
|
||||||
defaultDestinationSet = true;
|
|
||||||
this->defaultDestination = defaultDestination;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getDefaultDestination() const { return defaultDestination; }
|
|
||||||
|
|
||||||
bool MessageQueue::isDefaultDestinationSet() const { return defaultDestinationSet; }
|
|
||||||
|
|
||||||
// static core function to send messages.
|
// static core function to send messages.
|
||||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessageIF* message,
|
MessageQueueMessageIF* message,
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
#ifndef FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
||||||
#define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
#define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/MessageQueueBase.h>
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "TaskManagement.h"
|
#include "TaskManagement.h"
|
||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
@@ -33,7 +35,7 @@
|
|||||||
* @ingroup osal
|
* @ingroup osal
|
||||||
* @ingroup message_queue
|
* @ingroup message_queue
|
||||||
*/
|
*/
|
||||||
class MessageQueue : public MessageQueueIF {
|
class MessageQueue : public MessageQueueBase {
|
||||||
friend class MessageQueueSenderIF;
|
friend class MessageQueueSenderIF;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -75,40 +77,15 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
*/
|
*/
|
||||||
void switchSystemContext(CallContext callContext);
|
void switchSystemContext(CallContext callContext);
|
||||||
|
|
||||||
/** MessageQueueIF implementation */
|
QueueHandle_t getNativeQueueHandle();
|
||||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault = false) override;
|
|
||||||
|
|
||||||
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
|
||||||
|
|
||||||
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
|
||||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
MessageQueueId_t sentFrom = NO_QUEUE,
|
||||||
bool ignoreFault = false) override;
|
bool ignoreFault = false) override;
|
||||||
|
|
||||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
|
||||||
bool ignoreFault = false) override;
|
|
||||||
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) override;
|
|
||||||
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
||||||
|
|
||||||
ReturnValue_t flush(uint32_t* count) override;
|
ReturnValue_t flush(uint32_t* count) override;
|
||||||
|
|
||||||
MessageQueueId_t getLastPartner() const override;
|
|
||||||
|
|
||||||
MessageQueueId_t getId() const override;
|
|
||||||
|
|
||||||
void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
|
||||||
|
|
||||||
MessageQueueId_t getDefaultDestination() const override;
|
|
||||||
|
|
||||||
bool isDefaultDestinationSet() const override;
|
|
||||||
|
|
||||||
QueueHandle_t getNativeQueueHandle();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Implementation to be called from any send Call within
|
* @brief Implementation to be called from any send Call within
|
||||||
@@ -138,12 +115,8 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
|
static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool defaultDestinationSet = false;
|
|
||||||
QueueHandle_t handle;
|
QueueHandle_t handle;
|
||||||
MessageQueueId_t queueId = MessageQueueIF::NO_QUEUE;
|
|
||||||
|
|
||||||
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
|
|
||||||
MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE;
|
|
||||||
const size_t maxMessageSize;
|
const size_t maxMessageSize;
|
||||||
//! Stores the current system context
|
//! Stores the current system context
|
||||||
CallContext callContext = CallContext::TASK;
|
CallContext callContext = CallContext::TASK;
|
||||||
|
@@ -97,7 +97,11 @@ void PeriodicTask::taskFunctionality() {
|
|||||||
|
|
||||||
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
||||||
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
||||||
if (newObject == nullptr) {
|
return addComponent(newObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
|
||||||
|
if (object == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
||||||
"it implement ExecutableObjectIF"
|
"it implement ExecutableObjectIF"
|
||||||
@@ -105,8 +109,8 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
|||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
objectList.push_back(newObject);
|
objectList.push_back(object);
|
||||||
newObject->setTaskIF(this);
|
object->setTaskIF(this);
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@@ -63,6 +63,16 @@ class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t addComponent(object_id_t object) override;
|
ReturnValue_t addComponent(object_id_t object) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an object to the list of objects to be executed.
|
||||||
|
* The objects are executed in the order added.
|
||||||
|
* @param object Id of the object to add.
|
||||||
|
* @return
|
||||||
|
* -@c RETURN_OK on success
|
||||||
|
* -@c RETURN_FAILED if the object could not be added.
|
||||||
|
*/
|
||||||
|
ReturnValue_t addComponent(ExecutableObjectIF* object) override;
|
||||||
|
|
||||||
uint32_t getPeriodMs() const override;
|
uint32_t getPeriodMs() const override;
|
||||||
|
|
||||||
ReturnValue_t sleepFor(uint32_t ms) override;
|
ReturnValue_t sleepFor(uint32_t ms) override;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
@@ -11,9 +12,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t Clock::leapSeconds = 0;
|
|
||||||
MutexIF* Clock::timeMutex = NULL;
|
|
||||||
|
|
||||||
using SystemClock = std::chrono::system_clock;
|
using SystemClock = std::chrono::system_clock;
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void) {
|
uint32_t Clock::getTicksPerSecond(void) {
|
||||||
@@ -127,6 +125,13 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
|||||||
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
||||||
auto fraction = now - seconds;
|
auto fraction = now - seconds;
|
||||||
time_t tt = SystemClock::to_time_t(now);
|
time_t tt = SystemClock::to_time_t(now);
|
||||||
|
ReturnValue_t result = checkOrCreateClockMutex();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
MutexGuard helper(timeMutex);
|
||||||
|
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||||
|
// Therefore we have to use a Mutex here
|
||||||
struct tm* timeInfo;
|
struct tm* timeInfo;
|
||||||
timeInfo = gmtime(&tt);
|
timeInfo = gmtime(&tt);
|
||||||
time->year = timeInfo->tm_year + 1900;
|
time->year = timeInfo->tm_year + 1900;
|
||||||
|
@@ -9,9 +9,11 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
||||||
: messageSize(maxMessageSize), messageDepth(messageDepth) {
|
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args),
|
||||||
|
messageSize(maxMessageSize),
|
||||||
|
messageDepth(messageDepth) {
|
||||||
queueLock = MutexFactory::instance()->createMutex();
|
queueLock = MutexFactory::instance()->createMutex();
|
||||||
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);
|
auto result = QueueMapManager::instance()->addMessageQueue(this, &id);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MessageQueue::MessageQueue: Could not be created" << std::endl;
|
sif::error << "MessageQueue::MessageQueue: Could not be created" << std::endl;
|
||||||
@@ -23,42 +25,11 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* a
|
|||||||
|
|
||||||
MessageQueue::~MessageQueue() { MutexFactory::instance()->deleteMutex(queueLock); }
|
MessageQueue::~MessageQueue() { MutexFactory::instance()->deleteMutex(queueLock); }
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault) {
|
|
||||||
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
|
|
||||||
return sendToDefaultFrom(message, this->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
|
||||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
|
|
||||||
if (this->lastPartner != MessageQueueIF::NO_QUEUE) {
|
|
||||||
return sendMessageFrom(this->lastPartner, message, this->getId());
|
|
||||||
} else {
|
|
||||||
return MessageQueueIF::NO_REPLY_PARTNER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault);
|
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) {
|
|
||||||
ReturnValue_t status = this->receiveMessage(message);
|
|
||||||
if (status == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
*receivedFrom = this->lastPartner;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
||||||
if (messageQueue.empty()) {
|
if (messageQueue.empty()) {
|
||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
@@ -68,12 +39,10 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
message->getBuffer());
|
message->getBuffer());
|
||||||
messageQueue.pop();
|
messageQueue.pop();
|
||||||
// The last partner is the first uint32_t field in the message
|
// The last partner is the first uint32_t field in the message
|
||||||
this->lastPartner = message->getSender();
|
this->last = message->getSender();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getLastPartner() const { return lastPartner; }
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
||||||
*count = messageQueue.size();
|
*count = messageQueue.size();
|
||||||
// Clears the queue.
|
// Clears the queue.
|
||||||
@@ -81,17 +50,6 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getId() const { return mqId; }
|
|
||||||
|
|
||||||
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
|
||||||
defaultDestinationSet = true;
|
|
||||||
this->defaultDestination = defaultDestination;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getDefaultDestination() const { return defaultDestination; }
|
|
||||||
|
|
||||||
bool MessageQueue::isDefaultDestinationSet() const { return defaultDestinationSet; }
|
|
||||||
|
|
||||||
// static core function to send messages.
|
// static core function to send messages.
|
||||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessageIF* message,
|
MessageQueueMessageIF* message,
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueBase.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
* @ingroup osal
|
* @ingroup osal
|
||||||
* @ingroup message_queue
|
* @ingroup message_queue
|
||||||
*/
|
*/
|
||||||
class MessageQueue : public MessageQueueIF {
|
class MessageQueue : public MessageQueueBase {
|
||||||
friend class MessageQueueSenderIF;
|
friend class MessageQueueSenderIF;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -69,121 +70,12 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
*/
|
*/
|
||||||
virtual ~MessageQueue();
|
virtual ~MessageQueue();
|
||||||
|
|
||||||
/**
|
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
|
||||||
* @brief This operation sends a message to the given destination.
|
|
||||||
* @details It directly uses the sendMessage call of the MessageQueueSender
|
|
||||||
* parent, but passes its queue id as "sentFrom" parameter.
|
|
||||||
* @param sendTo This parameter specifies the message queue id of the
|
|
||||||
* destination message queue.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
* @param ignoreFault If set to true, the internal software fault counter
|
|
||||||
* is not incremented if queue is full.
|
|
||||||
*/
|
|
||||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault = false) override;
|
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the default destination.
|
|
||||||
* @details As in the sendMessage method, this function uses the
|
|
||||||
* sendToDefault call of the MessageQueueSender parent class and adds its
|
|
||||||
* queue id as "sentFrom" information.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
*/
|
|
||||||
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the last communication partner.
|
|
||||||
* @details This operation simplifies answering an incoming message by using
|
|
||||||
* the stored lastPartner information as destination. If there was no
|
|
||||||
* message received yet (i.e. lastPartner is zero), an error code is returned.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
*/
|
|
||||||
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief With the sendMessage call, a queue message is sent to a
|
|
||||||
* receiving queue.
|
|
||||||
* @details
|
|
||||||
* This method takes the message provided, adds the sentFrom information and
|
|
||||||
* passes it on to the destination provided with an operating system call.
|
|
||||||
* The OS's return value is returned.
|
|
||||||
* @param sendTo This parameter specifies the message queue id to send
|
|
||||||
* the message to.
|
|
||||||
* @param message This is a pointer to a previously created message,
|
|
||||||
* which is sent.
|
|
||||||
* @param sentFrom The sentFrom information can be set to inject the
|
|
||||||
* sender's queue id into the message. This variable is set to zero by
|
|
||||||
* default.
|
|
||||||
* @param ignoreFault If set to true, the internal software fault counter
|
|
||||||
* is not incremented if queue is full.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
MessageQueueId_t sentFrom = NO_QUEUE,
|
||||||
bool ignoreFault = false) override;
|
bool ignoreFault = false) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The sendToDefault method sends a queue message to the default
|
|
||||||
* destination.
|
|
||||||
* @details
|
|
||||||
* In all other aspects, it works identical to the sendMessage method.
|
|
||||||
* @param message This is a pointer to a previously created message,
|
|
||||||
* which is sent.
|
|
||||||
* @param sentFrom The sentFrom information can be set to inject the
|
|
||||||
* sender's queue id into the message. This variable is set to zero by
|
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
|
||||||
bool ignoreFault = false) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function reads available messages from the message queue
|
|
||||||
* and returns the sender.
|
|
||||||
* @details
|
|
||||||
* It works identically to the other receiveMessage call, but in addition
|
|
||||||
* returns the sender's queue id.
|
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
|
||||||
* @param receivedFrom A pointer to a queue id in which the sender's id is stored.
|
|
||||||
*/
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function reads available messages from the message queue.
|
|
||||||
* @details
|
|
||||||
* If data is available it is stored in the passed message pointer.
|
|
||||||
* The message's original content is overwritten and the sendFrom
|
|
||||||
* information is stored in the lastPartner attribute. Else, the lastPartner
|
|
||||||
* information remains untouched, the message's content is cleared and the
|
|
||||||
* function returns immediately.
|
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
|
||||||
*/
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
||||||
/**
|
|
||||||
* Deletes all pending messages in the queue.
|
|
||||||
* @param count The number of flushed messages.
|
|
||||||
* @return RETURN_OK on success.
|
|
||||||
*/
|
|
||||||
ReturnValue_t flush(uint32_t* count) override;
|
ReturnValue_t flush(uint32_t* count) override;
|
||||||
/**
|
|
||||||
* @brief This method returns the message queue id of the last
|
|
||||||
* communication partner.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getLastPartner() const override;
|
|
||||||
/**
|
|
||||||
* @brief This method returns the message queue id of this class's
|
|
||||||
* message queue.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getId() const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This method is a simple setter for the default destination.
|
|
||||||
*/
|
|
||||||
void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
|
||||||
/**
|
|
||||||
* @brief This method is a simple getter for the default destination.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getDefaultDestination() const override;
|
|
||||||
|
|
||||||
bool isDefaultDestinationSet() const override;
|
|
||||||
|
|
||||||
ReturnValue_t lockQueue(MutexIF::TimeoutType timeoutType, dur_millis_t lockTimeout);
|
ReturnValue_t lockQueue(MutexIF::TimeoutType timeoutType, dur_millis_t lockTimeout);
|
||||||
ReturnValue_t unlockQueue();
|
ReturnValue_t unlockQueue();
|
||||||
@@ -213,23 +105,14 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
MessageQueueId_t sentFrom = NO_QUEUE,
|
||||||
bool ignoreFault = false);
|
bool ignoreFault = false);
|
||||||
|
|
||||||
// static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::queue<std::vector<uint8_t>> messageQueue;
|
std::queue<std::vector<uint8_t>> messageQueue;
|
||||||
/**
|
|
||||||
* @brief The class stores the queue id it got assigned.
|
|
||||||
* If initialization fails, the queue id is set to zero.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t mqId = MessageQueueIF::NO_QUEUE;
|
|
||||||
size_t messageSize = 0;
|
size_t messageSize = 0;
|
||||||
size_t messageDepth = 0;
|
size_t messageDepth = 0;
|
||||||
|
|
||||||
MutexIF* queueLock;
|
MutexIF* queueLock;
|
||||||
|
|
||||||
bool defaultDestinationSet = false;
|
|
||||||
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
|
||||||
MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ */
|
#endif /* FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ */
|
||||||
|
@@ -102,11 +102,15 @@ void PeriodicTask::taskFunctionality() {
|
|||||||
|
|
||||||
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
||||||
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
||||||
if (newObject == nullptr) {
|
return addComponent(newObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
|
||||||
|
if (object == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
newObject->setTaskIF(this);
|
object->setTaskIF(this);
|
||||||
objectList.push_back(newObject);
|
objectList.push_back(object);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,6 +59,16 @@ class PeriodicTask : public PeriodicTaskIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t addComponent(object_id_t object);
|
ReturnValue_t addComponent(object_id_t object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an object to the list of objects to be executed.
|
||||||
|
* The objects are executed in the order added.
|
||||||
|
* @param object pointer to the object to add.
|
||||||
|
* @return
|
||||||
|
* -@c RETURN_OK on success
|
||||||
|
* -@c RETURN_FAILED if the object could not be added.
|
||||||
|
*/
|
||||||
|
ReturnValue_t addComponent(ExecutableObjectIF* object);
|
||||||
|
|
||||||
uint32_t getPeriodMs() const;
|
uint32_t getPeriodMs() const;
|
||||||
|
|
||||||
ReturnValue_t sleepFor(uint32_t ms);
|
ReturnValue_t sleepFor(uint32_t ms);
|
||||||
|
@@ -8,11 +8,9 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
uint16_t Clock::leapSeconds = 0;
|
|
||||||
MutexIF* Clock::timeMutex = NULL;
|
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void) {
|
uint32_t Clock::getTicksPerSecond(void) {
|
||||||
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||||
return ticks;
|
return ticks;
|
||||||
@@ -117,7 +115,13 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
|||||||
// TODO errno
|
// TODO errno
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
ReturnValue_t result = checkOrCreateClockMutex();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
MutexGuard helper(timeMutex);
|
||||||
|
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||||
|
// Therefore we have to use a Mutex here
|
||||||
struct tm* timeInfo;
|
struct tm* timeInfo;
|
||||||
timeInfo = gmtime(&timeUnix.tv_sec);
|
timeInfo = gmtime(&timeUnix.tv_sec);
|
||||||
time->year = timeInfo->tm_year + 1900;
|
time->year = timeInfo->tm_year + 1900;
|
||||||
|
@@ -12,12 +12,9 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
||||||
: id(MessageQueueIF::NO_QUEUE),
|
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args),
|
||||||
lastPartner(MessageQueueIF::NO_QUEUE),
|
|
||||||
defaultDestination(MessageQueueIF::NO_QUEUE),
|
|
||||||
maxMessageSize(maxMessageSize) {
|
maxMessageSize(maxMessageSize) {
|
||||||
mq_attr attributes;
|
mq_attr attributes;
|
||||||
this->id = 0;
|
|
||||||
// Set attributes
|
// Set attributes
|
||||||
attributes.mq_curmsgs = 0;
|
attributes.mq_curmsgs = 0;
|
||||||
attributes.mq_maxmsg = messageDepth;
|
attributes.mq_maxmsg = messageDepth;
|
||||||
@@ -37,9 +34,6 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs*
|
|||||||
// Successful mq_open call
|
// Successful mq_open call
|
||||||
this->id = tempId;
|
this->id = tempId;
|
||||||
}
|
}
|
||||||
if (args != nullptr) {
|
|
||||||
this->mqArgs = *args;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue::~MessageQueue() {
|
MessageQueue::~MessageQueue() {
|
||||||
@@ -53,30 +47,6 @@ MessageQueue::~MessageQueue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault) {
|
|
||||||
return sendMessageFrom(sendTo, message, this->getId(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
|
|
||||||
return sendToDefaultFrom(message, this->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
|
|
||||||
if (this->lastPartner != 0) {
|
|
||||||
return sendMessageFrom(this->lastPartner, message, this->getId());
|
|
||||||
} else {
|
|
||||||
return NO_REPLY_PARTNER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) {
|
|
||||||
ReturnValue_t status = this->receiveMessage(message);
|
|
||||||
*receivedFrom = this->lastPartner;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
||||||
if (message == nullptr) {
|
if (message == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@@ -99,7 +69,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
int status = mq_receive(id, reinterpret_cast<char*>(message->getBuffer()),
|
int status = mq_receive(id, reinterpret_cast<char*>(message->getBuffer()),
|
||||||
message->getMaximumMessageSize(), &messagePriority);
|
message->getMaximumMessageSize(), &messagePriority);
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
this->lastPartner = message->getSender();
|
this->last = message->getSender();
|
||||||
// Check size of incoming message.
|
// Check size of incoming message.
|
||||||
if (message->getMessageSize() < message->getMinimumMessageSize()) {
|
if (message->getMessageSize() < message->getMinimumMessageSize()) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
@@ -167,8 +137,6 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getLastPartner() const { return this->lastPartner; }
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
||||||
mq_attr attrib;
|
mq_attr attrib;
|
||||||
int status = mq_getattr(id, &attrib);
|
int status = mq_getattr(id, &attrib);
|
||||||
@@ -215,26 +183,11 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getId() const { return this->id; }
|
|
||||||
|
|
||||||
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
|
||||||
this->defaultDestination = defaultDestination;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
|
||||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault);
|
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getDefaultDestination() const { return this->defaultDestination; }
|
|
||||||
|
|
||||||
bool MessageQueue::isDefaultDestinationSet() const { return (defaultDestination != NO_QUEUE); }
|
|
||||||
|
|
||||||
uint16_t MessageQueue::queueCounter = 0;
|
uint16_t MessageQueue::queueCounter = 0;
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#ifndef FSFW_OSAL_LINUX_MESSAGEQUEUE_H_
|
#ifndef FSFW_OSAL_LINUX_MESSAGEQUEUE_H_
|
||||||
#define FSFW_OSAL_LINUX_MESSAGEQUEUE_H_
|
#define FSFW_OSAL_LINUX_MESSAGEQUEUE_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/MessageQueueBase.h>
|
||||||
#include <mqueue.h>
|
#include <mqueue.h>
|
||||||
|
|
||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
* makes use of the operating system calls provided.
|
* makes use of the operating system calls provided.
|
||||||
* @ingroup message_queue
|
* @ingroup message_queue
|
||||||
*/
|
*/
|
||||||
class MessageQueue : public MessageQueueIF {
|
class MessageQueue : public MessageQueueBase {
|
||||||
friend class MessageQueueSenderIF;
|
friend class MessageQueueSenderIF;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -45,103 +46,22 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
MessageQueue(uint32_t messageDepth = 3,
|
MessageQueue(uint32_t messageDepth = 3,
|
||||||
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
MqArgs* args = nullptr);
|
MqArgs* args = nullptr);
|
||||||
|
|
||||||
|
/** Copying message queues forbidden */
|
||||||
|
MessageQueue(const MessageQueue&) = delete;
|
||||||
|
MessageQueue& operator=(const MessageQueue&) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The destructor deletes the formerly created message queue.
|
* @brief The destructor deletes the formerly created message queue.
|
||||||
* @details This is accomplished by using the delete call provided by the operating system.
|
* @details This is accomplished by using the delete call provided by the operating system.
|
||||||
*/
|
*/
|
||||||
virtual ~MessageQueue();
|
virtual ~MessageQueue();
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the given destination.
|
|
||||||
* @details It directly uses the sendMessage call of the MessageQueueSender parent, but passes
|
|
||||||
* its queue id as "sentFrom" parameter.
|
|
||||||
* @param sendTo This parameter specifies the message queue id of the destination message
|
|
||||||
* queue.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
* @param ignoreFault If set to true, the internal software fault counter is not incremented if
|
|
||||||
* queue is full.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault = false);
|
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the default destination.
|
|
||||||
* @details As in the sendMessage method, this function uses the sendToDefault call of the
|
|
||||||
* MessageQueueSender parent class and adds its queue id as "sentFrom"
|
|
||||||
* information.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message);
|
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the last communication partner.
|
|
||||||
* @details This operation simplifies answering an incoming message by using the stored
|
|
||||||
* lastParnter information as destination. If there was no message received yet
|
|
||||||
* (i.e. lastPartner is zero), an error code is returned.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
*/
|
|
||||||
ReturnValue_t reply(MessageQueueMessageIF* message);
|
|
||||||
|
|
||||||
/**
|
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
|
||||||
* @brief This function reads available messages from the message queue and returns the
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
||||||
* sender.
|
ReturnValue_t flush(uint32_t* count) override;
|
||||||
* @details It works identically to the other receiveMessage call, but in addition returns the
|
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
* sender's queue id.
|
MessageQueueId_t sentFrom, bool ignoreFault = false) override;
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
|
||||||
* @param receivedFrom A pointer to a queue id in which the sender's id is stored.
|
|
||||||
*/
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function reads available messages from the message queue.
|
|
||||||
* @details If data is available it is stored in the passed message pointer. The message's
|
|
||||||
* original content is overwritten and the sendFrom information is stored in
|
|
||||||
* the lastPartner attribute. Else, the lastPartner information remains untouched, the message's
|
|
||||||
* content is cleared and the function returns immediately.
|
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
|
||||||
*/
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message);
|
|
||||||
/**
|
|
||||||
* Deletes all pending messages in the queue.
|
|
||||||
* @param count The number of flushed messages.
|
|
||||||
* @return RETURN_OK on success.
|
|
||||||
*/
|
|
||||||
ReturnValue_t flush(uint32_t* count);
|
|
||||||
/**
|
|
||||||
* @brief This method returns the message queue id of the last communication partner.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getLastPartner() const;
|
|
||||||
/**
|
|
||||||
* @brief This method returns the message queue id of this class's message queue.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getId() const;
|
|
||||||
/**
|
|
||||||
* \brief With the sendMessage call, a queue message is sent to a receiving queue.
|
|
||||||
* \param sendTo This parameter specifies the message queue id to send the message to.
|
|
||||||
* \param message This is a pointer to a previously created message, which is sent.
|
|
||||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the
|
|
||||||
* message. This variable is set to zero by default. \param ignoreFault If set to true, the
|
|
||||||
* internal software fault counter is not incremented if queue is full.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault = false);
|
|
||||||
/**
|
|
||||||
* \brief The sendToDefault method sends a queue message to the default destination.
|
|
||||||
* \details In all other aspects, it works identical to the sendMessage method.
|
|
||||||
* \param message This is a pointer to a previously created message, which is sent.
|
|
||||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the
|
|
||||||
* message. This variable is set to zero by default.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
|
||||||
bool ignoreFault = false);
|
|
||||||
/**
|
|
||||||
* \brief This method is a simple setter for the default destination.
|
|
||||||
*/
|
|
||||||
void setDefaultDestination(MessageQueueId_t defaultDestination);
|
|
||||||
/**
|
|
||||||
* \brief This method is a simple getter for the default destination.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getDefaultDestination() const;
|
|
||||||
|
|
||||||
bool isDefaultDestinationSet() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@@ -160,33 +80,10 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
bool ignoreFault = false);
|
bool ignoreFault = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* @brief The class stores the queue id it got assigned from the operating system in this
|
|
||||||
* attribute. If initialization fails, the queue id is set to zero.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t id;
|
|
||||||
/**
|
|
||||||
* @brief In this attribute, the queue id of the last communication partner is stored
|
|
||||||
* to allow for replying.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t lastPartner;
|
|
||||||
/**
|
|
||||||
* @brief The message queue's name -a user specific information for the operating system- is
|
|
||||||
* generated automatically with the help of this static counter.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \brief This attribute stores a default destination to send messages to.
|
|
||||||
* \details It is stored to simplify sending to always-the-same receiver. The attribute may
|
|
||||||
* be set in the constructor or by a setter call to setDefaultDestination.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t defaultDestination;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the message queue, stored for unlinking
|
* The name of the message queue, stored for unlinking
|
||||||
*/
|
*/
|
||||||
char name[16];
|
char name[16] = {};
|
||||||
|
|
||||||
MqArgs mqArgs = {};
|
|
||||||
|
|
||||||
static uint16_t queueCounter;
|
static uint16_t queueCounter;
|
||||||
const size_t maxMessageSize;
|
const size_t maxMessageSize;
|
||||||
|
@@ -28,7 +28,11 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
|
|||||||
|
|
||||||
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
|
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
|
||||||
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
||||||
if (newObject == nullptr) {
|
return addComponent(newObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) {
|
||||||
|
if (object == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
||||||
<< " it implements ExecutableObjectIF!" << std::endl;
|
<< " it implements ExecutableObjectIF!" << std::endl;
|
||||||
@@ -39,8 +43,8 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
|
|||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
objectList.push_back(newObject);
|
objectList.push_back(object);
|
||||||
newObject->setTaskIF(this);
|
object->setTaskIF(this);
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,14 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t addComponent(object_id_t object) override;
|
ReturnValue_t addComponent(object_id_t object) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an object to the list of objects to be executed.
|
||||||
|
* The objects are executed in the order added.
|
||||||
|
* @param object pointer to the object to add.
|
||||||
|
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
|
||||||
|
*/
|
||||||
|
ReturnValue_t addComponent(ExecutableObjectIF* object) override;
|
||||||
|
|
||||||
uint32_t getPeriodMs() const override;
|
uint32_t getPeriodMs() const override;
|
||||||
|
|
||||||
ReturnValue_t sleepFor(uint32_t ms) override;
|
ReturnValue_t sleepFor(uint32_t ms) override;
|
||||||
|
@@ -6,9 +6,6 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/osal/rtems/RtemsBasic.h"
|
#include "fsfw/osal/rtems/RtemsBasic.h"
|
||||||
|
|
||||||
uint16_t Clock::leapSeconds = 0;
|
|
||||||
MutexIF* Clock::timeMutex = nullptr;
|
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void) {
|
uint32_t Clock::getTicksPerSecond(void) {
|
||||||
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
||||||
return static_cast<uint32_t>(ticks_per_second);
|
return static_cast<uint32_t>(ticks_per_second);
|
||||||
|
@@ -7,7 +7,8 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size, MqArgs* args)
|
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size, MqArgs* args)
|
||||||
: id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
|
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, args),
|
||||||
|
internalErrorReporter(nullptr) {
|
||||||
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
|
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
|
||||||
rtems_status_code status =
|
rtems_status_code status =
|
||||||
rtems_message_queue_create(name, message_depth, max_message_size, 0, &(this->id));
|
rtems_message_queue_create(name, message_depth, max_message_size, 0, &(this->id));
|
||||||
@@ -16,43 +17,19 @@ MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size, MqArgs
|
|||||||
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex << name << std::dec
|
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex << name << std::dec
|
||||||
<< " failed with status:" << (uint32_t)status << std::endl;
|
<< " failed with status:" << (uint32_t)status << std::endl;
|
||||||
#endif
|
#endif
|
||||||
this->id = 0;
|
this->id = MessageQueueIF::NO_QUEUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue::~MessageQueue() { rtems_message_queue_delete(id); }
|
MessageQueue::~MessageQueue() { rtems_message_queue_delete(id); }
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault) {
|
|
||||||
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
|
|
||||||
return sendToDefaultFrom(message, this->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
|
|
||||||
if (this->lastPartner != 0) {
|
|
||||||
return sendMessage(this->lastPartner, message, this->getId());
|
|
||||||
} else {
|
|
||||||
return NO_REPLY_PARTNER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) {
|
|
||||||
ReturnValue_t status = this->receiveMessage(message);
|
|
||||||
*receivedFrom = this->lastPartner;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
rtems_status_code status =
|
rtems_status_code status =
|
||||||
rtems_message_queue_receive(id, message->getBuffer(), &size, RTEMS_NO_WAIT, 1);
|
rtems_message_queue_receive(id, message->getBuffer(), &size, RTEMS_NO_WAIT, 1);
|
||||||
if (status == RTEMS_SUCCESSFUL) {
|
if (status == RTEMS_SUCCESSFUL) {
|
||||||
message->setMessageSize(size);
|
message->setMessageSize(size);
|
||||||
this->lastPartner = message->getSender();
|
this->last = message->getSender();
|
||||||
// Check size of incoming message.
|
// Check size of incoming message.
|
||||||
if (message->getMessageSize() < message->getMinimumMessageSize()) {
|
if (message->getMessageSize() < message->getMinimumMessageSize()) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
@@ -65,19 +42,11 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
return convertReturnCode(status);
|
return convertReturnCode(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getLastPartner() const { return this->lastPartner; }
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
||||||
rtems_status_code status = rtems_message_queue_flush(id, count);
|
rtems_status_code status = rtems_message_queue_flush(id, count);
|
||||||
return convertReturnCode(status);
|
return convertReturnCode(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getId() const { return this->id; }
|
|
||||||
|
|
||||||
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
|
||||||
this->defaultDestination = defaultDestination;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
message->setSender(sentFrom);
|
message->setSender(sentFrom);
|
||||||
@@ -103,15 +72,6 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueu
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
|
||||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageQueueId_t MessageQueue::getDefaultDestination() const { return this->defaultDestination; }
|
|
||||||
|
|
||||||
bool MessageQueue::isDefaultDestinationSet() const { return (defaultDestination != NO_QUEUE); }
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::convertReturnCode(rtems_status_code inValue) {
|
ReturnValue_t MessageQueue::convertReturnCode(rtems_status_code inValue) {
|
||||||
switch (inValue) {
|
switch (inValue) {
|
||||||
case RTEMS_SUCCESSFUL:
|
case RTEMS_SUCCESSFUL:
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
#ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||||
#define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
#define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/MessageQueueBase.h>
|
||||||
|
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
@@ -20,7 +22,7 @@
|
|||||||
*as well as sending and receiving messages, the class makes use of the operating system calls
|
*as well as sending and receiving messages, the class makes use of the operating system calls
|
||||||
*provided. \ingroup message_queue
|
*provided. \ingroup message_queue
|
||||||
*/
|
*/
|
||||||
class MessageQueue : public MessageQueueIF {
|
class MessageQueue : public MessageQueueBase {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief The constructor initializes and configures the message queue.
|
* @brief The constructor initializes and configures the message queue.
|
||||||
@@ -37,130 +39,24 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
MessageQueue(size_t message_depth = 3,
|
MessageQueue(size_t message_depth = 3,
|
||||||
size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
MqArgs* args = nullptr);
|
MqArgs* args = nullptr);
|
||||||
|
|
||||||
|
/** Copying message queues forbidden */
|
||||||
|
MessageQueue(const MessageQueue&) = delete;
|
||||||
|
MessageQueue& operator=(const MessageQueue&) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The destructor deletes the formerly created message queue.
|
* @brief The destructor deletes the formerly created message queue.
|
||||||
* @details This is accomplished by using the delete call provided by the operating system.
|
* @details This is accomplished by using the delete call provided by the operating system.
|
||||||
*/
|
*/
|
||||||
virtual ~MessageQueue();
|
virtual ~MessageQueue();
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the given destination.
|
|
||||||
* @details It directly uses the sendMessage call of the MessageQueueSender parent, but passes
|
|
||||||
* its queue id as "sentFrom" parameter.
|
|
||||||
* @param sendTo This parameter specifies the message queue id of the destination message
|
|
||||||
* queue.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
* @param ignoreFault If set to true, the internal software fault counter is not incremented if
|
|
||||||
* queue is full.
|
|
||||||
*/
|
|
||||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault = false);
|
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the default destination.
|
|
||||||
* @details As in the sendMessage method, this function uses the sendToDefault call of the
|
|
||||||
* MessageQueueSender parent class and adds its queue id as "sentFrom"
|
|
||||||
* information.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
*/
|
|
||||||
ReturnValue_t sendToDefault(MessageQueueMessageIF* message);
|
|
||||||
/**
|
|
||||||
* @brief This operation sends a message to the last communication partner.
|
|
||||||
* @details This operation simplifies answering an incoming message by using the stored
|
|
||||||
* lastParnter information as destination. If there was no message received yet
|
|
||||||
* (i.e. lastPartner is zero), an error code is returned.
|
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
|
||||||
*/
|
|
||||||
ReturnValue_t reply(MessageQueueMessageIF* message);
|
|
||||||
|
|
||||||
/**
|
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
|
||||||
* @brief This function reads available messages from the message queue and returns the
|
ReturnValue_t flush(uint32_t* count) override;
|
||||||
* sender.
|
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
* @details It works identically to the other receiveMessage call, but in addition returns the
|
MessageQueueId_t sentFrom = NO_QUEUE,
|
||||||
* sender's queue id.
|
bool ignoreFault = false) override;
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
|
||||||
* @param receivedFrom A pointer to a queue id in which the sender's id is stored.
|
|
||||||
*/
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function reads available messages from the message queue.
|
|
||||||
* @details If data is available it is stored in the passed message pointer. The message's
|
|
||||||
* original content is overwritten and the sendFrom information is stored in
|
|
||||||
* the lastPartner attribute. Else, the lastPartner information remains untouched, the message's
|
|
||||||
* content is cleared and the function returns immediately.
|
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
|
||||||
*/
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message);
|
|
||||||
/**
|
|
||||||
* Deletes all pending messages in the queue.
|
|
||||||
* @param count The number of flushed messages.
|
|
||||||
* @return RETURN_OK on success.
|
|
||||||
*/
|
|
||||||
ReturnValue_t flush(uint32_t* count);
|
|
||||||
/**
|
|
||||||
* @brief This method returns the message queue id of the last communication partner.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getLastPartner() const;
|
|
||||||
/**
|
|
||||||
* @brief This method returns the message queue id of this class's message queue.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getId() const;
|
|
||||||
/**
|
|
||||||
* \brief With the sendMessage call, a queue message is sent to a receiving queue.
|
|
||||||
* \details This method takes the message provided, adds the sentFrom information and passes
|
|
||||||
* it on to the destination provided with an operating system call. The OS's
|
|
||||||
* return value is returned.
|
|
||||||
* \param sendTo This parameter specifies the message queue id to send the message to.
|
|
||||||
* \param message This is a pointer to a previously created message, which is sent.
|
|
||||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the
|
|
||||||
* message. This variable is set to zero by default. \param ignoreFault If set to true, the
|
|
||||||
* internal software fault counter is not incremented if queue is full.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
|
||||||
bool ignoreFault = false);
|
|
||||||
/**
|
|
||||||
* \brief The sendToDefault method sends a queue message to the default destination.
|
|
||||||
* \details In all other aspects, it works identical to the sendMessage method.
|
|
||||||
* \param message This is a pointer to a previously created message, which is sent.
|
|
||||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the
|
|
||||||
* message. This variable is set to zero by default.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t sentFrom = NO_QUEUE,
|
|
||||||
bool ignoreFault = false);
|
|
||||||
/**
|
|
||||||
* \brief This method is a simple setter for the default destination.
|
|
||||||
*/
|
|
||||||
void setDefaultDestination(MessageQueueId_t defaultDestination);
|
|
||||||
/**
|
|
||||||
* \brief This method is a simple getter for the default destination.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getDefaultDestination() const;
|
|
||||||
|
|
||||||
bool isDefaultDestinationSet() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* @brief The class stores the queue id it got assigned from the operating system in this
|
|
||||||
* attribute. If initialization fails, the queue id is set to zero.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t id;
|
|
||||||
/**
|
|
||||||
* @brief In this attribute, the queue id of the last communication partner is stored
|
|
||||||
* to allow for replying.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t lastPartner;
|
|
||||||
/**
|
|
||||||
* @brief The message queue's name -a user specific information for the operating system- is
|
|
||||||
* generated automatically with the help of this static counter.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \brief This attribute stores a default destination to send messages to.
|
|
||||||
* \details It is stored to simplify sending to always-the-same receiver. The attribute may
|
|
||||||
* be set in the constructor or by a setter call to setDefaultDestination.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t defaultDestination;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This attribute stores a reference to the internal error reporter for reporting full
|
* \brief This attribute stores a reference to the internal error reporter for reporting full
|
||||||
* queues. \details In the event of a full destination queue, the reporter will be notified. The
|
* queues. \details In the event of a full destination queue, the reporter will be notified. The
|
||||||
|
@@ -68,11 +68,15 @@ void PeriodicTask::taskFunctionality() {
|
|||||||
|
|
||||||
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
||||||
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
|
||||||
if (newObject == nullptr) {
|
return addComponent(newObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) {
|
||||||
|
if (object == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
objectList.push_back(newObject);
|
objectList.push_back(object);
|
||||||
newObject->setTaskIF(this);
|
object->setTaskIF(this);
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@@ -59,6 +59,14 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t addComponent(object_id_t object) override;
|
ReturnValue_t addComponent(object_id_t object) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an object to the list of objects to be executed.
|
||||||
|
* The objects are executed in the order added.
|
||||||
|
* @param object pointer to the object to add.
|
||||||
|
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
|
||||||
|
*/
|
||||||
|
ReturnValue_t addComponent(ExecutableObjectIF *object) override;
|
||||||
|
|
||||||
uint32_t getPeriodMs() const override;
|
uint32_t getPeriodMs() const override;
|
||||||
|
|
||||||
ReturnValue_t sleepFor(uint32_t ms) override;
|
ReturnValue_t sleepFor(uint32_t ms) override;
|
||||||
|
@@ -66,7 +66,7 @@ class HasParametersIF {
|
|||||||
* @param newValues
|
* @param newValues
|
||||||
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
||||||
* matrix indexes.
|
* 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,
|
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper,
|
||||||
|
@@ -211,13 +211,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable or "
|
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable!" << std::endl;
|
||||||
"data pointer not set"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning("ParameterWrapper::copyFrom: Called on read-only variable!\n");
|
||||||
"ParameterWrapper::copyFrom: Called on read-only variable "
|
|
||||||
"or data pointer not set\n");
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return READONLY;
|
return READONLY;
|
||||||
@@ -226,9 +222,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (from->readonlyData == nullptr) {
|
if (from->readonlyData == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 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
|
#else
|
||||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set\n");
|
sif::printWarning("ParameterWrapper::copyFrom: Source not set!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return SOURCE_NOT_SET;
|
return SOURCE_NOT_SET;
|
||||||
@@ -237,9 +233,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (type != from->type) {
|
if (type != from->type) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch" << std::endl;
|
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch\n");
|
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return DATATYPE_MISSMATCH;
|
return DATATYPE_MISSMATCH;
|
||||||
@@ -249,9 +245,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (rows == 0 or columns == 0) {
|
if (rows == 0 or columns == 0) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 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
|
#else
|
||||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero\n");
|
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return COLUMN_OR_ROWS_ZERO;
|
return COLUMN_OR_ROWS_ZERO;
|
||||||
|
@@ -34,14 +34,14 @@ class Fuse : public SystemObject,
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
|
||||||
//! PSS detected that current on a fuse is totally out of bounds.
|
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(
|
||||||
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW);
|
1, severity::LOW); //!< PSS detected that current on a fuse is totally out of bounds.
|
||||||
//! PSS detected a fuse that went off.
|
static const Event FUSE_WENT_OFF =
|
||||||
static const Event FUSE_WENT_OFF = MAKE_EVENT(2, severity::LOW);
|
MAKE_EVENT(2, severity::LOW); //!< PSS detected a fuse that went off.
|
||||||
//! PSS detected a fuse that violates its limits.
|
static const Event POWER_ABOVE_HIGH_LIMIT =
|
||||||
static const Event POWER_ABOVE_HIGH_LIMIT = MAKE_EVENT(4, severity::LOW);
|
MAKE_EVENT(4, severity::LOW); //!< PSS detected a fuse that violates its limits.
|
||||||
//! PSS detected a fuse that violates its limits.
|
static const Event POWER_BELOW_LOW_LIMIT =
|
||||||
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW);
|
MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits.
|
||||||
|
|
||||||
typedef std::list<PowerComponentIF *> DeviceList;
|
typedef std::list<PowerComponentIF *> DeviceList;
|
||||||
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
|
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
|
||||||
|
@@ -15,9 +15,7 @@ PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, Def
|
|||||||
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
|
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
|
||||||
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
|
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
|
||||||
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
|
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#ifndef FSFW_POWER_POWERSWITCHIF_H_
|
#ifndef FSFW_POWER_POWERSWITCHIF_H_
|
||||||
#define FSFW_POWER_POWERSWITCHIF_H_
|
#define FSFW_POWER_POWERSWITCHIF_H_
|
||||||
|
|
||||||
#include "definitions.h"
|
|
||||||
#include "../events/Event.h"
|
#include "../events/Event.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +37,7 @@ class PowerSwitchIF : public HasReturnvaluesIF {
|
|||||||
* @param switchNr
|
* @param switchNr
|
||||||
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
|
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
|
||||||
*/
|
*/
|
||||||
virtual void sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) const = 0;
|
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const = 0;
|
||||||
/**
|
/**
|
||||||
* Sends a command to the Power Unit to enable a certain fuse.
|
* Sends a command to the Power Unit to enable a certain fuse.
|
||||||
*/
|
*/
|
||||||
@@ -52,7 +51,7 @@ class PowerSwitchIF : public HasReturnvaluesIF {
|
|||||||
* - @c SWITCH_OFF if the specified switch is off.
|
* - @c SWITCH_OFF if the specified switch is off.
|
||||||
* - @c RETURN_FAILED if an error occured
|
* - @c RETURN_FAILED if an error occured
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const = 0;
|
virtual ReturnValue_t getSwitchState(uint8_t switchNr) const = 0;
|
||||||
/**
|
/**
|
||||||
* get state of a fuse.
|
* get state of a fuse.
|
||||||
* @param fuseNr
|
* @param fuseNr
|
||||||
|
@@ -1,12 +1,19 @@
|
|||||||
#include "definitions.h"
|
|
||||||
#include "fsfw/power/PowerSwitcher.h"
|
#include "fsfw/power/PowerSwitcher.h"
|
||||||
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
PowerSwitcher::PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1,
|
PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2,
|
||||||
power::Switch_t setSwitch2, PowerSwitcher::State_t setStartState)
|
PowerSwitcher::State_t setStartState)
|
||||||
: power(switcher), state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
|
: state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
|
||||||
|
power = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitchId);
|
||||||
|
if (power == nullptr) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t PowerSwitcher::getStateOfSwitches() {
|
ReturnValue_t PowerSwitcher::getStateOfSwitches() {
|
||||||
SwitchReturn_t result = howManySwitches();
|
SwitchReturn_t result = howManySwitches();
|
||||||
@@ -55,15 +62,8 @@ void PowerSwitcher::turnOff() {
|
|||||||
state = WAIT_OFF;
|
state = WAIT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PowerSwitcher::active() {
|
|
||||||
if(state == WAIT_OFF or state == WAIT_ON) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() {
|
PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() {
|
||||||
if (secondSwitch == power::NO_SWITCH) {
|
if (secondSwitch == NO_SWITCH) {
|
||||||
return ONE_SWITCH;
|
return ONE_SWITCH;
|
||||||
} else {
|
} else {
|
||||||
return TWO_SWITCHES;
|
return TWO_SWITCHES;
|
||||||
|
@@ -14,28 +14,28 @@ class PowerSwitcher : public HasReturnvaluesIF {
|
|||||||
SWITCH_IS_OFF,
|
SWITCH_IS_OFF,
|
||||||
SWITCH_IS_ON,
|
SWITCH_IS_ON,
|
||||||
};
|
};
|
||||||
|
State_t state;
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
|
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
|
||||||
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
|
||||||
PowerSwitcher(PowerSwitchIF* switcher, uint8_t setSwitch1, uint8_t setSwitch2 = power::NO_SWITCH,
|
PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH,
|
||||||
State_t setStartState = SWITCH_IS_OFF);
|
State_t setStartState = SWITCH_IS_OFF);
|
||||||
|
ReturnValue_t initialize(object_id_t powerSwitchId);
|
||||||
void turnOn();
|
void turnOn();
|
||||||
void turnOff();
|
void turnOff();
|
||||||
bool active();
|
|
||||||
void doStateMachine();
|
void doStateMachine();
|
||||||
State_t getState();
|
State_t getState();
|
||||||
ReturnValue_t checkSwitchState();
|
ReturnValue_t checkSwitchState();
|
||||||
uint32_t getSwitchDelay();
|
uint32_t getSwitchDelay();
|
||||||
power::Switch_t getFirstSwitch() const;
|
uint8_t getFirstSwitch() const;
|
||||||
power::Switch_t getSecondSwitch() const;
|
uint8_t getSecondSwitch() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint8_t firstSwitch;
|
||||||
|
uint8_t secondSwitch;
|
||||||
PowerSwitchIF* power = nullptr;
|
PowerSwitchIF* power = nullptr;
|
||||||
State_t state;
|
|
||||||
power::Switch_t firstSwitch = power::NO_SWITCH;
|
|
||||||
power::Switch_t secondSwitch = power::NO_SWITCH;
|
|
||||||
|
|
||||||
|
static const uint8_t NO_SWITCH = 0xFF;
|
||||||
enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 };
|
enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 };
|
||||||
ReturnValue_t getStateOfSwitches();
|
ReturnValue_t getStateOfSwitches();
|
||||||
void commandSwitches(ReturnValue_t onOff);
|
void commandSwitches(ReturnValue_t onOff);
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
#ifndef FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
|
|
||||||
#define FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace power {
|
|
||||||
|
|
||||||
using Switch_t = uint8_t;
|
|
||||||
static constexpr Switch_t NO_SWITCH = 0xFF;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFW_SRC_FSFW_POWER_DEFINITIONS_H_ */
|
|
@@ -16,9 +16,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
|||||||
apid(apid),
|
apid(apid),
|
||||||
serviceId(serviceId),
|
serviceId(serviceId),
|
||||||
targetDestination(targetDestination) {
|
targetDestination(targetDestination) {
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
tmQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
||||||
|
@@ -12,9 +12,7 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, uint16_t ap
|
|||||||
uint32_t messageQueueDepth)
|
uint32_t messageQueueDepth)
|
||||||
: PusServiceBase(objectId, apid, serviceId),
|
: PusServiceBase(objectId, apid, serviceId),
|
||||||
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Service5EventReporting::~Service5EventReporting() {
|
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;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) {
|
|||||||
// to be registered to the event manager to listen for events.
|
// to be registered to the event manager to listen for events.
|
||||||
ReturnValue_t Service5EventReporting::initialize() {
|
ReturnValue_t Service5EventReporting::initialize() {
|
||||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||||
if (manager == nullptr) {
|
if (manager == NULL) {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
// register Service 5 as listener for events
|
// register Service 5 as listener for events
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
class Service5EventReporting : public PusServiceBase {
|
class Service5EventReporting : public PusServiceBase {
|
||||||
public:
|
public:
|
||||||
Service5EventReporting(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
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();
|
virtual ~Service5EventReporting();
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
class Service9TimeManagement : public PusServiceBase {
|
class Service9TimeManagement : public PusServiceBase {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
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 =
|
||||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||||
//!< Clock could not be set. P1: Returncode.
|
static constexpr Event CLOCK_SET_FAILURE =
|
||||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
|
||||||
|
|
||||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||||
|
|
||||||
|
@@ -12,12 +12,8 @@
|
|||||||
#include "modes/ModeDefinitions.h"
|
#include "modes/ModeDefinitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class extends the SubsystemBase to perform the management of mode tables
|
* @brief TODO: documentation missing
|
||||||
* and mode sequences
|
|
||||||
* @details
|
* @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 {
|
class Subsystem : public SubsystemBase, public HasModeSequenceIF {
|
||||||
public:
|
public:
|
||||||
|
@@ -8,13 +8,11 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
|
|||||||
uint16_t commandQueueDepth)
|
uint16_t commandQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
mode(initialMode),
|
mode(initialMode),
|
||||||
|
commandQueue(QueueFactory::instance()->createMessageQueue(commandQueueDepth,
|
||||||
|
CommandMessage::MAX_MESSAGE_SIZE)),
|
||||||
healthHelper(this, setObjectId),
|
healthHelper(this, setObjectId),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
parentId(parent) {
|
parentId(parent) {}
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
|
||||||
@@ -33,9 +31,8 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
|
|||||||
info.mode = MODE_OFF;
|
info.mode = MODE_OFF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// intentional to force an initial command during system startup
|
|
||||||
info.commandQueue = child->getCommandQueue();
|
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;
|
info.submode = SUBMODE_NONE;
|
||||||
|
@@ -15,14 +15,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup subsystems Subsystem Objects
|
* @defgroup subsystems Subsystem Objects
|
||||||
* All Subsystem and Assemblies can derive from this class. It contains helper classes to
|
* Contains all Subsystem and Assemblies
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
class SubsystemBase : public SystemObject,
|
class SubsystemBase : public SystemObject,
|
||||||
public HasModesIF,
|
public HasModesIF,
|
||||||
@@ -103,7 +96,6 @@ class SubsystemBase : public SystemObject,
|
|||||||
Submode_t targetSubmode);
|
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
|
* 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
|
* Still, we have a default for all child implementations which do not use submode inheritance
|
||||||
*/
|
*/
|
||||||
@@ -131,11 +123,11 @@ class SubsystemBase : public SystemObject,
|
|||||||
virtual void performChildOperation() = 0;
|
virtual void performChildOperation() = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) override = 0;
|
uint32_t *msToReachTheMode) = 0;
|
||||||
|
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode) override = 0;
|
virtual void startTransition(Mode_t mode, Submode_t submode) = 0;
|
||||||
|
|
||||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||||
|
|
||||||
virtual void setToExternalControl();
|
virtual void setToExternalControl();
|
||||||
|
|
||||||
|
@@ -26,21 +26,25 @@ class PeriodicTaskIF {
|
|||||||
virtual ReturnValue_t startTask() = 0;
|
virtual ReturnValue_t startTask() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a component (object) to a periodic task. The pointer to the
|
* Add a component (object) to a periodic task.
|
||||||
* task can be set optionally
|
|
||||||
* @param object
|
* @param object
|
||||||
* Add an object to the task. The most important case is to add an
|
* Add an object to the task. The object needs to implement ExecutableObjectIF
|
||||||
* executable object with a function which will be called regularly
|
|
||||||
* (see ExecutableObjectIF)
|
|
||||||
* @param setTaskIF
|
|
||||||
* Can be used to specify whether the task object pointer is passed
|
|
||||||
* to the component.
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t addComponent(object_id_t object) {
|
virtual ReturnValue_t addComponent(object_id_t object) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an object to a periodic task.
|
||||||
|
* @param object
|
||||||
|
* Add an object to the task.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t addComponent(ExecutableObjectIF* object) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ReturnValue_t sleepFor(uint32_t ms) = 0;
|
virtual ReturnValue_t sleepFor(uint32_t ms) = 0;
|
||||||
|
|
||||||
virtual uint32_t getPeriodMs() const = 0;
|
virtual uint32_t getPeriodMs() const = 0;
|
||||||
|
@@ -5,9 +5,7 @@
|
|||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) {
|
TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) {
|
||||||
auto mqArgs = MqArgs(objectId);
|
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS);
|
||||||
tcQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
DISTRIBUTER_MAX_PACKETS, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }
|
TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }
|
||||||
|
@@ -4,13 +4,14 @@
|
|||||||
|
|
||||||
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
||||||
ThermalModuleIF *thermalModule)
|
ThermalModuleIF *thermalModule)
|
||||||
: SystemObject(setObjectid), healthHelper(this, setObjectid), parameterHelper(this) {
|
: SystemObject(setObjectid),
|
||||||
if (thermalModule != nullptr) {
|
commandQueue(NULL),
|
||||||
|
healthHelper(this, setObjectid),
|
||||||
|
parameterHelper(this) {
|
||||||
|
if (thermalModule != NULL) {
|
||||||
thermalModule->registerSensor(this);
|
thermalModule->registerSensor(this);
|
||||||
}
|
}
|
||||||
auto mqArgs = MqArgs(setObjectid, static_cast<void *>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
||||||
|
@@ -51,7 +51,7 @@ class AbstractTemperatureSensor : public HasHealthIF,
|
|||||||
HasHealthIF::HealthState getHealth();
|
HasHealthIF::HealthState getHealth();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* commandQueue = nullptr;
|
MessageQueueIF* commandQueue;
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
ParameterHelper parameterHelper;
|
ParameterHelper parameterHelper;
|
||||||
|
|
||||||
|
@@ -12,9 +12,7 @@ Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1)
|
|||||||
switch1(switch1),
|
switch1(switch1),
|
||||||
heaterOnCountdown(10800000) /*about two orbits*/,
|
heaterOnCountdown(10800000) /*about two orbits*/,
|
||||||
parameterHelper(this) {
|
parameterHelper(this) {
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
eventQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
||||||
|
@@ -91,7 +91,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(Clock::TimeOfDay_t* to, const uint8_t* f
|
|||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return convertTimevalToTimeOfDay(to, &time);
|
return Clock::convertTimevalToTimeOfDay(&time, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* from,
|
ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* from,
|
||||||
@@ -489,11 +489,6 @@ ReturnValue_t CCSDSTime::checkTimeOfDay(const Clock::TimeOfDay_t* time) {
|
|||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSTime::convertTimevalToTimeOfDay(Clock::TimeOfDay_t* to, timeval* from) {
|
|
||||||
// This is rather tricky. Implement only if needed. Also, if so, move to OSAL.
|
|
||||||
return UNSUPPORTED_TIME_FORMAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CCSDSTime::convertFromCDS(timeval* to, const uint8_t* from, size_t* foundLength,
|
ReturnValue_t CCSDSTime::convertFromCDS(timeval* to, const uint8_t* from, size_t* foundLength,
|
||||||
size_t maxLength) {
|
size_t maxLength) {
|
||||||
uint8_t pField = *from;
|
uint8_t pField = *from;
|
||||||
@@ -583,7 +578,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(Clock::TimeOfDay_t* to, const CCSDSTime:
|
|||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return CCSDSTime::convertTimevalToTimeOfDay(to, &tempTimeval);
|
return Clock::convertTimevalToTimeOfDay(&tempTimeval, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSTime::convertFromCUC(timeval* to, uint8_t pField, const uint8_t* from,
|
ReturnValue_t CCSDSTime::convertFromCUC(timeval* to, uint8_t pField, const uint8_t* from,
|
||||||
|
@@ -223,7 +223,6 @@ class CCSDSTime : public HasReturnvaluesIF {
|
|||||||
uint8_t *day);
|
uint8_t *day);
|
||||||
|
|
||||||
static bool isLeapYear(uint32_t year);
|
static bool isLeapYear(uint32_t year);
|
||||||
static ReturnValue_t convertTimevalToTimeOfDay(Clock::TimeOfDay_t *to, timeval *from);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_TIMEMANAGER_CCSDSTIME_H_ */
|
#endif /* FSFW_TIMEMANAGER_CCSDSTIME_H_ */
|
||||||
|
@@ -173,6 +173,7 @@ class Clock {
|
|||||||
|
|
||||||
static MutexIF *timeMutex;
|
static MutexIF *timeMutex;
|
||||||
static uint16_t leapSeconds;
|
static uint16_t leapSeconds;
|
||||||
|
static bool leapSecondsSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_TIMEMANAGER_CLOCK_H_ */
|
#endif /* FSFW_TIMEMANAGER_CLOCK_H_ */
|
||||||
|
@@ -3,6 +3,10 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/timemanager/Clock.h"
|
#include "fsfw/timemanager/Clock.h"
|
||||||
|
|
||||||
|
uint16_t Clock::leapSeconds = 0;
|
||||||
|
MutexIF* Clock::timeMutex = nullptr;
|
||||||
|
bool Clock::leapSecondsSet = false;
|
||||||
|
|
||||||
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
|
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
|
||||||
uint16_t leapSeconds;
|
uint16_t leapSeconds;
|
||||||
ReturnValue_t result = getLeapSeconds(&leapSeconds);
|
ReturnValue_t result = getLeapSeconds(&leapSeconds);
|
||||||
@@ -29,12 +33,16 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
|
|||||||
MutexGuard helper(timeMutex);
|
MutexGuard helper(timeMutex);
|
||||||
|
|
||||||
leapSeconds = leapSeconds_;
|
leapSeconds = leapSeconds_;
|
||||||
|
leapSecondsSet = true;
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
||||||
if (timeMutex == nullptr) {
|
if (not leapSecondsSet) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
MutexGuard helper(timeMutex);
|
MutexGuard helper(timeMutex);
|
||||||
@@ -46,6 +54,16 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
|||||||
|
|
||||||
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
|
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
|
||||||
struct tm* timeInfo;
|
struct tm* timeInfo;
|
||||||
|
// According to https://en.cppreference.com/w/c/chrono/gmtime, the implementation of gmtime_s
|
||||||
|
// in the Windows CRT is incompatible with the C standard but this should not be an issue for
|
||||||
|
// this implementation
|
||||||
|
ReturnValue_t result = checkOrCreateClockMutex();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
MutexGuard helper(timeMutex);
|
||||||
|
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||||
|
// Therefore we have to use a Mutex here
|
||||||
timeInfo = gmtime(&from->tv_sec);
|
timeInfo = gmtime(&from->tv_sec);
|
||||||
to->year = timeInfo->tm_year + 1900;
|
to->year = timeInfo->tm_year + 1900;
|
||||||
to->month = timeInfo->tm_mon + 1;
|
to->month = timeInfo->tm_mon + 1;
|
||||||
|
@@ -33,47 +33,50 @@ class TmStoreBackendIF : public HasParametersIF {
|
|||||||
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
|
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
|
||||||
//! Initiating sending data to store failed. Low, par1:
|
static const Event STORE_SEND_WRITE_FAILED =
|
||||||
//! returnCode, par2: integer (debug info)
|
MAKE_EVENT(0, severity::LOW); //!< Initiating sending data to store failed. Low, par1:
|
||||||
static const Event STORE_SEND_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
|
//!< returnCode, par2: integer (debug info)
|
||||||
//! Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
static const Event STORE_WRITE_FAILED = MAKE_EVENT(
|
||||||
static const Event STORE_WRITE_FAILED = MAKE_EVENT(1, severity::LOW);
|
1, severity::LOW); //!< Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
||||||
//! Initiating reading data from store failed. Low, par1: returnCode, par2: 0
|
static const Event STORE_SEND_READ_FAILED =
|
||||||
static const Event STORE_SEND_READ_FAILED = MAKE_EVENT(2, severity::LOW);
|
MAKE_EVENT(2, severity::LOW); //!< Initiating reading data from store failed. Low, par1:
|
||||||
//! Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
//!< returnCode, par2: 0
|
||||||
static const Event STORE_READ_FAILED = MAKE_EVENT(3, severity::LOW);
|
static const Event STORE_READ_FAILED = MAKE_EVENT(
|
||||||
//! An unexpected TM packet or data message occurred. Low, par1: 0, par2: integer (debug info)
|
3, severity::LOW); //!< Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
||||||
static const Event UNEXPECTED_MSG = MAKE_EVENT(4, severity::LOW);
|
static const Event UNEXPECTED_MSG =
|
||||||
//! Storing data failed. May simply be a full store. Low, par1: returnCode,
|
MAKE_EVENT(4, severity::LOW); //!< An unexpected TM packet or data message occurred. Low,
|
||||||
//! par2: integer (sequence count of failed packet).
|
//!< par1: 0, par2: integer (debug info)
|
||||||
static const Event STORING_FAILED = MAKE_EVENT(5, severity::LOW);
|
static const Event STORING_FAILED = MAKE_EVENT(
|
||||||
//! Dumping retrieved data failed. Low, par1: returnCode,
|
5, severity::LOW); //!< Storing data failed. May simply be a full store. Low, par1:
|
||||||
//! par2: integer (sequence count of failed packet).
|
//!< returnCode, par2: integer (sequence count of failed packet).
|
||||||
static const Event TM_DUMP_FAILED = MAKE_EVENT(6, severity::LOW);
|
static const Event TM_DUMP_FAILED =
|
||||||
//! Corrupted init data or read error. Low, par1: returnCode, par2: integer (debug info)
|
MAKE_EVENT(6, severity::LOW); //!< Dumping retrieved data failed. Low, par1: returnCode,
|
||||||
//! Store was not initialized. Starts empty. Info, parameters both zero.
|
//!< par2: integer (sequence count of failed packet).
|
||||||
static const Event STORE_INIT_FAILED = MAKE_EVENT(7, severity::LOW);
|
static const Event STORE_INIT_FAILED =
|
||||||
//! Data was read out, but it is inconsistent. Low par1:
|
MAKE_EVENT(7, severity::LOW); //!< Corrupted init data or read error. Low, par1: returnCode,
|
||||||
//! Memory address of corruption, par2: integer (debug info)
|
//!< par2: integer (debug info)
|
||||||
static const Event STORE_INIT_EMPTY = MAKE_EVENT(8, severity::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);
|
static const Event STORE_CONTENT_CORRUPTED =
|
||||||
//! Info event indicating the store will be initialized, either at boot or after IOB switch.
|
MAKE_EVENT(9, severity::LOW); //!< Data was read out, but it is inconsistent. Low par1:
|
||||||
//! Info. pars: 0
|
//!< Memory address of corruption, par2: integer (debug info)
|
||||||
static const Event STORE_INITIALIZE = MAKE_EVENT(10, severity::INFO);
|
static const Event STORE_INITIALIZE =
|
||||||
//! Info event indicating the store was successfully initialized, either at boot or after
|
MAKE_EVENT(10, severity::INFO); //!< Info event indicating the store will be initialized,
|
||||||
//! IOB switch. Info. pars: 0
|
//!< either at boot or after IOB switch. Info. pars: 0
|
||||||
static const Event INIT_DONE = MAKE_EVENT(11, severity::INFO);
|
static const Event INIT_DONE = MAKE_EVENT(
|
||||||
//! Info event indicating that dumping finished successfully.
|
11, severity::INFO); //!< Info event indicating the store was successfully initialized,
|
||||||
//! par1: Number of dumped packets. par2: APID/SSC (16bits each)
|
//!< either at boot or after IOB switch. Info. pars: 0
|
||||||
static const Event DUMP_FINISHED = MAKE_EVENT(12, severity::INFO);
|
static const Event DUMP_FINISHED = MAKE_EVENT(
|
||||||
//! Info event indicating that deletion finished successfully.
|
12, severity::INFO); //!< Info event indicating that dumping finished successfully. par1:
|
||||||
//! par1:Number of deleted packets. par2: APID/SSC (16bits each)
|
//!< Number of dumped packets. par2: APID/SSC (16bits each)
|
||||||
static const Event DELETION_FINISHED = MAKE_EVENT(13, severity::INFO);
|
static const Event DELETION_FINISHED = MAKE_EVENT(
|
||||||
//! Info event indicating that something went wrong during deletion. pars: 0
|
13, severity::INFO); //!< Info event indicating that deletion finished successfully. par1:
|
||||||
static const Event DELETION_FAILED = MAKE_EVENT(14, severity::LOW);
|
//!< Number of deleted packets. par2: APID/SSC (16bits each)
|
||||||
//! Info that the a auto catalog report failed
|
static const Event DELETION_FAILED = MAKE_EVENT(
|
||||||
static const Event AUTO_CATALOGS_SENDING_FAILED = MAKE_EVENT(15, severity::INFO);
|
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() {}
|
virtual ~TmStoreBackendIF() {}
|
||||||
|
|
||||||
|
@@ -20,10 +20,8 @@ CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t a
|
|||||||
service(service),
|
service(service),
|
||||||
timeoutSeconds(commandTimeoutSeconds),
|
timeoutSeconds(commandTimeoutSeconds),
|
||||||
commandMap(numberOfParallelCommands) {
|
commandMap(numberOfParallelCommands) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
||||||
size_t mqSz = MessageQueueMessage::MAX_MESSAGE_SIZE;
|
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
|
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandingServiceBase::setPacketSource(object_id_t packetSource) {
|
void CommandingServiceBase::setPacketSource(object_id_t packetSource) {
|
||||||
|
@@ -13,9 +13,7 @@ object_id_t PusServiceBase::packetDestination = 0;
|
|||||||
|
|
||||||
PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId)
|
PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId)
|
||||||
: SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) {
|
: SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
requestQueue = QueueFactory::instance()->createMessageQueue(PUS_SERVICE_MAX_RECEPTION);
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
PUS_SERVICE_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PusServiceBase::~PusServiceBase() { QueueFactory::instance()->deleteMessageQueue(requestQueue); }
|
PusServiceBase::~PusServiceBase() { QueueFactory::instance()->deleteMessageQueue(requestQueue); }
|
||||||
|
@@ -15,9 +15,7 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, object_i
|
|||||||
tcDestination(tcDestination)
|
tcDestination(tcDestination)
|
||||||
|
|
||||||
{
|
{
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
|
||||||
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
||||||
@@ -174,18 +172,15 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tmFifo->full()) {
|
if (tmFifo->full()) {
|
||||||
if (warningSwitch) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||||
"of stored packet IDs reached!"
|
"of stored packet IDs reached!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"TmTcBridge::storeDownlinkData: TM downlink max. number "
|
"TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||||
"of stored packet IDs reached!\n");
|
"of stored packet IDs reached!\n");
|
||||||
#endif
|
#endif
|
||||||
warningSwitch = true;
|
|
||||||
}
|
|
||||||
if (overwriteOld) {
|
if (overwriteOld) {
|
||||||
tmFifo->retrieve(&storeId);
|
tmFifo->retrieve(&storeId);
|
||||||
tmStore->deleteData(storeId);
|
tmStore->deleteData(storeId);
|
||||||
|
@@ -72,8 +72,6 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
virtual uint16_t getIdentifier() override;
|
virtual uint16_t getIdentifier() override;
|
||||||
virtual MessageQueueId_t getRequestQueue() override;
|
virtual MessageQueueId_t getRequestQueue() override;
|
||||||
|
|
||||||
bool warningSwitch = true;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Cached for initialize function.
|
//! Cached for initialize function.
|
||||||
object_id_t tmStoreId = objects::NO_OBJECT;
|
object_id_t tmStoreId = objects::NO_OBJECT;
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "fsfw/FSFWVersion.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "fsfw/FSFWVersion.h"
|
||||||
|
|
||||||
#ifdef major
|
#ifdef major
|
||||||
#undef major
|
#undef major
|
||||||
#endif
|
#endif
|
||||||
|
@@ -29,7 +29,7 @@ class Version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator>(const Version& v1, const Version& v2) {
|
friend bool operator>(const Version& v1, const Version& v2) {
|
||||||
return not (v1 < v2) and not (v1 == v2);
|
return not(v1 < v2) and not(v1 == v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator<=(const Version& v1, const Version& v2) { return ((v1 == v2) or (v1 < v2)); }
|
friend bool operator<=(const Version& v1, const Version& v2) { return ((v1 == v2) or (v1 < v2)); }
|
||||||
|
@@ -21,8 +21,10 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||||
|
|
||||||
MessageQueueMockBase* mqMock = poolOwner->getMockQueueHandle();
|
MessageQueueMockBase* poolOwnerMock = poolOwner->getMockQueueHandle();
|
||||||
REQUIRE(mqMock != nullptr);
|
REQUIRE(poolOwnerMock != nullptr);
|
||||||
|
|
||||||
|
// MessageQueueIF* hkCommander = QueueFactory::instance()->createMessageQueue();
|
||||||
CommandMessage messageSent;
|
CommandMessage messageSent;
|
||||||
uint8_t messagesSent = 0;
|
uint8_t messagesSent = 0;
|
||||||
|
|
||||||
@@ -41,9 +43,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
poolOwner->dataset.setChanged(true);
|
poolOwner->dataset.setChanged(true);
|
||||||
/* Now the update message should be generated. */
|
/* Now the update message should be generated. */
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent() == true);
|
REQUIRE(poolOwnerMock->wasMessageSent() == true);
|
||||||
|
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
|
||||||
@@ -53,9 +55,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
poolOwner->dataset.setChanged(true);
|
poolOwner->dataset.setChanged(true);
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
|
||||||
@@ -63,15 +65,15 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
||||||
poolOwner->dataset.setChanged(true);
|
poolOwner->dataset.setChanged(true);
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 2);
|
CHECK(messagesSent == 2);
|
||||||
/* first message sent should be the update notification, considering
|
/* first message sent should be the update notification, considering
|
||||||
the internal list is a vector checked in insertion order. */
|
the internal list is a vector checked in insertion order. */
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
||||||
/* Clear message to avoid memory leak, our mock won't do it for us (yet) */
|
/* Clear message to avoid memory leak, our mock won't do it for us (yet) */
|
||||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||||
@@ -99,9 +101,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
|
|
||||||
/* Trigger generation of snapshot */
|
/* Trigger generation of snapshot */
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
/* Check that snapshot was generated */
|
/* Check that snapshot was generated */
|
||||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::UPDATE_SNAPSHOT_SET));
|
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::UPDATE_SNAPSHOT_SET));
|
||||||
/* Now we deserialize the snapshot into a new dataset instance */
|
/* Now we deserialize the snapshot into a new dataset instance */
|
||||||
@@ -162,12 +164,12 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
|
||||||
/* Check update snapshot was sent. */
|
/* Check update snapshot was sent. */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
|
|
||||||
/* Should have been reset. */
|
/* Should have been reset. */
|
||||||
CHECK(poolVar->hasChanged() == false);
|
CHECK(poolVar->hasChanged() == false);
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE));
|
static_cast<int>(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE));
|
||||||
/* Now we deserialize the snapshot into a new dataset instance */
|
/* Now we deserialize the snapshot into a new dataset instance */
|
||||||
@@ -209,11 +211,11 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
|
||||||
/* Check update notification was sent. */
|
/* Check update notification was sent. */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
/* Should have been reset. */
|
/* Should have been reset. */
|
||||||
CHECK(poolVar->hasChanged() == false);
|
CHECK(poolVar->hasChanged() == false);
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||||
/* Now subscribe for the dataset update (HK and update) again with subscription interface */
|
/* Now subscribe for the dataset update (HK and update) again with subscription interface */
|
||||||
@@ -225,26 +227,26 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
poolOwner->dataset.setChanged(true);
|
poolOwner->dataset.setChanged(true);
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
/* Now two messages should be sent. */
|
/* Now two messages should be sent. */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 2);
|
CHECK(messagesSent == 2);
|
||||||
mqMock->clearMessages(true);
|
poolOwnerMock->clearMessages(true);
|
||||||
|
|
||||||
poolOwner->dataset.setChanged(true);
|
poolOwner->dataset.setChanged(true);
|
||||||
poolVar->setChanged(true);
|
poolVar->setChanged(true);
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
/* Now three messages should be sent. */
|
/* Now three messages should be sent. */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 3);
|
CHECK(messagesSent == 3);
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() ==
|
CHECK(messageSent.getCommand() ==
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
||||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||||
REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast<int>(MessageQueueIF::EMPTY));
|
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == static_cast<int>(MessageQueueIF::EMPTY));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("PeriodicHKAndMessaging") {
|
SECTION("PeriodicHKAndMessaging") {
|
||||||
@@ -255,38 +257,38 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK);
|
REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK);
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
/* Now HK packet should be sent as message immediately. */
|
/* Now HK packet should be sent as message immediately. */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid);
|
LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid);
|
||||||
REQUIRE(setHandle != nullptr);
|
REQUIRE(setHandle != nullptr);
|
||||||
CHECK(poolOwner->poolManager.generateHousekeepingPacket(lpool::testSid, setHandle, false) ==
|
CHECK(poolOwner->poolManager.generateHousekeepingPacket(lpool::testSid, setHandle, false) ==
|
||||||
retval::CATCH_OK);
|
retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
CHECK(setHandle->getReportingEnabled() == true);
|
CHECK(setHandle->getReportingEnabled() == true);
|
||||||
CommandMessage hkCmd;
|
CommandMessage hkCmd;
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
CHECK(setHandle->getReportingEnabled() == false);
|
CHECK(setHandle->getReportingEnabled() == false);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false);
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
CHECK(setHandle->getReportingEnabled() == true);
|
CHECK(setHandle->getReportingEnabled() == true);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
CHECK(setHandle->getReportingEnabled() == false);
|
CHECK(setHandle->getReportingEnabled() == false);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||||
false);
|
false);
|
||||||
@@ -294,23 +296,23 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
/* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the
|
/* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the
|
||||||
resulting collection interval should be 1.0 second */
|
resulting collection interval should be 1.0 second */
|
||||||
CHECK(poolOwner->dataset.getCollectionInterval() == 1.0);
|
CHECK(poolOwner->dataset.getCollectionInterval() == 1.0);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
/* Now HK packet should be sent as message. */
|
/* Now HK packet should be sent as message. */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid);
|
HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid);
|
||||||
sid_t sidToCheck;
|
sid_t sidToCheck;
|
||||||
@@ -326,62 +328,62 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||||
/* We still expect a failure message being sent */
|
/* We still expect a failure message being sent */
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||||
false);
|
false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||||
true);
|
true);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||||
CHECK(messagesSent == 1);
|
CHECK(messagesSent == 1);
|
||||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid);
|
HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid);
|
||||||
gp_id_t gpidToCheck;
|
gp_id_t gpidToCheck;
|
||||||
@@ -407,5 +409,5 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
|||||||
/* we need to reset the subscription list because the pool owner
|
/* we need to reset the subscription list because the pool owner
|
||||||
is a global object. */
|
is a global object. */
|
||||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||||
mqMock->clearMessages(true);
|
poolOwnerMock->clearMessages(true);
|
||||||
}
|
}
|
||||||
|
@@ -3,4 +3,5 @@ target_sources(${FSFW_TEST_TGT} PRIVATE
|
|||||||
testOpDivider.cpp
|
testOpDivider.cpp
|
||||||
testBitutil.cpp
|
testBitutil.cpp
|
||||||
testCRC.cpp
|
testCRC.cpp
|
||||||
|
testTimevalOperations.cpp
|
||||||
)
|
)
|
||||||
|
@@ -0,0 +1,124 @@
|
|||||||
|
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||||
|
|
||||||
|
#include <catch2/catch_approx.hpp>
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||||
|
|
||||||
|
TEST_CASE("TimevalTest", "[timevalOperations]") {
|
||||||
|
SECTION("Comparison") {
|
||||||
|
timeval t1;
|
||||||
|
t1.tv_sec = 1648227422;
|
||||||
|
t1.tv_usec = 123456;
|
||||||
|
timeval t2;
|
||||||
|
t2.tv_sec = 1648227422;
|
||||||
|
t2.tv_usec = 123456;
|
||||||
|
REQUIRE(t1 == t2);
|
||||||
|
REQUIRE(t2 == t1);
|
||||||
|
REQUIRE_FALSE(t1 != t2);
|
||||||
|
REQUIRE_FALSE(t2 != t1);
|
||||||
|
REQUIRE(t1 <= t2);
|
||||||
|
REQUIRE(t2 <= t1);
|
||||||
|
REQUIRE(t1 >= t2);
|
||||||
|
REQUIRE(t2 >= t1);
|
||||||
|
REQUIRE_FALSE(t1 < t2);
|
||||||
|
REQUIRE_FALSE(t2 < t1);
|
||||||
|
REQUIRE_FALSE(t1 > t2);
|
||||||
|
REQUIRE_FALSE(t2 > t1);
|
||||||
|
|
||||||
|
timeval t3;
|
||||||
|
t3.tv_sec = 1648227422;
|
||||||
|
t3.tv_usec = 123457;
|
||||||
|
REQUIRE_FALSE(t1 == t3);
|
||||||
|
REQUIRE(t1 != t3);
|
||||||
|
REQUIRE(t1 <= t3);
|
||||||
|
REQUIRE_FALSE(t3 <= t1);
|
||||||
|
REQUIRE_FALSE(t1 >= t3);
|
||||||
|
REQUIRE(t3 >= t1);
|
||||||
|
REQUIRE(t1 < t3);
|
||||||
|
REQUIRE_FALSE(t3 < t1);
|
||||||
|
REQUIRE_FALSE(t1 > t3);
|
||||||
|
REQUIRE(t3 > t1);
|
||||||
|
|
||||||
|
timeval t4;
|
||||||
|
t4.tv_sec = 1648227423;
|
||||||
|
t4.tv_usec = 123456;
|
||||||
|
REQUIRE_FALSE(t1 == t4);
|
||||||
|
REQUIRE(t1 != t4);
|
||||||
|
REQUIRE(t1 <= t4);
|
||||||
|
REQUIRE_FALSE(t4 <= t1);
|
||||||
|
REQUIRE_FALSE(t1 >= t4);
|
||||||
|
REQUIRE(t4 >= t1);
|
||||||
|
REQUIRE(t1 < t4);
|
||||||
|
REQUIRE_FALSE(t4 < t1);
|
||||||
|
REQUIRE_FALSE(t1 > t4);
|
||||||
|
REQUIRE(t4 > t1);
|
||||||
|
}
|
||||||
|
SECTION("Operators") {
|
||||||
|
timeval t1;
|
||||||
|
t1.tv_sec = 1648227422;
|
||||||
|
t1.tv_usec = 123456;
|
||||||
|
timeval t2;
|
||||||
|
t2.tv_sec = 1648227422;
|
||||||
|
t2.tv_usec = 123456;
|
||||||
|
timeval t3 = t1 - t2;
|
||||||
|
REQUIRE(t3.tv_sec == 0);
|
||||||
|
REQUIRE(t3.tv_usec == 0);
|
||||||
|
timeval t4 = t1 - t3;
|
||||||
|
REQUIRE(t4.tv_sec == 1648227422);
|
||||||
|
REQUIRE(t4.tv_usec == 123456);
|
||||||
|
timeval t5 = t3 - t1;
|
||||||
|
REQUIRE(t5.tv_sec == -1648227422);
|
||||||
|
REQUIRE(t5.tv_usec == -123456);
|
||||||
|
|
||||||
|
timeval t6;
|
||||||
|
t6.tv_sec = 1648227400;
|
||||||
|
t6.tv_usec = 999999;
|
||||||
|
|
||||||
|
timeval t7 = t6 + t1;
|
||||||
|
REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull));
|
||||||
|
REQUIRE(t7.tv_usec == 123455);
|
||||||
|
|
||||||
|
timeval t8 = t1 - t6;
|
||||||
|
REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1);
|
||||||
|
REQUIRE(t8.tv_usec == 123457);
|
||||||
|
|
||||||
|
double scalar = 2;
|
||||||
|
timeval t9 = t1 * scalar;
|
||||||
|
REQUIRE(t9.tv_sec == 3296454844);
|
||||||
|
REQUIRE(t9.tv_usec == 246912);
|
||||||
|
timeval t10 = scalar * t1;
|
||||||
|
REQUIRE(t10.tv_sec == 3296454844);
|
||||||
|
REQUIRE(t10.tv_usec == 246912);
|
||||||
|
timeval t11 = t6 * scalar;
|
||||||
|
REQUIRE(t11.tv_sec == (3296454800 + 1));
|
||||||
|
REQUIRE(t11.tv_usec == 999998);
|
||||||
|
|
||||||
|
timeval t12 = t1 / scalar;
|
||||||
|
REQUIRE(t12.tv_sec == 824113711);
|
||||||
|
REQUIRE(t12.tv_usec == 61728);
|
||||||
|
|
||||||
|
timeval t13 = t6 / scalar;
|
||||||
|
REQUIRE(t13.tv_sec == 824113700);
|
||||||
|
// Rounding issue
|
||||||
|
REQUIRE(t13.tv_usec == 499999);
|
||||||
|
|
||||||
|
double scalar2 = t9 / t1;
|
||||||
|
REQUIRE(scalar2 == Catch::Approx(2.0));
|
||||||
|
double scalar3 = t1 / t6;
|
||||||
|
REQUIRE(scalar3 == Catch::Approx(1.000000013));
|
||||||
|
double scalar4 = t3 / t1;
|
||||||
|
REQUIRE(scalar4 == Catch::Approx(0));
|
||||||
|
double scalar5 = t12 / t1;
|
||||||
|
REQUIRE(scalar5 == Catch::Approx(0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("timevalOperations::toTimeval") {
|
||||||
|
double seconds = 1648227422.123456;
|
||||||
|
timeval t1 = timevalOperations::toTimeval(seconds);
|
||||||
|
REQUIRE(t1.tv_sec == 1648227422);
|
||||||
|
// Allow 1 usec rounding tolerance
|
||||||
|
REQUIRE(t1.tv_usec >= 123455);
|
||||||
|
REQUIRE(t1.tv_usec <= 123457);
|
||||||
|
}
|
||||||
|
}
|
@@ -73,7 +73,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
|||||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||||
// This ensures that the tests do not block indefinitely
|
// This ensures that the tests do not block indefinitely
|
||||||
usleep(500);
|
usleep(500);
|
||||||
REQUIRE(limitIdx < 50000);
|
REQUIRE(limitIdx < 500);
|
||||||
}
|
}
|
||||||
limitIdx = 0;
|
limitIdx = 0;
|
||||||
CHECK(bytesHaveBeenRead == true);
|
CHECK(bytesHaveBeenRead == true);
|
||||||
|
@@ -5,15 +5,17 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "fsfw/ipc/CommandMessage.h"
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueBase.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||||
|
|
||||||
class MessageQueueMockBase : public MessageQueueIF {
|
class MessageQueueMockBase : public MessageQueueBase {
|
||||||
public:
|
public:
|
||||||
MessageQueueId_t myQueueId = tconst::testQueueId;
|
MessageQueueMockBase()
|
||||||
|
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {}
|
||||||
|
|
||||||
uint8_t messageSentCounter = 0;
|
uint8_t messageSentCounter = 0;
|
||||||
bool defaultDestSet = false;
|
|
||||||
bool messageSent = false;
|
bool messageSent = false;
|
||||||
|
|
||||||
bool wasMessageSent(uint8_t* messageSentCounter = nullptr, bool resetCounter = true) {
|
bool wasMessageSent(uint8_t* messageSentCounter = nullptr, bool resetCounter = true) {
|
||||||
@@ -38,53 +40,30 @@ class MessageQueueMockBase : public MessageQueueIF {
|
|||||||
return receiveMessage(&message);
|
return receiveMessage(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) {
|
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override {
|
||||||
return sendMessage(myQueueId, message);
|
|
||||||
};
|
|
||||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
|
||||||
MessageQueueId_t* receivedFrom) {
|
|
||||||
return receiveMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) {
|
|
||||||
if (messagesSentQueue.empty()) {
|
if (messagesSentQueue.empty()) {
|
||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
}
|
}
|
||||||
|
this->last = message->getSender();
|
||||||
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||||
message->getMessageSize());
|
message->getMessageSize());
|
||||||
messagesSentQueue.pop();
|
messagesSentQueue.pop();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
virtual ReturnValue_t flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; }
|
virtual ReturnValue_t flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; }
|
||||||
virtual MessageQueueId_t getLastPartner() const { return myQueueId; }
|
|
||||||
virtual MessageQueueId_t getId() const { return myQueueId; }
|
|
||||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault = false) {
|
MessageQueueId_t sentFrom,
|
||||||
return sendMessage(sendTo, message);
|
bool ignoreFault = false) override {
|
||||||
}
|
|
||||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
|
||||||
bool ignoreFault = false) {
|
|
||||||
return sendMessage(myQueueId, message);
|
|
||||||
}
|
|
||||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) {
|
|
||||||
return sendMessage(myQueueId, message);
|
|
||||||
}
|
|
||||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
|
||||||
bool ignoreFault = false) override {
|
|
||||||
messageSent = true;
|
messageSent = true;
|
||||||
messageSentCounter++;
|
messageSentCounter++;
|
||||||
MessageQueueMessage& messageRef = *(dynamic_cast<MessageQueueMessage*>(message));
|
MessageQueueMessage& messageRef = *(dynamic_cast<MessageQueueMessage*>(message));
|
||||||
messagesSentQueue.push(messageRef);
|
messagesSentQueue.push(messageRef);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) {
|
|
||||||
myQueueId = defaultDestination;
|
|
||||||
defaultDestSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual MessageQueueId_t getDefaultDestination() const { return myQueueId; }
|
virtual ReturnValue_t reply(MessageQueueMessageIF* message) override {
|
||||||
virtual bool isDefaultDestinationSet() const { return defaultDestSet; }
|
return sendMessageFrom(MessageQueueIF::NO_QUEUE, message, this->getId(), false);
|
||||||
|
}
|
||||||
|
|
||||||
void clearMessages(bool clearCommandMessages = true) {
|
void clearMessages(bool clearCommandMessages = true) {
|
||||||
while (not messagesSentQueue.empty()) {
|
while (not messagesSentQueue.empty()) {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
target_sources(${FSFW_TEST_TGT} PRIVATE
|
target_sources(${FSFW_TEST_TGT} PRIVATE
|
||||||
TestMessageQueue.cpp
|
TestMessageQueue.cpp
|
||||||
TestSemaphore.cpp
|
TestSemaphore.cpp
|
||||||
|
TestClock.cpp
|
||||||
)
|
)
|
||||||
|
86
tests/src/fsfw_tests/unit/osal/TestClock.cpp
Normal file
86
tests/src/fsfw_tests/unit/osal/TestClock.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||||
|
#include <fsfw/timemanager/Clock.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <catch2/catch_approx.hpp>
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||||
|
|
||||||
|
TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]") {
|
||||||
|
SECTION("Test getClock") {
|
||||||
|
timeval time;
|
||||||
|
ReturnValue_t result = Clock::getClock_timeval(&time);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
Clock::TimeOfDay_t timeOfDay;
|
||||||
|
result = Clock::getDateAndTime(&timeOfDay);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
timeval timeOfDayAsTimeval;
|
||||||
|
result = Clock::convertTimeOfDayToTimeval(&timeOfDay, &timeOfDayAsTimeval);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
// We require timeOfDayAsTimeval to be larger than time as it
|
||||||
|
// was request a few ns later
|
||||||
|
double difference = timevalOperations::toDouble(timeOfDayAsTimeval - time);
|
||||||
|
CHECK(difference >= 0.0);
|
||||||
|
CHECK(difference <= 0.005);
|
||||||
|
|
||||||
|
// Conversion in the other direction
|
||||||
|
Clock::TimeOfDay_t timevalAsTimeOfDay;
|
||||||
|
result = Clock::convertTimevalToTimeOfDay(&time, &timevalAsTimeOfDay);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
CHECK(timevalAsTimeOfDay.year <= timeOfDay.year);
|
||||||
|
// TODO We should write TimeOfDay operators!
|
||||||
|
}
|
||||||
|
SECTION("Leap seconds") {
|
||||||
|
uint16_t leapSeconds = 0;
|
||||||
|
ReturnValue_t result = Clock::getLeapSeconds(&leapSeconds);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||||
|
REQUIRE(leapSeconds == 0);
|
||||||
|
result = Clock::setLeapSeconds(18);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
result = Clock::getLeapSeconds(&leapSeconds);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
REQUIRE(leapSeconds == 18);
|
||||||
|
}
|
||||||
|
SECTION("usec Test") {
|
||||||
|
timeval timeAsTimeval;
|
||||||
|
ReturnValue_t result = Clock::getClock_timeval(&timeAsTimeval);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
uint64_t timeAsUsec = 0;
|
||||||
|
result = Clock::getClock_usecs(&timeAsUsec);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
double timeAsUsecDouble = static_cast<double>(timeAsUsec) / 1000000.0;
|
||||||
|
timeval timeAsUsecTimeval = timevalOperations::toTimeval(timeAsUsecDouble);
|
||||||
|
double difference = timevalOperations::toDouble(timeAsUsecTimeval - timeAsTimeval);
|
||||||
|
// We accept 5 ms difference
|
||||||
|
CHECK(difference >= 0.0);
|
||||||
|
CHECK(difference <= 0.005);
|
||||||
|
uint64_t timevalAsUint64 = static_cast<uint64_t>(timeAsTimeval.tv_sec) * 1000000ull +
|
||||||
|
static_cast<uint64_t>(timeAsTimeval.tv_usec);
|
||||||
|
CHECK((timeAsUsec - timevalAsUint64) >= 0);
|
||||||
|
CHECK((timeAsUsec - timevalAsUint64) <= (5 * 1000));
|
||||||
|
}
|
||||||
|
SECTION("Test j2000") {
|
||||||
|
double j2000;
|
||||||
|
timeval time;
|
||||||
|
time.tv_sec = 1648208539;
|
||||||
|
time.tv_usec = 0;
|
||||||
|
ReturnValue_t result = Clock::convertTimevalToJD2000(time, &j2000);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
double correctJ2000 = 2459663.98772 - 2451545.0;
|
||||||
|
CHECK(j2000 == Catch::Approx(correctJ2000).margin(1.2 * 1e-8));
|
||||||
|
}
|
||||||
|
SECTION("Convert to TT") {
|
||||||
|
timeval utcTime;
|
||||||
|
utcTime.tv_sec = 1648208539;
|
||||||
|
utcTime.tv_usec = 999000;
|
||||||
|
timeval tt;
|
||||||
|
ReturnValue_t result = Clock::setLeapSeconds(27);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
result = Clock::convertUTCToTT(utcTime, &tt);
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
CHECK(tt.tv_usec == 183000);
|
||||||
|
// The plus 1 is a own forced overflow of usecs
|
||||||
|
CHECK(tt.tv_sec == (1648208539 + 27 + 10 + 32 + 1));
|
||||||
|
}
|
||||||
|
}
|
@@ -81,7 +81,8 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
|||||||
std::string timeAscii = "2022-12-31T23:59:59.123Z";
|
std::string timeAscii = "2022-12-31T23:59:59.123Z";
|
||||||
Clock::TimeOfDay_t timeTo;
|
Clock::TimeOfDay_t timeTo;
|
||||||
const uint8_t* timeChar = reinterpret_cast<const uint8_t*>(timeAscii.c_str());
|
const uint8_t* timeChar = reinterpret_cast<const uint8_t*>(timeAscii.c_str());
|
||||||
CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length());
|
auto result = CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length());
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
REQUIRE(timeTo.year == 2022);
|
REQUIRE(timeTo.year == 2022);
|
||||||
REQUIRE(timeTo.month == 12);
|
REQUIRE(timeTo.month == 12);
|
||||||
REQUIRE(timeTo.day == 31);
|
REQUIRE(timeTo.day == 31);
|
||||||
@@ -89,6 +90,19 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
|||||||
REQUIRE(timeTo.minute == 59);
|
REQUIRE(timeTo.minute == 59);
|
||||||
REQUIRE(timeTo.second == 59);
|
REQUIRE(timeTo.second == 59);
|
||||||
REQUIRE(timeTo.usecond == Catch::Approx(123000));
|
REQUIRE(timeTo.usecond == Catch::Approx(123000));
|
||||||
|
|
||||||
|
std::string timeAscii2 = "2022-365T23:59:59.123Z";
|
||||||
|
const uint8_t* timeChar2 = reinterpret_cast<const uint8_t*>(timeAscii2.c_str());
|
||||||
|
Clock::TimeOfDay_t timeTo2;
|
||||||
|
result = CCSDSTime::convertFromCcsds(&timeTo2, timeChar2, timeAscii2.length());
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
REQUIRE(timeTo2.year == 2022);
|
||||||
|
REQUIRE(timeTo2.month == 12);
|
||||||
|
REQUIRE(timeTo2.day == 31);
|
||||||
|
REQUIRE(timeTo2.hour == 23);
|
||||||
|
REQUIRE(timeTo2.minute == 59);
|
||||||
|
REQUIRE(timeTo2.second == 59);
|
||||||
|
REQUIRE(timeTo2.usecond == Catch::Approx(123000));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("CDS Conversions") {
|
SECTION("CDS Conversions") {
|
||||||
@@ -119,6 +133,7 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
|||||||
CHECK(cdsTime.msDay_h == 0xE0);
|
CHECK(cdsTime.msDay_h == 0xE0);
|
||||||
CHECK(cdsTime.msDay_l == 0xC5);
|
CHECK(cdsTime.msDay_l == 0xC5);
|
||||||
CHECK(cdsTime.msDay_ll == 0xC3);
|
CHECK(cdsTime.msDay_ll == 0xC3);
|
||||||
|
CHECK(cdsTime.pField == CCSDSTime::P_FIELD_CDS_SHORT);
|
||||||
|
|
||||||
// Conversion back to timeval
|
// Conversion back to timeval
|
||||||
timeval timeReturnAsTimeval;
|
timeval timeReturnAsTimeval;
|
||||||
@@ -128,5 +143,56 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
|||||||
timeval difference = timeAsTimeval - timeReturnAsTimeval;
|
timeval difference = timeAsTimeval - timeReturnAsTimeval;
|
||||||
CHECK(difference.tv_usec == 456);
|
CHECK(difference.tv_usec == 456);
|
||||||
CHECK(difference.tv_sec == 0);
|
CHECK(difference.tv_sec == 0);
|
||||||
|
|
||||||
|
Clock::TimeOfDay_t timeReturnAsTimeOfDay;
|
||||||
|
result = CCSDSTime::convertFromCDS(&timeReturnAsTimeOfDay, &cdsTime);
|
||||||
|
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
CHECK(timeReturnAsTimeOfDay.year == 2020);
|
||||||
|
CHECK(timeReturnAsTimeOfDay.month == 2);
|
||||||
|
CHECK(timeReturnAsTimeOfDay.day == 29);
|
||||||
|
CHECK(timeReturnAsTimeOfDay.hour == 13);
|
||||||
|
CHECK(timeReturnAsTimeOfDay.minute == 24);
|
||||||
|
CHECK(timeReturnAsTimeOfDay.second == 45);
|
||||||
|
// micro seconds precision is lost
|
||||||
|
CHECK(timeReturnAsTimeOfDay.usecond == 123000);
|
||||||
|
|
||||||
|
Clock::TimeOfDay_t timeReturnAsTodFromBuffer;
|
||||||
|
const uint8_t* buffer = reinterpret_cast<const uint8_t*>(&cdsTime);
|
||||||
|
result = CCSDSTime::convertFromCDS(&timeReturnAsTodFromBuffer, buffer, sizeof(cdsTime));
|
||||||
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.year == time.year);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.month == time.month);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.day == time.day);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.hour == time.hour);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.minute == time.minute);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.second == time.second);
|
||||||
|
CHECK(timeReturnAsTodFromBuffer.usecond == 123000);
|
||||||
|
|
||||||
|
Clock::TimeOfDay_t todFromCCSDS;
|
||||||
|
result = CCSDSTime::convertFromCcsds(&todFromCCSDS, buffer, sizeof(cdsTime));
|
||||||
|
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
CHECK(todFromCCSDS.year == time.year);
|
||||||
|
CHECK(todFromCCSDS.month == time.month);
|
||||||
|
CHECK(todFromCCSDS.day == time.day);
|
||||||
|
CHECK(todFromCCSDS.hour == time.hour);
|
||||||
|
CHECK(todFromCCSDS.minute == time.minute);
|
||||||
|
CHECK(todFromCCSDS.second == time.second);
|
||||||
|
CHECK(todFromCCSDS.usecond == 123000);
|
||||||
|
}
|
||||||
|
SECTION("CCSDS Failures") {
|
||||||
|
Clock::TimeOfDay_t time;
|
||||||
|
time.year = 2020;
|
||||||
|
time.month = 12;
|
||||||
|
time.day = 32;
|
||||||
|
time.hour = 13;
|
||||||
|
time.minute = 24;
|
||||||
|
time.second = 45;
|
||||||
|
time.usecond = 123456;
|
||||||
|
CCSDSTime::Ccs_mseconds to;
|
||||||
|
auto result = CCSDSTime::convertToCcsds(&to, &time);
|
||||||
|
REQUIRE(result == CCSDSTime::INVALID_TIME_FORMAT);
|
||||||
|
CCSDSTime::Ccs_seconds to2;
|
||||||
|
result = CCSDSTime::convertToCcsds(&to2, &time);
|
||||||
|
REQUIRE(result == CCSDSTime::INVALID_TIME_FORMAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -17,15 +17,15 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") {
|
|||||||
fsfw::Version v1 = fsfw::Version(1, 1, 1);
|
fsfw::Version v1 = fsfw::Version(1, 1, 1);
|
||||||
fsfw::Version v2 = fsfw::Version(1, 1, 1);
|
fsfw::Version v2 = fsfw::Version(1, 1, 1);
|
||||||
REQUIRE(v1 == v2);
|
REQUIRE(v1 == v2);
|
||||||
REQUIRE(not (v1 < v2));
|
REQUIRE(not(v1 < v2));
|
||||||
REQUIRE(not (v1 > v2));
|
REQUIRE(not(v1 > v2));
|
||||||
REQUIRE(v1 <= v2);
|
REQUIRE(v1 <= v2);
|
||||||
REQUIRE(v1 >= v2);
|
REQUIRE(v1 >= v2);
|
||||||
v1.revision -= 1;
|
v1.revision -= 1;
|
||||||
REQUIRE(v1 != v2);
|
REQUIRE(v1 != v2);
|
||||||
REQUIRE(not (v1 == v2));
|
REQUIRE(not(v1 == v2));
|
||||||
REQUIRE(not (v1 > v2));
|
REQUIRE(not(v1 > v2));
|
||||||
REQUIRE(not (v1 >= v2));
|
REQUIRE(not(v1 >= v2));
|
||||||
REQUIRE(v1 < v2);
|
REQUIRE(v1 < v2);
|
||||||
REQUIRE(v1 <= v2);
|
REQUIRE(v1 <= v2);
|
||||||
v1.revision += 1;
|
v1.revision += 1;
|
||||||
@@ -33,60 +33,60 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") {
|
|||||||
REQUIRE(v1 != v2);
|
REQUIRE(v1 != v2);
|
||||||
REQUIRE(v1 < v2);
|
REQUIRE(v1 < v2);
|
||||||
REQUIRE(v1 <= v2);
|
REQUIRE(v1 <= v2);
|
||||||
REQUIRE(not (v1 == v2));
|
REQUIRE(not(v1 == v2));
|
||||||
REQUIRE(not (v1 > v2));
|
REQUIRE(not(v1 > v2));
|
||||||
REQUIRE(not (v1 >= v2));
|
REQUIRE(not(v1 >= v2));
|
||||||
v1.minor += 1;
|
v1.minor += 1;
|
||||||
v1.major -= 1;
|
v1.major -= 1;
|
||||||
REQUIRE(v1 != v2);
|
REQUIRE(v1 != v2);
|
||||||
REQUIRE(v1 < v2);
|
REQUIRE(v1 < v2);
|
||||||
REQUIRE(v1 <= v2);
|
REQUIRE(v1 <= v2);
|
||||||
REQUIRE(not (v1 == v2));
|
REQUIRE(not(v1 == v2));
|
||||||
REQUIRE(not (v1 > v2));
|
REQUIRE(not(v1 > v2));
|
||||||
REQUIRE(not (v1 >= v2));
|
REQUIRE(not(v1 >= v2));
|
||||||
v1.major += 1;
|
v1.major += 1;
|
||||||
REQUIRE(v1 == v2);
|
REQUIRE(v1 == v2);
|
||||||
REQUIRE(v1 <= v2);
|
REQUIRE(v1 <= v2);
|
||||||
REQUIRE(v1 >= v2);
|
REQUIRE(v1 >= v2);
|
||||||
REQUIRE(not (v1 != v2));
|
REQUIRE(not(v1 != v2));
|
||||||
REQUIRE(not (v1 > v2));
|
REQUIRE(not(v1 > v2));
|
||||||
REQUIRE(not (v1 < v2));
|
REQUIRE(not(v1 < v2));
|
||||||
v1.major += 1;
|
v1.major += 1;
|
||||||
v1.minor -= 1;
|
v1.minor -= 1;
|
||||||
REQUIRE(v1 != v2);
|
REQUIRE(v1 != v2);
|
||||||
REQUIRE(v1 > v2);
|
REQUIRE(v1 > v2);
|
||||||
REQUIRE(v1 >= v2);
|
REQUIRE(v1 >= v2);
|
||||||
REQUIRE(not (v1 == v2));
|
REQUIRE(not(v1 == v2));
|
||||||
REQUIRE(not (v1 < v2));
|
REQUIRE(not(v1 < v2));
|
||||||
REQUIRE(not (v1 <= v2));
|
REQUIRE(not(v1 <= v2));
|
||||||
v1.major -= 1;
|
v1.major -= 1;
|
||||||
v1.minor += 2;
|
v1.minor += 2;
|
||||||
v1.revision -= 1;
|
v1.revision -= 1;
|
||||||
REQUIRE(v1 != v2);
|
REQUIRE(v1 != v2);
|
||||||
REQUIRE(v1 > v2);
|
REQUIRE(v1 > v2);
|
||||||
REQUIRE(v1 >= v2);
|
REQUIRE(v1 >= v2);
|
||||||
REQUIRE(not (v1 == v2));
|
REQUIRE(not(v1 == v2));
|
||||||
REQUIRE(not (v1 < v2));
|
REQUIRE(not(v1 < v2));
|
||||||
REQUIRE(not (v1 <= v2));
|
REQUIRE(not(v1 <= v2));
|
||||||
v1.minor -= 1;
|
v1.minor -= 1;
|
||||||
v1.revision += 2;
|
v1.revision += 2;
|
||||||
REQUIRE(v1 != v2);
|
REQUIRE(v1 != v2);
|
||||||
REQUIRE(v1 > v2);
|
REQUIRE(v1 > v2);
|
||||||
REQUIRE(v1 >= v2);
|
REQUIRE(v1 >= v2);
|
||||||
REQUIRE(not (v1 == v2));
|
REQUIRE(not(v1 == v2));
|
||||||
REQUIRE(not (v1 < v2));
|
REQUIRE(not(v1 < v2));
|
||||||
REQUIRE(not (v1 <= v2));
|
REQUIRE(not(v1 <= v2));
|
||||||
v1.revision -= 1;
|
v1.revision -= 1;
|
||||||
REQUIRE(v1 == v2);
|
REQUIRE(v1 == v2);
|
||||||
REQUIRE(v1 <= v2);
|
REQUIRE(v1 <= v2);
|
||||||
REQUIRE(v1 >= v2);
|
REQUIRE(v1 >= v2);
|
||||||
REQUIRE(not (v1 != v2));
|
REQUIRE(not(v1 != v2));
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "v" << fsfw::FSFW_VERSION << std::endl;
|
sif::info << "v" << fsfw::FSFW_VERSION << std::endl;
|
||||||
#endif
|
#endif
|
||||||
char verString[10] = {};
|
char verString[10] = {};
|
||||||
fsfw::FSFW_VERSION.getVersion(verString, sizeof(verString));
|
fsfw::FSFW_VERSION.getVersion(verString, sizeof(verString));
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
printf("v%s\n",verString);
|
printf("v%s\n", verString);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user