Compare commits

..

135 Commits

Author SHA1 Message Date
2aa4af6974 make function public 2022-12-14 13:50:57 +01:00
75fc7a056d Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-12-12 09:02:04 +01:00
05cad893a2 introduce error counter to avoid spam 2022-12-06 10:05:23 +01:00
1b005d706a Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-12-01 16:40:39 +01:00
5b0ea91222 statically assert MAX_SIZE > 0 2022-11-29 23:24:29 +01:00
e68f54b9bd Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-11-28 11:37:15 +01:00
8eb869e073 run black 2022-11-28 11:21:36 +01:00
46a1c2bace remove data wrapper 2022-11-28 08:35:10 +01:00
2643ff194c Merge remote-tracking branch 'upstream/development' into develop 2022-11-28 08:34:04 +01:00
296bc56e2a Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-11-24 15:16:34 +01:00
d6ee2ed400 Merge pull request 'AcceptsTelemetryIF tweaks' (#712) from eive/fsfw:mueller/accepts_tm_if_adaptions into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #712
2022-11-21 16:30:43 +01:00
f2150ff9c2 Merge pull request 'only delete table entry if not nullptr' (#710) from eive/fsfw:mueller/health_helper_bugfix into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #710
2022-11-21 16:24:13 +01:00
1b9c98f3fe Merge pull request 'uio able to resolve symlinks now' (#709) from eive/fsfw:mueller/uio_mapper_handle_symlinks into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #709
2022-11-21 16:14:36 +01:00
742152b28e Merge branch 'development' into mueller/accepts_tm_if_adaptions
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 15:29:35 +01:00
14c681c93a Merge branch 'development' into mueller/uio_mapper_handle_symlinks
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 15:27:06 +01:00
0958c3a00e Merge branch 'development' into mueller/health_helper_bugfix
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 15:24:51 +01:00
d699d16307 Merge pull request 'SP reader getPacketData is const now' (#708) from eive/fsfw:mueller/sp_reader_const_get_data into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #708
2022-11-21 15:23:39 +01:00
3b0fed733f Merge branch 'development' into mueller/uio_mapper_handle_symlinks
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 15:23:15 +01:00
23d3812fe3 this is actually important
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 15:22:25 +01:00
dec7db3ae2 Merge remote-tracking branch 'upstream/development' into mueller/accepts_tm_if_adaptions
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 15:00:06 +01:00
65a5abab49 move free call
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 14:56:08 +01:00
0129783e34 Merge branch 'development' into mueller/sp_reader_const_get_data
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-21 14:50:44 +01:00
cabe0868ec Merge pull request 'move container returnvalues to namespace' (#707) from eive/fsfw:mueller/update_containers_retval into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #707
2022-11-21 14:49:44 +01:00
160ff799ac small fix to allow teardown handling 2022-11-17 15:09:08 +01:00
b85ca64690 update changelog
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 11:48:28 +01:00
3bc3da5a8d update changelog
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 11:47:26 +01:00
f8c07ec9cf update changelog
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 11:46:43 +01:00
cbc8dbcdd4 update changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-15 11:44:45 +01:00
d31a5306f0 fix mock
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 11:41:03 +01:00
a236a5ec50 adaptions for AcceptsTelemetryIF 2022-11-15 11:40:26 +01:00
03620970e2 function to get queue is const now 2022-11-15 11:38:32 +01:00
8fe8d810e9 only delete table if not nullptr
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 11:27:31 +01:00
fe3d6bd432 uio able to resolve symlinks now
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 10:56:46 +01:00
c5f91926c9 remove includes
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-15 10:54:47 +01:00
be4a87535d remove data wrapper 2022-11-15 10:54:11 +01:00
99927b8e95 afmt 2022-11-15 10:53:38 +01:00
5e5eb82830 make warning switch protected 2022-11-15 10:53:14 +01:00
686dc97234 this is better / more correct 2022-11-15 10:52:47 +01:00
2a842666d5 SP reader getPacketData is const now
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 10:46:46 +01:00
c013fcc1f5 move container retvals to namespace
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-15 10:01:37 +01:00
1f58ba1f9b update changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-15 09:58:15 +01:00
002845108d Merge remote-tracking branch 'upstream/development' into develop_update
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-14 15:05:47 +01:00
1b8fc2af19 Merge pull request 'CFDP Update' (#682) from mueller/cfdp-update-without-handlers into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #682
2022-11-14 15:04:43 +01:00
72d7c43445 updates for storage manager mock
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:57:37 +01:00
ab9b6c8c89 Merge remote-tracking branch 'origin/development' into mueller/cfdp-update-without-handlers
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-14 14:51:33 +01:00
69d338f9bb Merge pull request 'Local Pool Update Remove Add Data Ignore Fault Argument' (#701) from eive/fsfw:mueller/local-pool-update-remove-ignore-fault-arg into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #701
2022-11-14 14:49:34 +01:00
68223869d5 Merge branch 'development' into mueller/local-pool-update-remove-ignore-fault-arg
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:47:07 +01:00
93fda71989 Merge pull request 'refactoring of serial drivers for linux' (#705) from eive/fsfw:mueller/refactor_serial_linux into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #705
2022-11-14 14:39:41 +01:00
7b0db08962 Merge branch 'development' into mueller/refactor_serial_linux
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:36:31 +01:00
0956fbc740 Merge pull request 'fix compiler warning for fixed array list copy ctor' (#704) from eive/fsfw:mueller/fixed_array_list_copy_ctor into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #704
2022-11-14 14:28:46 +01:00
b48e0fdc0d Merge remote-tracking branch 'origin/development' into mueller/cfdp-update-without-handlers
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-14 14:25:36 +01:00
1d084ee22f Merge branch 'development' into mueller/fixed_array_list_copy_ctor
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:21:04 +01:00
1bea2344f6 remove using declaraction
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:21:00 +01:00
d7e16a67a7 Merge pull request 'Windows Tweaks' (#691) from eive/fsfw:windows-tweaks-upstream into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #691
2022-11-14 14:18:47 +01:00
6021d897b8 Merge branch 'development' into windows-tweaks-upstream
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:13:57 +01:00
83a6f0b5f8 reenable setup function call
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:12:26 +01:00
a9c6c088f2 remove leftover debugging code
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-14 14:08:38 +01:00
2b6a33e718 afmt 2022-11-11 14:13:46 +01:00
61fd5d1b62 impl function to generate ASCII timestamp sec accuracy 2022-11-11 14:12:42 +01:00
046dbe1deb Merge branch 'develop' into mueller/pus-15-tm-storage 2022-11-11 11:38:32 +01:00
e03e7f5260 Merge branch 'mueller/refactor_serial_linux' into develop
Some checks are pending
fsfw/fsfw/pipeline/pr-development Build started...
2022-11-11 11:37:55 +01:00
b6a3c206cc smaller include tweaks
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-11 11:34:58 +01:00
5b352978c5 rename cookie class
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-11 11:33:35 +01:00
0303c1a885 remove file 2022-11-11 11:31:22 +01:00
4d2802a470 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-11-11 11:29:29 +01:00
819a298b19 refactoring of serial drivers for linux
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-10 17:50:21 +01:00
39946bff58 some renaming and tweaks for linux serial driver
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 17:31:11 +01:00
16246d6ece replace other memcpy
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-10 16:18:36 +01:00
5c84f12440 this not crash
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-10 16:15:52 +01:00
2a203ae13d this not crash
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 16:15:28 +01:00
6ca1a5c796 fix unittests
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 16:11:05 +01:00
83c2c4825c fix compiler error for fixed array list copy ctor
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 15:54:03 +01:00
194b3e100a fix compiler error for fixed array list copy ctor
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 15:53:18 +01:00
177c39dd53 helper interface implementations
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 15:38:34 +01:00
530a261e14 dedicated header file for container retvals
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-10 15:12:18 +01:00
c913fe40bf tweaks
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-09 17:54:08 +01:00
70ec08bf1d Merge pull request 'missing include' (#703) from KSat/fsfw:mueller/time_reader_include into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #703
2022-11-09 16:59:25 +01:00
ef23665d9c Merge branch 'development' into mueller/time_reader_include 2022-11-09 16:39:55 +01:00
eefc122292 Merge pull request 'defaultconfig did not build anymore' (#702) from mohr/fix_defaultconfig into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
Reviewed-on: #702
2022-11-09 14:12:41 +01:00
bee33526a1 missing include
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-11-09 13:49:40 +01:00
0e8f5ddd26 added missing const specifier
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-08 11:07:56 +01:00
672fca5169 extend uart helper a bit
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-11-04 11:08:23 +01:00
84b9d1ce21 Merge pull request 'dhb2normal' (#115) from eive/dhb2normal into develop
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
Reviewed-on: eive/fsfw#115
2022-11-03 15:32:26 +01:00
e5b5c7d253 higher default MQ depth for events, printout tweak 2022-11-03 10:33:52 +01:00
9a0cc64be3 Merge branch 'develop' into eive/dhb2normal 2022-11-03 10:12:19 +01:00
00f1c5bbe9 missing replacements 2022-11-03 10:12:05 +01:00
8a61af779d Merge remote-tracking branch 'origin/develop' into eive/dhb2normal 2022-11-03 10:10:47 +01:00
6efa482eb0 use uniform uart api 2022-11-03 10:10:36 +01:00
f0fa1bf477 Merge remote-tracking branch 'origin/develop' into eive/dhb2normal 2022-11-03 10:08:35 +01:00
91ebf98c28 add new ping with data TC 2022-11-02 19:35:22 +01:00
e1d4209fbe missing fifo pop command 2022-11-02 16:07:00 +01:00
e302c89f74 health helper dtor bugfix 2022-11-02 15:48:13 +01:00
a38279f813 Merge branch 'develop' into eive/dhb2normal 2022-11-02 10:47:25 +01:00
7600ed1ea7 Merge pull request 'Improve Subsystem DHB logic' (#112) from mueller/improve-ss-dhb-logic into develop
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
Reviewed-on: eive/fsfw#112
2022-11-02 10:32:25 +01:00
61ab770d9d Merge branch 'develop' into mueller/improve-ss-dhb-logic 2022-11-02 10:31:43 +01:00
f715b65d6e Merge remote-tracking branch 'upstream/development' into mueller/local-pool-update-remove-ignore-fault-arg
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-28 10:06:04 +02:00
c11af63015 Merge remote-tracking branch 'origin/development' into mueller/cfdp-update-without-handlers
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-10-28 10:04:21 +02:00
852f27cec2 Merge remote-tracking branch 'origin/develop' into mueller/improve-ss-dhb-logic 2022-10-27 16:58:30 +02:00
fa01798ebb Merge remote-tracking branch 'origin/develop' into mueller/improve-ss-dhb-logic 2022-10-27 08:30:30 +02:00
819a2bfac4 add prototype for new ToAscii CCSDSTime function 2022-10-25 18:20:48 +02:00
dc1583c932 Merge branch 'development' into windows-tweaks-upstream
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-24 17:10:44 +02:00
81a7de2814 make dtor virtual
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-10-24 16:39:32 +02:00
d26f230bee builds
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-24 15:43:20 +02:00
4db124c680 ignore fault 2022-10-24 15:41:29 +02:00
2df66c9304 Merge branch 'mueller/local-pool-update' of https://egit.irs.uni-stuttgart.de/fsfw/fsfw into mueller/local-pool-update
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-10-24 14:39:11 +02:00
54ad6b3016 add some docs 2022-10-24 14:39:05 +02:00
73e313c35b Merge branch 'development' into mueller/local-pool-update
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-24 14:35:24 +02:00
dd2f42d22b Merge branch 'development' into mueller/local-pool-update
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-24 14:34:56 +02:00
096af44e39 needs some fixing 2022-10-24 10:56:01 +02:00
56e8e5a8b3 dont know if I am going to need this 2022-10-24 10:39:43 +02:00
11422a658c Merge remote-tracking branch 'origin/develop' into mueller/improve-ss-dhb-logic 2022-10-21 15:35:27 +02:00
ec7566fb8c Merge remote-tracking branch 'origin/develop' into mueller/improve-ss-dhb-logic 2022-10-20 16:59:53 +02:00
652c31a683 missing validity check
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2022-10-17 17:25:27 +02:00
bfe120636c this should have the same effect
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-17 15:08:46 +02:00
a8041f220f Merge branch 'development' into mueller/cfdp-update-without-handlers
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-17 14:44:28 +02:00
dd636b186b size check bugfix
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-17 14:30:27 +02:00
3349fc36f8 Merge branch 'development' into windows-tweaks-upstream
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-17 14:20:48 +02:00
df06064df0 Merge branch 'development' into windows-tweaks-upstream
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-10-10 13:41:09 +02:00
1d6ccfe5ab Service 200: Add mode announcement support 2022-10-10 11:06:58 +02:00
221df7ece6 allow recursive mode announcements 2022-10-10 10:46:29 +02:00
7f180ac1fa Merge remote-tracking branch 'origin/develop' into mueller/improve-ss-dhb-logic 2022-10-10 10:29:08 +02:00
1eceef4645 move retvals 2022-09-30 15:05:32 +02:00
acab5f6bce added missing health and mode helper init 2022-09-30 14:14:45 +02:00
10dd855244 expose child itself in interface 2022-09-30 13:30:07 +02:00
f824004897 need to fix all of these TODOs 2022-09-29 19:39:37 +02:00
7c5308429c this seems to work 2022-09-29 19:21:24 +02:00
f78344b8fb Merge remote-tracking branch 'origin/develop' into mueller/improve-ss-dhb-logic 2022-09-29 17:46:54 +02:00
77f7fa2ef1 typo 2022-09-29 16:48:23 +02:00
78314ad966 this makes a bit more sense 2022-09-29 16:47:23 +02:00
e0c780f21c better comment
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-09-28 09:59:31 +02:00
876815b1c9 another small windows tweak 2022-09-28 09:59:22 +02:00
b0ecf87580 last windows tweak 2022-09-28 09:59:12 +02:00
68ce8b5b08 tweaks to make windows build again 2022-09-28 09:59:02 +02:00
fe03da6def Merge remote-tracking branch 'origin/development' into mueller/cfdp-update-without-handlers
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-09-26 15:38:45 +02:00
4f7f8310c9 Merge remote-tracking branch 'origin/development' into mueller/local-pool-update
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2022-09-15 11:00:43 +02:00
86 changed files with 924 additions and 906 deletions

View File

@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Fixes ## Fixes
- 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 +27,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Added ## Added
- DHB TM handler `handleDeviceTM` renamed to `handleDeviceTm` and now takes - `UioMapper` is able to resolve symlinks now.
`util::DataWrapper` as the data input argument. This allows more flexibility in the possible PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
types of telemetry.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/669
- Add `util::DataWrapper` class inside the `util` module. This is a tagged union which allows
to specify raw data either as a classic C-style raw pointer and size or as a `SerializeIF`
pointer.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/668
- 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
- `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 +67,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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "DeviceHandlerBase.h"
#include "fsfw/datapoollocal/LocalPoolVariable.h" #include "fsfw/datapoollocal/LocalPoolVariable.h"
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h" #include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
@ -12,6 +12,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 +133,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 +361,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 +568,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
*/ */
@ -1587,19 +1581,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 +1607,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);

View File

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

View File

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

View File

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

View File

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

View File

@ -24,3 +24,13 @@ 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);
}

View File

@ -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 = MAKE_COMMAND_ID(0x01);
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID( //!> Command to set the specified Mode, regardless of external control flag, replies
0xF1); //!> 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 CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(0xF1);
static const Command_t REPLY_MODE_REPLY = //!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
MAKE_COMMAND_ID(0x02); //!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);
static const Command_t REPLY_MODE_INFO = //!> Unrequested info about the current mode (used for composites to
MAKE_COMMAND_ID(0x03); //!> 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_MODE_INFO = MAKE_COMMAND_ID(0x03);
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID( //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0 static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(0x04);
static const Command_t REPLY_WRONG_MODE_REPLY = //!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
MAKE_COMMAND_ID(0x05); //!> 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 REPLY_WRONG_MODE_REPLY = MAKE_COMMAND_ID(0x05);
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID( //!> Command to read the current mode and reply with a REPLY_MODE_REPLY
0x06); //!> Command to read the current mode and reply with a REPLY_MODE_REPLY static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(0x06);
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID( //!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
0x07); //!> Command to trigger an ModeInfo Event. This command does NOT have a reply. static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(0x07);
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY = //!> Command to trigger an ModeInfo Event and to send this command to
MAKE_COMMAND_ID(0x08); //!> 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,7 @@ 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 setModeAnnounceMessage(CommandMessage& message, bool recursive);
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);
}; };

View File

@ -274,6 +274,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) {

View File

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

View File

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

View File

@ -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,15 +54,26 @@ 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) {
ModePacket modeCommandPacket; ReturnValue_t result = returnvalue::OK;
ReturnValue_t result = if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE or
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG); subservice == Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY) {
if (result != returnvalue::OK) { bool recursive = true;
return result; if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
recursive = false;
}
ModeMessage::setModeAnnounceMessage(*message, recursive);
} else {
ModePacket modeCommandPacket;
ReturnValue_t result =
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
modeCommandPacket.getSubmode());
} }
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
modeCommandPacket.getSubmode());
return result; return result;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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_

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

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

View File

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

View File

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

View File

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

View File

@ -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,32 +41,34 @@ 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
* *
* Also adds them to the internal childrenMap. * Also adds them to the internal childrenMap.
* *
* @param objectId * @param objectId
* @return returnvalue::OK if successful * @return returnvalue::OK if successful
* 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;

View File

@ -0,0 +1,13 @@
#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;
}
healthHelper.setParentQueue(parent.getCommandQueue());
modeHelper.setParentQueue(parent.getCommandQueue());
return returnvalue::OK;
}

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

View File

@ -246,6 +246,20 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t*
return UNSUPPORTED_TIME_FORMAT; return UNSUPPORTED_TIME_FORMAT;
} }
ReturnValue_t CCSDSTime::convertToAsciiWithSecs(int8_t* to, const Clock::TimeOfDay_t* from,
uint8_t length) {
if (from == nullptr or to == nullptr) {
return returnvalue::FAILED;
}
int count = snprintf(reinterpret_cast<char*>(to), length,
"%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32,
from->year, from->month, from->day, from->hour, from->minute, from->second);
if (count >= length) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) { ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) {
const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time); const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time);

View File

@ -207,7 +207,8 @@ class CCSDSTime {
static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from, static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from,
uint8_t length); uint8_t length);
static ReturnValue_t convertToAsciiWithSecs(int8_t *to, const Clock::TimeOfDay_t *from,
uint8_t length);
static uint32_t subsecondsToMicroseconds(uint16_t subseconds); static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
private: private:

View File

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

View File

@ -6,47 +6,12 @@
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "tmStorageConf.h" #include "tmStorageConf.h"
class TmPacketMinimal; class PusTmReader;
class SpacePacketBase; class SpacePacketReader;
class TmStoreBackendIF; class TmStoreBackendIF;
class TmStoreFrontendIF { class TmStoreFrontendIF {
public: public:
virtual TmStoreBackendIF* getBackend() const = 0;
/**
* What do I need to implement here?
* This is propably used by PUS Service 15 so we should propably check for messages..
* Provide base implementation?
* @param opCode
* @return
*/
virtual ReturnValue_t performOperation(uint8_t opCode) = 0;
/**
* Callback from the back-end to indicate a certain packet was received.
* front-end takes care of discarding/downloading the packet.
* @param packet Pointer to the newly received Space Packet.
* @param address Start address of the packet found
* @param isLastPacket Indicates if no more packets can be fetched.
* @return If more packets shall be fetched, returnvalue::OK must be returned.
* Any other code stops fetching packets.
*/
virtual ReturnValue_t packetRetrieved(TmPacketMinimal* packet, uint32_t address) = 0;
virtual void noMorePacketsInStore() = 0;
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) = 0;
/**
* To get the queue where commands shall be sent.
* @return Id of command queue.
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
virtual ReturnValue_t checkPacket(SpacePacketBase* tmPacket) = 0;
virtual bool isEnabled() const = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void resetDownlinkedPacketCount() = 0;
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF; static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF;
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1); static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1);
static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2); static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2);
@ -57,7 +22,38 @@ class TmStoreFrontendIF {
static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7); static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7);
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8); static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8);
static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9); static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9);
virtual ~TmStoreFrontendIF() {}
virtual ~TmStoreFrontendIF() = default;
/**
* To get the queue where commands shall be sent.
* @return Id of command queue.
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
virtual TmStoreBackendIF* getBackend() const = 0;
/**
* Callback from the back-end to indicate a certain packet was received.
* front-end takes care of discarding/downloading the packet.
* @param packet Pointer to the newly received Space Packet.
* @param address Start address of the packet found
* @param isLastPacket Indicates if no more packets can be fetched.
* @return If more packets shall be fetched, returnvalue::OK must be returned.
* Any other code stops fetching packets.
*/
virtual ReturnValue_t packetRetrieved(PusTmReader* packet, uint32_t address) = 0;
virtual void noMorePacketsInStore() = 0;
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) = 0;
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
virtual ReturnValue_t checkPacket(SpacePacketReader* tmPacket) = 0;
virtual bool isEnabled() const = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void resetDownlinkedPacketCount() = 0;
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
}; };
#endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */ #endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */

View File

@ -0,0 +1,14 @@
#ifndef FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
#define FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
#include <fsfw/ipc/messageQueueDefinitions.h>
class TmStoreFrontendSimpleIF {
public:
virtual ~TmStoreFrontendSimpleIF() = default;
virtual MessageQueueId_t getCommandQueue() const = 0;
private:
};
#endif /* FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_ */

View File

@ -1,6 +1,10 @@
#ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_ #ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_
#define FSFW_TMSTORAGE_TMSTOREPACKETS_H_ #define FSFW_TMSTORAGE_TMSTOREPACKETS_H_
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
#include <vector>
#include "fsfw/globalfunctions/timevalOperations.h" #include "fsfw/globalfunctions/timevalOperations.h"
#include "fsfw/serialize/SerialBufferAdapter.h" #include "fsfw/serialize/SerialBufferAdapter.h"
#include "fsfw/serialize/SerialFixedArrayListAdapter.h" #include "fsfw/serialize/SerialFixedArrayListAdapter.h"
@ -24,7 +28,7 @@ class ServiceSubservice : public SerialLinkedListAdapter<SerializeIF> {
class ApidSsc : public SerializeIF { class ApidSsc : public SerializeIF {
public: public:
ApidSsc() : apid(SpacePacketBase::LIMIT_APID), ssc(0) {} ApidSsc() : apid(ccsds::LIMIT_APID), ssc(0) {}
ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {} ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {}
uint16_t apid; uint16_t apid;
uint16_t ssc; uint16_t ssc;
@ -62,51 +66,59 @@ class ChangeSelectionDefinition : public SerialLinkedListAdapter<SerializeIF> {
class TmPacketInformation : public SerializeIF { class TmPacketInformation : public SerializeIF {
public: public:
TmPacketInformation(TmPacketMinimal* packet) { setContent(packet); } TmPacketInformation(PusTmReader* packet, size_t timestampLen) : rawTimestamp(timestampLen) {
TmPacketInformation() setContent(packet);
: apid(SpacePacketBase::LIMIT_APID), }
TmPacketInformation(size_t timestampLen)
: apid(ccsds::LIMIT_APID),
sourceSequenceCount(0), sourceSequenceCount(0),
serviceType(0), serviceType(0),
serviceSubtype(0), serviceSubtype(0),
subCounter(0) {} subCounter(0),
rawTimestamp(timestampLen) {}
void reset() { void reset() {
apid = SpacePacketBase::LIMIT_APID; apid = ccsds::LIMIT_APID;
sourceSequenceCount = 0; sourceSequenceCount = 0;
serviceType = 0; serviceType = 0;
serviceSubtype = 0; serviceSubtype = 0;
subCounter = 0; subCounter = 0;
memset(rawTimestamp, 0, sizeof(rawTimestamp)); memset(rawTimestamp.data(), 0, rawTimestamp.size());
} }
void setContent(TmPacketMinimal* packet) { void setContent(PusTmReader* packet) {
apid = packet->getAPID(); apid = packet->getApid();
sourceSequenceCount = packet->getPacketSequenceCount(); sourceSequenceCount = packet->getSequenceCount();
serviceType = packet->getService(); serviceType = packet->getService();
serviceSubtype = packet->getSubService(); serviceSubtype = packet->getSubService();
subCounter = packet->getPacketSubcounter(); subCounter = packet->getMessageTypeCounter();
memset(rawTimestamp, 0, sizeof(rawTimestamp)); memset(rawTimestamp.data(), 0, rawTimestamp.size());
const uint8_t* pField = NULL; // TODO: Fix all of this
uint32_t size = 0; // const uint8_t* pField = NULL;
ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size); // uint32_t size = 0;
if (result != returnvalue::OK) { // auto* timeReader = packet->getTimeReader();
return; // ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
} // if (result != returnvalue::OK) {
if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE) { // return;
// Shortcut to avoid converting CDS back and forth. //}
memcpy(rawTimestamp, pField, size); // if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE)
return; // {
} // Shortcut to avoid converting CDS back and forth.
timeval time = {0, 0}; // TODO: Fix
result = packet->getPacketTime(&time); // memcpy(rawTimestamp, pField, size);
if (result != returnvalue::OK) { // return;
return; // }
} // timeval time = {0, 0};
// result = packet->getPacketTime(&time);
CCSDSTime::CDS_short cdsFormat; // if (result != returnvalue::OK) {
result = CCSDSTime::convertToCcsds(&cdsFormat, &time); // return;
if (result != returnvalue::OK) { // }
return; //
} // CCSDSTime::CDS_short cdsFormat;
memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat)); // result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
// if (result != returnvalue::OK) {
// return;
// }
// TODO: Fix
// memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
} }
void setContent(TmPacketInformation* content) { void setContent(TmPacketInformation* content) {
apid = content->apid; apid = content->apid;
@ -114,9 +126,10 @@ class TmPacketInformation : public SerializeIF {
serviceType = content->serviceType; serviceType = content->serviceType;
serviceSubtype = content->serviceSubtype; serviceSubtype = content->serviceSubtype;
subCounter = content->subCounter; subCounter = content->subCounter;
memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp)); // TODO: Fix
// memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp));
} }
bool isValid() const { return (apid < SpacePacketBase::LIMIT_APID) ? true : false; } bool isValid() const { return (apid < ccsds::LIMIT_APID) ? true : false; }
static void reset(TmPacketInformation* packet) { packet->reset(); } static void reset(TmPacketInformation* packet) { packet->reset(); }
static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) { static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) {
@ -216,7 +229,7 @@ class TmPacketInformation : public SerializeIF {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp)); SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
return adapter.serialize(buffer, size, maxSize, streamEndianness); return adapter.serialize(buffer, size, maxSize, streamEndianness);
} }
@ -227,7 +240,7 @@ class TmPacketInformation : public SerializeIF {
size += SerializeAdapter::getSerializedSize(&serviceType); size += SerializeAdapter::getSerializedSize(&serviceType);
size += SerializeAdapter::getSerializedSize(&serviceSubtype); size += SerializeAdapter::getSerializedSize(&serviceSubtype);
size += SerializeAdapter::getSerializedSize(&subCounter); size += SerializeAdapter::getSerializedSize(&subCounter);
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp)); SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
size += adapter.getSerializedSize(); size += adapter.getSerializedSize();
return size; return size;
}; };
@ -253,7 +266,7 @@ class TmPacketInformation : public SerializeIF {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp)); SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
return adapter.deSerialize(buffer, size, streamEndianness); return adapter.deSerialize(buffer, size, streamEndianness);
} }
@ -263,6 +276,6 @@ class TmPacketInformation : public SerializeIF {
uint8_t serviceType; uint8_t serviceType;
uint8_t serviceSubtype; uint8_t serviceSubtype;
uint8_t subCounter; uint8_t subCounter;
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; std::vector<uint8_t> rawTimestamp;
}; };
#endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */ #endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */

View File

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

View File

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

View File

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

View File

@ -183,7 +183,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 +226,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);

View File

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

View File

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

View File

@ -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_LIBGPIOD)
add_subdirectory(gpio)
endif()
if(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS)
add_subdirectory(serial)
endif()
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS) if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
add_subdirectory(gpio)
endif()
add_subdirectory(uart)
# 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)

View File

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

View File

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

View File

@ -0,0 +1,2 @@
target_sources(${LIB_FSFW_NAME} PUBLIC SerialComIF.cpp SerialCookie.cpp
helper.cpp)

View File

@ -1,4 +1,4 @@
#include "UartComIF.h" #include "SerialComIF.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -11,18 +11,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 +59,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 +88,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 +114,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 +126,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 +150,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 +173,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 +188,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 +219,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 +257,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 +315,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 +350,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 +380,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 +399,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 +418,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;

View File

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

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

View File

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

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

View File

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

View File

@ -1 +0,0 @@
target_sources(${LIB_FSFW_NAME} PUBLIC UartComIF.cpp UartCookie.cpp helper.cpp)

View File

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

View File

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

View File

@ -21,10 +21,12 @@ 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;
free(res);
} else { } else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl; sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl;
#endif
} }
free(res);
} else { } else {
this->uioFile = std::move(uioFile); this->uioFile = std::move(uioFile);
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -43,7 +43,7 @@ TEST_CASE("Array List", "[containers]") {
for (auto i = 0; i < 20; i++) { for (auto i = 0; i < 20; i++) {
REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK)); REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK));
} }
REQUIRE(list.insert(20) == static_cast<int>(ArrayList<uint16_t>::FULL)); REQUIRE(list.insert(20) == static_cast<int>(containers::LIST_FULL));
ArrayList<uint16_t>::Iterator it = list.begin(); ArrayList<uint16_t>::Iterator it = list.begin();
REQUIRE((*it) == 0); REQUIRE((*it) == 0);
it++; it++;

View File

@ -31,7 +31,7 @@ TEST_CASE("FixedArrayList Tests", "[containers]") {
for (auto i = 1; i < 260; i++) { for (auto i = 1; i < 260; i++) {
REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK)); REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK));
} }
REQUIRE(list.insert(260) == static_cast<int>(ArrayList<uint32_t, uint16_t>::FULL)); REQUIRE(list.insert(260) == static_cast<int>(containers::LIST_FULL));
list.clear(); list.clear();
REQUIRE(list.size == 0); REQUIRE(list.size == 0);
} }

View File

@ -7,6 +7,8 @@
template class FixedMap<unsigned int, unsigned short>; template class FixedMap<unsigned int, unsigned short>;
using namespace returnvalue;
TEST_CASE("FixedMap Tests", "[containers]") { TEST_CASE("FixedMap Tests", "[containers]") {
INFO("FixedMap Tests"); INFO("FixedMap Tests");
@ -24,9 +26,9 @@ TEST_CASE("FixedMap Tests", "[containers]") {
REQUIRE(map.find(i)->second == i + 1); REQUIRE(map.find(i)->second == i + 1);
REQUIRE(not map.empty()); REQUIRE(not map.empty());
} }
REQUIRE(map.insert(0, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS)); REQUIRE(map.insert(0, 0) == static_cast<int>(containers::KEY_ALREADY_EXISTS));
REQUIRE(map.insert(31, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::MAP_FULL)); REQUIRE(map.insert(31, 0) == static_cast<int>(containers::MAP_FULL));
REQUIRE(map.exists(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST)); REQUIRE(map.exists(31) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
REQUIRE(map.size() == 30); REQUIRE(map.size() == 30);
REQUIRE(map.full()); REQUIRE(map.full());
{ {
@ -34,15 +36,14 @@ TEST_CASE("FixedMap Tests", "[containers]") {
REQUIRE(map.find(5, &ptr) == static_cast<int>(returnvalue::OK)); REQUIRE(map.find(5, &ptr) == static_cast<int>(returnvalue::OK));
REQUIRE(*ptr == 6); REQUIRE(*ptr == 6);
REQUIRE(*(map.findValue(6)) == 7); REQUIRE(*(map.findValue(6)) == 7);
REQUIRE(map.find(31, &ptr) == REQUIRE(map.find(31, &ptr) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
} }
REQUIRE(map.getSerializedSize() == REQUIRE(map.getSerializedSize() ==
(sizeof(uint32_t) + 30 * (sizeof(uint32_t) + sizeof(uint16_t)))); (sizeof(uint32_t) + 30 * (sizeof(uint32_t) + sizeof(uint16_t))));
REQUIRE(map.erase(2) == static_cast<int>(returnvalue::OK)); REQUIRE(map.erase(2) == static_cast<int>(returnvalue::OK));
REQUIRE(map.erase(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST)); REQUIRE(map.erase(31) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
REQUIRE(map.exists(2) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST)); REQUIRE(map.exists(2) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
REQUIRE(map.size() == 29); REQUIRE(map.size() == 29);
for (auto element : map) { for (auto element : map) {
@ -79,8 +80,7 @@ TEST_CASE("FixedMap Tests", "[containers]") {
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(returnvalue::OK)); REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(returnvalue::OK));
REQUIRE(map.find(37)->second == 38); REQUIRE(map.find(37)->second == 38);
REQUIRE(map.size() == 2); REQUIRE(map.size() == 2);
REQUIRE(map.insert(37, 24, nullptr) == REQUIRE(map.insert(37, 24, nullptr) == static_cast<int>(containers::KEY_ALREADY_EXISTS));
static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
REQUIRE(map.find(37)->second != 24); REQUIRE(map.find(37)->second != 24);
REQUIRE(map.size() == 2); REQUIRE(map.size() == 2);
}; };
@ -137,7 +137,7 @@ TEST_CASE("FixedMap Tests", "[containers]") {
FixedMap<uint32_t, uint16_t>::Iterator it; FixedMap<uint32_t, uint16_t>::Iterator it;
std::pair<uint32_t, uint16_t> pair = std::make_pair(44, 43); std::pair<uint32_t, uint16_t> pair = std::make_pair(44, 43);
it = FixedMap<uint32_t, uint16_t>::Iterator(&pair); it = FixedMap<uint32_t, uint16_t>::Iterator(&pair);
REQUIRE(map.erase(&it) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST)); REQUIRE(map.erase(&it) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
REQUIRE(map.find(45) == map.end()); REQUIRE(map.find(45) == map.end());
size_t toLargeMap = 100; size_t toLargeMap = 100;
const uint8_t* ptr = reinterpret_cast<uint8_t*>(&toLargeMap); const uint8_t* ptr = reinterpret_cast<uint8_t*>(&toLargeMap);

View File

@ -56,61 +56,65 @@ TEST_CASE("TimevalTest", "[timevalOperations]") {
} }
SECTION("Operators") { SECTION("Operators") {
timeval t1; timeval t1;
t1.tv_sec = 1648227422; if (sizeof(t1.tv_sec) == 8) {
t1.tv_usec = 123456; t1.tv_sec = 1648227422;
timeval t2; t1.tv_usec = 123456;
t2.tv_sec = 1648227422; timeval t2;
t2.tv_usec = 123456; t2.tv_sec = 1648227422;
timeval t3 = t1 - t2; t2.tv_usec = 123456;
REQUIRE(t3.tv_sec == 0); timeval t3 = t1 - t2;
REQUIRE(t3.tv_usec == 0); REQUIRE(t3.tv_sec == 0);
timeval t4 = t1 - t3; REQUIRE(t3.tv_usec == 0);
REQUIRE(t4.tv_sec == 1648227422); timeval t4 = t1 - t3;
REQUIRE(t4.tv_usec == 123456); REQUIRE(t4.tv_sec == 1648227422);
timeval t5 = t3 - t1; REQUIRE(t4.tv_usec == 123456);
REQUIRE(t5.tv_sec == -1648227422); timeval t5 = t3 - t1;
REQUIRE(t5.tv_usec == -123456); REQUIRE(t5.tv_sec == -1648227422);
REQUIRE(t5.tv_usec == -123456);
timeval t6; timeval t6;
t6.tv_sec = 1648227400; t6.tv_sec = 1648227400;
t6.tv_usec = 999999; t6.tv_usec = 999999;
timeval t7 = t6 + t1; timeval t7 = t6 + t1;
REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull)); // Overflow test
REQUIRE(t7.tv_usec == 123455); REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull));
timeval t8 = t1 - t6; REQUIRE(t7.tv_usec == 123455);
REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1);
REQUIRE(t8.tv_usec == 123457);
double scalar = 2; timeval t8 = t1 - t6;
timeval t9 = t1 * scalar; REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1);
REQUIRE(t9.tv_sec == 3296454844); REQUIRE(t8.tv_usec == 123457);
REQUIRE(t9.tv_usec == 246912);
timeval t10 = scalar * t1;
REQUIRE(t10.tv_sec == 3296454844);
REQUIRE(t10.tv_usec == 246912);
timeval t11 = t6 * scalar;
REQUIRE(t11.tv_sec == (3296454800 + 1));
REQUIRE(t11.tv_usec == 999998);
timeval t12 = t1 / scalar; double scalar = 2;
REQUIRE(t12.tv_sec == 824113711); timeval t9 = t1 * scalar;
REQUIRE(t12.tv_usec == 61728); REQUIRE(t9.tv_sec == 3296454844);
REQUIRE(t9.tv_usec == 246912);
timeval t10 = scalar * t1;
REQUIRE(t10.tv_sec == 3296454844);
REQUIRE(t10.tv_usec == 246912);
timeval t11 = t6 * scalar;
REQUIRE(t11.tv_sec == (3296454800 + 1));
REQUIRE(t11.tv_usec == 999998);
timeval t13 = t6 / scalar; timeval t12 = t1 / scalar;
REQUIRE(t13.tv_sec == 824113700); REQUIRE(t12.tv_sec == 824113711);
// Rounding issue REQUIRE(t12.tv_usec == 61728);
REQUIRE(t13.tv_usec == 499999);
double scalar2 = t9 / t1; timeval t13 = t6 / scalar;
REQUIRE(scalar2 == Catch::Approx(2.0)); REQUIRE(t13.tv_sec == 824113700);
double scalar3 = t1 / t6; // Rounding issue
REQUIRE(scalar3 == Catch::Approx(1.000000013)); REQUIRE(t13.tv_usec == 499999);
double scalar4 = t3 / t1;
REQUIRE(scalar4 == Catch::Approx(0)); double scalar2 = t9 / t1;
double scalar5 = t12 / t1; REQUIRE(scalar2 == Catch::Approx(2.0));
REQUIRE(scalar5 == Catch::Approx(0.5)); double scalar3 = t1 / t6;
REQUIRE(scalar3 == Catch::Approx(1.000000013));
double scalar4 = t3 / t1;
REQUIRE(scalar4 == Catch::Approx(0));
double scalar5 = t12 / t1;
REQUIRE(scalar5 == Catch::Approx(0.5));
}
} }
SECTION("timevalOperations::toTimeval") { SECTION("timevalOperations::toTimeval") {

View File

@ -1,2 +1,5 @@
target_sources(${FSFW_TEST_TGT} PRIVATE testCommandExecutor.cpp target_sources(${FSFW_TEST_TGT} PRIVATE testHostFilesystem.cpp testFsMock.cpp)
testHostFilesystem.cpp testFsMock.cpp)
if(UNIX)
target_sources(${FSFW_TEST_TGT} PRIVATE testCommandExecutor.cpp)
endif()

View File

@ -6,7 +6,7 @@ AcceptsTmMock::AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToR
AcceptsTmMock::AcceptsTmMock(MessageQueueId_t queueToReturn) AcceptsTmMock::AcceptsTmMock(MessageQueueId_t queueToReturn)
: SystemObject(objects::NO_OBJECT, false), returnedQueue(queueToReturn) {} : SystemObject(objects::NO_OBJECT, false), returnedQueue(queueToReturn) {}
MessageQueueId_t AcceptsTmMock::getReportReceptionQueue(uint8_t virtualChannel) { MessageQueueId_t AcceptsTmMock::getReportReceptionQueue(uint8_t virtualChannel) const {
return returnedQueue; return returnedQueue;
} }

View File

@ -9,7 +9,7 @@ class AcceptsTmMock : public SystemObject, public AcceptsTelemetryIF {
AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToReturn); AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToReturn);
explicit AcceptsTmMock(MessageQueueId_t queueToReturn); explicit AcceptsTmMock(MessageQueueId_t queueToReturn);
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) override; MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
const char* getName() const override; const char* getName() const override;
MessageQueueId_t returnedQueue; MessageQueueId_t returnedQueue;

View File

@ -1,11 +1,11 @@
#include "StorageManagerMock.h" #include "StorageManagerMock.h"
ReturnValue_t StorageManagerMock::addData(store_address_t *storageId, const uint8_t *data, ReturnValue_t StorageManagerMock::addData(store_address_t *storageId, const uint8_t *data,
size_t size, bool ignoreFault) { size_t size) {
if (nextAddDataCallFails.first) { if (nextAddDataCallFails.first) {
return nextAddDataCallFails.second; return nextAddDataCallFails.second;
} }
return LocalPool::addData(storageId, data, size, ignoreFault); return LocalPool::addData(storageId, data, size);
} }
ReturnValue_t StorageManagerMock::deleteData(store_address_t packet_id) { ReturnValue_t StorageManagerMock::deleteData(store_address_t packet_id) {
if (nextDeleteDataCallFails.first) { if (nextDeleteDataCallFails.first) {
@ -36,11 +36,11 @@ ReturnValue_t StorageManagerMock::modifyData(store_address_t packet_id, uint8_t
} }
ReturnValue_t StorageManagerMock::getFreeElement(store_address_t *storageId, size_t size, ReturnValue_t StorageManagerMock::getFreeElement(store_address_t *storageId, size_t size,
uint8_t **p_data, bool ignoreFault) { uint8_t **p_data) {
if (nextFreeElementCallFails.first) { if (nextFreeElementCallFails.first) {
return nextFreeElementCallFails.second; return nextFreeElementCallFails.second;
} }
return LocalPool::getFreeElement(storageId, size, p_data, ignoreFault); return LocalPool::getFreeElement(storageId, size, p_data);
} }
bool StorageManagerMock::hasDataAtId(store_address_t storeId) const { bool StorageManagerMock::hasDataAtId(store_address_t storeId) const {

View File

@ -8,15 +8,13 @@ class StorageManagerMock : public LocalPool {
public: public:
StorageManagerMock(object_id_t setObjectId, const LocalPoolConfig &poolConfig); StorageManagerMock(object_id_t setObjectId, const LocalPoolConfig &poolConfig);
ReturnValue_t addData(store_address_t *storageId, const uint8_t *data, size_t size, ReturnValue_t addData(store_address_t *storageId, const uint8_t *data, size_t size) override;
bool ignoreFault) override;
ReturnValue_t deleteData(store_address_t packet_id) override; ReturnValue_t deleteData(store_address_t packet_id) override;
ReturnValue_t deleteData(uint8_t *buffer, size_t size, store_address_t *storeId) override; ReturnValue_t deleteData(uint8_t *buffer, size_t size, store_address_t *storeId) override;
ReturnValue_t getData(store_address_t packet_id, const uint8_t **packet_ptr, ReturnValue_t getData(store_address_t packet_id, const uint8_t **packet_ptr,
size_t *size) override; size_t *size) override;
ReturnValue_t modifyData(store_address_t packet_id, uint8_t **packet_ptr, size_t *size) override; ReturnValue_t modifyData(store_address_t packet_id, uint8_t **packet_ptr, size_t *size) override;
ReturnValue_t getFreeElement(store_address_t *storageId, size_t size, uint8_t **p_data, ReturnValue_t getFreeElement(store_address_t *storageId, size_t size, uint8_t **p_data) override;
bool ignoreFault) override;
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override; [[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
void clearStore() override; void clearStore() override;
void clearSubPool(uint8_t poolIndex) override; void clearSubPool(uint8_t poolIndex) override;

View File

@ -1,55 +0,0 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "fsfw/util/dataWrapper.h"
#include "mocks/SimpleSerializable.h"
TEST_CASE("Data Wrapper", "[util]") {
util::DataWrapper wrapper;
SECTION("State") {
REQUIRE(wrapper.isNull());
REQUIRE(wrapper.type == util::DataTypes::NONE);
}
SECTION("Set Raw Data") {
util::DataWrapper* instance = &wrapper;
bool deleteInst = false;
REQUIRE(wrapper.isNull());
std::array<uint8_t, 4> data = {1, 2, 3, 4};
SECTION("Setter") { wrapper.setRawData({data.data(), data.size()}); }
SECTION("Direct Construction Pair") {
instance = new util::DataWrapper(util::BufPair(data.data(), data.size()));
deleteInst = true;
}
SECTION("Direct Construction Single Args") {
instance = new util::DataWrapper(data.data(), data.size());
deleteInst = true;
}
REQUIRE(not instance->isNull());
REQUIRE(instance->type == util::DataTypes::RAW);
REQUIRE(instance->dataUnion.raw.data == data.data());
REQUIRE(instance->dataUnion.raw.len == data.size());
if (deleteInst) {
delete instance;
}
}
SECTION("Simple Serializable") {
util::DataWrapper* instance = &wrapper;
bool deleteInst = false;
REQUIRE(instance->isNull());
SimpleSerializable serializable;
SECTION("Setter") { wrapper.setSerializable(serializable); }
SECTION("Direct Construction") {
instance = new util::DataWrapper(serializable);
deleteInst = true;
}
REQUIRE(not instance->isNull());
REQUIRE(instance->type == util::DataTypes::SERIALIZABLE);
REQUIRE(instance->dataUnion.serializable == &serializable);
if (deleteInst) {
delete instance;
}
}
}