Compare commits
208 Commits
mohr/dhb2n
...
tmtcbridge
Author | SHA1 | Date | |
---|---|---|---|
6f05d6b7b0 | |||
84bbef0167 | |||
88b2b0e005 | |||
6445debfa1 | |||
8014e4adf9 | |||
84dc7ac0ce | |||
ec12ab5daa | |||
69c94645df | |||
37e850c5a7 | |||
2646707d3f | |||
539d7aac9e | |||
0a23f2c85a | |||
06e30684fe | |||
e2b66df72e | |||
7b828f233a | |||
c3d1000cd5 | |||
8e0e57714d | |||
cc9e54ea6b | |||
31465a4e0f | |||
c0e5d1eb99 | |||
3bc5d4a2e0 | |||
ab86599db3 | |||
034eb34c2e | |||
38789e053b | |||
4374c7c4f4 | |||
5343844be5 | |||
e11eabdbcf | |||
3250bbf269 | |||
a78fe0a7f3 | |||
acfc1cbf21 | |||
d17ec02cf0 | |||
e300490b93 | |||
f2461cd7e9 | |||
01cc619e67 | |||
0f811777a7 | |||
e93137939e | |||
2339712373 | |||
d9d253d3bb | |||
bd586f6564 | |||
1f88c006d9 | |||
5f481739d8 | |||
7e94baceef | |||
7ee83e4e5d | |||
64787f85ca | |||
1cacceddad | |||
5c35b8e3cd | |||
9b05e8f274 | |||
7766b24a1d | |||
eb223dae88 | |||
3656662d88 | |||
fe71978467 | |||
b646717a76 | |||
99d8c845f2 | |||
9a4ae550ab | |||
c64b9b3e71 | |||
226818886f | |||
da12495335 | |||
049e3b431d | |||
bd189518b6 | |||
0e7c6b117f | |||
accaf855ee | |||
75fa7caf25 | |||
d16c5024dc | |||
a4531e4ced | |||
97c629ad84 | |||
bf12f284fa | |||
ba62c28b64 | |||
7adb47aecb | |||
5bb66c9723 | |||
8589f4d63a | |||
ca80589233 | |||
f2ebaed092 | |||
f0b89e98df | |||
05cad893a2 | |||
5557d95994 | |||
fc24c9b5d8 | |||
5b0ea91222 | |||
7ef69c839c | |||
9b798d798e | |||
8eb869e073 | |||
b13453f46b | |||
d0e322d7e2 | |||
46a1c2bace | |||
2643ff194c | |||
ecde164f68 | |||
50930b41ba | |||
d6ee2ed400 | |||
f2150ff9c2 | |||
1b9c98f3fe | |||
742152b28e | |||
bf4ca56658 | |||
16ffa00155 | |||
14c681c93a | |||
0958c3a00e | |||
d699d16307 | |||
3b0fed733f | |||
23d3812fe3 | |||
dec7db3ae2 | |||
65a5abab49 | |||
0129783e34 | |||
cabe0868ec | |||
f05295bada | |||
160ff799ac | |||
b85ca64690 | |||
3bc3da5a8d | |||
f8c07ec9cf | |||
8199b8f359 | |||
cbc8dbcdd4 | |||
d31a5306f0 | |||
a236a5ec50 | |||
03620970e2 | |||
8fe8d810e9 | |||
9483c2809d | |||
fe3d6bd432 | |||
c5f91926c9 | |||
be4a87535d | |||
99927b8e95 | |||
5e5eb82830 | |||
686dc97234 | |||
2a842666d5 | |||
c013fcc1f5 | |||
1f58ba1f9b | |||
002845108d | |||
1b8fc2af19 | |||
72d7c43445 | |||
ab9b6c8c89 | |||
69d338f9bb | |||
68223869d5 | |||
93fda71989 | |||
7b0db08962 | |||
0956fbc740 | |||
b48e0fdc0d | |||
1d084ee22f | |||
1bea2344f6 | |||
d7e16a67a7 | |||
6021d897b8 | |||
83a6f0b5f8 | |||
a9c6c088f2 | |||
e03e7f5260 | |||
b6a3c206cc | |||
5b352978c5 | |||
819a298b19 | |||
39946bff58 | |||
16246d6ece | |||
5c84f12440 | |||
2a203ae13d | |||
6ca1a5c796 | |||
83c2c4825c | |||
194b3e100a | |||
177c39dd53 | |||
530a261e14 | |||
c913fe40bf | |||
70ec08bf1d | |||
ef23665d9c | |||
eefc122292 | |||
bee33526a1 | |||
0e8f5ddd26 | |||
672fca5169 | |||
84b9d1ce21 | |||
e5b5c7d253 | |||
9a0cc64be3 | |||
00f1c5bbe9 | |||
8a61af779d | |||
6efa482eb0 | |||
f0fa1bf477 | |||
91ebf98c28 | |||
e1d4209fbe | |||
e302c89f74 | |||
a38279f813 | |||
7600ed1ea7 | |||
61ab770d9d | |||
f715b65d6e | |||
c11af63015 | |||
852f27cec2 | |||
fa01798ebb | |||
dc1583c932 | |||
81a7de2814 | |||
d26f230bee | |||
4db124c680 | |||
2df66c9304 | |||
54ad6b3016 | |||
73e313c35b | |||
dd2f42d22b | |||
11422a658c | |||
ec7566fb8c | |||
652c31a683 | |||
bfe120636c | |||
a8041f220f | |||
dd636b186b | |||
3349fc36f8 | |||
df06064df0 | |||
1d6ccfe5ab | |||
221df7ece6 | |||
7f180ac1fa | |||
1eceef4645 | |||
acab5f6bce | |||
10dd855244 | |||
f824004897 | |||
7c5308429c | |||
f78344b8fb | |||
77f7fa2ef1 | |||
78314ad966 | |||
e0c780f21c | |||
876815b1c9 | |||
b0ecf87580 | |||
68ce8b5b08 | |||
fe03da6def | |||
4f7f8310c9 |
71
CHANGELOG.md
71
CHANGELOG.md
@ -12,6 +12,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
|
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
|
||||||
|
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
|
||||||
|
subservice not working properly.
|
||||||
|
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
||||||
|
seconds instead of uptime.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
||||||
|
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
||||||
|
only the X scaling factor was used.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
||||||
|
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||||
|
to false correctly because the `read` and `write` calls were missing.
|
||||||
|
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
||||||
|
of the correct unsegmented flags (0b11) as specified in the standard.
|
||||||
|
- TC Scheduler Service 11: Add size and CRC check for contained TC.
|
||||||
|
- Only delete health table entry in `HealthHelper` destructor if
|
||||||
|
health table was set.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
|
||||||
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
|
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
|
||||||
Also properly reset the reply size for successfull transfers and erroneous transfers.
|
Also properly reset the reply size for successfull transfers and erroneous transfers.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
|
||||||
@ -24,19 +41,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
- DHB TM handler `handleDeviceTM` renamed to `handleDeviceTm` and now takes
|
- `CServiceHealthCommanding`: Add announce all health info implementation
|
||||||
`util::DataWrapper` as the data input argument. This allows more flexibility in the possible
|
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
||||||
types of telemetry.
|
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/669
|
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
||||||
- Add `util::DataWrapper` class inside the `util` module. This is a tagged union which allows
|
option on the TCP server. CTOR prototype has changed and expects an explicit
|
||||||
to specify raw data either as a classic C-style raw pointer and size or as a `SerializeIF`
|
TCP configuration struct to be passed.
|
||||||
pointer.
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/722
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/668
|
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
|
||||||
|
- `UioMapper` is able to resolve symlinks now.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
|
||||||
- Add new `UnsignedByteField` class
|
- Add new `UnsignedByteField` class
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
|
- `CService201HealthCommanding` renamed to `CServiceHealthCommanding`,
|
||||||
|
service ID customizable now. `CServiceHealthCommanding` expects configuration struct
|
||||||
|
`HealthServiceCfg` now
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
||||||
|
- `AcceptsTelemetryIF`: `getReportReceptionQueue` is const now
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/712
|
||||||
|
- Moved some container returnvalues to dedicated header and namespace
|
||||||
|
to they can be used without template specification.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/707
|
||||||
- Remove default secondary header argument for
|
- Remove default secondary header argument for
|
||||||
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
|
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
|
||||||
`uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)`
|
`uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)`
|
||||||
@ -65,6 +94,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
|
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
|
||||||
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
|
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
|
||||||
|
- Move some generic `StorageManagerIF` implementations from `LocalPool` to
|
||||||
|
interface itself so it can be re-used more easily. Also add new
|
||||||
|
abstract function `bool hasDataAtId(store_address_t storeId) const`.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/685
|
||||||
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
|
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
|
||||||
- Make functions `const` where it makes sense
|
- Make functions `const` where it makes sense
|
||||||
- Add `const char* getName const` abstract function
|
- Add `const char* getName const` abstract function
|
||||||
@ -92,6 +125,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
implementation without an extra component
|
implementation without an extra component
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
|
||||||
|
|
||||||
|
## HAL
|
||||||
|
|
||||||
|
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
||||||
|
lot more sense because each ComIF should be responsible for one SPI bus.
|
||||||
|
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
||||||
|
it is not automatically called when calling the setter function for SPI speed and mode.
|
||||||
|
The user should call this function after locking the CS mutex if multiple SPI devices with
|
||||||
|
differing speeds and modes are attached to one bus.
|
||||||
|
- SPI: Getter functions for SPI speed and mode.
|
||||||
|
|
||||||
# [v5.0.0] 25.07.2022
|
# [v5.0.0] 25.07.2022
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
@ -225,6 +268,7 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||||
Easiest solution for now: Keep this option OFF by default.
|
Easiest solution for now: Keep this option OFF by default.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
||||||
|
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
||||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||||
inside `fsfw/version.h`
|
inside `fsfw/version.h`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||||
@ -239,17 +283,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
- `Subsystem`: New API to add table and sequence entries
|
- `Subsystem`: New API to add table and sequence entries
|
||||||
|
|
||||||
## HAL
|
|
||||||
|
|
||||||
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
|
||||||
lot more sense because each ComIF should be responsible for one SPI bus.
|
|
||||||
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
|
||||||
it is not automatically called when calling the setter function for SPI speed and mode.
|
|
||||||
The user should call this function after locking the CS mutex if multiple SPI devices with
|
|
||||||
differing speeds and modes are attached to one bus.
|
|
||||||
- SPI: Getter functions for SPI speed and mode.
|
|
||||||
- I2C: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1.
|
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- TCP TMTC Server: `MutexGuard` was not created properly in
|
- TCP TMTC Server: `MutexGuard` was not created properly in
|
||||||
|
@ -122,6 +122,7 @@ if(UNIX)
|
|||||||
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers"
|
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers"
|
||||||
OFF)
|
OFF)
|
||||||
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF)
|
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF)
|
||||||
|
option(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS "Add serial drivers" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Optional sources
|
# Optional sources
|
||||||
|
56
automation/Jenkinsfile
vendored
56
automation/Jenkinsfile
vendored
@ -1,48 +1,90 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
environment {
|
environment {
|
||||||
BUILDDIR = 'cmake-build-tests'
|
BUILDDIR_HOST = 'cmake-build-tests-host'
|
||||||
|
BUILDDIR_LINUX = 'cmake-build-tests-linux'
|
||||||
DOCDDIR = 'cmake-build-documentation'
|
DOCDDIR = 'cmake-build-documentation'
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
image 'fsfw-ci:d6'
|
image 'fsfw-ci:d6'
|
||||||
args '--network host'
|
args '--network host --sysctl fs.mqueue.msg_max=100'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
|
stage('Host') {
|
||||||
|
stages{
|
||||||
stage('Clean') {
|
stage('Clean') {
|
||||||
steps {
|
steps {
|
||||||
sh 'rm -rf $BUILDDIR'
|
sh 'rm -rf $BUILDDIR_HOST'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Configure') {
|
stage('Configure') {
|
||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR_HOST) {
|
||||||
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Build') {
|
stage('Build') {
|
||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR_HOST) {
|
||||||
sh 'cmake --build . -j4'
|
sh 'cmake --build . -j4'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Unittests') {
|
stage('Unittests') {
|
||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR_HOST) {
|
||||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Valgrind') {
|
stage('Valgrind') {
|
||||||
steps {
|
steps {
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR_HOST) {
|
||||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Linux') {
|
||||||
|
stages{
|
||||||
|
stage('Clean') {
|
||||||
|
steps {
|
||||||
|
sh 'rm -rf $BUILDDIR_LINUX'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Configure') {
|
||||||
|
steps {
|
||||||
|
dir(BUILDDIR_LINUX) {
|
||||||
|
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
dir(BUILDDIR_LINUX) {
|
||||||
|
sh 'cmake --build . -j4'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Unittests') {
|
||||||
|
steps {
|
||||||
|
dir(BUILDDIR_LINUX) {
|
||||||
|
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Valgrind') {
|
||||||
|
steps {
|
||||||
|
dir(BUILDDIR_LINUX) {
|
||||||
|
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
stage('Documentation') {
|
stage('Documentation') {
|
||||||
when {
|
when {
|
||||||
branch 'development'
|
branch 'development'
|
||||||
|
@ -140,7 +140,7 @@ find_program( GCOV_PATH gcov )
|
|||||||
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
|
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
|
||||||
find_program( FASTCOV_PATH NAMES fastcov fastcov.py )
|
find_program( FASTCOV_PATH NAMES fastcov fastcov.py )
|
||||||
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
|
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
|
||||||
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
find_program( GCOVR_PATH gcovr )
|
||||||
find_program( CPPFILT_PATH NAMES c++filt )
|
find_program( CPPFILT_PATH NAMES c++filt )
|
||||||
|
|
||||||
if(NOT GCOV_PATH)
|
if(NOT GCOV_PATH)
|
||||||
|
@ -51,7 +51,10 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|||||||
html_theme = "alabaster"
|
html_theme = "alabaster"
|
||||||
|
|
||||||
html_theme_options = {
|
html_theme_options = {
|
||||||
"extra_nav_links": {"Impressum" : "https://www.uni-stuttgart.de/impressum", "Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html"}
|
"extra_nav_links": {
|
||||||
|
"Impressum": "https://www.uni-stuttgart.de/impressum",
|
||||||
|
"Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "../returnvalues/returnvalue.h"
|
#include "../returnvalues/returnvalue.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A List that stores its values in an array.
|
* @brief A List that stores its values in an array.
|
||||||
@ -19,9 +20,6 @@ class ArrayList {
|
|||||||
friend class SerialArrayListAdapter;
|
friend class SerialArrayListAdapter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
|
||||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the allocating constructor.
|
* This is the allocating constructor.
|
||||||
* It allocates an array of the specified size.
|
* It allocates an array of the specified size.
|
||||||
@ -187,7 +185,7 @@ class ArrayList {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t insert(T entry) {
|
ReturnValue_t insert(T entry) {
|
||||||
if (size >= maxSize_) {
|
if (size >= maxSize_) {
|
||||||
return FULL;
|
return containers::LIST_FULL;
|
||||||
}
|
}
|
||||||
entries[size] = entry;
|
entries[size] = entry;
|
||||||
++size;
|
++size;
|
||||||
|
@ -12,6 +12,7 @@ template <typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
|||||||
class FixedArrayList : public ArrayList<T, count_t> {
|
class FixedArrayList : public ArrayList<T, count_t> {
|
||||||
static_assert(MAX_SIZE <= std::numeric_limits<count_t>::max(),
|
static_assert(MAX_SIZE <= std::numeric_limits<count_t>::max(),
|
||||||
"count_t is not large enough to hold MAX_SIZE");
|
"count_t is not large enough to hold MAX_SIZE");
|
||||||
|
static_assert(MAX_SIZE > 0, "MAX_SIZE is 0");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T data[MAX_SIZE];
|
T data[MAX_SIZE];
|
||||||
@ -20,15 +21,19 @@ class FixedArrayList : public ArrayList<T, count_t> {
|
|||||||
FixedArrayList() : ArrayList<T, count_t>(data, MAX_SIZE) {}
|
FixedArrayList() : ArrayList<T, count_t>(data, MAX_SIZE) {}
|
||||||
|
|
||||||
FixedArrayList(const FixedArrayList& other) : ArrayList<T, count_t>(data, MAX_SIZE) {
|
FixedArrayList(const FixedArrayList& other) : ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
this->size = other.size;
|
this->size = other.size;
|
||||||
|
for (size_t idx = 0; idx < this->size; idx++) {
|
||||||
|
data[idx] = other.data[idx];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedArrayList& operator=(FixedArrayList other) {
|
FixedArrayList& operator=(FixedArrayList other) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
this->size = other.size;
|
this->size = other.size;
|
||||||
|
for (size_t idx = 0; idx < this->size; idx++) {
|
||||||
|
data[idx] = other.data[idx];
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "../returnvalues/returnvalue.h"
|
|
||||||
#include "ArrayList.h"
|
#include "ArrayList.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map implementation for maps with a pre-defined size.
|
* @brief Map implementation for maps with a pre-defined size.
|
||||||
@ -24,11 +24,6 @@ class FixedMap : public SerializeIF {
|
|||||||
"derived class from SerializeIF to be serialize-able");
|
"derived class from SerializeIF to be serialize-able");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
|
||||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
|
||||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
|
||||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const key_t EMPTY_SLOT = -1;
|
static const key_t EMPTY_SLOT = -1;
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
||||||
@ -76,10 +71,10 @@ class FixedMap : public SerializeIF {
|
|||||||
|
|
||||||
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr) {
|
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr) {
|
||||||
if (exists(key) == returnvalue::OK) {
|
if (exists(key) == returnvalue::OK) {
|
||||||
return KEY_ALREADY_EXISTS;
|
return containers::KEY_ALREADY_EXISTS;
|
||||||
}
|
}
|
||||||
if (_size == theMap.maxSize()) {
|
if (_size == theMap.maxSize()) {
|
||||||
return MAP_FULL;
|
return containers::MAP_FULL;
|
||||||
}
|
}
|
||||||
theMap[_size].first = key;
|
theMap[_size].first = key;
|
||||||
theMap[_size].second = value;
|
theMap[_size].second = value;
|
||||||
@ -93,7 +88,7 @@ class FixedMap : public SerializeIF {
|
|||||||
ReturnValue_t insert(std::pair<key_t, T> pair) { return insert(pair.first, pair.second); }
|
ReturnValue_t insert(std::pair<key_t, T> pair) { return insert(pair.first, pair.second); }
|
||||||
|
|
||||||
ReturnValue_t exists(key_t key) const {
|
ReturnValue_t exists(key_t key) const {
|
||||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
ReturnValue_t result = containers::KEY_DOES_NOT_EXIST;
|
||||||
if (findIndex(key) < _size) {
|
if (findIndex(key) < _size) {
|
||||||
result = returnvalue::OK;
|
result = returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -103,7 +98,7 @@ class FixedMap : public SerializeIF {
|
|||||||
ReturnValue_t erase(Iterator* iter) {
|
ReturnValue_t erase(Iterator* iter) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = findIndex((*iter).value->first)) >= _size) {
|
if ((i = findIndex((*iter).value->first)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return containers::KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
theMap[i] = theMap[_size - 1];
|
theMap[i] = theMap[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
@ -114,7 +109,7 @@ class FixedMap : public SerializeIF {
|
|||||||
ReturnValue_t erase(key_t key) {
|
ReturnValue_t erase(key_t key) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = findIndex(key)) >= _size) {
|
if ((i = findIndex(key)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return containers::KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
theMap[i] = theMap[_size - 1];
|
theMap[i] = theMap[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
|
14
src/fsfw/container/definitions.h
Normal file
14
src/fsfw/container/definitions.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef FSFW_CONTAINER_DEFINITIONS_H_
|
||||||
|
#define FSFW_CONTAINER_DEFINITIONS_H_
|
||||||
|
|
||||||
|
#include "fsfw/retval.h"
|
||||||
|
|
||||||
|
namespace containers {
|
||||||
|
static const ReturnValue_t KEY_ALREADY_EXISTS = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x01);
|
||||||
|
static const ReturnValue_t MAP_FULL = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x02);
|
||||||
|
static const ReturnValue_t KEY_DOES_NOT_EXIST = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x03);
|
||||||
|
|
||||||
|
static const ReturnValue_t LIST_FULL = returnvalue::makeCode(CLASS_ID::ARRAY_LIST, 0x01);
|
||||||
|
} // namespace containers
|
||||||
|
|
||||||
|
#endif /* FSFW_CONTAINER_DEFINITIONS_H_ */
|
@ -4,11 +4,10 @@
|
|||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/subsystem/SubsystemBase.h"
|
#include "fsfw/subsystem/SubsystemBase.h"
|
||||||
|
#include "fsfw/subsystem/helper.h"
|
||||||
|
|
||||||
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
ControllerBase::ControllerBase(object_id_t setObjectId, size_t commandQueueDepth)
|
||||||
size_t commandQueueDepth)
|
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
parentId(parentId),
|
|
||||||
mode(MODE_OFF),
|
mode(MODE_OFF),
|
||||||
submode(SUBMODE_NONE),
|
submode(SUBMODE_NONE),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
@ -21,33 +20,15 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
|||||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::initialize() {
|
ReturnValue_t ControllerBase::initialize() {
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
ReturnValue_t result = modeHelper.initialize();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
result = healthHelper.initialize();
|
||||||
MessageQueueId_t parentQueue = 0;
|
|
||||||
if (parentId != objects::NO_OBJECT) {
|
|
||||||
auto* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
|
||||||
if (parent == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
parentQueue = parent->getCommandQueue();
|
|
||||||
|
|
||||||
parent->registerChild(getObjectId());
|
|
||||||
}
|
|
||||||
|
|
||||||
result = healthHelper.initialize(parentQueue);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
return SystemObject::initialize();
|
||||||
result = modeHelper.initialize(parentQueue);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->getId(); }
|
MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
@ -120,3 +101,13 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
|||||||
void ControllerBase::changeHK(Mode_t mode_, Submode_t submode_, bool enable) {}
|
void ControllerBase::changeHK(Mode_t mode_, Submode_t submode_, bool enable) {}
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return returnvalue::OK; }
|
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return returnvalue::OK; }
|
||||||
|
|
||||||
|
const HasHealthIF* ControllerBase::getOptHealthIF() const { return this; }
|
||||||
|
|
||||||
|
const HasModesIF& ControllerBase::getModeIF() const { return *this; }
|
||||||
|
|
||||||
|
ModeTreeChildIF& ControllerBase::getModeTreeChildIF() { return *this; }
|
||||||
|
|
||||||
|
ReturnValue_t ControllerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
|
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
||||||
|
}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
#include "fsfw/modes/HasModesIF.h"
|
#include "fsfw/modes/HasModesIF.h"
|
||||||
#include "fsfw/modes/ModeHelper.h"
|
#include "fsfw/modes/ModeHelper.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
|
||||||
|
#include "fsfw/subsystem/ModeTreeChildIF.h"
|
||||||
|
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||||
|
|
||||||
@ -18,13 +21,18 @@
|
|||||||
class ControllerBase : public HasModesIF,
|
class ControllerBase : public HasModesIF,
|
||||||
public HasHealthIF,
|
public HasHealthIF,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
|
public ModeTreeChildIF,
|
||||||
|
public ModeTreeConnectionIF,
|
||||||
public SystemObject {
|
public SystemObject {
|
||||||
public:
|
public:
|
||||||
static const Mode_t MODE_NORMAL = 2;
|
static const Mode_t MODE_NORMAL = 2;
|
||||||
|
|
||||||
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
ControllerBase(object_id_t setObjectId, size_t commandQueueDepth = 3);
|
||||||
~ControllerBase() override;
|
~ControllerBase() override;
|
||||||
|
|
||||||
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||||
|
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||||
|
|
||||||
/** SystemObject override */
|
/** SystemObject override */
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
@ -38,6 +46,8 @@ class ControllerBase : public HasModesIF,
|
|||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
void setTaskIF(PeriodicTaskIF *task) override;
|
void setTaskIF(PeriodicTaskIF *task) override;
|
||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
const HasHealthIF *getOptHealthIF() const override;
|
||||||
|
const HasModesIF &getModeIF() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -56,8 +66,6 @@ class ControllerBase : public HasModesIF,
|
|||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) override = 0;
|
uint32_t *msToReachTheMode) override = 0;
|
||||||
|
|
||||||
const object_id_t parentId;
|
|
||||||
|
|
||||||
Mode_t mode;
|
Mode_t mode;
|
||||||
|
|
||||||
Submode_t submode;
|
Submode_t submode;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||||
|
|
||||||
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t parentId,
|
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth)
|
||||||
size_t commandQueueDepth)
|
: ControllerBase(objectId, commandQueueDepth),
|
||||||
: ControllerBase(objectId, parentId, commandQueueDepth),
|
|
||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
actionHelper(this, commandQueue) {}
|
actionHelper(this, commandQueue) {}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class ExtendedControllerBase : public ControllerBase,
|
|||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
public HasLocalDataPoolIF {
|
public HasLocalDataPoolIF {
|
||||||
public:
|
public:
|
||||||
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth = 3);
|
||||||
~ExtendedControllerBase() override;
|
~ExtendedControllerBase() override;
|
||||||
|
|
||||||
/* SystemObjectIF overrides */
|
/* SystemObjectIF overrides */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "fsfw/devicehandlers/AssemblyBase.h"
|
#include "fsfw/devicehandlers/AssemblyBase.h"
|
||||||
|
|
||||||
AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth)
|
AssemblyBase::AssemblyBase(object_id_t objectId, uint16_t commandQueueDepth)
|
||||||
: SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth),
|
: SubsystemBase(objectId, MODE_OFF, commandQueueDepth),
|
||||||
internalState(STATE_NONE),
|
internalState(STATE_NONE),
|
||||||
recoveryState(RECOVERY_IDLE),
|
recoveryState(RECOVERY_IDLE),
|
||||||
recoveringDevice(childrenMap.end()),
|
recoveringDevice(childrenMap.end()),
|
||||||
|
@ -41,7 +41,7 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
static const ReturnValue_t NEED_TO_CHANGE_HEALTH = MAKE_RETURN_CODE(0x05);
|
static const ReturnValue_t NEED_TO_CHANGE_HEALTH = MAKE_RETURN_CODE(0x05);
|
||||||
static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE = MAKE_RETURN_CODE(0xa1);
|
static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE = MAKE_RETURN_CODE(0xa1);
|
||||||
|
|
||||||
AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth = 8);
|
AssemblyBase(object_id_t objectId, uint16_t commandQueueDepth = 8);
|
||||||
virtual ~AssemblyBase();
|
virtual ~AssemblyBase();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -3,17 +3,12 @@
|
|||||||
#include "fsfw/subsystem/SubsystemBase.h"
|
#include "fsfw/subsystem/SubsystemBase.h"
|
||||||
|
|
||||||
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
|
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
|
||||||
CookieIF* cookie, object_id_t hkDestination,
|
CookieIF* cookie, HasModeTreeChildrenIF& parent,
|
||||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
|
FailureIsolationBase* customFdir, size_t cmdQueueSize)
|
||||||
object_id_t parent, FailureIsolationBase* customFdir,
|
|
||||||
size_t cmdQueueSize)
|
|
||||||
: DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
|
: DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
|
||||||
(customFdir == nullptr ? &childHandlerFdir : customFdir), cmdQueueSize),
|
(customFdir == nullptr ? &childHandlerFdir : customFdir), cmdQueueSize),
|
||||||
parentId(parent),
|
parent(parent),
|
||||||
childHandlerFdir(setObjectId) {
|
childHandlerFdir(setObjectId) {}
|
||||||
this->setHkDestination(hkDestination);
|
|
||||||
this->setThermalStateRequestPoolIds(thermalStatePoolId, thermalRequestPoolId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ChildHandlerBase::~ChildHandlerBase() {}
|
ChildHandlerBase::~ChildHandlerBase() {}
|
||||||
|
|
||||||
@ -23,21 +18,5 @@ ReturnValue_t ChildHandlerBase::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t parentQueue = 0;
|
return DeviceHandlerBase::connectModeTreeParent(parent);
|
||||||
|
|
||||||
if (parentId != objects::NO_OBJECT) {
|
|
||||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
|
||||||
if (parent == NULL) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
parentQueue = parent->getCommandQueue();
|
|
||||||
|
|
||||||
parent->registerChild(getObjectId());
|
|
||||||
}
|
|
||||||
|
|
||||||
healthHelper.setParentQueue(parentQueue);
|
|
||||||
|
|
||||||
modeHelper.setParentQueue(parentQueue);
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
#ifndef FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_
|
#ifndef FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_
|
||||||
#define FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_
|
#define FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_
|
||||||
|
|
||||||
|
#include <fsfw/subsystem/HasModeTreeChildrenIF.h>
|
||||||
|
|
||||||
#include "ChildHandlerFDIR.h"
|
#include "ChildHandlerFDIR.h"
|
||||||
#include "DeviceHandlerBase.h"
|
#include "DeviceHandlerBase.h"
|
||||||
|
|
||||||
class ChildHandlerBase : public DeviceHandlerBase {
|
class ChildHandlerBase : public DeviceHandlerBase {
|
||||||
public:
|
public:
|
||||||
ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF* cookie,
|
ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF* cookie,
|
||||||
object_id_t hkDestination, uint32_t thermalStatePoolId,
|
HasModeTreeChildrenIF& parent, FailureIsolationBase* customFdir = nullptr,
|
||||||
uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT,
|
size_t cmdQueueSize = 20);
|
||||||
FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20);
|
|
||||||
|
|
||||||
virtual ~ChildHandlerBase();
|
virtual ~ChildHandlerBase();
|
||||||
|
|
||||||
virtual ReturnValue_t initialize();
|
virtual ReturnValue_t initialize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const uint32_t parentId;
|
HasModeTreeChildrenIF& parent;
|
||||||
ChildHandlerFDIR childHandlerFdir;
|
ChildHandlerFDIR childHandlerFdir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "DeviceHandlerBase.h"
|
||||||
|
|
||||||
|
#include "fsfw/datapool/PoolReadGuard.h"
|
||||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||||
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
||||||
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
#include "fsfw/subsystem/SubsystemBase.h"
|
#include "fsfw/subsystem/SubsystemBase.h"
|
||||||
|
#include "fsfw/subsystem/helper.h"
|
||||||
#include "fsfw/thermal/ThermalComponentIF.h"
|
#include "fsfw/thermal/ThermalComponentIF.h"
|
||||||
|
|
||||||
object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||||
@ -132,14 +134,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->parent != objects::NO_OBJECT) {
|
|
||||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
|
||||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
|
||||||
if (modeIF != nullptr and healthIF != nullptr) {
|
|
||||||
setParentQueue(modeIF->getCommandQueue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
communicationInterface =
|
communicationInterface =
|
||||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||||
if (communicationInterface == nullptr) {
|
if (communicationInterface == nullptr) {
|
||||||
@ -368,6 +362,8 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
if ((switchState == PowerSwitchIF::SWITCH_ON) || (switchState == NO_SWITCH)) {
|
if ((switchState == PowerSwitchIF::SWITCH_ON) || (switchState == NO_SWITCH)) {
|
||||||
// NOTE: TransitionSourceMode and -SubMode are set by handleCommandedModeTransition
|
// NOTE: TransitionSourceMode and -SubMode are set by handleCommandedModeTransition
|
||||||
childTransitionFailure = CHILD_TIMEOUT;
|
childTransitionFailure = CHILD_TIMEOUT;
|
||||||
|
transitionSourceMode = _MODE_SHUT_DOWN;
|
||||||
|
transitionSourceSubMode = SUBMODE_NONE;
|
||||||
setMode(_MODE_START_UP);
|
setMode(_MODE_START_UP);
|
||||||
callChildStatemachine();
|
callChildStatemachine();
|
||||||
}
|
}
|
||||||
@ -573,7 +569,6 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* handle transition from OFF to NORMAL by continuing towards normal when ON is reached
|
* handle transition from OFF to NORMAL by continuing towards normal when ON is reached
|
||||||
*/
|
*/
|
||||||
@ -1530,9 +1525,12 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
|||||||
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
||||||
for (const auto& reply : deviceReplyMap) {
|
for (const auto& reply : deviceReplyMap) {
|
||||||
if (reply.second.dataSet != nullptr) {
|
if (reply.second.dataSet != nullptr) {
|
||||||
|
PoolReadGuard pg(reply.second.dataSet);
|
||||||
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
reply.second.dataSet->setValidity(false, true);
|
reply.second.dataSet->setValidity(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const char* functionName,
|
void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const char* functionName,
|
||||||
@ -1587,19 +1585,13 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
|||||||
|
|
||||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
||||||
|
|
||||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
||||||
this->powerSwitcher = switcher;
|
this->powerSwitcher = switcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode_t DeviceHandlerBase::getMode() {
|
Mode_t DeviceHandlerBase::getMode() { return mode; }
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Submode_t DeviceHandlerBase::getSubmode() {
|
Submode_t DeviceHandlerBase::getSubmode() { return submode; }
|
||||||
return submode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeviceHandlerBase::disableCommandsAndReplies() {
|
void DeviceHandlerBase::disableCommandsAndReplies() {
|
||||||
for (auto& command : deviceCommandMap) {
|
for (auto& command : deviceCommandMap) {
|
||||||
@ -1619,6 +1611,16 @@ void DeviceHandlerBase::disableCommandsAndReplies() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
|
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HasHealthIF* DeviceHandlerBase::getOptHealthIF() const { return this; }
|
||||||
|
|
||||||
|
const HasModesIF& DeviceHandlerBase::getModeIF() const { return *this; }
|
||||||
|
|
||||||
|
ModeTreeChildIF& DeviceHandlerBase::getModeTreeChildIF() { return *this; }
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::finishAction(bool success, DeviceCommandId_t action,
|
ReturnValue_t DeviceHandlerBase::finishAction(bool success, DeviceCommandId_t action,
|
||||||
ReturnValue_t result) {
|
ReturnValue_t result) {
|
||||||
auto commandIter = deviceCommandMap.find(action);
|
auto commandIter = deviceCommandMap.find(action);
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||||
|
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||||
#include "fsfw/util/dataWrapper.h"
|
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
void setStaticFrameworkObjectIds();
|
void setStaticFrameworkObjectIds();
|
||||||
@ -84,6 +84,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
public HasModesIF,
|
public HasModesIF,
|
||||||
public HasHealthIF,
|
public HasHealthIF,
|
||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
|
public ModeTreeChildIF,
|
||||||
|
public ModeTreeConnectionIF,
|
||||||
public ReceivesParameterMessagesIF,
|
public ReceivesParameterMessagesIF,
|
||||||
public HasLocalDataPoolIF {
|
public HasLocalDataPoolIF {
|
||||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||||
@ -104,7 +106,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||||
|
|
||||||
void setCustomFdir(FailureIsolationBase *fdir);
|
void setCustomFdir(FailureIsolationBase *fdir);
|
||||||
void setParent(object_id_t parent);
|
|
||||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
void setPowerSwitcher(PowerSwitchIF *switcher);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,6 +170,10 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID,
|
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID,
|
||||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID);
|
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID);
|
||||||
|
|
||||||
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||||
|
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper function to ease device handler development.
|
* @brief Helper function to ease device handler development.
|
||||||
* This will instruct the transition to MODE_ON immediately
|
* This will instruct the transition to MODE_ON immediately
|
||||||
@ -214,7 +219,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @param counter Specifies which Action to perform
|
* @param counter Specifies which Action to perform
|
||||||
* @return returnvalue::OK for successful execution
|
* @return returnvalue::OK for successful execution
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t performOperation(uint8_t counter) override;
|
ReturnValue_t performOperation(uint8_t counter) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the device handler
|
* @brief Initializes the device handler
|
||||||
@ -224,14 +229,14 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* Calls fillCommandAndReplyMap().
|
* Calls fillCommandAndReplyMap().
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Intialization steps performed after all tasks have been created.
|
* @brief Intialization steps performed after all tasks have been created.
|
||||||
* This function will be called by the executing task.
|
* This function will be called by the executing task.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
virtual ~DeviceHandlerBase();
|
virtual ~DeviceHandlerBase();
|
||||||
@ -248,6 +253,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
virtual object_id_t getObjectId() const override;
|
virtual object_id_t getObjectId() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This is a helper method for classes which are parent nodes in the mode tree.
|
||||||
|
* It registers the passed queue as the destination for mode and health messages.
|
||||||
* @param parentQueueId
|
* @param parentQueueId
|
||||||
*/
|
*/
|
||||||
virtual void setParentQueue(MessageQueueId_t parentQueueId);
|
virtual void setParentQueue(MessageQueueId_t parentQueueId);
|
||||||
@ -1012,6 +1019,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
LocalDataPoolManager *getHkManagerHandle() override;
|
LocalDataPoolManager *getHkManagerHandle() override;
|
||||||
|
|
||||||
|
const HasHealthIF *getOptHealthIF() const override;
|
||||||
|
const HasModesIF &getModeIF() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the delay cycle count of a reply.
|
* Returns the delay cycle count of a reply.
|
||||||
* A count != 0 indicates that the command is already executed.
|
* A count != 0 indicates that the command is already executed.
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||||
#include "fsfw/serialize/SerializeIF.h"
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
#include "fsfw/util/dataWrapper.h"
|
|
||||||
|
|
||||||
class DeviceTmReportingWrapper : public SerializeIF {
|
class DeviceTmReportingWrapper : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +24,7 @@ EventManager::EventManager(object_id_t setObjectId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager() {
|
EventManager::~EventManager() {
|
||||||
|
listenerList.clear();
|
||||||
QueueFactory::instance()->deleteMessageQueue(eventReportQueue);
|
QueueFactory::instance()->deleteMessageQueue(eventReportQueue);
|
||||||
MutexFactory::instance()->deleteMutex(mutex);
|
MutexFactory::instance()->deleteMutex(mutex);
|
||||||
}
|
}
|
||||||
@ -73,9 +74,14 @@ ReturnValue_t EventManager::registerListener(MessageQueueId_t listener,
|
|||||||
if (!result.second) {
|
if (!result.second) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t EventManager::unregisterListener(MessageQueueId_t listener) {
|
||||||
|
return listenerList.erase(listener) == 1 ? returnvalue::OK : returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t EventManager::subscribeToEvent(MessageQueueId_t listener, EventId_t event) {
|
ReturnValue_t EventManager::subscribeToEvent(MessageQueueId_t listener, EventId_t event) {
|
||||||
return subscribeToEventRange(listener, event);
|
return subscribeToEventRange(listener, event);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
MessageQueueId_t getEventReportQueue();
|
MessageQueueId_t getEventReportQueue();
|
||||||
|
|
||||||
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
|
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
|
||||||
|
ReturnValue_t unregisterListener(MessageQueueId_t listener) override;
|
||||||
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
|
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
|
||||||
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
|
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
|
||||||
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||||
|
@ -18,6 +18,7 @@ class EventManagerIF {
|
|||||||
|
|
||||||
virtual ReturnValue_t registerListener(MessageQueueId_t listener,
|
virtual ReturnValue_t registerListener(MessageQueueId_t listener,
|
||||||
bool forwardAllButSelected = false) = 0;
|
bool forwardAllButSelected = false) = 0;
|
||||||
|
virtual ReturnValue_t unregisterListener(MessageQueueId_t listener) = 0;
|
||||||
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
|
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
|
||||||
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0;
|
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0;
|
||||||
virtual ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) = 0;
|
virtual ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) = 0;
|
||||||
|
@ -24,7 +24,7 @@ FailureIsolationBase::~FailureIsolationBase() {
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
manager->unsubscribeFromAllEvents(eventQueue->getId(), ownerId);
|
manager->unregisterListener(eventQueue->getId());
|
||||||
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
|
|||||||
MatchTree(iterator root, uint8_t maxDepth = -1)
|
MatchTree(iterator root, uint8_t maxDepth = -1)
|
||||||
: BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(maxDepth) {}
|
: BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(maxDepth) {}
|
||||||
MatchTree() : BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {}
|
MatchTree() : BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {}
|
||||||
virtual ~MatchTree() {}
|
virtual ~MatchTree() { clear(); }
|
||||||
virtual bool match(T number) override { return matchesTree(number); }
|
virtual bool match(T number) override { return matchesTree(number); }
|
||||||
bool matchesTree(T number) {
|
bool matchesTree(T number) {
|
||||||
iterator iter = this->begin();
|
iterator iter = this->begin();
|
||||||
@ -176,6 +176,45 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
|
|||||||
return cleanUpElement(position);
|
return cleanUpElement(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
Node* localRoot = BinaryTree<SerializeableMatcherIF<T>>::rootNode;
|
||||||
|
|
||||||
|
if (localRoot == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* node = localRoot->left;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (node->left != nullptr) {
|
||||||
|
node = node->left;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (node->right != nullptr) {
|
||||||
|
node = node->right;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (node->parent == nullptr) {
|
||||||
|
// this is the root node with no children
|
||||||
|
if (node->value != nullptr) {
|
||||||
|
cleanUpElement(iterator(node));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// leaf
|
||||||
|
{
|
||||||
|
Node* parent = node->parent;
|
||||||
|
if (parent->left == node) {
|
||||||
|
parent->left = nullptr;
|
||||||
|
} else {
|
||||||
|
parent->right = nullptr;
|
||||||
|
}
|
||||||
|
cleanUpElement(iterator(node));
|
||||||
|
node = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual ReturnValue_t cleanUpElement(iterator position) { return returnvalue::OK; }
|
virtual ReturnValue_t cleanUpElement(iterator position) { return returnvalue::OK; }
|
||||||
|
|
||||||
bool matchSubtree(iterator iter, T number) {
|
bool matchSubtree(iterator iter, T number) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "fsfw/globalfunctions/timevalOperations.h"
|
#include "fsfw/globalfunctions/timevalOperations.h"
|
||||||
|
|
||||||
timeval& operator+=(timeval& lhs, const timeval& rhs) {
|
timeval& operator+=(timeval& lhs, const timeval& rhs) {
|
||||||
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
|
int64_t sum = static_cast<int64_t>(lhs.tv_sec) * 1000000. + lhs.tv_usec;
|
||||||
sum += rhs.tv_sec * 1000000. + rhs.tv_usec;
|
sum += static_cast<int64_t>(rhs.tv_sec) * 1000000. + rhs.tv_usec;
|
||||||
lhs.tv_sec = sum / 1000000;
|
lhs.tv_sec = sum / 1000000;
|
||||||
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
|
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
||||||
: objectId(objectId), owner(owner) {}
|
: objectId(objectId), owner(owner) {}
|
||||||
|
|
||||||
HealthHelper::~HealthHelper() { healthTable->removeObject(objectId); }
|
HealthHelper::~HealthHelper() {
|
||||||
|
if (healthTable != nullptr) {
|
||||||
|
healthTable->removeObject(objectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
|
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
;
|
|
||||||
|
|
||||||
mapIterator = healthMap.begin();
|
mapIterator = healthMap.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "HealthTableIF.h"
|
#include "HealthTableIF.h"
|
||||||
|
|
||||||
class HealthTable : public HealthTableIF, public SystemObject {
|
class HealthTable : public HealthTableIF, public SystemObject {
|
||||||
|
friend class CServiceHealthCommanding;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit HealthTable(object_id_t objectid);
|
explicit HealthTable(object_id_t objectid);
|
||||||
~HealthTable() override;
|
~HealthTable() override;
|
||||||
|
@ -10,13 +10,17 @@ InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t m
|
|||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(this) {
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
InternalErrorReporter::~InternalErrorReporter() {
|
||||||
|
MutexFactory::instance()->deleteMutex(mutex);
|
||||||
|
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
||||||
|
}
|
||||||
|
|
||||||
void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
|
void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
|
||||||
this->diagnosticPrintout = enable;
|
this->diagnosticPrintout = enable;
|
||||||
|
@ -24,3 +24,19 @@ void ModeMessage::setCantReachMode(CommandMessage* message, ReturnValue_t reason
|
|||||||
message->setParameter(reason);
|
message->setParameter(reason);
|
||||||
message->setParameter2(0);
|
message->setParameter2(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModeMessage::setModeAnnounceMessage(CommandMessage& message, bool recursive) {
|
||||||
|
Command_t cmd;
|
||||||
|
if (recursive) {
|
||||||
|
cmd = CMD_MODE_ANNOUNCE_RECURSIVELY;
|
||||||
|
} else {
|
||||||
|
cmd = CMD_MODE_ANNOUNCE;
|
||||||
|
}
|
||||||
|
message.setCommand(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModeMessage::setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode) {
|
||||||
|
setModeMessage(&message, CMD_MODE_COMMAND, mode, submode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModeMessage::setModeReadMessage(CommandMessage& message) { message.setCommand(CMD_MODE_READ); }
|
||||||
|
@ -1,43 +1,42 @@
|
|||||||
#ifndef FSFW_MODES_MODEMESSAGE_H_
|
#ifndef FSFW_MODES_MODEMESSAGE_H_
|
||||||
#define FSFW_MODES_MODEMESSAGE_H_
|
#define FSFW_MODES_MODEMESSAGE_H_
|
||||||
|
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
|
|
||||||
typedef uint32_t Mode_t;
|
typedef uint32_t Mode_t;
|
||||||
typedef uint8_t Submode_t;
|
typedef uint8_t Submode_t;
|
||||||
|
|
||||||
class ModeMessage {
|
class ModeMessage {
|
||||||
private:
|
|
||||||
ModeMessage();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND;
|
static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND;
|
||||||
static const Command_t CMD_MODE_COMMAND =
|
//!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY,
|
||||||
MAKE_COMMAND_ID(0x01); //!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY,
|
|
||||||
//! REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies,
|
//! REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies,
|
||||||
//! as this will break the subsystem mode machine!!
|
//! as this will break the subsystem mode machine!!
|
||||||
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(
|
static const Command_t CMD_MODE_COMMAND = MAKE_COMMAND_ID(0x01);
|
||||||
0xF1); //!> Command to set the specified Mode, regardless of external control flag, replies
|
//!> Command to set the specified Mode, regardless of external control flag, replies
|
||||||
//! are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any
|
//! are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any
|
||||||
//! replies, as this will break the subsystem mode machine!!
|
//! replies, as this will break the subsystem mode machine!!
|
||||||
static const Command_t REPLY_MODE_REPLY =
|
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(0xF1);
|
||||||
MAKE_COMMAND_ID(0x02); //!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
||||||
static const Command_t REPLY_MODE_INFO =
|
static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);
|
||||||
MAKE_COMMAND_ID(0x03); //!> Unrequested info about the current mode (used for composites to
|
//!> Unrequested info about the current mode (used for composites to
|
||||||
//! inform their container of a changed mode)
|
//! inform their container of a changed mode)
|
||||||
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(
|
static const Command_t REPLY_MODE_INFO = MAKE_COMMAND_ID(0x03);
|
||||||
0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
//!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
||||||
static const Command_t REPLY_WRONG_MODE_REPLY =
|
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(0x04);
|
||||||
MAKE_COMMAND_ID(0x05); //!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
|
//!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
|
||||||
//! and a transition started but was aborted; the parameters contain
|
//! and a transition started but was aborted; the parameters contain
|
||||||
//! the mode that was reached
|
//! the mode that was reached
|
||||||
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(
|
static const Command_t REPLY_WRONG_MODE_REPLY = MAKE_COMMAND_ID(0x05);
|
||||||
0x06); //!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
//!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
||||||
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(
|
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(0x06);
|
||||||
0x07); //!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
//!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
||||||
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY =
|
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(0x07);
|
||||||
MAKE_COMMAND_ID(0x08); //!> Command to trigger an ModeInfo Event and to send this command to
|
//!> Command to trigger an ModeInfo Event and to send this command to
|
||||||
//! every child. This command does NOT have a reply.
|
//! every child. This command does NOT have a reply.
|
||||||
|
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY = MAKE_COMMAND_ID(0x08);
|
||||||
|
|
||||||
|
ModeMessage() = delete;
|
||||||
|
|
||||||
static Mode_t getMode(const CommandMessage* message);
|
static Mode_t getMode(const CommandMessage* message);
|
||||||
static Submode_t getSubmode(const CommandMessage* message);
|
static Submode_t getSubmode(const CommandMessage* message);
|
||||||
@ -45,6 +44,9 @@ class ModeMessage {
|
|||||||
|
|
||||||
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
|
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
|
||||||
Submode_t submode);
|
Submode_t submode);
|
||||||
|
static void setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode);
|
||||||
|
static void setModeAnnounceMessage(CommandMessage& message, bool recursive);
|
||||||
|
static void setModeReadMessage(CommandMessage& message);
|
||||||
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
|
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
|
||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
};
|
};
|
||||||
|
@ -23,9 +23,17 @@ void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc,
|
|||||||
|
|
||||||
ObjectManager::ObjectManager() = default;
|
ObjectManager::ObjectManager() = default;
|
||||||
|
|
||||||
|
void ObjectManager::clear() {
|
||||||
|
if (objManagerInstance != nullptr) {
|
||||||
|
delete objManagerInstance;
|
||||||
|
objManagerInstance = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ObjectManager::~ObjectManager() {
|
ObjectManager::~ObjectManager() {
|
||||||
for (auto const& iter : objectList) {
|
teardown = true;
|
||||||
delete iter.second;
|
for (auto iter = objectList.begin(); iter != objectList.end(); iter = objectList.erase(iter)) {
|
||||||
|
delete iter->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +61,12 @@ ReturnValue_t ObjectManager::insert(object_id_t id, SystemObjectIF* object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ObjectManager::remove(object_id_t id) {
|
ReturnValue_t ObjectManager::remove(object_id_t id) {
|
||||||
|
// this function is called during destruction of System Objects
|
||||||
|
// disabeld for teardown to avoid iterator invalidation and
|
||||||
|
// double free
|
||||||
|
if (teardown) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
if (this->getSystemObject(id) != nullptr) {
|
if (this->getSystemObject(id) != nullptr) {
|
||||||
this->objectList.erase(id);
|
this->objectList.erase(id);
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
@ -24,12 +24,17 @@ class ObjectManager : public ObjectManagerIF {
|
|||||||
using produce_function_t = void (*)(void* args);
|
using produce_function_t = void (*)(void* args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the single instance of TaskFactory.
|
* Returns the single instance of ObjectManager.
|
||||||
* The implementation of #instance is found in its subclasses.
|
* The implementation of #instance is found in its subclasses.
|
||||||
* Thus, we choose link-time variability of the instance.
|
* Thus, we choose link-time variability of the instance.
|
||||||
*/
|
*/
|
||||||
static ObjectManager* instance();
|
static ObjectManager* instance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the single instance of ObjectManager
|
||||||
|
*/
|
||||||
|
static void clear();
|
||||||
|
|
||||||
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
|
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -66,6 +71,9 @@ class ObjectManager : public ObjectManagerIF {
|
|||||||
*/
|
*/
|
||||||
std::map<object_id_t, SystemObjectIF*> objectList;
|
std::map<object_id_t, SystemObjectIF*> objectList;
|
||||||
static ObjectManager* objManagerInstance;
|
static ObjectManager* objManagerInstance;
|
||||||
|
// used when the OM itself is deleted to modify behaviour of remove()
|
||||||
|
// to avoid iterator invalidation and double free
|
||||||
|
bool teardown = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Documentation can be found in the class method declaration above
|
// Documentation can be found in the class method declaration above
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
# Check the OS_FSFW variable
|
# Check the OS_FSFW variable
|
||||||
if(FSFW_OSAL MATCHES "freertos")
|
if(FSFW_OSAL MATCHES "freertos")
|
||||||
add_subdirectory(freertos)
|
add_subdirectory(freertos)
|
||||||
|
set(FSFW_OSAL_FREERTOS 1)
|
||||||
elseif(FSFW_OSAL MATCHES "rtems")
|
elseif(FSFW_OSAL MATCHES "rtems")
|
||||||
add_subdirectory(rtems)
|
add_subdirectory(rtems)
|
||||||
|
set(FSFW_OSAL_RTEMS 1)
|
||||||
elseif(FSFW_OSAL MATCHES "linux")
|
elseif(FSFW_OSAL MATCHES "linux")
|
||||||
add_subdirectory(linux)
|
add_subdirectory(linux)
|
||||||
|
set(FSFW_OSAL_LINUX 1)
|
||||||
elseif(FSFW_OSAL MATCHES "host")
|
elseif(FSFW_OSAL MATCHES "host")
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@ -13,18 +16,20 @@ elseif(FSFW_OSAL MATCHES "host")
|
|||||||
# We still need to pull in some Linux specific sources
|
# We still need to pull in some Linux specific sources
|
||||||
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
|
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
set(FSFW_OSAL_HOST 1)
|
||||||
else()
|
else()
|
||||||
|
|
||||||
message(
|
message(
|
||||||
WARNING
|
WARNING
|
||||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
||||||
|
|
||||||
# Not set. Assumuing this is a host build, try to determine host OS
|
# Not set. Assumuing this is a host build, try to determine host OS
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
add_subdirectory(windows)
|
add_subdirectory(windows)
|
||||||
|
set(FSFW_OSAL_HOST 1)
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
add_subdirectory(linux)
|
add_subdirectory(linux)
|
||||||
|
set(FSFW_OSAL_LINUX 1)
|
||||||
else()
|
else()
|
||||||
# MacOS or other OSes have not been tested yet / are not supported.
|
# MacOS or other OSes have not been tested yet / are not supported.
|
||||||
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
|
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
|
||||||
@ -33,3 +38,5 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
|
|
||||||
|
configure_file(osal.h.in ${CMAKE_BINARY_DIR}/fsfw/osal/osal.h)
|
||||||
|
@ -26,12 +26,12 @@
|
|||||||
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
||||||
size_t receptionBufferSize, size_t ringBufferSize,
|
TcpTmTcServer::TcpConfig cfg, size_t receptionBufferSize,
|
||||||
std::string customTcpServerPort, ReceptionModes receptionMode)
|
size_t ringBufferSize, ReceptionModes receptionMode)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
tmtcBridgeId(tmtcTcpBridge),
|
tmtcBridgeId(tmtcTcpBridge),
|
||||||
receptionMode(receptionMode),
|
receptionMode(receptionMode),
|
||||||
tcpConfig(std::move(customTcpServerPort)),
|
tcpConfig(cfg),
|
||||||
receptionBuffer(receptionBufferSize),
|
receptionBuffer(receptionBufferSize),
|
||||||
ringBuffer(ringBufferSize, true) {}
|
ringBuffer(ringBufferSize, true) {}
|
||||||
|
|
||||||
@ -91,6 +91,15 @@ ReturnValue_t TcpTmTcServer::initialize() {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tcpConfig.reuseAddr) {
|
||||||
|
unsigned int enable = 1;
|
||||||
|
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||||
|
}
|
||||||
|
if (tcpConfig.reusePort) {
|
||||||
|
unsigned int enable = 1;
|
||||||
|
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
|
||||||
|
}
|
||||||
|
|
||||||
// Bind to the address found by getaddrinfo
|
// Bind to the address found by getaddrinfo
|
||||||
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
||||||
if (retval == SOCKET_ERROR) {
|
if (retval == SOCKET_ERROR) {
|
||||||
@ -274,6 +283,8 @@ ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent)
|
|||||||
ConstStorageAccessor storeAccessor(storeId);
|
ConstStorageAccessor storeAccessor(storeId);
|
||||||
ReturnValue_t result = tmStore->getData(storeId, storeAccessor);
|
ReturnValue_t result = tmStore->getData(storeId, storeAccessor);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
|
// Invalid entry, pop FIFO
|
||||||
|
tmtcBridge->tmFifo->pop();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (wiretappingEnabled) {
|
if (wiretappingEnabled) {
|
||||||
|
@ -41,11 +41,11 @@ class SpacePacketParser;
|
|||||||
*/
|
*/
|
||||||
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
|
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
enum class ReceptionModes { SPACE_PACKETS };
|
|
||||||
|
|
||||||
struct TcpConfig {
|
struct TcpConfig {
|
||||||
public:
|
public:
|
||||||
explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {}
|
TcpConfig(bool reuseAddr, bool reusePort) : reuseAddr(reuseAddr), reusePort(reusePort) {}
|
||||||
|
TcpConfig(std::string tcpPort, bool reuseAddr, bool reusePort)
|
||||||
|
: tcpPort(std::move(tcpPort)), reuseAddr(reuseAddr), reusePort(reusePort) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passed to the recv call
|
* Passed to the recv call
|
||||||
@ -63,9 +63,25 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
|||||||
*/
|
*/
|
||||||
int tcpTmFlags = 0;
|
int tcpTmFlags = 0;
|
||||||
|
|
||||||
const std::string tcpPort;
|
std::string tcpPort = DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the SO_REUSEADDR option on the socket. See
|
||||||
|
* https://man7.org/linux/man-pages/man7/socket.7.html for more details. This option is
|
||||||
|
* especially useful in a debugging and development environment where an OBSW image might be
|
||||||
|
* re-flashed oftentimes and where all incoming telecommands are received on a dedicated TCP
|
||||||
|
* port.
|
||||||
|
*/
|
||||||
|
bool reuseAddr = false;
|
||||||
|
/**
|
||||||
|
* Sets the SO_REUSEPORT option on the socket. See
|
||||||
|
* https://man7.org/linux/man-pages/man7/socket.7.html for more details.
|
||||||
|
*/
|
||||||
|
bool reusePort = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ReceptionModes { SPACE_PACKETS };
|
||||||
|
|
||||||
static const std::string DEFAULT_SERVER_PORT;
|
static const std::string DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
static constexpr size_t ETHERNET_MTU_SIZE = 1500;
|
static constexpr size_t ETHERNET_MTU_SIZE = 1500;
|
||||||
@ -80,10 +96,9 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
|||||||
* size will be the Ethernet MTU size
|
* size will be the Ethernet MTU size
|
||||||
* @param customTcpServerPort The user can specify another port than the default (7301) here.
|
* @param customTcpServerPort The user can specify another port than the default (7301) here.
|
||||||
*/
|
*/
|
||||||
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpConfig cfg,
|
||||||
size_t receptionBufferSize = RING_BUFFER_SIZE,
|
size_t receptionBufferSize = RING_BUFFER_SIZE,
|
||||||
size_t ringBufferSize = RING_BUFFER_SIZE,
|
size_t ringBufferSize = RING_BUFFER_SIZE,
|
||||||
std::string customTcpServerPort = DEFAULT_SERVER_PORT,
|
|
||||||
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
|
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
|
||||||
~TcpTmTcServer() override;
|
~TcpTmTcServer() override;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs*
|
|||||||
attributes.mq_msgsize = maxMessageSize;
|
attributes.mq_msgsize = maxMessageSize;
|
||||||
attributes.mq_flags = 0; // Flags are ignored on Linux during mq_open
|
attributes.mq_flags = 0; // Flags are ignored on Linux during mq_open
|
||||||
// Set the name of the queue. The slash is mandatory!
|
// Set the name of the queue. The slash is mandatory!
|
||||||
sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
|
sprintf(name, "/FSFW_MQ%u", queueCounter++);
|
||||||
|
|
||||||
// Create a nonblocking queue if the name is available (the queue is read
|
// Create a nonblocking queue if the name is available (the queue is read
|
||||||
// and writable for the owner as well as the group)
|
// and writable for the owner as well as the group)
|
||||||
|
36
src/fsfw/osal/osal.h.in
Normal file
36
src/fsfw/osal/osal.h.in
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace osal {
|
||||||
|
enum osalTarget{
|
||||||
|
HOST,
|
||||||
|
LINUX,
|
||||||
|
WINDOWS,
|
||||||
|
FREERTOS,
|
||||||
|
RTEMS,
|
||||||
|
};
|
||||||
|
|
||||||
|
#cmakedefine FSFW_OSAL_HOST
|
||||||
|
#cmakedefine FSFW_OSAL_LINUX
|
||||||
|
#cmakedefine FSFW_OSAL_WINDOWS
|
||||||
|
#cmakedefine FSFW_OSAL_FREERTOS
|
||||||
|
#cmakedefine FSFW_OSAL_RTEMS
|
||||||
|
|
||||||
|
|
||||||
|
constexpr osalTarget getTarget() {
|
||||||
|
#ifdef FSFW_OSAL_HOST
|
||||||
|
return HOST;
|
||||||
|
#endif
|
||||||
|
#ifdef FSFW_OSAL_LINUX
|
||||||
|
return LINUX;
|
||||||
|
#endif
|
||||||
|
#ifdef FSFW_OSAL_WINDOWS
|
||||||
|
return WINDOWS;
|
||||||
|
#endif
|
||||||
|
#ifdef FSFW_OSAL_FREERTOS
|
||||||
|
return FREERTOS;
|
||||||
|
#endif
|
||||||
|
#ifdef FSFW_OSAL_RTEMS
|
||||||
|
return RTEMS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
@ -3,7 +3,7 @@
|
|||||||
#include <fsfw/ipc/QueueFactory.h>
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
#include <fsfw/power/PowerSwitchIF.h>
|
#include <fsfw/power/PowerSwitchIF.h>
|
||||||
|
|
||||||
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
|
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||||
power::Switch_t pwrSwitch)
|
power::Switch_t pwrSwitch)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
switcher(pwrSwitcher, pwrSwitch),
|
switcher(pwrSwitcher, pwrSwitch),
|
||||||
@ -54,7 +54,7 @@ ReturnValue_t PowerSwitcherComponent::initialize() {
|
|||||||
|
|
||||||
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { return queue->getId(); }
|
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { return queue->getId(); }
|
||||||
|
|
||||||
void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) {
|
void PowerSwitcherComponent::getMode(Mode_t* mode, Submode_t* submode) {
|
||||||
*mode = this->mode;
|
*mode = this->mode;
|
||||||
*submode = this->submode;
|
*submode = this->submode;
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode) {
|
uint32_t* msToReachTheMode) {
|
||||||
*msToReachTheMode = 5000;
|
*msToReachTheMode = 5000;
|
||||||
if (mode != MODE_ON and mode != MODE_OFF) {
|
if (mode != MODE_ON and mode != MODE_OFF) {
|
||||||
return TRANS_NOT_ALLOWED;
|
return TRANS_NOT_ALLOWED;
|
||||||
@ -105,3 +105,15 @@ void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { return healthHelper.getHealth(); }
|
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { return healthHelper.getHealth(); }
|
||||||
|
|
||||||
|
const HasHealthIF* PowerSwitcherComponent::getOptHealthIF() const { return this; }
|
||||||
|
|
||||||
|
const HasModesIF& PowerSwitcherComponent::getModeIF() const { return *this; }
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherComponent::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
|
return parent.registerChild(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_t PowerSwitcherComponent::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
|
ModeTreeChildIF& PowerSwitcherComponent::getModeTreeChildIF() { return *this; }
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
#include <fsfw/power/PowerSwitcher.h>
|
#include <fsfw/power/PowerSwitcher.h>
|
||||||
#include <fsfw/power/definitions.h>
|
#include <fsfw/power/definitions.h>
|
||||||
|
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
||||||
|
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
|
||||||
class PowerSwitchIF;
|
class PowerSwitchIF;
|
||||||
@ -24,12 +26,17 @@ class PowerSwitchIF;
|
|||||||
*/
|
*/
|
||||||
class PowerSwitcherComponent : public SystemObject,
|
class PowerSwitcherComponent : public SystemObject,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
|
public ModeTreeChildIF,
|
||||||
|
public ModeTreeConnectionIF,
|
||||||
public HasModesIF,
|
public HasModesIF,
|
||||||
public HasHealthIF {
|
public HasHealthIF {
|
||||||
public:
|
public:
|
||||||
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
|
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
|
||||||
power::Switch_t pwrSwitch);
|
power::Switch_t pwrSwitch);
|
||||||
|
|
||||||
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||||
|
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageQueueIF *queue = nullptr;
|
MessageQueueIF *queue = nullptr;
|
||||||
PowerSwitcher switcher;
|
PowerSwitcher switcher;
|
||||||
@ -56,6 +63,10 @@ class PowerSwitcherComponent : public SystemObject,
|
|||||||
|
|
||||||
ReturnValue_t setHealth(HealthState health) override;
|
ReturnValue_t setHealth(HealthState health) override;
|
||||||
HasHealthIF::HealthState getHealth() override;
|
HasHealthIF::HealthState getHealth() override;
|
||||||
|
|
||||||
|
object_id_t getObjectId() const override;
|
||||||
|
const HasHealthIF *getOptHealthIF() const override;
|
||||||
|
const HasModesIF &getModeIF() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */
|
#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */
|
||||||
|
@ -9,4 +9,4 @@ target_sources(
|
|||||||
Service17Test.cpp
|
Service17Test.cpp
|
||||||
Service20ParameterManagement.cpp
|
Service20ParameterManagement.cpp
|
||||||
CService200ModeCommanding.cpp
|
CService200ModeCommanding.cpp
|
||||||
CService201HealthCommanding.cpp)
|
CServiceHealthCommanding.cpp)
|
||||||
|
@ -20,6 +20,7 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
|
|||||||
case (Subservice::COMMAND_MODE_COMMAND):
|
case (Subservice::COMMAND_MODE_COMMAND):
|
||||||
case (Subservice::COMMAND_MODE_READ):
|
case (Subservice::COMMAND_MODE_READ):
|
||||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||||
|
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
default:
|
default:
|
||||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||||
@ -53,6 +54,8 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
|||||||
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||||
const uint8_t *tcData, size_t tcDataLen,
|
const uint8_t *tcData, size_t tcDataLen,
|
||||||
uint32_t *state, object_id_t objectId) {
|
uint32_t *state, object_id_t objectId) {
|
||||||
|
switch (subservice) {
|
||||||
|
case (Subservice::COMMAND_MODE_COMMAND): {
|
||||||
ModePacket modeCommandPacket;
|
ModePacket modeCommandPacket;
|
||||||
ReturnValue_t result =
|
ReturnValue_t result =
|
||||||
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||||
@ -60,9 +63,27 @@ ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND,
|
||||||
modeCommandPacket.getSubmode());
|
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
|
||||||
return result;
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||||
|
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY): {
|
||||||
|
bool recursive = true;
|
||||||
|
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
||||||
|
recursive = false;
|
||||||
|
}
|
||||||
|
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
||||||
|
return EXECUTION_COMPLETE;
|
||||||
|
}
|
||||||
|
case (Subservice::COMMAND_MODE_READ): {
|
||||||
|
ModeMessage::setModeReadMessage(*message);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return CommandingServiceBase::INVALID_SUBSERVICE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
|
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
|
||||||
@ -73,8 +94,10 @@ ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply
|
|||||||
ReturnValue_t result = returnvalue::FAILED;
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
switch (replyId) {
|
switch (replyId) {
|
||||||
case (ModeMessage::REPLY_MODE_REPLY): {
|
case (ModeMessage::REPLY_MODE_REPLY): {
|
||||||
result = prepareModeReply(reply, objectId);
|
if (previousCommand != ModeMessage::CMD_MODE_COMMAND) {
|
||||||
break;
|
return prepareModeReply(reply, objectId);
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
case (ModeMessage::REPLY_WRONG_MODE_REPLY): {
|
case (ModeMessage::REPLY_WRONG_MODE_REPLY): {
|
||||||
result = prepareWrongModeReply(reply, objectId);
|
result = prepareWrongModeReply(reply, objectId);
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
#include "fsfw/pus/CService201HealthCommanding.h"
|
|
||||||
|
|
||||||
#include "fsfw/health/HasHealthIF.h"
|
|
||||||
#include "fsfw/health/HealthMessage.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
|
||||||
#include "fsfw/pus/servicepackets/Service201Packets.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
|
|
||||||
CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, uint16_t apid,
|
|
||||||
uint8_t serviceId,
|
|
||||||
uint8_t numParallelCommands,
|
|
||||||
uint16_t commandTimeoutSeconds)
|
|
||||||
: CommandingServiceBase(objectId, apid, "PUS 201 Health MGMT", serviceId, numParallelCommands,
|
|
||||||
commandTimeoutSeconds) {}
|
|
||||||
|
|
||||||
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) {
|
|
||||||
switch (subservice) {
|
|
||||||
case (Subservice::COMMAND_SET_HEALTH):
|
|
||||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH):
|
|
||||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL):
|
|
||||||
return returnvalue::OK;
|
|
||||||
default:
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "Invalid Subservice" << std::endl;
|
|
||||||
#endif
|
|
||||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subservice,
|
|
||||||
const uint8_t *tcData,
|
|
||||||
size_t tcDataLen,
|
|
||||||
MessageQueueId_t *id,
|
|
||||||
object_id_t *objectId) {
|
|
||||||
if (tcDataLen < sizeof(object_id_t)) {
|
|
||||||
return CommandingServiceBase::INVALID_TC;
|
|
||||||
}
|
|
||||||
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
|
||||||
|
|
||||||
return checkInterfaceAndAcquireMessageQueue(id, objectId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue(
|
|
||||||
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
|
|
||||||
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
|
|
||||||
if (destination == nullptr) {
|
|
||||||
return CommandingServiceBase::INVALID_OBJECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
*messageQueueToSet = destination->getCommandQueue();
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *message,
|
|
||||||
uint8_t subservice, const uint8_t *tcData,
|
|
||||||
size_t tcDataLen, uint32_t *state,
|
|
||||||
object_id_t objectId) {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
switch (subservice) {
|
|
||||||
case (Subservice::COMMAND_SET_HEALTH): {
|
|
||||||
HealthSetCommand healthCommand;
|
|
||||||
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET,
|
|
||||||
healthCommand.getHealth());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
|
|
||||||
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
|
|
||||||
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE_ALL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
// Should never happen, subservice was already checked
|
|
||||||
result = returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *reply,
|
|
||||||
Command_t previousCommand, uint32_t *state,
|
|
||||||
CommandMessage *optionalNextCommand,
|
|
||||||
object_id_t objectId, bool *isStep) {
|
|
||||||
Command_t replyId = reply->getCommand();
|
|
||||||
if (replyId == HealthMessage::REPLY_HEALTH_SET) {
|
|
||||||
return EXECUTION_COMPLETE;
|
|
||||||
} else if (replyId == CommandMessageIF::REPLY_REJECTED) {
|
|
||||||
return reply->getReplyRejectedReason();
|
|
||||||
}
|
|
||||||
return CommandingServiceBase::INVALID_REPLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not used for now, health state already reported by event
|
|
||||||
[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(
|
|
||||||
const CommandMessage *reply) {
|
|
||||||
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
|
|
||||||
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
|
|
||||||
HealthSetReply healthSetReply(health, oldHealth);
|
|
||||||
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
|
|
||||||
}
|
|
152
src/fsfw/pus/CServiceHealthCommanding.cpp
Normal file
152
src/fsfw/pus/CServiceHealthCommanding.cpp
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include <fsfw/events/EventManagerIF.h>
|
||||||
|
#include <fsfw/pus/CServiceHealthCommanding.h>
|
||||||
|
|
||||||
|
#include "fsfw/health/HasHealthIF.h"
|
||||||
|
#include "fsfw/health/HealthMessage.h"
|
||||||
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/pus/servicepackets/Service201Packets.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
|
CServiceHealthCommanding::CServiceHealthCommanding(HealthServiceCfg args)
|
||||||
|
: CommandingServiceBase(args.objectId, args.apid, "PUS 201 Health MGMT", args.service,
|
||||||
|
args.numParallelCommands, args.commandTimeoutSeconds),
|
||||||
|
healthTable(args.table),
|
||||||
|
maxNumHealthInfoPerCycle(args.maxNumHealthInfoPerCycle) {}
|
||||||
|
|
||||||
|
ReturnValue_t CServiceHealthCommanding::isValidSubservice(uint8_t subservice) {
|
||||||
|
switch (subservice) {
|
||||||
|
case (Subservice::COMMAND_SET_HEALTH):
|
||||||
|
case (Subservice::COMMAND_ANNOUNCE_HEALTH):
|
||||||
|
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL):
|
||||||
|
return returnvalue::OK;
|
||||||
|
default:
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "Invalid Subservice" << std::endl;
|
||||||
|
#endif
|
||||||
|
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CServiceHealthCommanding::getMessageQueueAndObject(uint8_t subservice,
|
||||||
|
const uint8_t *tcData,
|
||||||
|
size_t tcDataLen,
|
||||||
|
MessageQueueId_t *id,
|
||||||
|
object_id_t *objectId) {
|
||||||
|
switch (subservice) {
|
||||||
|
case (Subservice::COMMAND_SET_HEALTH):
|
||||||
|
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
|
||||||
|
if (tcDataLen < sizeof(object_id_t)) {
|
||||||
|
return CommandingServiceBase::INVALID_TC;
|
||||||
|
}
|
||||||
|
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||||
|
|
||||||
|
return checkInterfaceAndAcquireMessageQueue(id, objectId);
|
||||||
|
}
|
||||||
|
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CServiceHealthCommanding::checkInterfaceAndAcquireMessageQueue(
|
||||||
|
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
|
||||||
|
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
|
||||||
|
if (destination == nullptr) {
|
||||||
|
return CommandingServiceBase::INVALID_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
*messageQueueToSet = destination->getCommandQueue();
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||||
|
const uint8_t *tcData, size_t tcDataLen,
|
||||||
|
uint32_t *state, object_id_t objectId) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
switch (subservice) {
|
||||||
|
case (Subservice::COMMAND_SET_HEALTH): {
|
||||||
|
HealthSetCommand healthCommand;
|
||||||
|
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET,
|
||||||
|
healthCommand.getHealth());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
|
||||||
|
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
|
||||||
|
ReturnValue_t result = iterateHealthTable(true);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
reportAllHealth = true;
|
||||||
|
return EXECUTION_COMPLETE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
while (true) {
|
||||||
|
ReturnValue_t result = iterateHealthTable(false);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// Should never happen, subservice was already checked
|
||||||
|
result = returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CServiceHealthCommanding::handleReply(const CommandMessage *reply,
|
||||||
|
Command_t previousCommand, uint32_t *state,
|
||||||
|
CommandMessage *optionalNextCommand,
|
||||||
|
object_id_t objectId, bool *isStep) {
|
||||||
|
Command_t replyId = reply->getCommand();
|
||||||
|
if (replyId == HealthMessage::REPLY_HEALTH_SET) {
|
||||||
|
return EXECUTION_COMPLETE;
|
||||||
|
} else if (replyId == CommandMessageIF::REPLY_REJECTED) {
|
||||||
|
return reply->getReplyRejectedReason();
|
||||||
|
}
|
||||||
|
return CommandingServiceBase::INVALID_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CServiceHealthCommanding::doPeriodicOperation() {
|
||||||
|
if (reportAllHealth) {
|
||||||
|
for (uint8_t i = 0; i < maxNumHealthInfoPerCycle; i++) {
|
||||||
|
ReturnValue_t result = iterateHealthTable(false);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
reportAllHealth = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not used for now, health state already reported by event
|
||||||
|
[[maybe_unused]] ReturnValue_t CServiceHealthCommanding::prepareHealthSetReply(
|
||||||
|
const CommandMessage *reply) {
|
||||||
|
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
|
||||||
|
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
|
||||||
|
HealthSetReply healthSetReply(health, oldHealth);
|
||||||
|
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CServiceHealthCommanding::iterateHealthTable(bool reset) {
|
||||||
|
std::pair<object_id_t, HasHealthIF::HealthState> pair;
|
||||||
|
|
||||||
|
ReturnValue_t result = healthTable.iterate(&pair, reset);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
EventManagerIF::triggerEvent(pair.first, HasHealthIF::HEALTH_INFO, pair.second, pair.second);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,26 @@
|
|||||||
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
||||||
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
||||||
|
|
||||||
|
#include <fsfw/health/HealthTable.h>
|
||||||
|
|
||||||
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
||||||
|
|
||||||
|
struct HealthServiceCfg {
|
||||||
|
HealthServiceCfg(object_id_t objectId, uint16_t apid, HealthTable &healthTable,
|
||||||
|
uint16_t maxNumHealthInfoPerCycle)
|
||||||
|
: objectId(objectId),
|
||||||
|
apid(apid),
|
||||||
|
table(healthTable),
|
||||||
|
maxNumHealthInfoPerCycle(maxNumHealthInfoPerCycle) {}
|
||||||
|
object_id_t objectId;
|
||||||
|
uint16_t apid;
|
||||||
|
HealthTable &table;
|
||||||
|
uint16_t maxNumHealthInfoPerCycle;
|
||||||
|
uint8_t service = 201;
|
||||||
|
uint8_t numParallelCommands = 4;
|
||||||
|
uint16_t commandTimeoutSeconds = 60;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Custom PUS service to set health of all objects
|
* @brief Custom PUS service to set health of all objects
|
||||||
* implementing hasHealthIF.
|
* implementing hasHealthIF.
|
||||||
@ -17,11 +35,10 @@
|
|||||||
* child class like this service
|
* child class like this service
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CService201HealthCommanding : public CommandingServiceBase {
|
class CServiceHealthCommanding : public CommandingServiceBase {
|
||||||
public:
|
public:
|
||||||
CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
CServiceHealthCommanding(HealthServiceCfg args);
|
||||||
uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
|
~CServiceHealthCommanding() override = default;
|
||||||
~CService201HealthCommanding() override = default;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* CSB abstract function implementations */
|
/* CSB abstract function implementations */
|
||||||
@ -37,7 +54,13 @@ class CService201HealthCommanding : public CommandingServiceBase {
|
|||||||
CommandMessage *optionalNextCommand, object_id_t objectId,
|
CommandMessage *optionalNextCommand, object_id_t objectId,
|
||||||
bool *isStep) override;
|
bool *isStep) override;
|
||||||
|
|
||||||
|
void doPeriodicOperation() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
HealthTable &healthTable;
|
||||||
|
uint16_t maxNumHealthInfoPerCycle = 0;
|
||||||
|
bool reportAllHealth = false;
|
||||||
|
ReturnValue_t iterateHealthTable(bool reset);
|
||||||
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
|
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
|
||||||
const object_id_t *objectId);
|
const object_id_t *objectId);
|
||||||
|
|
@ -41,6 +41,8 @@ class Service11TelecommandScheduling final : public PusServiceBase {
|
|||||||
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
||||||
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
||||||
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
||||||
|
static constexpr ReturnValue_t CONTAINED_TC_TOO_SMALL = returnvalue::makeCode(CLASS_ID, 5);
|
||||||
|
static constexpr ReturnValue_t CONTAINED_TC_CRC_MISSMATCH = returnvalue::makeCode(CLASS_ID, 6);
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
||||||
|
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
|
||||||
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
||||||
@ -171,6 +173,14 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size < PusTcIF::MIN_SIZE) {
|
||||||
|
return CONTAINED_TC_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CRC::crc16ccitt(data, size) != 0) {
|
||||||
|
return CONTAINED_TC_CRC_MISSMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
// store currentPacket and receive the store address
|
// store currentPacket and receive the store address
|
||||||
store_address_t addr{};
|
store_address_t addr{};
|
||||||
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "fsfw/pus/Service17Test.h"
|
#include "fsfw/pus/Service17Test.h"
|
||||||
|
|
||||||
|
#include <fsfw/serialize/SerializeElement.h>
|
||||||
|
|
||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/FSFW.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
@ -31,6 +33,15 @@ ReturnValue_t Service17Test::handleRequest(uint8_t subservice) {
|
|||||||
}
|
}
|
||||||
return tmHelper.storeAndSendTmPacket();
|
return tmHelper.storeAndSendTmPacket();
|
||||||
}
|
}
|
||||||
|
case Subservice::PING_WITH_DATA: {
|
||||||
|
SerializeElement<uint32_t> receivedDataLen = currentPacket.getUserDataLen();
|
||||||
|
ReturnValue_t result =
|
||||||
|
tmHelper.prepareTmPacket(Subservice::PING_WITH_DATA_REPORT_WITH_SIZE, receivedDataLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return tmHelper.storeAndSendTmPacket();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,9 @@ class Service17Test : public PusServiceBase {
|
|||||||
CONNECTION_TEST_REPORT = 2,
|
CONNECTION_TEST_REPORT = 2,
|
||||||
//! [EXPORT] : [COMMAND] Trigger test reply and test event
|
//! [EXPORT] : [COMMAND] Trigger test reply and test event
|
||||||
EVENT_TRIGGER_TEST = 128,
|
EVENT_TRIGGER_TEST = 128,
|
||||||
|
PING_WITH_DATA = 129,
|
||||||
|
//! [EXPORT] : [COMMAND] Report which reports the sent user data size
|
||||||
|
PING_WITH_DATA_REPORT_WITH_SIZE = 130
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Service17Test(PsbParams params);
|
explicit Service17Test(PsbParams params);
|
||||||
|
@ -69,14 +69,14 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
|
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||||
<< "MessageQueue: Can't access object" << std::endl;
|
<< "MessageQueue: Can't access object" << std::endl;
|
||||||
sif::error << "Object ID: " << std::hex << objectId << std::dec << std::endl;
|
sif::error << "Object ID: 0x" << std::hex << *objectId << std::dec << std::endl;
|
||||||
sif::error << "Make sure it implements ReceivesParameterMessagesIF!" << std::endl;
|
sif::error << "Make sure it implements ReceivesParameterMessagesIF" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError(
|
sif::printError(
|
||||||
"Service20ParameterManagement::checkInterfaceAndAcquire"
|
"Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||||
"MessageQueue: Can't access object\n");
|
"MessageQueue: Can't access object\n");
|
||||||
sif::printError("Object ID: 0x%08x\n", *objectId);
|
sif::printError("Object ID: 0x%08x\n", *objectId);
|
||||||
sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n");
|
sif::printError("Make sure it implements ReceivesParameterMessagesIF\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return CommandingServiceBase::INVALID_OBJECT;
|
return CommandingServiceBase::INVALID_OBJECT;
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
class Service5EventReporting : public PusServiceBase {
|
class Service5EventReporting : public PusServiceBase {
|
||||||
public:
|
public:
|
||||||
Service5EventReporting(PsbParams params, size_t maxNumberReportsPerCycle = 10,
|
Service5EventReporting(PsbParams params, size_t maxNumberReportsPerCycle = 10,
|
||||||
uint32_t messageQueueDepth = 10);
|
uint32_t messageQueueDepth = 20);
|
||||||
~Service5EventReporting() override;
|
~Service5EventReporting() override;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "fsfw/pus/Service9TimeManagement.h"
|
#include "fsfw/pus/Service9TimeManagement.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "fsfw/events/EventManagerIF.h"
|
#include "fsfw/events/EventManagerIF.h"
|
||||||
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
@ -15,9 +17,17 @@ ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK;
|
|||||||
|
|
||||||
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
||||||
switch (subservice) {
|
switch (subservice) {
|
||||||
case SUBSERVICE::SET_TIME: {
|
case Subservice::SET_TIME: {
|
||||||
return setTime();
|
return setTime();
|
||||||
}
|
}
|
||||||
|
case Subservice::DUMP_TIME: {
|
||||||
|
timeval newTime;
|
||||||
|
Clock::getClock_timeval(&newTime);
|
||||||
|
uint32_t subsecondMs =
|
||||||
|
static_cast<uint32_t>(std::floor(static_cast<double>(newTime.tv_usec) / 1000.0));
|
||||||
|
triggerEvent(CLOCK_DUMP, newTime.tv_sec, subsecondMs);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||||
}
|
}
|
||||||
@ -33,14 +43,14 @@ ReturnValue_t Service9TimeManagement::setTime() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t formerUptime;
|
timeval time;
|
||||||
Clock::getUptime(&formerUptime);
|
Clock::getClock_timeval(&time);
|
||||||
result = Clock::setClock(&timeToSet);
|
result = Clock::setClock(&timeToSet);
|
||||||
|
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
uint32_t newUptime;
|
timeval newTime;
|
||||||
Clock::getUptime(&newUptime);
|
Clock::getClock_timeval(&newTime);
|
||||||
triggerEvent(CLOCK_SET, newUptime, formerUptime);
|
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
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
|
|
||||||
|
//!< Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
|
||||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
||||||
|
//!< Clock dump event. P1: timeval seconds P2: timeval milliseconds.
|
||||||
|
static constexpr Event CLOCK_DUMP = MAKE_EVENT(1, severity::INFO);
|
||||||
//!< Clock could not be set. P1: Returncode.
|
//!< Clock could not be set. P1: Returncode.
|
||||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||||
|
|
||||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||||
|
|
||||||
@ -30,8 +33,9 @@ class Service9TimeManagement : public PusServiceBase {
|
|||||||
virtual ReturnValue_t setTime();
|
virtual ReturnValue_t setTime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum SUBSERVICE {
|
enum Subservice {
|
||||||
SET_TIME = 128 //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
||||||
|
DUMP_TIME = 129,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
||||||
#define FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
#define FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
||||||
|
|
||||||
#include "../../modes/ModeMessage.h"
|
#include "fsfw/modes/ModeMessage.h"
|
||||||
#include "../../serialize/SerialLinkedListAdapter.h"
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
#include "../../serialize/SerializeIF.h"
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subservice 1, 2, 3, 4, 5
|
* @brief Subservice 1, 2, 3, 4, 5
|
||||||
|
@ -31,9 +31,8 @@ LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig,
|
|||||||
|
|
||||||
LocalPool::~LocalPool() = default;
|
LocalPool::~LocalPool() = default;
|
||||||
|
|
||||||
ReturnValue_t LocalPool::addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
ReturnValue_t LocalPool::addData(store_address_t* storageId, const uint8_t* data, size_t size) {
|
||||||
bool ignoreFault) {
|
ReturnValue_t status = reserveSpace(size, storageId);
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
|
||||||
if (status == returnvalue::OK) {
|
if (status == returnvalue::OK) {
|
||||||
write(*storageId, data, size);
|
write(*storageId, data, size);
|
||||||
}
|
}
|
||||||
@ -49,8 +48,8 @@ ReturnValue_t LocalPool::getData(store_address_t packetId, const uint8_t** packe
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t size,
|
ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t size,
|
||||||
uint8_t** pData, bool ignoreFault) {
|
uint8_t** pData) {
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
ReturnValue_t status = reserveSpace(size, storageId);
|
||||||
if (status == returnvalue::OK) {
|
if (status == returnvalue::OK) {
|
||||||
*pData = &store[storageId->poolIndex][getRawPosition(*storageId)];
|
*pData = &store[storageId->poolIndex][getRawPosition(*storageId)];
|
||||||
} else {
|
} else {
|
||||||
@ -167,7 +166,7 @@ void LocalPool::clearStore() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::reserveSpace(size_t size, store_address_t* storeId, bool ignoreFault) {
|
ReturnValue_t LocalPool::reserveSpace(size_t size, store_address_t* storeId) {
|
||||||
ReturnValue_t status = getSubPoolIndex(size, &storeId->poolIndex);
|
ReturnValue_t status = getSubPoolIndex(size, &storeId->poolIndex);
|
||||||
if (status != returnvalue::OK) {
|
if (status != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -318,27 +317,3 @@ bool LocalPool::hasDataAtId(store_address_t storeId) const {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) {
|
|
||||||
return StorageManagerIF::getFreeElement(storeId, size, pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstAccessorPair LocalPool::getData(store_address_t storeId) {
|
|
||||||
return StorageManagerIF::getData(storeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::addData(store_address_t* storeId, const uint8_t* data, size_t size) {
|
|
||||||
return StorageManagerIF::addData(storeId, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getData(store_address_t storeId, ConstStorageAccessor& accessor) {
|
|
||||||
return StorageManagerIF::getData(storeId, accessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::modifyData(store_address_t storeId, StorageAccessor& accessor) {
|
|
||||||
return StorageManagerIF::modifyData(storeId, accessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
AccessorPair LocalPool::modifyData(store_address_t storeId) {
|
|
||||||
return StorageManagerIF::modifyData(storeId);
|
|
||||||
}
|
|
||||||
|
@ -86,21 +86,13 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
/**
|
/**
|
||||||
* Documentation: See StorageManagerIF.h
|
* Documentation: See StorageManagerIF.h
|
||||||
*/
|
*/
|
||||||
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size,
|
|
||||||
bool ignoreFault) override;
|
|
||||||
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size) override;
|
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) override;
|
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) override;
|
||||||
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData,
|
|
||||||
bool ignoreFault) override;
|
|
||||||
|
|
||||||
ConstAccessorPair getData(store_address_t storeId) override;
|
|
||||||
ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& accessor) override;
|
|
||||||
ReturnValue_t getData(store_address_t storeId, const uint8_t** packet_ptr, size_t* size) override;
|
ReturnValue_t getData(store_address_t storeId, const uint8_t** packet_ptr, size_t* size) override;
|
||||||
|
|
||||||
AccessorPair modifyData(store_address_t storeId) override;
|
|
||||||
ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t* size) override;
|
ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t* size) override;
|
||||||
ReturnValue_t modifyData(store_address_t storeId, StorageAccessor& accessor) override;
|
|
||||||
|
|
||||||
ReturnValue_t deleteData(store_address_t storeId) override;
|
ReturnValue_t deleteData(store_address_t storeId) override;
|
||||||
ReturnValue_t deleteData(uint8_t* ptr, size_t size, store_address_t* storeId) override;
|
ReturnValue_t deleteData(uint8_t* ptr, size_t size, store_address_t* storeId) override;
|
||||||
@ -136,6 +128,12 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
[[nodiscard]] max_subpools_t getNumberOfSubPools() const override;
|
[[nodiscard]] max_subpools_t getNumberOfSubPools() const override;
|
||||||
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
||||||
|
|
||||||
|
// Using functions provided by StorageManagerIF requires either a fully qualified path
|
||||||
|
// like for example localPool.StorageManagerIF::getFreeElement(...) or re-exporting
|
||||||
|
// the fully qualified path with the using directive.
|
||||||
|
using StorageManagerIF::getData;
|
||||||
|
using StorageManagerIF::modifyData;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* With this helper method, a free element of @c size is reserved.
|
* With this helper method, a free element of @c size is reserved.
|
||||||
@ -144,7 +142,7 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
* @return - returnvalue::OK on success,
|
* @return - returnvalue::OK on success,
|
||||||
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t reserveSpace(size_t size, store_address_t* address, bool ignoreFault);
|
virtual ReturnValue_t reserveSpace(size_t size, store_address_t* address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -188,6 +186,8 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
std::vector<std::vector<size_type>> sizeLists =
|
std::vector<std::vector<size_type>> sizeLists =
|
||||||
std::vector<std::vector<size_type>>(NUMBER_OF_SUBPOOLS);
|
std::vector<std::vector<size_type>>(NUMBER_OF_SUBPOOLS);
|
||||||
|
|
||||||
|
bool ignoreFault = false;
|
||||||
|
|
||||||
//! A variable to determine whether higher n pools are used if
|
//! A variable to determine whether higher n pools are used if
|
||||||
//! the store is full.
|
//! the store is full.
|
||||||
bool spillsToHigherPools = false;
|
bool spillsToHigherPools = false;
|
||||||
|
@ -9,10 +9,9 @@ PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPo
|
|||||||
|
|
||||||
PoolManager::~PoolManager() { MutexFactory::instance()->deleteMutex(mutex); }
|
PoolManager::~PoolManager() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
|
|
||||||
ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* address,
|
ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* address) {
|
||||||
bool ignoreFault) {
|
|
||||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs);
|
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs);
|
||||||
ReturnValue_t status = LocalPool::reserveSpace(size, address, ignoreFault);
|
ReturnValue_t status = LocalPool::reserveSpace(size, address);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class PoolManager : public LocalPool {
|
|||||||
//! Default mutex timeout value to prevent permanent blocking.
|
//! Default mutex timeout value to prevent permanent blocking.
|
||||||
uint32_t mutexTimeoutMs = 20;
|
uint32_t mutexTimeoutMs = 20;
|
||||||
|
|
||||||
ReturnValue_t reserveSpace(size_t size, store_address_t* address, bool ignoreFault) override;
|
ReturnValue_t reserveSpace(size_t size, store_address_t* address) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The mutex is created in the constructor and makes
|
* @brief The mutex is created in the constructor and makes
|
||||||
|
@ -55,7 +55,7 @@ class StorageManagerIF {
|
|||||||
/**
|
/**
|
||||||
* @brief This is the empty virtual destructor as required for C++ interfaces.
|
* @brief This is the empty virtual destructor as required for C++ interfaces.
|
||||||
*/
|
*/
|
||||||
~StorageManagerIF() = default;
|
virtual ~StorageManagerIF() = default;
|
||||||
/**
|
/**
|
||||||
* @brief With addData, a free storage position is allocated and data
|
* @brief With addData, a free storage position is allocated and data
|
||||||
* stored there.
|
* stored there.
|
||||||
@ -66,12 +66,7 @@ class StorageManagerIF {
|
|||||||
* @return Returns @returnvalue::OK if data was added.
|
* @return Returns @returnvalue::OK if data was added.
|
||||||
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size) = 0;
|
||||||
bool ignoreFault) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size) {
|
|
||||||
return addData(storageId, data, size, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief With deleteData, the storageManager frees the memory region
|
* @brief With deleteData, the storageManager frees the memory region
|
||||||
@ -186,12 +181,8 @@ class StorageManagerIF {
|
|||||||
* @return Returns @returnvalue::OK if data was added.
|
* @return Returns @returnvalue::OK if data was added.
|
||||||
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** dataPtr,
|
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size,
|
||||||
bool ignoreFault) = 0;
|
uint8_t** dataPtr) = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** dataPtr) {
|
|
||||||
return getFreeElement(storageId, size, dataPtr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0;
|
[[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp)
|
target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp
|
||||||
|
helper.cpp)
|
||||||
|
|
||||||
add_subdirectory(modes)
|
add_subdirectory(modes)
|
||||||
|
13
src/fsfw/subsystem/HasModeTreeChildrenIF.h
Normal file
13
src/fsfw/subsystem/HasModeTreeChildrenIF.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef FSFW_SUBSYSTEM_HASMODETREECHILDRENIF_H_
|
||||||
|
#define FSFW_SUBSYSTEM_HASMODETREECHILDRENIF_H_
|
||||||
|
|
||||||
|
#include "ModeTreeChildIF.h"
|
||||||
|
|
||||||
|
class HasModeTreeChildrenIF {
|
||||||
|
public:
|
||||||
|
virtual ~HasModeTreeChildrenIF() = default;
|
||||||
|
virtual ReturnValue_t registerChild(const ModeTreeChildIF& child) = 0;
|
||||||
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FSFW_SUBSYSTEM_HASMODETREECHILDRENIF_H_
|
15
src/fsfw/subsystem/ModeTreeChildIF.h
Normal file
15
src/fsfw/subsystem/ModeTreeChildIF.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef FSFW_SUBSYSTEM_MODETREECHILDIF_H_
|
||||||
|
#define FSFW_SUBSYSTEM_MODETREECHILDIF_H_
|
||||||
|
|
||||||
|
#include <fsfw/health/HasHealthIF.h>
|
||||||
|
#include <fsfw/modes/HasModesIF.h>
|
||||||
|
|
||||||
|
class ModeTreeChildIF {
|
||||||
|
public:
|
||||||
|
virtual ~ModeTreeChildIF() = default;
|
||||||
|
virtual object_id_t getObjectId() const = 0;
|
||||||
|
virtual const HasHealthIF* getOptHealthIF() const = 0;
|
||||||
|
virtual const HasModesIF& getModeIF() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SUBSYSTEM_MODETREECHILDIF_H_ */
|
13
src/fsfw/subsystem/ModeTreeConnectionIF.h
Normal file
13
src/fsfw/subsystem/ModeTreeConnectionIF.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef FSFW_SUBSYSTEM_MODES_MODETREECONNECTIONIF_H_
|
||||||
|
#define FSFW_SUBSYSTEM_MODES_MODETREECONNECTIONIF_H_
|
||||||
|
|
||||||
|
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
|
||||||
|
|
||||||
|
class ModeTreeConnectionIF {
|
||||||
|
public:
|
||||||
|
virtual ~ModeTreeConnectionIF() = default;
|
||||||
|
virtual ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) = 0;
|
||||||
|
virtual ModeTreeChildIF& getModeTreeChildIF() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_SUBSYSTEM_MODES_MODETREECONNECTIONIF_H_ */
|
@ -9,9 +9,9 @@
|
|||||||
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
#include "fsfw/serialize/SerializeElement.h"
|
#include "fsfw/serialize/SerializeElement.h"
|
||||||
|
|
||||||
Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent, uint32_t maxNumberOfSequences,
|
Subsystem::Subsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
|
||||||
uint32_t maxNumberOfTables)
|
uint32_t maxNumberOfTables)
|
||||||
: SubsystemBase(setObjectId, parent, 0),
|
: SubsystemBase(setObjectId, 0),
|
||||||
isInTransition(false),
|
isInTransition(false),
|
||||||
childrenChangedHealth(false),
|
childrenChangedHealth(false),
|
||||||
currentTargetTable(),
|
currentTargetTable(),
|
||||||
@ -36,6 +36,13 @@ ReturnValue_t Subsystem::checkSequence(HybridIterator<ModeListEntry> iter,
|
|||||||
|
|
||||||
for (; iter.value != nullptr; ++iter) {
|
for (; iter.value != nullptr; ++iter) {
|
||||||
if (!existsModeTable(iter->getTableId())) {
|
if (!existsModeTable(iter->getTableId())) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
using namespace std;
|
||||||
|
sif::warning << "Subsystem::checkSequence: "
|
||||||
|
<< "Object " << setfill('0') << hex << "0x" << setw(8) << getObjectId()
|
||||||
|
<< setw(0) << ": Mode table for mode ID "
|
||||||
|
<< "0x" << setw(8) << iter->getTableId() << " does not exist" << dec << endl;
|
||||||
|
#endif
|
||||||
return TABLE_DOES_NOT_EXIST;
|
return TABLE_DOES_NOT_EXIST;
|
||||||
} else {
|
} else {
|
||||||
ReturnValue_t result = checkTable(getTable(iter->getTableId()));
|
ReturnValue_t result = checkTable(getTable(iter->getTableId()));
|
||||||
|
@ -66,8 +66,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF {
|
|||||||
* @param maxNumberOfSequences
|
* @param maxNumberOfSequences
|
||||||
* @param maxNumberOfTables
|
* @param maxNumberOfTables
|
||||||
*/
|
*/
|
||||||
Subsystem(object_id_t setObjectId, object_id_t parent, uint32_t maxNumberOfSequences,
|
Subsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
|
||||||
uint32_t maxNumberOfTables);
|
|
||||||
virtual ~Subsystem();
|
virtual ~Subsystem();
|
||||||
|
|
||||||
ReturnValue_t addSequence(SequenceEntry sequence);
|
ReturnValue_t addSequence(SequenceEntry sequence);
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
#include "fsfw/subsystem/SubsystemBase.h"
|
#include "fsfw/subsystem/SubsystemBase.h"
|
||||||
|
|
||||||
|
#include "fsfw/FSFW.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
#include "fsfw/subsystem/helper.h"
|
||||||
|
|
||||||
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode,
|
SubsystemBase::SubsystemBase(object_id_t setObjectId, Mode_t initialMode,
|
||||||
uint16_t commandQueueDepth)
|
uint16_t commandQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
mode(initialMode),
|
mode(initialMode),
|
||||||
healthHelper(this, setObjectId),
|
healthHelper(this, setObjectId),
|
||||||
modeHelper(this),
|
modeHelper(this) {
|
||||||
parentId(parent) {
|
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
@ -18,36 +19,6 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
|
|||||||
|
|
||||||
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
|
|
||||||
ChildInfo info;
|
|
||||||
|
|
||||||
HasModesIF* child = ObjectManager::instance()->get<HasModesIF>(objectId);
|
|
||||||
// This is a rather ugly hack to have the changedHealth info for all
|
|
||||||
// children available.
|
|
||||||
HasHealthIF* healthChild = ObjectManager::instance()->get<HasHealthIF>(objectId);
|
|
||||||
if (child == nullptr) {
|
|
||||||
if (healthChild == nullptr) {
|
|
||||||
return CHILD_DOESNT_HAVE_MODES;
|
|
||||||
} else {
|
|
||||||
info.commandQueue = healthChild->getCommandQueue();
|
|
||||||
info.mode = MODE_OFF;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// intentional to force an initial command during system startup
|
|
||||||
info.commandQueue = child->getCommandQueue();
|
|
||||||
info.mode = HasModesIF::MODE_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.submode = SUBMODE_NONE;
|
|
||||||
info.healthChanged = false;
|
|
||||||
|
|
||||||
auto resultPair = childrenMap.emplace(objectId, info);
|
|
||||||
if (not resultPair.second) {
|
|
||||||
return COULD_NOT_INSERT_CHILD;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::checkStateAgainstTable(HybridIterator<ModeListEntry> tableIter,
|
ReturnValue_t SubsystemBase::checkStateAgainstTable(HybridIterator<ModeListEntry> tableIter,
|
||||||
Submode_t targetSubmode) {
|
Submode_t targetSubmode) {
|
||||||
std::map<object_id_t, ChildInfo>::iterator childIter;
|
std::map<object_id_t, ChildInfo>::iterator childIter;
|
||||||
@ -87,7 +58,8 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
|
|||||||
if ((iter = childrenMap.find(object)) == childrenMap.end()) {
|
if ((iter = childrenMap.find(object)) == childrenMap.end()) {
|
||||||
// illegal table entry, should only happen due to misconfigured mode table
|
// illegal table entry, should only happen due to misconfigured mode table
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << std::hex << getObjectId() << ": invalid mode table entry" << std::endl;
|
sif::debug << std::hex << SystemObject::getObjectId() << ": invalid mode table entry"
|
||||||
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -158,36 +130,15 @@ ReturnValue_t SubsystemBase::updateChildChangedHealth(MessageQueueId_t queue, bo
|
|||||||
MessageQueueId_t SubsystemBase::getCommandQueue() const { return commandQueue->getId(); }
|
MessageQueueId_t SubsystemBase::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::initialize() {
|
ReturnValue_t SubsystemBase::initialize() {
|
||||||
MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE;
|
ReturnValue_t result = modeHelper.initialize();
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
|
||||||
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
result = healthHelper.initialize();
|
||||||
if (parentId != objects::NO_OBJECT) {
|
|
||||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
|
||||||
if (parent == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
parentQueue = parent->getCommandQueue();
|
|
||||||
|
|
||||||
parent->registerChild(getObjectId());
|
|
||||||
}
|
|
||||||
|
|
||||||
result = healthHelper.initialize(parentQueue);
|
|
||||||
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
return SystemObject::initialize();
|
||||||
result = modeHelper.initialize(parentQueue);
|
|
||||||
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::performOperation(uint8_t opCode) {
|
ReturnValue_t SubsystemBase::performOperation(uint8_t opCode) {
|
||||||
@ -240,8 +191,14 @@ ReturnValue_t SubsystemBase::handleModeReply(CommandMessage* message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::checkTable(HybridIterator<ModeListEntry> tableIter) {
|
ReturnValue_t SubsystemBase::checkTable(HybridIterator<ModeListEntry> tableIter) {
|
||||||
for (; tableIter.value != NULL; ++tableIter) {
|
for (; tableIter.value != nullptr; ++tableIter) {
|
||||||
if (childrenMap.find(tableIter.value->getObject()) == childrenMap.end()) {
|
if (childrenMap.find(tableIter.value->getObject()) == childrenMap.end()) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
using namespace std;
|
||||||
|
sif::warning << "SubsystemBase::checkTable: Could not find object " << setfill('0') << hex
|
||||||
|
<< "0x" << setw(8) << tableIter.value->getObject() << " in object " << setw(8)
|
||||||
|
<< setw(0) << "0x" << setw(8) << SystemObject::getObjectId() << dec << std::endl;
|
||||||
|
#endif
|
||||||
return TABLE_CONTAINS_INVALID_OBJECT_ID;
|
return TABLE_CONTAINS_INVALID_OBJECT_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,4 +283,33 @@ ReturnValue_t SubsystemBase::setHealth(HealthState health) {
|
|||||||
|
|
||||||
HasHealthIF::HealthState SubsystemBase::getHealth() { return healthHelper.getHealth(); }
|
HasHealthIF::HealthState SubsystemBase::getHealth() { return healthHelper.getHealth(); }
|
||||||
|
|
||||||
|
ReturnValue_t SubsystemBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
|
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_t SubsystemBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
void SubsystemBase::modeChanged() {}
|
void SubsystemBase::modeChanged() {}
|
||||||
|
|
||||||
|
ReturnValue_t SubsystemBase::registerChild(const ModeTreeChildIF& child) {
|
||||||
|
ChildInfo info;
|
||||||
|
|
||||||
|
const HasModesIF& modeChild = child.getModeIF();
|
||||||
|
// intentional to force an initial command during system startup
|
||||||
|
info.commandQueue = modeChild.getCommandQueue();
|
||||||
|
info.mode = HasModesIF::MODE_UNDEFINED;
|
||||||
|
info.submode = SUBMODE_NONE;
|
||||||
|
info.healthChanged = false;
|
||||||
|
|
||||||
|
auto resultPair = childrenMap.emplace(child.getObjectId(), info);
|
||||||
|
if (not resultPair.second) {
|
||||||
|
return COULD_NOT_INSERT_CHILD;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HasHealthIF* SubsystemBase::getOptHealthIF() const { return this; }
|
||||||
|
|
||||||
|
const HasModesIF& SubsystemBase::getModeIF() const { return *this; }
|
||||||
|
|
||||||
|
ModeTreeChildIF& SubsystemBase::getModeTreeChildIF() { return *this; }
|
||||||
|
@ -3,14 +3,16 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "../container/HybridIterator.h"
|
#include "fsfw/container/HybridIterator.h"
|
||||||
#include "../health/HasHealthIF.h"
|
#include "fsfw/health/HasHealthIF.h"
|
||||||
#include "../health/HealthHelper.h"
|
#include "fsfw/health/HealthHelper.h"
|
||||||
#include "../ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "../modes/HasModesIF.h"
|
#include "fsfw/modes/HasModesIF.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "../returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "../tasks/ExecutableObjectIF.h"
|
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
|
||||||
|
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||||
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "modes/HasModeSequenceIF.h"
|
#include "modes/HasModeSequenceIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,6 +29,9 @@
|
|||||||
class SubsystemBase : public SystemObject,
|
class SubsystemBase : public SystemObject,
|
||||||
public HasModesIF,
|
public HasModesIF,
|
||||||
public HasHealthIF,
|
public HasHealthIF,
|
||||||
|
public HasModeTreeChildrenIF,
|
||||||
|
public ModeTreeConnectionIF,
|
||||||
|
public ModeTreeChildIF,
|
||||||
public ExecutableObjectIF {
|
public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUBSYSTEM_BASE;
|
static const uint8_t INTERFACE_ID = CLASS_ID::SUBSYSTEM_BASE;
|
||||||
@ -36,12 +41,14 @@ class SubsystemBase : public SystemObject,
|
|||||||
static const ReturnValue_t COULD_NOT_INSERT_CHILD = MAKE_RETURN_CODE(0x04);
|
static const ReturnValue_t COULD_NOT_INSERT_CHILD = MAKE_RETURN_CODE(0x04);
|
||||||
static const ReturnValue_t TABLE_CONTAINS_INVALID_OBJECT_ID = MAKE_RETURN_CODE(0x05);
|
static const ReturnValue_t TABLE_CONTAINS_INVALID_OBJECT_ID = MAKE_RETURN_CODE(0x05);
|
||||||
|
|
||||||
SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode = 0,
|
SubsystemBase(object_id_t setObjectId, Mode_t initialMode = 0, uint16_t commandQueueDepth = 8);
|
||||||
uint16_t commandQueueDepth = 8);
|
|
||||||
virtual ~SubsystemBase();
|
virtual ~SubsystemBase();
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||||
|
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to register the child objects.
|
* Function to register the child objects.
|
||||||
* Performs a checks if the child does implement HasHealthIF and/or HasModesIF
|
* Performs a checks if the child does implement HasHealthIF and/or HasModesIF
|
||||||
@ -53,15 +60,15 @@ class SubsystemBase : public SystemObject,
|
|||||||
* CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF
|
* CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF
|
||||||
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
||||||
*/
|
*/
|
||||||
ReturnValue_t registerChild(object_id_t objectId);
|
ReturnValue_t registerChild(const ModeTreeChildIF &child) override;
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
virtual ReturnValue_t setHealth(HealthState health) override;
|
ReturnValue_t setHealth(HealthState health) override;
|
||||||
|
|
||||||
virtual HasHealthIF::HealthState getHealth() override;
|
HasHealthIF::HealthState getHealth() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct ChildInfo {
|
struct ChildInfo {
|
||||||
@ -88,8 +95,6 @@ class SubsystemBase : public SystemObject,
|
|||||||
|
|
||||||
ModeHelper modeHelper;
|
ModeHelper modeHelper;
|
||||||
|
|
||||||
const object_id_t parentId;
|
|
||||||
|
|
||||||
typedef std::map<object_id_t, ChildInfo> ChildrenMap;
|
typedef std::map<object_id_t, ChildInfo> ChildrenMap;
|
||||||
ChildrenMap childrenMap;
|
ChildrenMap childrenMap;
|
||||||
|
|
||||||
@ -136,6 +141,10 @@ class SubsystemBase : public SystemObject,
|
|||||||
|
|
||||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||||
|
|
||||||
|
object_id_t getObjectId() const override;
|
||||||
|
const HasHealthIF *getOptHealthIF() const override;
|
||||||
|
const HasModesIF &getModeIF() const override;
|
||||||
|
|
||||||
virtual void setToExternalControl() override;
|
virtual void setToExternalControl() override;
|
||||||
|
|
||||||
virtual void announceMode(bool recursive) override;
|
virtual void announceMode(bool recursive) override;
|
||||||
|
15
src/fsfw/subsystem/helper.cpp
Normal file
15
src/fsfw/subsystem/helper.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "helper.h"
|
||||||
|
|
||||||
|
ReturnValue_t modetree::connectModeTreeParent(HasModeTreeChildrenIF& parent,
|
||||||
|
const ModeTreeChildIF& child,
|
||||||
|
HealthHelper* healthHelper, ModeHelper& modeHelper) {
|
||||||
|
ReturnValue_t result = parent.registerChild(child);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (healthHelper != nullptr) {
|
||||||
|
healthHelper->setParentQueue(parent.getCommandQueue());
|
||||||
|
}
|
||||||
|
modeHelper.setParentQueue(parent.getCommandQueue());
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
14
src/fsfw/subsystem/helper.h
Normal file
14
src/fsfw/subsystem/helper.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef FSFW_SUBSYSTEM_HELPER_H_
|
||||||
|
#define FSFW_SUBSYSTEM_HELPER_H_
|
||||||
|
|
||||||
|
#include "HasModeTreeChildrenIF.h"
|
||||||
|
#include "fsfw/health/HealthHelper.h"
|
||||||
|
|
||||||
|
namespace modetree {
|
||||||
|
|
||||||
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent, const ModeTreeChildIF& child,
|
||||||
|
HealthHelper* healthHelper, ModeHelper& modeHelper);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_SUBSYSTEM_HELPER_H_ */
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef FSFW_TIMEMANAGER_TIMEREADERIF_H
|
#ifndef FSFW_TIMEMANAGER_TIMEREADERIF_H
|
||||||
#define FSFW_TIMEMANAGER_TIMEREADERIF_H
|
#define FSFW_TIMEMANAGER_TIMEREADERIF_H
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
|
@ -21,7 +21,7 @@ SpacePacketReader::~SpacePacketReader() = default;
|
|||||||
|
|
||||||
inline uint16_t SpacePacketReader::getPacketIdRaw() const { return ccsds::getPacketId(*spHeader); }
|
inline uint16_t SpacePacketReader::getPacketIdRaw() const { return ccsds::getPacketId(*spHeader); }
|
||||||
|
|
||||||
const uint8_t* SpacePacketReader::getPacketData() { return packetDataField; }
|
const uint8_t* SpacePacketReader::getPacketData() const { return packetDataField; }
|
||||||
|
|
||||||
ReturnValue_t SpacePacketReader::setData(uint8_t* data, size_t maxSize_, void* args) {
|
ReturnValue_t SpacePacketReader::setData(uint8_t* data, size_t maxSize_, void* args) {
|
||||||
return setInternalFields(data, maxSize_);
|
return setInternalFields(data, maxSize_);
|
||||||
|
@ -71,7 +71,7 @@ class SpacePacketReader : public SpacePacketIF,
|
|||||||
// Helper methods:
|
// Helper methods:
|
||||||
[[nodiscard]] ReturnValue_t checkSize() const;
|
[[nodiscard]] ReturnValue_t checkSize() const;
|
||||||
|
|
||||||
const uint8_t* getPacketData();
|
const uint8_t* getPacketData() const;
|
||||||
|
|
||||||
ReturnValue_t setReadOnlyData(const uint8_t* data, size_t maxSize);
|
ReturnValue_t setReadOnlyData(const uint8_t* data, size_t maxSize);
|
||||||
|
|
||||||
|
@ -100,5 +100,6 @@ ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializa
|
|||||||
void PusTcCreator::setup() {
|
void PusTcCreator::setup() {
|
||||||
spCreator.setPacketType(ccsds::PacketType::TC);
|
spCreator.setPacketType(ccsds::PacketType::TC);
|
||||||
spCreator.setSecHeaderFlag();
|
spCreator.setSecHeaderFlag();
|
||||||
|
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ void PusTmCreator::setup() {
|
|||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
spCreator.setPacketType(ccsds::PacketType::TM);
|
spCreator.setPacketType(ccsds::PacketType::TM);
|
||||||
spCreator.setSecHeaderFlag();
|
spCreator.setSecHeaderFlag();
|
||||||
|
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
||||||
|
@ -27,8 +27,8 @@ ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) {
|
|||||||
ReturnValue_t result = performService();
|
ReturnValue_t result = performService();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PusService " << psbParams.serviceId << ": performService returned with "
|
sif::error << "PusService " << static_cast<int>(psbParams.serviceId)
|
||||||
<< static_cast<uint16_t>(result) << std::endl;
|
<< ": performService returned with " << static_cast<uint16_t>(result) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ class SourceSequenceCounter {
|
|||||||
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
||||||
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
uint16_t get() { return this->sequenceCount; }
|
uint16_t get() const { return this->sequenceCount; }
|
||||||
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
SourceSequenceCounter& operator++(int) {
|
SourceSequenceCounter& operator++(int) {
|
||||||
this->increment();
|
this->increment();
|
||||||
|
@ -145,13 +145,17 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
||||||
|
|
||||||
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
|
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
|
||||||
storeDownlinkData(&message);
|
ReturnValue_t result = storeDownlinkData(&message);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = tmStore->getData(message.getStorageId(), &data, &size);
|
result = tmStore->getData(message.getStorageId(), &data, &size);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,9 +163,9 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
} else {
|
} else {
|
||||||
tmStore->deleteData(message.getStorageId());
|
|
||||||
packetSentCounter++;
|
packetSentCounter++;
|
||||||
}
|
}
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -183,7 +187,7 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
|
|||||||
"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;
|
warningSwitch = false;
|
||||||
}
|
}
|
||||||
if (overwriteOld) {
|
if (overwriteOld) {
|
||||||
tmFifo->retrieve(&storeId);
|
tmFifo->retrieve(&storeId);
|
||||||
@ -226,6 +230,7 @@ ReturnValue_t TmTcBridge::handleStoredTm() {
|
|||||||
packetSentCounter++;
|
packetSentCounter++;
|
||||||
|
|
||||||
if (tmFifo->empty()) {
|
if (tmFifo->empty()) {
|
||||||
|
warningSwitch = true;
|
||||||
tmStored = false;
|
tmStored = false;
|
||||||
}
|
}
|
||||||
tmStore->deleteData(storeId);
|
tmStore->deleteData(storeId);
|
||||||
|
@ -65,15 +65,13 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
|
||||||
/** AcceptsTelemetryIF override */
|
/** AcceptsTelemetryIF override */
|
||||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||||
|
|
||||||
/** AcceptsTelecommandsIF override */
|
/** AcceptsTelecommandsIF override */
|
||||||
uint32_t getIdentifier() const override;
|
uint32_t getIdentifier() const override;
|
||||||
MessageQueueId_t getRequestQueue() const override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
const char* getName() const override;
|
const char* getName() const override;
|
||||||
|
|
||||||
bool warningSwitch = true;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char* name = "";
|
const char* name = "";
|
||||||
|
|
||||||
@ -93,6 +91,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
//! by default, so telemetry will be handled immediately.
|
//! by default, so telemetry will be handled immediately.
|
||||||
bool communicationLinkUp = true;
|
bool communicationLinkUp = true;
|
||||||
bool tmStored = false;
|
bool tmStored = false;
|
||||||
|
bool warningSwitch = true;
|
||||||
bool overwriteOld = true;
|
bool overwriteOld = true;
|
||||||
uint8_t packetSentCounter = 0;
|
uint8_t packetSentCounter = 0;
|
||||||
|
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
#ifndef FSFW_UTIL_DATAWRAPPER_H
|
|
||||||
#define FSFW_UTIL_DATAWRAPPER_H
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "fsfw/serialize.h"
|
|
||||||
|
|
||||||
namespace util {
|
|
||||||
|
|
||||||
using BufPair = std::pair<const uint8_t*, size_t>;
|
|
||||||
|
|
||||||
struct RawData {
|
|
||||||
RawData() = default;
|
|
||||||
const uint8_t* data = nullptr;
|
|
||||||
size_t len = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DataTypes { NONE, RAW, SERIALIZABLE };
|
|
||||||
|
|
||||||
union DataUnion {
|
|
||||||
RawData raw{};
|
|
||||||
SerializeIF* serializable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DataWrapper {
|
|
||||||
DataWrapper() = default;
|
|
||||||
|
|
||||||
DataWrapper(const uint8_t* data, size_t size) : type(DataTypes::RAW) { setRawData({data, size}); }
|
|
||||||
|
|
||||||
explicit DataWrapper(BufPair raw) : type(DataTypes::RAW) { setRawData(raw); }
|
|
||||||
|
|
||||||
explicit DataWrapper(SerializeIF& serializable) : type(DataTypes::SERIALIZABLE) {
|
|
||||||
setSerializable(serializable);
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTypes type = DataTypes::NONE;
|
|
||||||
DataUnion dataUnion;
|
|
||||||
|
|
||||||
[[nodiscard]] size_t getLength() const {
|
|
||||||
if (type == DataTypes::RAW) {
|
|
||||||
return dataUnion.raw.len;
|
|
||||||
} else if (type == DataTypes::SERIALIZABLE and dataUnion.serializable != nullptr) {
|
|
||||||
return dataUnion.serializable->getSerializedSize();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool isNull() const {
|
|
||||||
if ((type == DataTypes::NONE) or (type == DataTypes::RAW and dataUnion.raw.data == nullptr) or
|
|
||||||
(type == DataTypes::SERIALIZABLE and dataUnion.serializable == nullptr)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRawData(BufPair bufPair) {
|
|
||||||
type = DataTypes::RAW;
|
|
||||||
dataUnion.raw.data = bufPair.first;
|
|
||||||
dataUnion.raw.len = bufPair.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSerializable(SerializeIF& serializable) {
|
|
||||||
type = DataTypes::SERIALIZABLE;
|
|
||||||
dataUnion.serializable = &serializable;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace util
|
|
||||||
|
|
||||||
#endif // FSFW_UTIL_DATAWRAPPER_H
|
|
@ -325,12 +325,12 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
|||||||
// trickery here to calculate the raw values first
|
// trickery here to calculate the raw values first
|
||||||
int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8;
|
int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8;
|
||||||
int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8;
|
int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8;
|
||||||
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8;
|
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[9] << 8)) >> 8;
|
||||||
|
|
||||||
// Now scale to physical value in microtesla
|
// Now scale to physical value in microtesla
|
||||||
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
|
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
|
||||||
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
|
float fieldStrengthY = fieldStrengthRawY * scaleFactorY;
|
||||||
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
|
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorZ;
|
||||||
|
|
||||||
if (periodicPrintout) {
|
if (periodicPrintout) {
|
||||||
if (debugDivider.checkAndIncrement()) {
|
if (debugDivider.checkAndIncrement()) {
|
||||||
|
@ -5,11 +5,14 @@ endif()
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp
|
target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp
|
||||||
utility.cpp)
|
utility.cpp)
|
||||||
|
|
||||||
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
||||||
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
|
||||||
add_subdirectory(gpio)
|
add_subdirectory(gpio)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(uart)
|
if(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS)
|
||||||
|
add_subdirectory(serial)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
||||||
# Adding those does not really make sense on Apple systems which are generally
|
# Adding those does not really make sense on Apple systems which are generally
|
||||||
# host systems. It won't even compile as the headers are missing
|
# host systems. It won't even compile as the headers are missing
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
|
@ -109,14 +109,17 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (write(fd, sendData, sendLen) != static_cast<int>(sendLen)) {
|
if (write(fd, sendData, sendLen) != static_cast<int>(sendLen)) {
|
||||||
|
i2cCookie->errorCounter++;
|
||||||
|
if (i2cCookie->errorCounter < 3) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "I2cComIF::sendMessage: Failed to send data to I2C "
|
sif::error << "I2cComIF::sendMessage: Failed to send data to I2C "
|
||||||
"device with error code "
|
"device with error code "
|
||||||
<< errno << ". Error description: " << strerror(errno) << std::endl;
|
<< errno << ". Error description: " << strerror(errno) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
i2cCookie->errorCounter = 0;
|
||||||
#if FSFW_HAL_I2C_WIRETAPPING == 1
|
#if FSFW_HAL_I2C_WIRETAPPING == 1
|
||||||
sif::info << "Sent I2C data to bus " << deviceFile << ":" << std::endl;
|
sif::info << "Sent I2C data to bus " << deviceFile << ":" << std::endl;
|
||||||
arrayprinter::print(sendData, sendLen);
|
arrayprinter::print(sendData, sendLen);
|
||||||
@ -180,10 +183,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
|
|
||||||
<< " bytes" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ class I2cCookie : public CookieIF {
|
|||||||
size_t getMaxReplyLen() const;
|
size_t getMaxReplyLen() const;
|
||||||
std::string getDeviceFile() const;
|
std::string getDeviceFile() const;
|
||||||
|
|
||||||
|
uint8_t errorCounter = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
address_t i2cAddress = 0;
|
address_t i2cAddress = 0;
|
||||||
size_t maxReplyLen = 0;
|
size_t maxReplyLen = 0;
|
||||||
|
2
src/fsfw_hal/linux/serial/CMakeLists.txt
Normal file
2
src/fsfw_hal/linux/serial/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
target_sources(${LIB_FSFW_NAME} PUBLIC SerialComIF.cpp SerialCookie.cpp
|
||||||
|
helper.cpp)
|
@ -1,7 +1,8 @@
|
|||||||
#include "UartComIF.h"
|
#include "SerialComIF.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <fsfw_hal/linux/serial/SerialComIF.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -11,18 +12,18 @@
|
|||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw_hal/linux/utility.h"
|
#include "fsfw_hal/linux/utility.h"
|
||||||
|
|
||||||
UartComIF::UartComIF(object_id_t objectId) : SystemObject(objectId) {}
|
SerialComIF::SerialComIF(object_id_t objectId) : SystemObject(objectId) {}
|
||||||
|
|
||||||
UartComIF::~UartComIF() {}
|
SerialComIF::~SerialComIF() {}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::initializeInterface(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
if (cookie == nullptr) {
|
if (cookie == nullptr) {
|
||||||
return NULLPOINTER;
|
return NULLPOINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl;
|
sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl;
|
||||||
@ -59,7 +60,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
|
||||||
struct termios options = {};
|
struct termios options = {};
|
||||||
|
|
||||||
std::string deviceFile = uartCookie->getDeviceFile();
|
std::string deviceFile = uartCookie->getDeviceFile();
|
||||||
@ -88,7 +89,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
setParityOptions(&options, uartCookie);
|
uart::setParity(options, uartCookie->getParity());
|
||||||
setStopBitOptions(&options, uartCookie);
|
setStopBitOptions(&options, uartCookie);
|
||||||
setDatasizeOptions(&options, uartCookie);
|
setDatasizeOptions(&options, uartCookie);
|
||||||
setFixedOptions(&options);
|
setFixedOptions(&options);
|
||||||
@ -114,24 +115,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartComIF::setParityOptions(struct termios* options, UartCookie* uartCookie) {
|
void SerialComIF::setStopBitOptions(struct termios* options, SerialCookie* uartCookie) {
|
||||||
/* Clear parity bit */
|
|
||||||
options->c_cflag &= ~PARENB;
|
|
||||||
switch (uartCookie->getParity()) {
|
|
||||||
case Parity::EVEN:
|
|
||||||
options->c_cflag |= PARENB;
|
|
||||||
options->c_cflag &= ~PARODD;
|
|
||||||
break;
|
|
||||||
case Parity::ODD:
|
|
||||||
options->c_cflag |= PARENB;
|
|
||||||
options->c_cflag |= PARODD;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCookie) {
|
|
||||||
/* Clear stop field. Sets stop bit to one bit */
|
/* Clear stop field. Sets stop bit to one bit */
|
||||||
options->c_cflag &= ~CSTOPB;
|
options->c_cflag &= ~CSTOPB;
|
||||||
switch (uartCookie->getStopBits()) {
|
switch (uartCookie->getStopBits()) {
|
||||||
@ -143,7 +127,7 @@ void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCooki
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCookie) {
|
void SerialComIF::setDatasizeOptions(struct termios* options, SerialCookie* uartCookie) {
|
||||||
/* Clear size bits */
|
/* Clear size bits */
|
||||||
options->c_cflag &= ~CSIZE;
|
options->c_cflag &= ~CSIZE;
|
||||||
switch (uartCookie->getBitsPerWord()) {
|
switch (uartCookie->getBitsPerWord()) {
|
||||||
@ -167,7 +151,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartComIF::setFixedOptions(struct termios* options) {
|
void SerialComIF::setFixedOptions(struct termios* options) {
|
||||||
/* Disable RTS/CTS hardware flow control */
|
/* Disable RTS/CTS hardware flow control */
|
||||||
options->c_cflag &= ~CRTSCTS;
|
options->c_cflag &= ~CRTSCTS;
|
||||||
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
|
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
|
||||||
@ -190,7 +174,7 @@ void UartComIF::setFixedOptions(struct termios* options) {
|
|||||||
options->c_oflag &= ~ONLCR;
|
options->c_oflag &= ~ONLCR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
ReturnValue_t SerialComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
@ -205,7 +189,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
|
sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
|
||||||
@ -236,12 +220,12 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
ReturnValue_t SerialComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
||||||
|
|
||||||
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
ReturnValue_t SerialComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl;
|
sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl;
|
||||||
@ -274,8 +258,8 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
ReturnValue_t SerialComIF::handleCanonicalRead(SerialCookie& uartCookie,
|
||||||
size_t requestLen) {
|
UartDeviceMap::iterator& iter, size_t requestLen) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
uint8_t maxReadCycles = uartCookie.getReadCycles();
|
uint8_t maxReadCycles = uartCookie.getReadCycles();
|
||||||
uint8_t currentReadCycles = 0;
|
uint8_t currentReadCycles = 0;
|
||||||
@ -332,8 +316,9 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie,
|
ReturnValue_t SerialComIF::handleNoncanonicalRead(SerialCookie& uartCookie,
|
||||||
UartDeviceMap::iterator& iter, size_t requestLen) {
|
UartDeviceMap::iterator& iter,
|
||||||
|
size_t requestLen) {
|
||||||
int fd = iter->second.fileDescriptor;
|
int fd = iter->second.fileDescriptor;
|
||||||
auto bufferPtr = iter->second.replyBuffer.data();
|
auto bufferPtr = iter->second.replyBuffer.data();
|
||||||
// Size check to prevent buffer overflow
|
// Size check to prevent buffer overflow
|
||||||
@ -366,10 +351,10 @@ ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
ReturnValue_t SerialComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
|
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
|
||||||
@ -396,9 +381,9 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::flushUartRxBuffer(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl;
|
sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl;
|
||||||
@ -415,9 +400,9 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::flushUartTxBuffer(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl;
|
sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl;
|
||||||
@ -434,9 +419,9 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl;
|
sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl;
|
@ -3,13 +3,12 @@
|
|||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw_hal/linux/serial/SerialCookie.h>
|
||||||
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "UartCookie.h"
|
|
||||||
#include "helper.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the communication interface to access serial ports on linux based operating
|
* @brief This is the communication interface to access serial ports on linux based operating
|
||||||
* systems.
|
* systems.
|
||||||
@ -19,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
class SerialComIF : public DeviceCommunicationIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
|
static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
|
||||||
|
|
||||||
@ -27,9 +26,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2);
|
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2);
|
||||||
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3);
|
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3);
|
||||||
|
|
||||||
UartComIF(object_id_t objectId);
|
SerialComIF(object_id_t objectId);
|
||||||
|
|
||||||
virtual ~UartComIF();
|
virtual ~SerialComIF();
|
||||||
|
|
||||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||||
@ -76,20 +75,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
* uart device file, baudrate, parity, stopbits etc.
|
* uart device file, baudrate, parity, stopbits etc.
|
||||||
* @return The file descriptor of the configured uart.
|
* @return The file descriptor of the configured uart.
|
||||||
*/
|
*/
|
||||||
int configureUartPort(UartCookie* uartCookie);
|
int configureUartPort(SerialCookie* uartCookie);
|
||||||
|
|
||||||
/**
|
void setStopBitOptions(struct termios* options, SerialCookie* uartCookie);
|
||||||
* @brief This function adds the parity settings to the termios options struct.
|
|
||||||
*
|
|
||||||
* @param options Pointer to termios options struct which will be modified to enable or disable
|
|
||||||
* parity checking.
|
|
||||||
* @param uartCookie Pointer to uart cookie containing the information about the desired
|
|
||||||
* parity settings.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void setParityOptions(struct termios* options, UartCookie* uartCookie);
|
|
||||||
|
|
||||||
void setStopBitOptions(struct termios* options, UartCookie* uartCookie);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sets options which are not configurable by the uartCookie.
|
* @brief This function sets options which are not configurable by the uartCookie.
|
||||||
@ -99,11 +87,11 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
/**
|
/**
|
||||||
* @brief With this function the datasize settings are added to the termios options struct.
|
* @brief With this function the datasize settings are added to the termios options struct.
|
||||||
*/
|
*/
|
||||||
void setDatasizeOptions(struct termios* options, UartCookie* uartCookie);
|
void setDatasizeOptions(struct termios* options, SerialCookie* uartCookie);
|
||||||
|
|
||||||
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
ReturnValue_t handleCanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter,
|
||||||
size_t requestLen);
|
size_t requestLen);
|
||||||
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
ReturnValue_t handleNoncanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter,
|
||||||
size_t requestLen);
|
size_t requestLen);
|
||||||
};
|
};
|
||||||
|
|
51
src/fsfw_hal/linux/serial/SerialCookie.cpp
Normal file
51
src/fsfw_hal/linux/serial/SerialCookie.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "SerialCookie.h"
|
||||||
|
|
||||||
|
#include <fsfw/serviceinterface.h>
|
||||||
|
|
||||||
|
SerialCookie::SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
||||||
|
size_t maxReplyLen, UartModes uartMode)
|
||||||
|
: handlerId(handlerId),
|
||||||
|
deviceFile(deviceFile),
|
||||||
|
uartMode(uartMode),
|
||||||
|
baudrate(baudrate),
|
||||||
|
maxReplyLen(maxReplyLen) {}
|
||||||
|
|
||||||
|
SerialCookie::~SerialCookie() {}
|
||||||
|
|
||||||
|
UartBaudRate SerialCookie::getBaudrate() const { return baudrate; }
|
||||||
|
|
||||||
|
size_t SerialCookie::getMaxReplyLen() const { return maxReplyLen; }
|
||||||
|
|
||||||
|
std::string SerialCookie::getDeviceFile() const { return deviceFile; }
|
||||||
|
|
||||||
|
void SerialCookie::setParityOdd() { parity = Parity::ODD; }
|
||||||
|
|
||||||
|
void SerialCookie::setParityEven() { parity = Parity::EVEN; }
|
||||||
|
|
||||||
|
Parity SerialCookie::getParity() const { return parity; }
|
||||||
|
|
||||||
|
void SerialCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
|
||||||
|
|
||||||
|
BitsPerWord SerialCookie::getBitsPerWord() const { return bitsPerWord; }
|
||||||
|
|
||||||
|
StopBits SerialCookie::getStopBits() const { return stopBits; }
|
||||||
|
|
||||||
|
void SerialCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
|
||||||
|
|
||||||
|
void SerialCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
|
||||||
|
|
||||||
|
UartModes SerialCookie::getUartMode() const { return uartMode; }
|
||||||
|
|
||||||
|
void SerialCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; }
|
||||||
|
|
||||||
|
void SerialCookie::setToFlushInput(bool enable) { this->flushInput = enable; }
|
||||||
|
|
||||||
|
uint8_t SerialCookie::getReadCycles() const { return readCycles; }
|
||||||
|
|
||||||
|
bool SerialCookie::getInputShouldBeFlushed() { return this->flushInput; }
|
||||||
|
|
||||||
|
object_id_t SerialCookie::getHandlerId() const { return this->handlerId; }
|
||||||
|
|
||||||
|
void SerialCookie::setNoFixedSizeReply() { replySizeFixed = false; }
|
||||||
|
|
||||||
|
bool SerialCookie::isReplySizeFixed() { return replySizeFixed; }
|
@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||||
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "helper.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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
|
||||||
@ -15,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class UartCookie : public CookieIF {
|
class SerialCookie : public CookieIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for the uart cookie.
|
* @brief Constructor for the uart cookie.
|
||||||
@ -30,10 +29,10 @@ class UartCookie : public CookieIF {
|
|||||||
* 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, UartBaudRate baudrate,
|
SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
||||||
size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL);
|
size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL);
|
||||||
|
|
||||||
virtual ~UartCookie();
|
virtual ~SerialCookie();
|
||||||
|
|
||||||
UartBaudRate getBaudrate() const;
|
UartBaudRate getBaudrate() const;
|
||||||
size_t getMaxReplyLen() const;
|
size_t getMaxReplyLen() const;
|
163
src/fsfw_hal/linux/serial/helper.cpp
Normal file
163
src/fsfw_hal/linux/serial/helper.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
|
void uart::setMode(struct termios& options, UartModes mode) {
|
||||||
|
if (mode == UartModes::NON_CANONICAL) {
|
||||||
|
/* Disable canonical mode */
|
||||||
|
options.c_lflag &= ~ICANON;
|
||||||
|
} else if (mode == UartModes::CANONICAL) {
|
||||||
|
options.c_lflag |= ICANON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||||
|
switch (baud) {
|
||||||
|
case UartBaudRate::RATE_50:
|
||||||
|
cfsetspeed(&options, B50);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_75:
|
||||||
|
cfsetspeed(&options, B75);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_110:
|
||||||
|
cfsetspeed(&options, B110);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_134:
|
||||||
|
cfsetspeed(&options, B134);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_150:
|
||||||
|
cfsetspeed(&options, B150);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_200:
|
||||||
|
cfsetspeed(&options, B200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_300:
|
||||||
|
cfsetspeed(&options, B300);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_600:
|
||||||
|
cfsetspeed(&options, B600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1200:
|
||||||
|
cfsetspeed(&options, B1200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1800:
|
||||||
|
cfsetspeed(&options, B1800);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_2400:
|
||||||
|
cfsetspeed(&options, B2400);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_4800:
|
||||||
|
cfsetspeed(&options, B4800);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_9600:
|
||||||
|
cfsetspeed(&options, B9600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_19200:
|
||||||
|
cfsetspeed(&options, B19200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_38400:
|
||||||
|
cfsetspeed(&options, B38400);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_57600:
|
||||||
|
cfsetspeed(&options, B57600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_115200:
|
||||||
|
cfsetspeed(&options, B115200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_230400:
|
||||||
|
cfsetspeed(&options, B230400);
|
||||||
|
break;
|
||||||
|
#ifndef __APPLE__
|
||||||
|
case UartBaudRate::RATE_460800:
|
||||||
|
cfsetspeed(&options, B460800);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_500000:
|
||||||
|
cfsetspeed(&options, B500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_576000:
|
||||||
|
cfsetspeed(&options, B576000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_921600:
|
||||||
|
cfsetspeed(&options, B921600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1000000:
|
||||||
|
cfsetspeed(&options, B1000000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1152000:
|
||||||
|
cfsetspeed(&options, B1152000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1500000:
|
||||||
|
cfsetspeed(&options, B1500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_2000000:
|
||||||
|
cfsetspeed(&options, B2000000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_2500000:
|
||||||
|
cfsetspeed(&options, B2500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_3000000:
|
||||||
|
cfsetspeed(&options, B3000000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_3500000:
|
||||||
|
cfsetspeed(&options, B3500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_4000000:
|
||||||
|
cfsetspeed(&options, B4000000);
|
||||||
|
break;
|
||||||
|
#endif // ! __APPLE__
|
||||||
|
default:
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||||
|
options.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||||
|
if (bits == BitsPerWord::BITS_5) {
|
||||||
|
options.c_cflag |= CS5;
|
||||||
|
} else if (bits == BitsPerWord::BITS_6) {
|
||||||
|
options.c_cflag |= CS6;
|
||||||
|
} else if (bits == BitsPerWord::BITS_7) {
|
||||||
|
options.c_cflag |= CS7;
|
||||||
|
} else if (bits == BitsPerWord::BITS_8) {
|
||||||
|
options.c_cflag |= CS8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
||||||
|
|
||||||
|
void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
||||||
|
|
||||||
|
void uart::setParity(struct termios& options, Parity parity) {
|
||||||
|
/* Clear parity bit */
|
||||||
|
options.c_cflag &= ~PARENB;
|
||||||
|
switch (parity) {
|
||||||
|
case Parity::EVEN:
|
||||||
|
options.c_cflag |= PARENB;
|
||||||
|
options.c_cflag &= ~PARODD;
|
||||||
|
break;
|
||||||
|
case Parity::ODD:
|
||||||
|
options.c_cflag |= PARENB;
|
||||||
|
options.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
||||||
|
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::setStopbits(struct termios& options, StopBits bits) {
|
||||||
|
if (bits == StopBits::TWO_STOP_BITS) {
|
||||||
|
// Use two stop bits
|
||||||
|
options.c_cflag |= CSTOPB;
|
||||||
|
} else {
|
||||||
|
// Clear stop field, only one stop bit used in communication
|
||||||
|
options.c_cflag &= ~CSTOPB;
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,16 @@ void setMode(struct termios& options, UartModes mode);
|
|||||||
*/
|
*/
|
||||||
void setBaudrate(struct termios& options, UartBaudRate baud);
|
void setBaudrate(struct termios& options, UartBaudRate baud);
|
||||||
|
|
||||||
|
void setStopbits(struct termios& options, StopBits bits);
|
||||||
|
|
||||||
|
void setBitsPerWord(struct termios& options, BitsPerWord bits);
|
||||||
|
|
||||||
|
void enableRead(struct termios& options);
|
||||||
|
|
||||||
|
void setParity(struct termios& options, Parity parity);
|
||||||
|
|
||||||
|
void ignoreCtrlLines(struct termios& options);
|
||||||
|
|
||||||
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
||||||
|
|
||||||
} // namespace uart
|
} // namespace uart
|
@ -1 +0,0 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PUBLIC UartComIF.cpp UartCookie.cpp helper.cpp)
|
|
@ -1,51 +0,0 @@
|
|||||||
#include "UartCookie.h"
|
|
||||||
|
|
||||||
#include <fsfw/serviceinterface.h>
|
|
||||||
|
|
||||||
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
|
||||||
size_t maxReplyLen, UartModes uartMode)
|
|
||||||
: handlerId(handlerId),
|
|
||||||
deviceFile(deviceFile),
|
|
||||||
uartMode(uartMode),
|
|
||||||
baudrate(baudrate),
|
|
||||||
maxReplyLen(maxReplyLen) {}
|
|
||||||
|
|
||||||
UartCookie::~UartCookie() {}
|
|
||||||
|
|
||||||
UartBaudRate UartCookie::getBaudrate() const { return baudrate; }
|
|
||||||
|
|
||||||
size_t UartCookie::getMaxReplyLen() const { return maxReplyLen; }
|
|
||||||
|
|
||||||
std::string UartCookie::getDeviceFile() const { return deviceFile; }
|
|
||||||
|
|
||||||
void UartCookie::setParityOdd() { parity = Parity::ODD; }
|
|
||||||
|
|
||||||
void UartCookie::setParityEven() { parity = Parity::EVEN; }
|
|
||||||
|
|
||||||
Parity UartCookie::getParity() const { return parity; }
|
|
||||||
|
|
||||||
void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
|
|
||||||
|
|
||||||
BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; }
|
|
||||||
|
|
||||||
StopBits UartCookie::getStopBits() const { return stopBits; }
|
|
||||||
|
|
||||||
void UartCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
|
|
||||||
|
|
||||||
void UartCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
|
|
||||||
|
|
||||||
UartModes UartCookie::getUartMode() const { return uartMode; }
|
|
||||||
|
|
||||||
void UartCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; }
|
|
||||||
|
|
||||||
void UartCookie::setToFlushInput(bool enable) { this->flushInput = enable; }
|
|
||||||
|
|
||||||
uint8_t UartCookie::getReadCycles() const { return readCycles; }
|
|
||||||
|
|
||||||
bool UartCookie::getInputShouldBeFlushed() { return this->flushInput; }
|
|
||||||
|
|
||||||
object_id_t UartCookie::getHandlerId() const { return this->handlerId; }
|
|
||||||
|
|
||||||
void UartCookie::setNoFixedSizeReply() { replySizeFixed = false; }
|
|
||||||
|
|
||||||
bool UartCookie::isReplySizeFixed() { return replySizeFixed; }
|
|
@ -1,148 +0,0 @@
|
|||||||
#include "helper.h"
|
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include "fsfw/serviceinterface.h"
|
|
||||||
|
|
||||||
void uart::setMode(struct termios& options, UartModes mode) {
|
|
||||||
if (mode == UartModes::NON_CANONICAL) {
|
|
||||||
/* Disable canonical mode */
|
|
||||||
options.c_lflag &= ~ICANON;
|
|
||||||
} else if (mode == UartModes::CANONICAL) {
|
|
||||||
options.c_lflag |= ICANON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
|
||||||
switch (baud) {
|
|
||||||
case UartBaudRate::RATE_50:
|
|
||||||
cfsetispeed(&options, B50);
|
|
||||||
cfsetospeed(&options, B50);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_75:
|
|
||||||
cfsetispeed(&options, B75);
|
|
||||||
cfsetospeed(&options, B75);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_110:
|
|
||||||
cfsetispeed(&options, B110);
|
|
||||||
cfsetospeed(&options, B110);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_134:
|
|
||||||
cfsetispeed(&options, B134);
|
|
||||||
cfsetospeed(&options, B134);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_150:
|
|
||||||
cfsetispeed(&options, B150);
|
|
||||||
cfsetospeed(&options, B150);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_200:
|
|
||||||
cfsetispeed(&options, B200);
|
|
||||||
cfsetospeed(&options, B200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_300:
|
|
||||||
cfsetispeed(&options, B300);
|
|
||||||
cfsetospeed(&options, B300);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_600:
|
|
||||||
cfsetispeed(&options, B600);
|
|
||||||
cfsetospeed(&options, B600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1200:
|
|
||||||
cfsetispeed(&options, B1200);
|
|
||||||
cfsetospeed(&options, B1200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1800:
|
|
||||||
cfsetispeed(&options, B1800);
|
|
||||||
cfsetospeed(&options, B1800);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_2400:
|
|
||||||
cfsetispeed(&options, B2400);
|
|
||||||
cfsetospeed(&options, B2400);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_4800:
|
|
||||||
cfsetispeed(&options, B4800);
|
|
||||||
cfsetospeed(&options, B4800);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_9600:
|
|
||||||
cfsetispeed(&options, B9600);
|
|
||||||
cfsetospeed(&options, B9600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_19200:
|
|
||||||
cfsetispeed(&options, B19200);
|
|
||||||
cfsetospeed(&options, B19200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_38400:
|
|
||||||
cfsetspeed(&options, B38400);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_57600:
|
|
||||||
cfsetispeed(&options, B57600);
|
|
||||||
cfsetospeed(&options, B57600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_115200:
|
|
||||||
cfsetspeed(&options, B115200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_230400:
|
|
||||||
cfsetispeed(&options, B230400);
|
|
||||||
cfsetospeed(&options, B230400);
|
|
||||||
break;
|
|
||||||
#ifndef __APPLE__
|
|
||||||
case UartBaudRate::RATE_460800:
|
|
||||||
cfsetispeed(&options, B460800);
|
|
||||||
cfsetospeed(&options, B460800);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_500000:
|
|
||||||
cfsetispeed(&options, B500000);
|
|
||||||
cfsetospeed(&options, B500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_576000:
|
|
||||||
cfsetispeed(&options, B576000);
|
|
||||||
cfsetospeed(&options, B576000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_921600:
|
|
||||||
cfsetispeed(&options, B921600);
|
|
||||||
cfsetospeed(&options, B921600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1000000:
|
|
||||||
cfsetispeed(&options, B1000000);
|
|
||||||
cfsetospeed(&options, B1000000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1152000:
|
|
||||||
cfsetispeed(&options, B1152000);
|
|
||||||
cfsetospeed(&options, B1152000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1500000:
|
|
||||||
cfsetispeed(&options, B1500000);
|
|
||||||
cfsetospeed(&options, B1500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_2000000:
|
|
||||||
cfsetispeed(&options, B2000000);
|
|
||||||
cfsetospeed(&options, B2000000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_2500000:
|
|
||||||
cfsetispeed(&options, B2500000);
|
|
||||||
cfsetospeed(&options, B2500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_3000000:
|
|
||||||
cfsetispeed(&options, B3000000);
|
|
||||||
cfsetospeed(&options, B3000000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_3500000:
|
|
||||||
cfsetispeed(&options, B3500000);
|
|
||||||
cfsetospeed(&options, B3500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_4000000:
|
|
||||||
cfsetispeed(&options, B4000000);
|
|
||||||
cfsetospeed(&options, B4000000);
|
|
||||||
break;
|
|
||||||
#endif // ! __APPLE__
|
|
||||||
default:
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
|
||||||
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
|
||||||
}
|
|
@ -21,11 +21,13 @@ UioMapper::UioMapper(std::string uioFile, int mapNum) : mapNum(mapNum) {
|
|||||||
char* res = realpath(uioFile.c_str(), nullptr);
|
char* res = realpath(uioFile.c_str(), nullptr);
|
||||||
if (res) {
|
if (res) {
|
||||||
this->uioFile = res;
|
this->uioFile = res;
|
||||||
} else {
|
|
||||||
sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl;
|
|
||||||
}
|
|
||||||
free(res);
|
free(res);
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
this->uioFile = std::move(uioFile);
|
this->uioFile = std::move(uioFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,17 @@
|
|||||||
|
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
|
||||||
TestAssembly::TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
TestAssembly::TestAssembly(object_id_t objectId, object_id_t parentId, ModeTreeChildIF& testDevice0,
|
||||||
object_id_t testDevice1)
|
ModeTreeChildIF& testDevice1)
|
||||||
: AssemblyBase(objectId, parentId),
|
: AssemblyBase(objectId, parentId), deviceHandler0(testDevice0), deviceHandler1(testDevice1) {
|
||||||
deviceHandler0Id(testDevice0),
|
|
||||||
deviceHandler1Id(testDevice1) {
|
|
||||||
ModeListEntry newModeListEntry;
|
ModeListEntry newModeListEntry;
|
||||||
newModeListEntry.setObject(testDevice0);
|
newModeListEntry.setObject(testDevice0.getObjectId());
|
||||||
newModeListEntry.setMode(MODE_OFF);
|
newModeListEntry.setMode(MODE_OFF);
|
||||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||||
|
|
||||||
commandTable.insert(newModeListEntry);
|
commandTable.insert(newModeListEntry);
|
||||||
|
|
||||||
newModeListEntry.setObject(testDevice1);
|
newModeListEntry.setObject(testDevice1.getObjectId());
|
||||||
newModeListEntry.setMode(MODE_OFF);
|
newModeListEntry.setMode(MODE_OFF);
|
||||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||||
|
|
||||||
@ -43,8 +41,8 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
|||||||
commandTable[1].setMode(MODE_OFF);
|
commandTable[1].setMode(MODE_OFF);
|
||||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||||
if (isDeviceAvailable(deviceHandler0Id)) {
|
if (isDeviceAvailable(deviceHandler0.getObjectId())) {
|
||||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
if (childrenMap[deviceHandler0.getObjectId()].mode == MODE_ON) {
|
||||||
commandTable[0].setMode(mode);
|
commandTable[0].setMode(mode);
|
||||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||||
} else {
|
} else {
|
||||||
@ -53,7 +51,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
|||||||
result = NEED_SECOND_STEP;
|
result = NEED_SECOND_STEP;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
if (childrenMap[deviceHandler1.getObjectId()].mode == MODE_ON) {
|
||||||
commandTable[1].setMode(mode);
|
commandTable[1].setMode(mode);
|
||||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||||
} else {
|
} else {
|
||||||
@ -64,7 +62,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Dual Mode Normal
|
// Dual Mode Normal
|
||||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
if (childrenMap[deviceHandler0.getObjectId()].mode == MODE_ON) {
|
||||||
commandTable[0].setMode(mode);
|
commandTable[0].setMode(mode);
|
||||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||||
} else {
|
} else {
|
||||||
@ -72,7 +70,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
|||||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||||
result = NEED_SECOND_STEP;
|
result = NEED_SECOND_STEP;
|
||||||
}
|
}
|
||||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
if (childrenMap[deviceHandler1.getObjectId()].mode == MODE_ON) {
|
||||||
commandTable[1].setMode(mode);
|
commandTable[1].setMode(mode);
|
||||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||||
} else {
|
} else {
|
||||||
@ -89,7 +87,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
|||||||
commandTable[1].setMode(MODE_OFF);
|
commandTable[1].setMode(MODE_OFF);
|
||||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||||
if (isDeviceAvailable(deviceHandler0Id)) {
|
if (isDeviceAvailable(deviceHandler0.getObjectId())) {
|
||||||
commandTable[0].setMode(MODE_ON);
|
commandTable[0].setMode(MODE_ON);
|
||||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||||
} else {
|
} else {
|
||||||
@ -133,23 +131,14 @@ ReturnValue_t TestAssembly::initialize() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
handler0 = ObjectManager::instance()->get<TestDevice>(deviceHandler0Id);
|
auto* handler0 = ObjectManager::instance()->get<TestDevice>(deviceHandler0.getObjectId());
|
||||||
handler1 = ObjectManager::instance()->get<TestDevice>(deviceHandler1Id);
|
auto* handler1 = ObjectManager::instance()->get<TestDevice>(deviceHandler1.getObjectId());
|
||||||
if ((handler0 == nullptr) or (handler1 == nullptr)) {
|
if ((handler0 == nullptr) or (handler1 == nullptr)) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler0->setParentQueue(this->getCommandQueue());
|
handler0->connectModeTreeParent(*this);
|
||||||
handler1->setParentQueue(this->getCommandQueue());
|
handler1->connectModeTreeParent(*this);
|
||||||
|
|
||||||
result = registerChild(deviceHandler0Id);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = registerChild(deviceHandler1Id);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
class TestAssembly : public AssemblyBase {
|
class TestAssembly : public AssemblyBase {
|
||||||
public:
|
public:
|
||||||
TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
TestAssembly(object_id_t objectId, object_id_t parentId, ModeTreeChildIF& testDevice0,
|
||||||
object_id_t testDevice1);
|
ModeTreeChildIF& testDevice1);
|
||||||
virtual ~TestAssembly();
|
virtual ~TestAssembly();
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
@ -41,10 +41,8 @@ class TestAssembly : public AssemblyBase {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FixedArrayList<ModeListEntry, 2> commandTable;
|
FixedArrayList<ModeListEntry, 2> commandTable;
|
||||||
object_id_t deviceHandler0Id = 0;
|
ModeTreeChildIF& deviceHandler0;
|
||||||
object_id_t deviceHandler1Id = 0;
|
ModeTreeChildIF& deviceHandler1;
|
||||||
TestDevice* handler0 = nullptr;
|
|
||||||
TestDevice* handler1 = nullptr;
|
|
||||||
|
|
||||||
bool isDeviceAvailable(object_id_t object);
|
bool isDeviceAvailable(object_id_t object);
|
||||||
};
|
};
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
|
||||||
TestController::TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth)
|
TestController::TestController(object_id_t objectId, size_t commandQueueDepth)
|
||||||
: ExtendedControllerBase(objectId, parentId, commandQueueDepth) {}
|
: ExtendedControllerBase(objectId, commandQueueDepth) {}
|
||||||
|
|
||||||
TestController::~TestController() {}
|
TestController::~TestController() {}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
class TestController : public ExtendedControllerBase {
|
class TestController : public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 10);
|
TestController(object_id_t objectId, size_t commandQueueDepth = 10);
|
||||||
virtual ~TestController();
|
virtual ~TestController();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -31,4 +31,7 @@ int customSetup() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int customTeardown() { return 0; }
|
int customTeardown() {
|
||||||
|
ObjectManager::clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user