Compare commits

..

73 Commits

Author SHA1 Message Date
e73b9ff72c Merge pull request 'v6.0.0' (#729) from development into master
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
Reviewed-on: #729
2023-02-23 13:42:48 +01:00
dc7afc5415 Version bump, CHANGELOG update, format
Some checks failed
fsfw/fsfw/pipeline/pr-master This commit looks good
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-02-23 13:38:24 +01:00
9bf3ff95b7 Merge pull request 'Add Health Service Announce All Health Info' (#725) from eive/fsfw:add_health_service_announce_all into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #725
2023-02-23 13:13:56 +01:00
61562b18ab Merge branch 'development' into add_health_service_announce_all
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-23 12:56:12 +01:00
d76d97a36b changed health table parameter to objectId
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-23 12:44:42 +01:00
76b377c4c0 Merge pull request 'Mode Service: Add allowed subservice' (#739) from eive/fsfw:small_mode_service_fix into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #739
2023-02-20 13:40:53 +01:00
3562bf11b9 CHANGELOG update
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
2023-02-10 11:06:46 +01:00
fffb2b61e5 release check helper 2023-02-10 11:06:30 +01:00
94e5f62331
add allowed subservice
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-09 18:30:08 +01:00
0a9c563bbc format 2023-02-09 15:58:48 +01:00
fa7675897d Merge pull request 'Mode Service Bugfixes' (#736) from eive/fsfw:mode_service_fixes into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #736
2023-02-09 15:56:26 +01:00
3a2393885f more style
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-09 15:44:39 +01:00
c752b6d143 Merge pull request 'Generic TMTC Bridge Update' (#734) from eive/fsfw:tmtcbridge_tweaks into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #734
2023-02-09 15:37:35 +01:00
b676040c7c Merge pull request 'CMakeLists file updates' (#731) from eive/fsfw:cmakelists_update into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #731
2023-02-09 15:29:46 +01:00
010509efb4 removed unneeded find_package parameter for etl
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-09 13:50:16 +01:00
dfb1633f00 Merge branch 'development' into mode_service_fixes
Some checks reported errors
fsfw/fsfw/pipeline/pr-development Something is wrong with the build of this commit
2023-02-09 13:46:19 +01:00
5f7172e130 Merge pull request 'TCP/IP TMTC bridge memory leak fixes' (#737) from eive/fsfw:possible_tcpip_bridge_fixes into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #737
2023-02-09 12:15:45 +01:00
0c6465cd95 Merge pull request 'time stamper empty ctor' (#730) from eive/fsfw:empty_cds_short_ctor into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #730
2023-02-09 11:45:49 +01:00
f94987c46d Merge pull request 'RM3100 important bugfix' (#733) from eive/fsfw:rm3100_fixes into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #733
2023-02-09 11:41:53 +01:00
1809ce359b Merge pull request 'comment tweak to event parser can read everything' (#732) from eive/fsfw:health_if_update into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #732
2023-02-09 11:39:53 +01:00
8c712441ab Making fetch Catch2 quiet as well.
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-09 11:34:58 +01:00
f1b0ca7cff
add PR link
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-08 21:26:37 +01:00
000df85556
bump changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-08 21:24:00 +01:00
1fffcc2229 possiible leak fixes 2023-02-08 21:23:21 +01:00
a419806a05
Merge remote-tracking branch 'upstream/development' into mode_service_fixes
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-08 09:33:13 +01:00
6445debfa1
bump changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-08 09:24:55 +01:00
8014e4adf9
mode service fixes 2023-02-08 09:23:48 +01:00
134d908f26
that stuff is not in upstream yet..
Some checks are pending
fsfw/fsfw/pipeline/pr-development Build started...
2023-02-07 12:52:18 +01:00
40a9e12416
1000 is a bit much
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-07 12:47:40 +01:00
f39054edd4
introduce warning switch 2023-02-07 12:45:29 +01:00
5adf89b911
changelog update
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-07 12:41:42 +01:00
c2e6a22dec
important bugfix for RM3100 2023-02-07 12:39:43 +01:00
c8e065a713
comment tweak to event parser can read everything
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-07 12:36:42 +01:00
3ed49dbae3
Merge remote-tracking branch 'upstream/development' into empty_cds_short_ctor
Some checks are pending
fsfw/fsfw/pipeline/pr-development Build started...
2023-02-07 12:24:02 +01:00
4cf52d5dfe Merge pull request 'Time Service 9 update' (#726) from eive/fsfw:updates_fixes_pus_time_service into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #726
2023-02-07 12:19:45 +01:00
539d7aac9e
suppress error if ETL is not found
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-07 12:17:03 +01:00
0a23f2c85a
correction for printout, add prefix
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-07 12:15:44 +01:00
46230e6c6d
Merge remote-tracking branch 'upstream/development' into updates_fixes_pus_time_service
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-07 12:11:29 +01:00
b22d439300
bump changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-07 12:10:11 +01:00
7e7b3bbbc9
time stamper empty ctor
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-07 12:07:41 +01:00
5b92247fbd Merge branch 'development' into add_health_service_announce_all
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-06 16:31:05 +01:00
e2b66df72e Merge pull request 'various fixes related to linux Unittests and memory leaks' (#715) from eive/fsfw:unittest_fix_semaphore into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #715
2023-02-06 16:30:37 +01:00
d9da55fdab Merge branch 'development' into add_health_service_announce_all
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-06 15:03:52 +01:00
7b828f233a Merge pull request 'I2C Linux: remove duplicate printout' (#718) from eive/fsfw:i2c_remove_duplicate_printout into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #718
2023-02-06 14:54:58 +01:00
c3d1000cd5 Merge branch 'development' into unittest_fix_semaphore
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-06 14:46:45 +01:00
8e0e57714d Merge pull request 'allow using SO_REUSEADDR and SO_REUSEPORT on TCP server' (#722) from eive/fsfw:tcp_server_reuseaddr_reusesocket into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #722
2023-02-06 14:45:40 +01:00
066f7a6f9b
remove unreachable code
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-06 14:41:14 +01:00
cc9e54ea6b Merge pull request 'improve srv20 error messages' (#723) from eive/fsfw:srv20_error_msgs into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #723
2023-02-06 14:37:26 +01:00
31465a4e0f Merge pull request 'MGM: small tweak, gain factor was always them same' (#724) from eive/fsfw:mgm_handler_small_fix into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #724
2023-02-06 14:36:34 +01:00
c0e5d1eb99 Merge branch 'development' into tcp_server_reuseaddr_reusesocket
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-06 14:34:52 +01:00
3bc5d4a2e0
Merge remote-tracking branch 'upstream/development' into mgm_handler_small_fix
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-06 14:25:33 +01:00
b1e9dd9e4a
Merge remote-tracking branch 'upstream/development' into updates_fixes_pus_time_service
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-06 14:24:38 +01:00
ab86599db3 Merge pull request 'Bugfix DHB setNormalDatapoolEntriesInvalid' (#728) from eive/fsfw:bugfix_dhb_set_datapool_entries_invalid into development
All checks were successful
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #728
2023-02-06 14:20:34 +01:00
034eb34c2e
small tweak
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-03 16:05:50 +01:00
4374c7c4f4
changelog
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-03 16:01:56 +01:00
5343844be5 bugfix in setNormalDataPoolEntriesInvalid
Do not forget to call read and write to actually update the
validity state
2023-02-03 16:00:55 +01:00
e300490b93 Merge pull request 'Bugfix PUS packet creators Sequence flags' (#727) from eive/fsfw:bugfix_pus_packets_seq_flags into development
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
fsfw/fsfw/pipeline/pr-master This commit looks good
Reviewed-on: #727
2023-02-02 17:22:29 +01:00
0f811777a7
changelog update
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-01 20:49:53 +01:00
e93137939e set sequence flags for PUS TMTC to unsegmented 2023-02-01 20:48:26 +01:00
c1f42618db small but important bugfix for health service
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-01 19:59:32 +01:00
1f88c006d9
update changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-02-01 18:42:09 +01:00
7e94baceef
service 9 update
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
- fix time info event
- add time dump subservice
2023-02-01 18:39:23 +01:00
61df451dd8
update changelog
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-02-01 17:41:47 +01:00
29ea89044e beatufil 2023-02-01 17:35:49 +01:00
e487f5be87
proper announce all impl 2023-02-01 17:35:32 +01:00
9b05e8f274 re-order fields in TcpConfig
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-01-30 14:24:48 +01:00
eb223dae88
bump changelog
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
2023-01-30 14:20:28 +01:00
3656662d88 small tweak, gain factory was always them same
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-01-30 14:18:03 +01:00
fe71978467 improve srv20 error messages
Some checks are pending
fsfw/fsfw/pipeline/pr-development Build started...
2023-01-30 14:15:37 +01:00
b646717a76
bump changelog
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-01-30 14:11:00 +01:00
99d8c845f2 allow using SO_REUSEADDR and SO_REUSEPORT on TCP server
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-01-30 14:07:41 +01:00
ba62c28b64 adding linux ci and fixing problems
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-01-12 15:40:52 +01:00
7adb47aecb remove duplicate printout
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
2023-01-11 08:45:37 +01:00
128 changed files with 1390 additions and 1242 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "automation/msvc-wine"]
path = automation/msvc-wine
url = https://github.com/mstorsjo/msvc-wine

View File

@ -8,14 +8,38 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
# [v6.0.0]
# [v6.0.0] 2023-02-10
## Fixes
- Mode Service: Add allowed subservice
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/739
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
subservice not working properly.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/736
- Memory leak fixes for the TCP/IP TMTC bridge.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/737
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
seconds instead of uptime.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
only the X scaling factor was used.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
- HAL MGM3100 Handler: Z value was previously calculated with bytes of the X value.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/733
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
to false correctly because the `read` and `write` calls were missing.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/728
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
of the correct unsegmented flags (0b11) as specified in the standard.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/727
- TC Scheduler Service 11: Add size and CRC check for contained TC.
Bug: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/issues/719
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/720
- 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
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710
- 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.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
@ -25,22 +49,82 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `TcpTmTcServer.cpp`: The server was actually not able to handle
CCSDS packets which were clumped together. This has been fixed now.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/673
- `CServiceHealthCommanding`: Add announce all health info implementation
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725
- various fixes related to linux Unittests and memory leaks
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/715
- small fix to allow teardown handling
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/713
- fix compiler warning for fixed array list copy ctor
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/704
- missing include
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/703
- defaultconfig did not build anymore
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/702
- hotfix
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/699
- small fix for helper
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/698
- missing retval conv
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/697
- DHB Countdown Bug
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/693
- doc corrections
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/687
- better error printout
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/686
- include correction
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/683
- better warning for missing include paths
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/676
- Service 11 regression
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/670
## Added
- Empty constructor for `CdsShortTimeStamper` which does not do an object manager registration.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/730
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
option on the TCP server. CTOR prototype has changed and expects an explicit
TCP configuration struct to be passed.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/722
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
- `UioMapper` is able to resolve symlinks now.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
- Add new `UnsignedByteField` class
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
- publish documentation for development and master branch
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/681
- Add Linux HAL options
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/663
- Expand SerializeIF
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/656
- PUS Service 11: Additional Safety Check
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/666
- improvements for auto-formatter script
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/665
- provide a weak print char impl
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/674
## Removed
- now that doc server is up, remove markdown files
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/688
- remove bsp specific code
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/679
## Changes
- `CService201HealthCommanding` renamed to `CServiceHealthCommanding`,
service ID customizable now. `CServiceHealthCommanding` expects configuration struct
`HealthServiceCfg` now
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725
- `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.
so they can be used without template specification.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/707
- Remove default secondary header argument for
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
@ -70,18 +154,41 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
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`:
- Make functions `const` where it makes sense
- Add `const char* getName const` abstract function
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/684
- 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
- Generic TMTC Bridge Update
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/734
- comment tweak to event parser can read everything
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/732
- CMakeLists file updates
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/731
- improve srv20 error messages
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/723
- I2C Linux: remove duplicate printout
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/718
- printout handling improvements
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/717
- vec getter, reset for content
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/716
- updates for source sequence counter
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/714
- SP reader getPacketData is const now
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/708
- refactoring of serial drivers for linux
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/705
- Local Pool Update Remove Add Data Ignore Fault Argument
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/701
- Switch to new documentation server
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/694
- Windows Tweaks
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/691
- Refactor Local Pool API
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/667
- group MGM data in local pool vectors
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/664
## CFDP
@ -101,7 +208,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
implementation without an extra component
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
# [v5.0.0] 25.07.2022
# [v5.0.0] 2022-07-25
## Changes

View File

@ -13,7 +13,7 @@ list(APPEND CMAKE_MODULE_PATH
# Version file handling #
# ##############################################################################
set(FSFW_VERSION_IF_GIT_FAILS 5)
set(FSFW_VERSION_IF_GIT_FAILS 6)
set(FSFW_SUBVERSION_IF_GIT_FAILS 0)
set(FSFW_REVISION_IF_GIT_FAILS 0)
@ -64,13 +64,6 @@ elseif(${CMAKE_CXX_STANDARD} LESS 17)
"${MSG_PREFIX} Compiling the FSFW requires a minimum of C++17 support")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Manually tweak MSVC to emit (about) the same warnings as clang and gcc on linux
# needs to be done here using add_compile_definitions() (as opposed to target_compile_definitions()) to be available for all binaries and libraries
add_compile_options("/permissive-" /wd4267 /wd4244 /wd4244 /wd4305 /wd4805 /wd4267 /wd4646 /wd4065 /wd4996 /Dand=&& /Dor=|| /Dnot=!)
add_compile_definitions(NOMINMAX)
endif()
set(FSFW_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw")
set(FSFW_ETL_LIB_NAME etl)
@ -165,7 +158,7 @@ if(FSFW_BUILD_TESTS)
if(NOT Catch2_FOUND)
message(
STATUS
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent"
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent."
)
include(FetchContent)
@ -181,27 +174,6 @@ if(FSFW_BUILD_TESTS)
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
if(FSFW_OSAL MATCHES "freertos")
message(STATUS "${MSG_PREFIX} Downloading FreeRTOS with FetchContent")
include(FetchContent)
set(FreeRTOS_PORT posix)
FetchContent_Declare(
FreeRTOS
GIT_REPOSITORY https://egit.irs.uni-stuttgart.de/fsfw/FreeRTOS-LTS
GIT_TAG develop
GIT_SUBMODULES FreeRTOS/FreeRTOS-Kernel)
FetchContent_MakeAvailable(FreeRTOS)
set(LIB_OS_NAME FreeRTOS)
target_include_directories(FreeRTOS PUBLIC unittests/testcfg/freertos)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(FreeRTOS PRIVATE ${CMAKE_THREAD_LIBS_INIT})
endif()
project(${FSFW_TEST_TGT} CXX C)
add_executable(${FSFW_TEST_TGT})
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
@ -229,8 +201,8 @@ find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
message(
STATUS
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
"etl with FindPackage")
"${MSG_PREFIX} ETL installation not found. Downloading ETL with FetchContent."
)
include(FetchContent)
FetchContent_Declare(
@ -254,7 +226,6 @@ if(FSFW_FETCH_CONTENT_TARGETS)
# GitHub issue: https://github.com/catchorg/Catch2/issues/2417
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
endif()
endif()
set(FSFW_CORE_INC_PATH "inc")
@ -389,9 +360,6 @@ if(FSFW_BUILD_TESTS)
endif()
target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2
${LIB_FSFW_NAME})
if(FSFW_OSAL MATCHES "freertos")
target_link_libraries(${FSFW_TEST_TGT} PRIVATE FreeRTOS)
endif()
endif()
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. If
@ -479,8 +447,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(FSFW_WARNING_FLAGS -Wall -Wno-gnu-anonymous-struct)
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
endif()
# Required include paths to compile the FSFW

View File

@ -5,7 +5,7 @@ RUN apt-get --yes upgrade
#tzdata is a dependency, won't install otherwise
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get --yes install ca-certificates clang cmake doxygen g++ gcc git graphviz iputils-ping lcov make msitools nano ninja-build pip python3 python3-simplejson python3-six qemu-system-arm rsync valgrind wget winbind
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping python3 pip doxygen graphviz rsync
RUN python3 -m pip install sphinx breathe
@ -21,37 +21,9 @@ RUN git clone https://github.com/ETLCPP/etl.git && \
cmake -B build . && \
cmake --install build/
# install our own rtems build
RUN wget -qO- https://buggy.irs.uni-stuttgart.de/rtems_releases/rtems6-12.2.1.tar.bz2 | tar -xj -C /opt/
ENV PATH="$PATH:/opt/rtems/6/bin"
# install modern wine for MSVC, removing a conflicting file
RUN dpkg --add-architecture i386 && \
mkdir -pm755 /etc/apt/keyrings && \
wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key && \
wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/focal/winehq-focal.sources && \
apt-get update && \
apt-get --yes install winehq-stable
# silence wine
ENV WINEDEBUG=-all
# install MSVC using https://github.com/mstorsjo/msvc-wine
# see msvc-wine/LICENSE.txt
COPY msvc-wine/lowercase msvc-wine/fixinclude msvc-wine/install.sh msvc-wine/vsdownload.py ./
COPY msvc-wine/wrappers/* ./wrappers/
RUN PYTHONUNBUFFERED=1 ./vsdownload.py --accept-license --dest /opt/msvc && \
./install.sh /opt/msvc && \
rm lowercase fixinclude install.sh vsdownload.py && \
rm -rf wrappers
RUN wine64 wineboot --init && \
while pgrep wineserver > /dev/null; do sleep 1; done
#ssh needs a valid user to work
RUN addgroup -q --gid 117 jenkins && adduser -q --uid 114 --gid 117 jenkins
RUN adduser --uid 114 jenkins
#add documentation server to known hosts
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
RUN echo "|1|CcBvBc3EG03G+XM5rqRHs6gK/Gg=|oGeJQ+1I8NGI2THIkJsW92DpTzs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
RUN echo "|1|CcBvBc3EG03G+XM5rqRHs6gK/Gg=|oGeJQ+1I8NGI2THIkJsW92DpTzs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts

121
automation/Jenkinsfile vendored
View File

@ -2,71 +2,86 @@ pipeline {
environment {
BUILDDIR_HOST = 'cmake-build-tests-host'
BUILDDIR_LINUX = 'cmake-build-tests-linux'
BUILDDIR_FREERTOS = 'cmake-build-tests-freertos'
BUILDDIR_RTEMS = 'cmake-build-tests-rtems'
BUILDDIR_WIN = 'cmake-build-tests-windows'
DOCDDIR = 'cmake-build-documentation'
}
agent {
docker {
image 'fsfw-ci:d8'
image 'fsfw-ci:d6'
args '--network host --sysctl fs.mqueue.msg_max=100'
}
}
stages {
stage('Host-clang') {
steps {
sh 'rm -rf $BUILDDIR_HOST'
dir(BUILDDIR_HOST) {
sh 'CC=clang CXX=clang++ cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
sh 'cmake --build . -j4'
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
stage('Host') {
stages{
stage('Clean') {
steps {
sh 'rm -rf $BUILDDIR_HOST'
}
}
stage('Configure') {
steps {
dir(BUILDDIR_HOST) {
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
}
}
}
stage('Build') {
steps {
dir(BUILDDIR_HOST) {
sh 'cmake --build . -j4'
}
}
}
stage('Unittests') {
steps {
dir(BUILDDIR_HOST) {
sh 'cmake --build . -- fsfw-tests_coverage -j4'
}
}
}
stage('Valgrind') {
steps {
dir(BUILDDIR_HOST) {
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
}
}
}
}
stage('Linux-gcc') {
steps {
sh 'rm -rf $BUILDDIR_LINUX'
dir(BUILDDIR_LINUX) {
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
sh 'cmake --build . -j4'
sh 'cmake --build . -- fsfw-tests_coverage -j4'
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
stage('Linux') {
stages{
stage('Clean') {
steps {
sh 'rm -rf $BUILDDIR_LINUX'
}
}
}
}
stage('FreeRTOS-gcc') {
steps {
sh 'rm -rf $BUILDDIR_FREERTOS'
dir(BUILDDIR_FREERTOS) {
sh 'cmake -DFSFW_OSAL=freertos -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
sh 'cmake --build . -j4'
sh './fsfw-tests'
//sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
stage('Configure') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
}
}
}
}
}
stage('rtems-gcc') {
steps {
sh 'rm -rf $BUILDDIR_RTEMS'
dir(BUILDDIR_RTEMS) {
sh 'cmake -DFSFW_OSAL=rtems -DFSFW_BUILD_TESTS=ON -DFSFW_TESTS_GEN_COV=OFF -DFSFW_CICD_BUILD=ON -DCMAKE_TOOLCHAIN_FILE=../unittests/testcfg/rtems/cmake/aarch64-rtems6-toolchain.cmake ..'
sh 'cmake --build . -j4'
sh 'qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -semihosting -machine virt,gic-version=3 -cpu cortex-a72 -m 4000 -kernel fsfw-tests'
stage('Build') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake --build . -j4'
}
}
}
}
}
stage('Host-msvc') {
steps {
sh 'rm -rf $BUILDDIR_WIN'
dir(BUILDDIR_WIN) {
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_TESTS_GEN_COV=OFF -DFSFW_CICD_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../unittests/testcfg/windows/cmake/x64-windows-toolchain.cmake -GNinja ..'
sh 'cmake --build . -j4'
stage('Unittests') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake --build . -- fsfw-tests_coverage -j4'
}
}
}
stage('Valgrind') {
steps {
dir(BUILDDIR_LINUX) {
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
}
}
}
}
@ -82,7 +97,7 @@ pipeline {
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
}
}
dir(BUILDDIR_LINUX) {
dir(BUILDDIR) {
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
}
@ -101,7 +116,7 @@ pipeline {
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
}
}
dir(BUILDDIR_LINUX) {
dir(BUILDDIR) {
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
}

@ -1 +0,0 @@
Subproject commit 2d2d7db0b55b0f061eca5f4f1c149608d5501ec6

110
scripts/check_release.py Executable file
View File

@ -0,0 +1,110 @@
#! /bin/python
import argparse
import json
import urllib.request
import re
from pathlib import Path
def main() -> None:
parser = argparse.ArgumentParser(
description="List undocumented PRs"
)
parser.add_argument("-v", "--version", type=str, required=True)
args = parser.parse_args()
match = re.search("([0-9]+\.[0-9]+\.[0-9]+)", args.version)
if not match:
print("invalid version")
exit(1)
version = "v" + match.group(1)
print("looking for milestone for " + version + " ...")
with urllib.request.urlopen("https://egit.irs.uni-stuttgart.de/api/v1/repos/fsfw/fsfw/milestones?name=" + version) as milestone_json:
milestones = json.load(milestone_json)
if (len(milestones) == 0):
print("did not find any milestone")
exit(1)
if (len(milestones) > 1):
print("found multiple milestons")
milestone_title = milestones[0]['title']
milestone = str(milestones[0]['id'])
print("Using Milestone \""+ milestone_title + "\" with id " + milestone)
milestone_prs = []
page = 1
last_count = 1;
while last_count != 0:
with urllib.request.urlopen("https://egit.irs.uni-stuttgart.de/api/v1/repos/fsfw/fsfw/pulls?state=closed&milestone=" + str(milestone) + "&limit=100&page=" + str(page)) as pull_requests_json:
pull_requests = json.load(pull_requests_json)
for pr in pull_requests:
milestone_prs.append({'number': str(pr['number']), 'title' : pr['title']})
page += 1
last_count = len(pull_requests)
print("Found " + str(len(milestone_prs)) + " closed PRs in Milestone")
print("looking for CHANGELOG.md ...")
path = Path(".")
files = list(path.glob("CHANGELOG.md"))
if (len(files) != 1):
files = list(path.glob("../CHANGELOG.md"))
if (len(files) != 1):
print("did not find CHANGELOG.md. Run script in either root directory or scripts subfolder.")
exit(1)
print("Scanning CHANGELOG.md ...")
changelog_prs = []
with open(files[0]) as changelog:
line = changelog.readline()
while (line):
#print("line: " + line)
match = re.search("\#.+(v[0-9]+\.[0-9]+\.[0-9]+)", line)
if (match):
if match.group(1) == version:
#print("found version")
line = changelog.readline()
continue
else:
#print("done with " + match.group(1))
break
match = re.search("PR: https://egit\.irs\.uni-stuttgart\.de/fsfw/fsfw/pulls/([0-9]+)", line)
if match:
changelog_prs.append(match.group(1))
line = changelog.readline()
print("Found " + str(len(changelog_prs)) + " PRs in CHANGELOG.md")
print("")
copy_array = changelog_prs.copy()
print("PRs in CHANGELOG.md that are not in Milestone:")
for pr in milestone_prs:
if pr['number'] in copy_array:
copy_array.remove(pr['number'])
for pr in copy_array:
print("https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/" + pr)
print("")
print("PRs in milestone that are not in CHANGELOG.md:")
for pr in milestone_prs:
if pr['number'] not in changelog_prs:
print("- " + pr['title'] + "\n PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/" + pr['number'])
main()

View File

@ -21,7 +21,7 @@ struct FileSize : public SerializeIF {
this->largeFile = isLarge;
return serialize(buffer, size, maxSize, streamEndianness);
}
using SerializeIF::serialize;
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override {
if (not largeFile) {

View File

@ -3,7 +3,7 @@
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface.h"
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_t value) : VarLenField() {
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
ReturnValue_t result = this->setValue(width, value);
if (result != returnvalue::OK) {
#if FSFW_DISABLE_PRINTOUT == 0
@ -20,7 +20,7 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, uint64_t value_) {
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) {
switch (widthInBytes) {
case (cfdp::WidthInBytes::ONE_BYTE): {
if (value_ > UINT8_MAX) {
@ -51,7 +51,7 @@ ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, uint6
return returnvalue::OK;
}
uint64_t cfdp::VarLenField::getValue() const {
size_t cfdp::VarLenField::getValue() const {
switch (width) {
case (cfdp::WidthInBytes::ONE_BYTE): {
return value.oneByte;

View File

@ -25,13 +25,13 @@ class VarLenField : public SerializeIF {
template <typename T>
explicit VarLenField(UnsignedByteField<T> byteField);
VarLenField(cfdp::WidthInBytes width, uint64_t value);
VarLenField(cfdp::WidthInBytes width, size_t value);
bool operator==(const VarLenField &other) const;
bool operator!=(const VarLenField &other) const;
bool operator<(const VarLenField &other) const;
ReturnValue_t setValue(cfdp::WidthInBytes, uint64_t value);
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
@ -42,7 +42,7 @@ class VarLenField : public SerializeIF {
Endianness streamEndianness);
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
[[nodiscard]] uint64_t getValue() const;
[[nodiscard]] size_t getValue() const;
#if FSFW_CPP_OSTREAM_ENABLED == 1
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
@ -53,7 +53,6 @@ class VarLenField : public SerializeIF {
#endif
private:
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;

View File

@ -9,11 +9,6 @@
#include "fsfw/returnvalues/FwClassIds.h"
#include "fsfw/returnvalues/returnvalue.h"
// Thanks, windows
#ifdef NO_ERROR
#undef NO_ERROR
#endif
namespace cfdp {
static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";

View File

@ -42,6 +42,6 @@ size_t EofInfo::getSerializedSize(bool fssLarge) {
return size;
}
ReturnValue_t EofInfo::setFileSize(uint64_t fileSize, bool isLarge) {
ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) {
return this->fileSize.setFileSize(fileSize, isLarge);
}

View File

@ -21,7 +21,7 @@ struct EofInfo {
void setChecksum(uint32_t checksum);
void setConditionCode(cfdp::ConditionCode conditionCode);
void setFaultLoc(EntityIdTlv* faultLoc);
ReturnValue_t setFileSize(uint64_t size, bool isLarge);
ReturnValue_t setFileSize(size_t size, bool isLarge);
private:
cfdp::ConditionCode conditionCode;

View File

@ -1,10 +1,5 @@
#include "FinishedPduReader.h"
// Thanks, windows
#ifdef NO_ERROR
#undef NO_ERROR
#endif
FinishPduReader::FinishPduReader(const uint8_t* pduBuf, size_t maxSize, FinishedInfo& info)
: FileDirectiveReader(pduBuf, maxSize), finishedInfo(info) {}

View File

@ -23,7 +23,6 @@ class EntityIdTlv : public TlvIF {
*/
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;

View File

@ -26,7 +26,6 @@ class FilestoreRequestTlv : public cfdp::FilestoreTlvBase {
*/
ReturnValue_t deSerialize(cfdp::Tlv &tlv, Endianness endianness);
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;

View File

@ -29,7 +29,6 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
*/
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;

View File

@ -364,10 +364,6 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
void printWarningOrError(sif::OutputTypes outputType, const char* functionName,
ReturnValue_t errorCode = returnvalue::FAILED,
const char* errorPrint = nullptr);
private:
using ProvidesDataPoolSubscriptionIF::subscribeForPeriodicPacket;
using ProvidesDataPoolSubscriptionIF::subscribeForUpdatePacket;
};
template <class T>

View File

@ -1,5 +1,6 @@
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/datapool/PoolReadGuard.h"
#include "fsfw/datapoollocal/LocalPoolVariable.h"
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
@ -321,7 +322,8 @@ void DeviceHandlerBase::doStateMachine() {
if (mode != currentMode) {
break;
}
uint32_t currentUptime = Clock::getUptime_ms();
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
if (currentUptime - timeoutStart >= childTransitionDelay) {
#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0
char printout[60];
@ -345,7 +347,8 @@ void DeviceHandlerBase::doStateMachine() {
setMode(_MODE_WAIT_ON);
break;
case _MODE_WAIT_ON: {
uint32_t currentUptime = Clock::getUptime_ms();
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
if (powerSwitcher != nullptr and
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
@ -364,7 +367,8 @@ void DeviceHandlerBase::doStateMachine() {
}
} break;
case _MODE_WAIT_OFF: {
uint32_t currentUptime = Clock::getUptime_ms();
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
if (powerSwitcher == nullptr) {
setMode(MODE_OFF);
@ -574,7 +578,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
modeHelper.modeChanged(newMode, newSubmode);
announceMode(false);
}
timeoutStart = Clock::getUptime_ms();
Clock::getUptime(&timeoutStart);
if (mode == MODE_OFF and thermalSet != nullptr) {
ReturnValue_t result = thermalSet->read();
@ -1505,7 +1509,10 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
for (const auto& reply : deviceReplyMap) {
if (reply.second.dataSet != nullptr) {
reply.second.dataSet->setValidity(false, true);
PoolReadGuard pg(reply.second.dataSet);
if (pg.getReadResult() == returnvalue::OK) {
reply.second.dataSet->setValidity(false, true);
}
}
}
}

View File

@ -206,9 +206,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
Mode_t getTransitionSourceMode() const;
Submode_t getTransitionSourceSubMode() const;
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
HealthState getHealth() override;
ReturnValue_t setHealth(HealthState health) override;
virtual void getMode(Mode_t *mode, Submode_t *submode);
HealthState getHealth();
ReturnValue_t setHealth(HealthState health);
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues,
@ -1073,7 +1073,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
bool forceDirectTm = false);
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) override;
uint32_t *msToReachTheMode);
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);

View File

@ -28,23 +28,22 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
MessageQueueId_t getEventReportQueue() override;
MessageQueueId_t getEventReportQueue();
ReturnValue_t registerListener(MessageQueueId_t listener,
bool forwardAllButSelected = false) override;
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
ReturnValue_t unregisterListener(MessageQueueId_t listener) override;
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) override;
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) override;
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
EventId_t idTo = 0, bool idInverted = false,
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
bool reporterInverted = false) override;
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) override;
bool reporterInverted = false);
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object);
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
EventId_t idTo = 0, bool idInverted = false,
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
bool reporterInverted = false) override;
ReturnValue_t performOperation(uint8_t opCode) override;
bool reporterInverted = false);
ReturnValue_t performOperation(uint8_t opCode);
protected:
MessageQueueIF* eventReportQueue = nullptr;

View File

@ -52,7 +52,6 @@ ReturnValue_t DleParser::parseRingBuf(size_t& readSize) {
// without skipping the STX
readSize = vectorIdx;
ErrorInfo info;
info.len = vectorIdx;
setErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
return POSSIBLE_PACKET_LOSS;
}

View File

@ -58,7 +58,7 @@ class Type : public SerializeIF {
template <typename T>
struct PodTypeConversion {
static_assert(!std::is_same<T, bool>::value,
static_assert(not std::is_same<T, bool>::value,
"Do not use boolean for the PoolEntry type, use uint8_t "
"instead! The ECSS standard defines a boolean as a one bit "
"field. Therefore it is preferred to store a boolean as an "

View File

@ -37,16 +37,16 @@ void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, bool
}
}
void arrayprinter::printHex(const uint8_t *data, size_t datasize, size_t maxCharPerLine) {
void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerLine) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
if (sif::info.crAdditionEnabled()) {
std::cout << "\r" << std::endl;
}
std::cout << "hex [" << std::setfill('0') << std::hex;
for (size_t i = 0; i < datasize; i++) {
for (size_t i = 0; i < size; i++) {
std::cout << std::setw(2) << static_cast<int>(data[i]);
if (i < datasize - 1) {
if (i < size - 1) {
std::cout << ",";
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
std::cout << std::endl;
@ -56,11 +56,27 @@ void arrayprinter::printHex(const uint8_t *data, size_t datasize, size_t maxChar
std::cout << std::dec << std::setfill(' ');
std::cout << "]" << std::endl;
#else
printf("hex [");
for (size_t i = 0; i < datasize; i++) {
printf("0x%02x ", data[i]);
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
// plus line break plus small safety margin.
char printBuffer[(size + 1) * 7 + 1] = {};
size_t currentPos = 0;
for (size_t i = 0; i < size; i++) {
// To avoid buffer overflows.
if (sizeof(printBuffer) - currentPos <= 7) {
break;
}
currentPos += snprintf(printBuffer + currentPos, 6, "%02x", data[i]);
if (i < size - 1) {
currentPos += sprintf(printBuffer + currentPos, ",");
if ((i + 1) % maxCharPerLine == 0) {
currentPos += sprintf(printBuffer + currentPos, "\n");
}
}
}
printf("]\n");
#if FSFW_DISABLE_PRINTOUT == 0
printf("hex [%s]\n", printBuffer);
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
#endif
}
@ -84,10 +100,26 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerL
#else
// General format: 32,243,-12 so it is number of chars times 4
// plus line break plus small safety margin.
uint16_t expectedLines = ceil((double)size / maxCharPerLine);
char printBuffer[size * 4 + 1 + expectedLines] = {};
size_t currentPos = 0;
for (size_t i = 0; i < size; i++) {
// TODO
// To avoid buffer overflows.
if (sizeof(printBuffer) - currentPos <= 4) {
break;
}
currentPos += snprintf(printBuffer + currentPos, 4, "%d", data[i]);
if (i < size - 1) {
currentPos += sprintf(printBuffer + currentPos, ",");
if ((i + 1) % maxCharPerLine == 0) {
currentPos += sprintf(printBuffer + currentPos, "\n");
}
}
}
#if FSFW_DISABLE_PRINTOUT == 0
printf("dec [%s]\n", printBuffer);
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
#endif
}

View File

@ -16,26 +16,24 @@ class HasHealthIF {
};
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY = returnvalue::makeCode(INTERFACE_ID, 1);
static constexpr ReturnValue_t INVALID_HEALTH_STATE = returnvalue::makeCode(INTERFACE_ID, 2);
static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED = returnvalue::makeCode(INTERFACE_ID, 3);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
//! P1: New Health, P2: Old Health
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
static const Event OVERWRITING_HEALTH =
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
//!< satellite alive.
static const Event TRYING_RECOVERY =
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
//!< power-cycle). No parameters.
static const Event RECOVERY_STEP =
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
//!< 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_DONE = MAKE_EVENT(
12,
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
//! Assembly overwrites health information of children to keep satellite alive.
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
//! Recovery is ongoing. Comes twice during recovery.
//! P1: 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
//! Recovery was completed. Not necessarily successful. No parameters.
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
virtual ~HasHealthIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@ -8,6 +8,8 @@
#include "HealthTableIF.h"
class HealthTable : public HealthTableIF, public SystemObject {
friend class CServiceHealthCommanding;
public:
explicit HealthTable(object_id_t objectid);
~HealthTable() override;

View File

@ -55,7 +55,7 @@ class HousekeepingSnapshot : public SerializeIF {
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
Endianness streamEndianness) const {
if (timeStamp != nullptr) {
/* Endianness will always be MACHINE, so we can simply use memcpy
here. */
@ -70,7 +70,7 @@ class HousekeepingSnapshot : public SerializeIF {
return updateData->serialize(buffer, size, maxSize, streamEndianness);
}
virtual size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const {
if (updateData == nullptr) {
return 0;
}

View File

@ -7,10 +7,10 @@
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
: SystemObject(setObjectId),
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
poolManager(this, commandQueue),
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
internalErrorDataset(this) {
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
mutex = MutexFactory::instance()->createMutex();
}

View File

@ -24,3 +24,19 @@ void ModeMessage::setCantReachMode(CommandMessage* message, ReturnValue_t reason
message->setParameter(reason);
message->setParameter2(0);
}
void ModeMessage::setModeAnnounceMessage(CommandMessage& message, bool recursive) {
Command_t cmd;
if (recursive) {
cmd = CMD_MODE_ANNOUNCE_RECURSIVELY;
} else {
cmd = CMD_MODE_ANNOUNCE;
}
message.setCommand(cmd);
}
void ModeMessage::setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode) {
setModeMessage(&message, CMD_MODE_COMMAND, mode, submode);
}
void ModeMessage::setModeReadMessage(CommandMessage& message) { message.setCommand(CMD_MODE_READ); }

View File

@ -45,6 +45,9 @@ class ModeMessage {
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
Submode_t submode);
static void setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode);
static void setModeAnnounceMessage(CommandMessage& message, bool recursive);
static void setModeReadMessage(CommandMessage& message);
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
static void clear(CommandMessage* message);
};

View File

@ -18,7 +18,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
violationEvent(violationEvent),
aboveIsViolation(aboveIsViolation) {}
virtual ~AbsLimitMonitor() {}
ReturnValue_t checkSample(T sample, T *crossedLimit) override {
virtual ReturnValue_t checkSample(T sample, T *crossedLimit) {
*crossedLimit = limit;
if (aboveIsViolation) {
if ((std::abs(sample) > limit)) {
@ -32,9 +32,9 @@ class AbsLimitMonitor : public MonitorBase<T> {
return returnvalue::OK; // We're not out of range.
}
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
uint16_t startAtIndex) override {
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) {
ReturnValue_t result = this->MonitorBase<T>::getParameter(
domainId, parameterId, parameterWrapper, newValues, startAtIndex);
// We'll reuse the DOMAIN_ID of MonitorReporter,
@ -61,7 +61,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
void setLimit(T value) { limit = value; }
protected:
void sendTransitionEvent(T currentValue, ReturnValue_t state) override {
void sendTransitionEvent(T currentValue, ReturnValue_t state) {
switch (state) {
case MonitoringIF::OUT_OF_RANGE:
EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->globalPoolId.objectId,

View File

@ -18,7 +18,10 @@ elseif(FSFW_OSAL MATCHES "host")
endif()
set(FSFW_OSAL_HOST 1)
else()
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
message(
WARNING
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
# Not set. Assumuing this is a host build, try to determine host OS
if(WIN32)
add_subdirectory(host)

View File

@ -24,11 +24,8 @@
#else
#ifdef WIN32
// Thanks, windows
// clang-format off
#include <winsock2.h>
#include <windows.h>
// clang-format on
#include <winsock2.h>
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
#define BYTE_ORDER_SYSTEM LITTLE_ENDIAN
#else

View File

@ -16,7 +16,7 @@
#ifdef PLATFORM_WIN
#include <winsock2.h>
typedef SSIZE_T ssize_t;
#include <ws2tcpip.h>
#elif defined(PLATFORM_UNIX)
#include <netdb.h>
@ -26,12 +26,12 @@ typedef SSIZE_T ssize_t;
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
size_t receptionBufferSize, size_t ringBufferSize,
std::string customTcpServerPort, ReceptionModes receptionMode)
TcpTmTcServer::TcpConfig cfg, size_t receptionBufferSize,
size_t ringBufferSize, ReceptionModes receptionMode)
: SystemObject(objectId),
tmtcBridgeId(tmtcTcpBridge),
receptionMode(receptionMode),
tcpConfig(std::move(customTcpServerPort)),
tcpConfig(cfg),
receptionBuffer(receptionBufferSize),
ringBuffer(ringBufferSize, true) {}
@ -91,6 +91,15 @@ ReturnValue_t TcpTmTcServer::initialize() {
return returnvalue::FAILED;
}
if (tcpConfig.reuseAddr) {
unsigned int enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
}
if (tcpConfig.reusePort) {
unsigned int enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
}
// Bind to the address found by getaddrinfo
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
if (retval == SOCKET_ERROR) {

View File

@ -41,11 +41,11 @@ class SpacePacketParser;
*/
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
public:
enum class ReceptionModes { SPACE_PACKETS };
struct TcpConfig {
public:
explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {}
TcpConfig(bool reuseAddr, bool reusePort) : reuseAddr(reuseAddr), reusePort(reusePort) {}
TcpConfig(std::string tcpPort, bool reuseAddr, bool reusePort)
: tcpPort(std::move(tcpPort)), reuseAddr(reuseAddr), reusePort(reusePort) {}
/**
* Passed to the recv call
@ -63,8 +63,23 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
*/
int tcpTmFlags = 0;
const std::string tcpPort;
std::string tcpPort = DEFAULT_SERVER_PORT;
/**
* Sets the SO_REUSEADDR option on the socket. See
* https://man7.org/linux/man-pages/man7/socket.7.html for more details. This option is
* especially useful in a debugging and development environment where an OBSW image might be
* re-flashed oftentimes and where all incoming telecommands are received on a dedicated TCP
* port.
*/
bool reuseAddr = false;
/**
* Sets the SO_REUSEPORT option on the socket. See
* https://man7.org/linux/man-pages/man7/socket.7.html for more details.
*/
bool reusePort = false;
};
enum class ReceptionModes { SPACE_PACKETS };
static const std::string DEFAULT_SERVER_PORT;
@ -80,10 +95,9 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
* size will be the Ethernet MTU size
* @param customTcpServerPort The user can specify another port than the default (7301) here.
*/
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpConfig cfg,
size_t receptionBufferSize = RING_BUFFER_SIZE,
size_t ringBufferSize = RING_BUFFER_SIZE,
std::string customTcpServerPort = DEFAULT_SERVER_PORT,
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
~TcpTmTcServer() override;
@ -116,7 +130,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
ReceptionModes receptionMode;
TcpConfig tcpConfig;
// struct sockaddr tcpAddress = {};
struct sockaddr tcpAddress = {};
socket_t listenerTcpSocket = 0;
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;

View File

@ -8,7 +8,6 @@
#ifdef PLATFORM_WIN
#include <winsock2.h>
typedef SSIZE_T ssize_t;
#elif defined(PLATFORM_UNIX)
#include <sys/socket.h>
#include <sys/types.h>

View File

@ -7,7 +7,6 @@
#ifdef PLATFORM_WIN
#include <ws2tcpip.h>
typedef SSIZE_T ssize_t;
#elif defined(PLATFORM_UNIX)
#include <arpa/inet.h>
#include <netdb.h>

View File

@ -40,7 +40,7 @@ class BinarySemaphoreUsingTask : public SemaphoreIF {
void refreshTaskHandle();
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
uint32_t timeoutMs = 0) override;
uint32_t timeoutMs = portMAX_DELAY) override;
ReturnValue_t release() override;
uint8_t getSemaphoreCounter() const override;
static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle);

View File

@ -51,7 +51,7 @@ class BinarySemaphore : public SemaphoreIF {
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
uint32_t timeoutMs = 0) override;
uint32_t timeoutMs = portMAX_DELAY) override;
/**
* Same as lockBinarySemaphore() with timeout in FreeRTOS ticks.

View File

@ -11,6 +11,19 @@
// TODO sanitize input?
// TODO much of this code can be reused for tick-only systems
uint32_t Clock::getTicksPerSecond(void) { return 1000; }
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
timeval time_timeval;
ReturnValue_t result = convertTimeOfDayToTimeval(time, &time_timeval);
if (result != returnvalue::OK) {
return result;
}
return setClock(&time_timeval);
}
ReturnValue_t Clock::setClock(const timeval* time) {
timeval uptime = getUptime();
@ -31,12 +44,81 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
return returnvalue::OK;
}
ReturnValue_t Clock::getUptime(timeval* uptime) {
*uptime = getUptime();
return returnvalue::OK;
}
timeval Clock::getUptime() {
TickType_t ticksSinceStart = xTaskGetTickCount();
return Timekeeper::ticksToTimeval(ticksSinceStart);
}
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
timeval uptime = getUptime();
*uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000;
return returnvalue::OK;
}
// uint32_t Clock::getUptimeSeconds() {
// timeval uptime = getUptime();
// return uptime.tv_sec;
// }
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
timeval time_timeval;
ReturnValue_t result = getClock_timeval(&time_timeval);
if (result != returnvalue::OK) {
return result;
}
*time = time_timeval.tv_sec * 1000000 + time_timeval.tv_usec;
return returnvalue::OK;
}
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
timeval time_timeval;
ReturnValue_t result = getClock_timeval(&time_timeval);
if (result != returnvalue::OK) {
return result;
}
struct tm time_tm;
gmtime_r(&time_timeval.tv_sec, &time_tm);
time->year = time_tm.tm_year + 1900;
time->month = time_tm.tm_mon + 1;
time->day = time_tm.tm_mday;
time->hour = time_tm.tm_hour;
time->minute = time_tm.tm_min;
time->second = time_tm.tm_sec;
time->usecond = time_timeval.tv_usec;
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
struct tm time_tm = {};
time_tm.tm_year = from->year - 1900;
time_tm.tm_mon = from->month - 1;
time_tm.tm_mday = from->day;
time_tm.tm_hour = from->hour;
time_tm.tm_min = from->minute;
time_tm.tm_sec = from->second;
time_t seconds = mktime(&time_tm);
to->tv_sec = seconds;
to->tv_usec = from->usecond;
// Fails in 2038..
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
return returnvalue::OK;
}

View File

@ -34,7 +34,7 @@ class CountingSemaphoreUsingTask : public SemaphoreIF {
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
uint32_t timeoutMs = 0) override;
uint32_t timeoutMs = portMAX_DELAY) override;
/**
* Release a semaphore, increasing the number of available counting

View File

@ -56,9 +56,7 @@ ReturnValue_t FixedTimeslotTask::startTask() {
// start time for the first entry.
auto slotListIter = pollingSeqTable.current;
ReturnValue_t result = pollingSeqTable.intializeSequenceAfterTaskCreation();
// Ignore returnvalue for now
static_cast<void>(result);
pollingSeqTable.intializeSequenceAfterTaskCreation();
// The start time for the first entry is read.
uint32_t intervalMs = slotListIter->pollingTimeMs;

View File

@ -22,7 +22,7 @@ ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
return MutexIF::MUTEX_NOT_FOUND;
}
// If the timeout type is BLOCKING, this will be the correct value.
TickType_t timeout = portMAX_DELAY;
uint32_t timeout = portMAX_DELAY;
if (timeoutType == TimeoutType::POLLING) {
timeout = 0;
} else if (timeoutType == TimeoutType::WAITING) {

View File

@ -3,16 +3,16 @@
void TaskManagement::vRequestContextSwitchFromTask() { vTaskDelay(0); }
void TaskManagement::requestContextSwitch(CallContext callContext = CallContext::TASK) {
// if (callContext == CallContext::ISR) {
// // This function depends on the partmacro.h definition for the specific device
// vRequestContextSwitchFromISR();
// } else {
vRequestContextSwitchFromTask();
// }
if (callContext == CallContext::ISR) {
// This function depends on the partmacro.h definition for the specific device
vRequestContextSwitchFromISR();
} else {
vRequestContextSwitchFromTask();
}
}
TaskHandle_t TaskManagement::getCurrentTaskHandle() { return xTaskGetCurrentTaskHandle(); }
// size_t TaskManagement::getTaskStackHighWatermark(TaskHandle_t task) {
// return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
// }
size_t TaskManagement::getTaskStackHighWatermark(TaskHandle_t task) {
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
}

View File

@ -11,7 +11,7 @@
* Architecture dependant portmacro.h function call.
* Should be implemented in bsp.
*/
// extern "C" void vRequestContextSwitchFromISR();
extern "C" void vRequestContextSwitchFromISR();
/*!
* Used by functions to tell if they are being called from
@ -53,7 +53,7 @@ TaskHandle_t getCurrentTaskHandle();
* @return Smallest value of stack remaining since the task was started in
* words.
*/
// size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
}; // namespace TaskManagement

View File

@ -15,6 +15,27 @@
using SystemClock = std::chrono::system_clock;
uint32_t Clock::getTicksPerSecond(void) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Clock::getTicksPerSecond: Not implemented for host OSAL" << std::endl;
#else
sif::printWarning("Clock::getTicksPerSecond: Not implemented for host OSAL\n");
#endif
/* To avoid division by zero */
return 1;
}
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
/* I don't know why someone would need to set a clock which is probably perfectly fine on a
host system with internet access so this is not implemented for now. */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Clock::setClock: Not implemented for host OSAL" << std::endl;
#else
sif::printWarning("Clock::setClock: Not implemented for host OSAL\n");
#endif
return returnvalue::OK;
}
ReturnValue_t Clock::setClock(const timeval* time) {
/* I don't know why someone would need to set a clock which is probably perfectly fine on a
host system with internet access so this is not implemented for now. */
@ -45,7 +66,6 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
time->tv_usec = timeUnix.tv_nsec / 1000.0;
return returnvalue::OK;
#else
#warning Clock::getClock_timeval() not implemented for your platform
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Clock::getUptime: Not implemented for found OS!" << std::endl;
#else
@ -55,6 +75,15 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
#endif
}
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
if (time == nullptr) {
return returnvalue::FAILED;
}
using namespace std::chrono;
*time = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
return returnvalue::OK;
}
timeval Clock::getUptime() {
timeval timeval;
#if defined(PLATFORM_WIN)
@ -71,10 +100,73 @@ timeval Clock::getUptime() {
timeval.tv_usec = uptimeSeconds * (double)1e6 - (timeval.tv_sec * 1e6);
}
#else
#warning Clock::getUptime() not implemented for your platform
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
#endif
#endif
return timeval;
}
ReturnValue_t Clock::getUptime(timeval* uptime) {
*uptime = getUptime();
return returnvalue::OK;
}
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
timeval uptime = getUptime();
*uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000;
return returnvalue::OK;
}
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
/* Do some magic with chrono (C++20!) */
/* Right now, the library doesn't have the new features to get the required values yet.
so we work around that for now. */
auto now = SystemClock::now();
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
auto fraction = now - seconds;
time_t tt = SystemClock::to_time_t(now);
ReturnValue_t result = checkOrCreateClockMutex();
if (result != returnvalue::OK) {
return result;
}
MutexGuard helper(timeMutex);
// gmtime writes its output in a global buffer which is not Thread Safe
// Therefore we have to use a Mutex here
struct tm* timeInfo;
timeInfo = gmtime(&tt);
time->year = timeInfo->tm_year + 1900;
time->month = timeInfo->tm_mon + 1;
time->day = timeInfo->tm_mday;
time->hour = timeInfo->tm_hour;
time->minute = timeInfo->tm_min;
time->second = timeInfo->tm_sec;
auto usecond = std::chrono::duration_cast<std::chrono::microseconds>(fraction);
time->usecond = usecond.count();
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
struct tm time_tm {};
time_tm.tm_year = from->year - 1900;
time_tm.tm_mon = from->month - 1;
time_tm.tm_mday = from->day;
time_tm.tm_hour = from->hour;
time_tm.tm_min = from->minute;
time_tm.tm_sec = from->second;
time_tm.tm_isdst = 0;
time_t seconds = timegm(&time_tm);
to->tv_sec = seconds;
to->tv_usec = from->usecond;
// Fails in 2038..
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
return returnvalue::OK;
}

View File

@ -9,6 +9,7 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
#if defined(PLATFORM_WIN)
#include <processthreadsapi.h>
#include "fsfw/osal/windows/winTaskHelpers.h"
#elif defined(PLATFORM_UNIX)

View File

@ -50,6 +50,6 @@ void TaskFactory::printMissedDeadline() {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl;
#else
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name.c_str());
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
}

View File

@ -3,7 +3,6 @@
#include <fsfw/returnvalues/returnvalue.h>
#include <string>
#include <thread>
namespace tasks {

View File

@ -10,6 +10,26 @@
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
uint32_t Clock::getTicksPerSecond() {
uint32_t ticks = sysconf(_SC_CLK_TCK);
return ticks;
}
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
timespec timeUnix{};
timeval timeTimeval{};
convertTimeOfDayToTimeval(time, &timeTimeval);
timeUnix.tv_sec = timeTimeval.tv_sec;
timeUnix.tv_nsec = (__syscall_slong_t)timeTimeval.tv_usec * 1000;
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
if (status != 0) {
// TODO errno
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t Clock::setClock(const timeval* time) {
timespec timeUnix{};
timeUnix.tv_sec = time->tv_sec;
@ -33,12 +53,104 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
return returnvalue::OK;
}
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
timeval timeVal{};
ReturnValue_t result = getClock_timeval(&timeVal);
if (result != returnvalue::OK) {
return result;
}
*time = static_cast<uint64_t>(timeVal.tv_sec) * 1e6 + timeVal.tv_usec;
return returnvalue::OK;
}
timeval Clock::getUptime() {
timeval uptime{0, 0};
double uptimeSeconds;
if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) {
uptime.tv_sec = uptimeSeconds;
uptime.tv_usec = uptimeSeconds * (double)1e6 - (uptime.tv_sec * 1e6);
timeval uptime{};
auto result = getUptime(&uptime);
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Clock::getUptime: Error getting uptime" << std::endl;
#endif
}
return uptime;
}
}
ReturnValue_t Clock::getUptime(timeval* uptime) {
// TODO This is not posix compatible and delivers only seconds precision
// Linux specific file read but more precise.
double uptimeSeconds;
if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) {
uptime->tv_sec = uptimeSeconds;
uptime->tv_usec = uptimeSeconds * (double)1e6 - (uptime->tv_sec * 1e6);
}
return returnvalue::OK;
}
// Wait for new FSFW Clock function delivering seconds uptime.
// uint32_t Clock::getUptimeSeconds() {
// //TODO This is not posix compatible and delivers only seconds precision
// struct sysinfo sysInfo;
// int result = sysinfo(&sysInfo);
// if(result != 0){
// return returnvalue::FAILED;
// }
// return sysInfo.uptime;
//}
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
timeval uptime{};
ReturnValue_t result = getUptime(&uptime);
if (result != returnvalue::OK) {
return result;
}
*uptimeMs = uptime.tv_sec * 1e3 + uptime.tv_usec / 1e3;
return returnvalue::OK;
}
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
timespec timeUnix{};
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
if (status != 0) {
// TODO errno
return returnvalue::FAILED;
}
ReturnValue_t result = checkOrCreateClockMutex();
if (result != returnvalue::OK) {
return result;
}
MutexGuard helper(timeMutex);
// gmtime writes its output in a global buffer which is not Thread Safe
// Therefore we have to use a Mutex here
struct std::tm* timeInfo;
timeInfo = gmtime(&timeUnix.tv_sec);
time->year = timeInfo->tm_year + 1900;
time->month = timeInfo->tm_mon + 1;
time->day = timeInfo->tm_mday;
time->hour = timeInfo->tm_hour;
time->minute = timeInfo->tm_min;
time->second = timeInfo->tm_sec;
time->usecond = timeUnix.tv_nsec / 1000.0;
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
std::tm fromTm{};
// Note: Fails for years before AD
fromTm.tm_year = from->year - 1900;
fromTm.tm_mon = from->month - 1;
fromTm.tm_mday = from->day;
fromTm.tm_hour = from->hour;
fromTm.tm_min = from->minute;
fromTm.tm_sec = from->second;
fromTm.tm_isdst = 0;
to->tv_sec = timegm(&fromTm);
to->tv_usec = from->usecond;
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
return returnvalue::OK;
}

View File

@ -2,8 +2,6 @@
#include <rtems/rtems/sem.h>
// TODO
BinarySemaphore::BinarySemaphore() {}
BinarySemaphore::~BinarySemaphore() {}

View File

@ -6,21 +6,20 @@
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/osal/rtems/RtemsBasic.h"
ReturnValue_t Clock::setClock(const timeval* time) {
TimeOfDay_t time_tod;
ReturnValue_t result = convertTimevalToTimeOfDay(time, &time_tod);
if (result != returnvalue::OK) {
return result;
}
uint32_t Clock::getTicksPerSecond(void) {
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
return static_cast<uint32_t>(ticks_per_second);
}
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
rtems_time_of_day timeRtems;
timeRtems.year = time_tod.year;
timeRtems.month = time_tod.month;
timeRtems.day = time_tod.day;
timeRtems.hour = time_tod.hour;
timeRtems.minute = time_tod.minute;
timeRtems.second = time_tod.second;
timeRtems.ticks =
static_cast<uint64_t>(time_tod.usecond) * rtems_clock_get_ticks_per_second() / 1e6;
timeRtems.year = time->year;
timeRtems.month = time->month;
timeRtems.day = time->day;
timeRtems.hour = time->hour;
timeRtems.minute = time->minute;
timeRtems.second = time->second;
timeRtems.ticks = time->usecond * getTicksPerSecond() / 1e6;
rtems_status_code status = rtems_clock_set(&timeRtems);
switch (status) {
case RTEMS_SUCCESSFUL:
@ -34,6 +33,27 @@ ReturnValue_t Clock::setClock(const timeval* time) {
}
}
ReturnValue_t Clock::setClock(const timeval* time) {
timespec newTime;
newTime.tv_sec = time->tv_sec;
if (time->tv_usec < 0) {
// better returnvalue.
return returnvalue::FAILED;
}
newTime.tv_nsec = time->tv_usec * TOD_NANOSECONDS_PER_MICROSECOND;
ISR_lock_Context context;
_TOD_Lock();
_TOD_Acquire(&context);
Status_Control status = _TOD_Set(&newTime, &context);
_TOD_Unlock();
if (status == STATUS_SUCCESSFUL) {
return returnvalue::OK;
}
// better returnvalue
return returnvalue::FAILED;
}
ReturnValue_t Clock::getClock_timeval(timeval* time) {
// Callable from ISR
rtems_status_code status = rtems_clock_get_tod_timeval(time);
@ -47,13 +67,86 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
}
}
timeval Clock::getUptime() {
ReturnValue_t Clock::getUptime(timeval* uptime) {
// According to docs.rtems.org for rtems 5 this method is more accurate than
// rtems_clock_get_ticks_since_boot
timeval time_timeval;
timespec time;
rtems_status_code status = rtems_clock_get_uptime(&time);
time_timeval.tv_sec = time.tv_sec;
time_timeval.tv_usec = time.tv_nsec / 1000;
return time_timeval;
}
uptime->tv_sec = time.tv_sec;
time.tv_nsec = time.tv_nsec / 1000;
uptime->tv_usec = time.tv_nsec;
switch (status) {
case RTEMS_SUCCESSFUL:
return returnvalue::OK;
default:
return returnvalue::FAILED;
}
}
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
// This counter overflows after 50 days
*uptimeMs = rtems_clock_get_ticks_since_boot();
return returnvalue::OK;
}
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
timeval temp_time;
rtems_status_code returnValue = rtems_clock_get_tod_timeval(&temp_time);
*time = ((uint64_t)temp_time.tv_sec * 1000000) + temp_time.tv_usec;
switch (returnValue) {
case RTEMS_SUCCESSFUL:
return returnvalue::OK;
default:
return returnvalue::FAILED;
}
}
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
/* For all but the last field, the struct will be filled with the correct values */
rtems_time_of_day timeRtems;
rtems_status_code status = rtems_clock_get_tod(&timeRtems);
switch (status) {
case RTEMS_SUCCESSFUL: {
/* The last field now contains the RTEMS ticks of the seconds from 0
to rtems_clock_get_ticks_per_second() minus one.
We calculate the microseconds accordingly */
time->day = timeRtems.day;
time->hour = timeRtems.hour;
time->minute = timeRtems.minute;
time->month = timeRtems.month;
time->second = timeRtems.second;
time->usecond =
static_cast<float>(timeRtems.ticks) / rtems_clock_get_ticks_per_second() * 1e6;
time->year = timeRtems.year;
return returnvalue::OK;
}
case RTEMS_NOT_DEFINED:
/* System date and time is not set */
return returnvalue::FAILED;
case RTEMS_INVALID_ADDRESS:
/* time_buffer is NULL */
return returnvalue::FAILED;
default:
return returnvalue::FAILED;
}
}
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
// Fails in 2038..
rtems_time_of_day timeRtems;
timeRtems.year = from->year;
timeRtems.month = from->month;
timeRtems.day = from->day;
timeRtems.hour = from->hour;
timeRtems.minute = from->minute;
timeRtems.second = from->second;
timeRtems.ticks = from->usecond * getTicksPerSecond() / 1e6;
to->tv_sec = _TOD_To_seconds(&timeRtems);
to->tv_usec = from->usecond;
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
return returnvalue::OK;
}

View File

@ -93,8 +93,8 @@ ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size, size_t maxSize
streamEndianness);
}
size_t CpuUsage::getSerializedSize() const {
size_t size = 0;
uint32_t CpuUsage::getSerializedSize() const {
uint32_t size = 0;
size += sizeof(timeSinceLastReset);
size += SerialArrayListAdapter<ThreadData>::getSerializedSize(&threadData);
@ -136,8 +136,8 @@ ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, size_t* size, si
return returnvalue::OK;
}
size_t CpuUsage::ThreadData::getSerializedSize() const {
size_t size = 0;
uint32_t CpuUsage::ThreadData::getSerializedSize() const {
uint32_t size = 0;
size += sizeof(id);
size += MAX_LENGTH_OF_THREAD_NAME;

View File

@ -35,19 +35,20 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
return OUT_OF_PROXIES;
case INTERNAL_ERROR_INVALID_GLOBAL_ID:
return INVALID_GLOBAL_ID;
// TODO this one is not there anymore in rtems-6 (5 as well?)
// case INTERNAL_ERROR_BAD_STACK_HOOK:
// return BAD_STACK_HOOK;
// case INTERNAL_ERROR_BAD_ATTRIBUTES:
// return BAD_ATTRIBUTES;
// case INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY:
// return IMPLEMENTATION_KEY_CREATE_INCONSISTENCY;
// case INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL:
// return IMPLEMENTATION_BLOCKING_OPERATION_CANCEL;
// case INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE:
// return MUTEX_OBTAIN_FROM_BAD_STATE;
// case INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0:
// return UNLIMITED_AND_MAXIMUM_IS_0;
#ifndef STM32H743ZI_NUCLEO
case INTERNAL_ERROR_BAD_STACK_HOOK:
return BAD_STACK_HOOK;
#endif
// case INTERNAL_ERROR_BAD_ATTRIBUTES:
// return BAD_ATTRIBUTES;
// case INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY:
// return IMPLEMENTATION_KEY_CREATE_INCONSISTENCY;
// case INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL:
// return IMPLEMENTATION_BLOCKING_OPERATION_CANCEL;
// case INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE:
// return MUTEX_OBTAIN_FROM_BAD_STATE;
// case INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0:
// return UNLIMITED_AND_MAXIMUM_IS_0;
default:
return returnvalue::FAILED;
}

View File

@ -18,9 +18,7 @@ SemaphoreFactory* SemaphoreFactory::instance() {
}
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) {
return nullptr;
// TODO
// return new BinarySemaphore();
return new BinarySemaphore();
}
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount, uint8_t initCount,

View File

@ -5,11 +5,7 @@
#ifdef _WIN32
// Thanks, windows
// clang-format off
#include <windows.h>
#include <processthreadsapi.h>
// clang-format on
#include <minwindef.h>
namespace tasks {

View File

@ -45,7 +45,6 @@ class ParameterWrapper : public SerializeIF {
virtual size_t getSerializedSize() const override;
using SerializeIF::deSerialize;
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;

View File

@ -62,13 +62,13 @@ class Fuse : public SystemObject,
SerializeIF::Endianness streamEndianness) override;
void setAllMonitorsToUnchecked();
ReturnValue_t performOperation(uint8_t opCode);
MessageQueueId_t getCommandQueue() const override;
MessageQueueId_t getCommandQueue() const;
void setDataPoolEntriesInvalid();
ReturnValue_t setHealth(HealthState health) override;
HasHealthIF::HealthState getHealth() override;
ReturnValue_t setHealth(HealthState health);
HasHealthIF::HealthState getHealth();
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
const ParameterWrapper *newValues, uint16_t startAtIndex);
private:
uint8_t oldFuseState;

View File

@ -10,15 +10,15 @@ class PowerComponent : public PowerComponentIF {
PowerComponent(object_id_t setId, uint8_t moduleId, float minPower, float maxPower,
uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF);
object_id_t getDeviceObjectId() override;
virtual object_id_t getDeviceObjectId();
uint8_t getSwitchId1() override;
uint8_t getSwitchId2() override;
virtual uint8_t getSwitchId1();
virtual uint8_t getSwitchId2();
bool hasTwoSwitches() override;
bool hasTwoSwitches();
float getMin() override;
float getMax() override;
float getMin();
float getMax();
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
@ -29,7 +29,7 @@ class PowerComponent : public PowerComponentIF {
Endianness streamEndianness) override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
const ParameterWrapper* newValues, uint16_t startAtIndex);
private:
const object_id_t deviceObjectId = objects::NO_OBJECT;

View File

@ -9,4 +9,4 @@ target_sources(
Service17Test.cpp
Service20ParameterManagement.cpp
CService200ModeCommanding.cpp
CService201HealthCommanding.cpp)
CServiceHealthCommanding.cpp)

View File

@ -19,7 +19,8 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_MODE_COMMAND):
case (Subservice::COMMAND_MODE_READ):
case (Subservice::COMMAND_MODE_ANNCOUNCE):
case (Subservice::COMMAND_MODE_ANNOUNCE):
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
return returnvalue::OK;
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
@ -53,16 +54,32 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) {
ModePacket modeCommandPacket;
ReturnValue_t result =
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
bool recursive = false;
switch (subservice) {
case (Subservice::COMMAND_MODE_COMMAND): {
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());
return result;
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND,
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
return returnvalue::OK;
}
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
recursive = true;
[[fallthrough]];
case (Subservice::COMMAND_MODE_ANNOUNCE):
ModeMessage::setModeAnnounceMessage(*message, recursive);
return EXECUTION_COMPLETE;
case (Subservice::COMMAND_MODE_READ):
ModeMessage::setModeReadMessage(*message);
return returnvalue::OK;
default:
return CommandingServiceBase::INVALID_SUBSERVICE;
}
}
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
@ -73,8 +90,10 @@ ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply
ReturnValue_t result = returnvalue::FAILED;
switch (replyId) {
case (ModeMessage::REPLY_MODE_REPLY): {
result = prepareModeReply(reply, objectId);
break;
if (previousCommand != ModeMessage::CMD_MODE_COMMAND) {
return prepareModeReply(reply, objectId);
}
return returnvalue::OK;
}
case (ModeMessage::REPLY_WRONG_MODE_REPLY): {
result = prepareWrongModeReply(reply, objectId);

View File

@ -52,7 +52,7 @@ class CService200ModeCommanding : public CommandingServiceBase {
COMMAND_MODE_READ = 3,
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
//! This command does NOT have a reply
COMMAND_MODE_ANNCOUNCE = 4,
COMMAND_MODE_ANNOUNCE = 4,
//!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this
//! command to every child. This command does NOT have a reply.
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,

View File

@ -1,106 +0,0 @@
#include "fsfw/pus/CService201HealthCommanding.h"
#include "fsfw/health/HasHealthIF.h"
#include "fsfw/health/HealthMessage.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/pus/servicepackets/Service201Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, uint16_t apid,
uint8_t serviceId,
uint8_t numParallelCommands,
uint16_t commandTimeoutSeconds)
: CommandingServiceBase(objectId, apid, "PUS 201 Health MGMT", serviceId, numParallelCommands,
commandTimeoutSeconds) {}
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL):
return returnvalue::OK;
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Invalid Subservice" << std::endl;
#endif
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData,
size_t tcDataLen,
MessageQueueId_t *id,
object_id_t *objectId) {
if (tcDataLen < sizeof(object_id_t)) {
return CommandingServiceBase::INVALID_TC;
}
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
return checkInterfaceAndAcquireMessageQueue(id, objectId);
}
ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if (destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}
*messageQueueToSet = destination->getCommandQueue();
return returnvalue::OK;
}
ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *message,
uint8_t subservice, const uint8_t *tcData,
size_t tcDataLen, uint32_t *state,
object_id_t objectId) {
ReturnValue_t result = returnvalue::OK;
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH): {
HealthSetCommand healthCommand;
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
break;
}
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET,
healthCommand.getHealth());
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE_ALL);
break;
}
default: {
// Should never happen, subservice was already checked
result = returnvalue::FAILED;
}
}
return result;
}
ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *reply,
Command_t previousCommand, uint32_t *state,
CommandMessage *optionalNextCommand,
object_id_t objectId, bool *isStep) {
Command_t replyId = reply->getCommand();
if (replyId == HealthMessage::REPLY_HEALTH_SET) {
return EXECUTION_COMPLETE;
} else if (replyId == CommandMessageIF::REPLY_REJECTED) {
return reply->getReplyRejectedReason();
}
return CommandingServiceBase::INVALID_REPLY;
}
// Not used for now, health state already reported by event
[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(
const CommandMessage *reply) {
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
HealthSetReply healthSetReply(health, oldHealth);
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
}

View File

@ -0,0 +1,158 @@
#include <fsfw/events/EventManagerIF.h>
#include <fsfw/pus/CServiceHealthCommanding.h>
#include "fsfw/health/HasHealthIF.h"
#include "fsfw/health/HealthMessage.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/pus/servicepackets/Service201Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
CServiceHealthCommanding::CServiceHealthCommanding(HealthServiceCfg args)
: CommandingServiceBase(args.objectId, args.apid, "PUS 201 Health MGMT", args.service,
args.numParallelCommands, args.commandTimeoutSeconds),
healthTableId(args.table),
maxNumHealthInfoPerCycle(args.maxNumHealthInfoPerCycle) {}
ReturnValue_t CServiceHealthCommanding::initialize() {
ReturnValue_t result = CommandingServiceBase::initialize();
if (result != returnvalue::OK) {
return result;
}
healthTable = ObjectManager::instance()->get<HealthTable>(healthTableId);
if (healthTable == nullptr) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t CServiceHealthCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL):
return returnvalue::OK;
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Invalid Subservice" << std::endl;
#endif
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
ReturnValue_t CServiceHealthCommanding::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData,
size_t tcDataLen,
MessageQueueId_t *id,
object_id_t *objectId) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
if (tcDataLen < sizeof(object_id_t)) {
return CommandingServiceBase::INVALID_TC;
}
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
return checkInterfaceAndAcquireMessageQueue(id, objectId);
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
return returnvalue::OK;
}
default: {
return returnvalue::FAILED;
}
}
}
ReturnValue_t CServiceHealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if (destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}
*messageQueueToSet = destination->getCommandQueue();
return returnvalue::OK;
}
ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) {
ReturnValue_t result = returnvalue::OK;
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH): {
HealthSetCommand healthCommand;
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
break;
}
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET,
healthCommand.getHealth());
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
ReturnValue_t result = iterateHealthTable(true);
if (result == returnvalue::OK) {
reportAllHealth = true;
return EXECUTION_COMPLETE;
}
return result;
}
default: {
// Should never happen, subservice was already checked
result = returnvalue::FAILED;
}
}
return result;
}
ReturnValue_t CServiceHealthCommanding::handleReply(const CommandMessage *reply,
Command_t previousCommand, uint32_t *state,
CommandMessage *optionalNextCommand,
object_id_t objectId, bool *isStep) {
Command_t replyId = reply->getCommand();
if (replyId == HealthMessage::REPLY_HEALTH_SET) {
return EXECUTION_COMPLETE;
} else if (replyId == CommandMessageIF::REPLY_REJECTED) {
return reply->getReplyRejectedReason();
}
return CommandingServiceBase::INVALID_REPLY;
}
void CServiceHealthCommanding::doPeriodicOperation() {
if (reportAllHealth) {
for (uint8_t i = 0; i < maxNumHealthInfoPerCycle; i++) {
ReturnValue_t result = iterateHealthTable(false);
if (result != returnvalue::OK) {
reportAllHealth = false;
break;
}
}
}
}
// Not used for now, health state already reported by event
[[maybe_unused]] ReturnValue_t CServiceHealthCommanding::prepareHealthSetReply(
const CommandMessage *reply) {
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
HealthSetReply healthSetReply(health, oldHealth);
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
}
ReturnValue_t CServiceHealthCommanding::iterateHealthTable(bool reset) {
std::pair<object_id_t, HasHealthIF::HealthState> pair;
ReturnValue_t result = healthTable->iterate(&pair, reset);
if (result != returnvalue::OK) {
return result;
} else {
EventManagerIF::triggerEvent(pair.first, HasHealthIF::HEALTH_INFO, pair.second, pair.second);
return returnvalue::OK;
}
}

View File

@ -1,8 +1,26 @@
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
#include <fsfw/health/HealthTable.h>
#include "fsfw/tmtcservices/CommandingServiceBase.h"
struct HealthServiceCfg {
HealthServiceCfg(object_id_t objectId, uint16_t apid, object_id_t healthTable,
uint16_t maxNumHealthInfoPerCycle)
: objectId(objectId),
apid(apid),
table(healthTable),
maxNumHealthInfoPerCycle(maxNumHealthInfoPerCycle) {}
object_id_t objectId;
uint16_t apid;
object_id_t table;
uint16_t maxNumHealthInfoPerCycle;
uint8_t service = 201;
uint8_t numParallelCommands = 4;
uint16_t commandTimeoutSeconds = 60;
};
/**
* @brief Custom PUS service to set health of all objects
* implementing hasHealthIF.
@ -17,11 +35,12 @@
* child class like this service
*
*/
class CService201HealthCommanding : public CommandingServiceBase {
class CServiceHealthCommanding : public CommandingServiceBase {
public:
CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId,
uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
~CService201HealthCommanding() override = default;
CServiceHealthCommanding(HealthServiceCfg args);
~CServiceHealthCommanding() override = default;
ReturnValue_t initialize() override;
protected:
/* CSB abstract function implementations */
@ -37,7 +56,14 @@ class CService201HealthCommanding : public CommandingServiceBase {
CommandMessage *optionalNextCommand, object_id_t objectId,
bool *isStep) override;
void doPeriodicOperation() override;
private:
const object_id_t healthTableId;
HealthTable *healthTable;
uint16_t maxNumHealthInfoPerCycle = 0;
bool reportAllHealth = false;
ReturnValue_t iterateHealthTable(bool reset);
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
const object_id_t *objectId);

View File

@ -13,7 +13,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
uint16_t messageQueueDepth,
TimeWriterIF* timeStamper)
: SystemObject(objectId),
// apid(apid),
apid(apid),
serviceId(serviceId),
targetDestination(targetDestination),
storeHelper(apid),

View File

@ -72,7 +72,7 @@ class Service1TelecommandVerification : public AcceptsVerifyMessageIF,
ReturnValue_t initialize() override;
private:
// uint16_t apid = 0;
uint16_t apid = 0;
uint8_t serviceId = 0;
object_id_t targetDestination = objects::NO_OBJECT;

View File

@ -69,14 +69,14 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
<< "MessageQueue: Can't access object" << std::endl;
sif::error << "Object ID: " << std::hex << objectId << std::dec << std::endl;
sif::error << "Make sure it implements ReceivesParameterMessagesIF!" << std::endl;
sif::error << "Object ID: 0x" << std::hex << *objectId << std::dec << std::endl;
sif::error << "Make sure it implements ReceivesParameterMessagesIF" << std::endl;
#else
sif::printError(
"Service20ParameterManagement::checkInterfaceAndAcquire"
"MessageQueue: Can't access object\n");
sif::printError("Object ID: 0x%08x\n", *objectId);
sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n");
sif::printError("Make sure it implements ReceivesParameterMessagesIF\n");
#endif
return CommandingServiceBase::INVALID_OBJECT;

View File

@ -1,5 +1,7 @@
#include "fsfw/pus/Service9TimeManagement.h"
#include <cmath>
#include "fsfw/events/EventManagerIF.h"
#include "fsfw/pus/servicepackets/Service9Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
@ -15,9 +17,17 @@ ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK;
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
switch (subservice) {
case SUBSERVICE::SET_TIME: {
case Subservice::SET_TIME: {
return setTime();
}
case Subservice::DUMP_TIME: {
timeval newTime;
Clock::getClock_timeval(&newTime);
uint32_t subsecondMs =
static_cast<uint32_t>(std::floor(static_cast<double>(newTime.tv_usec) / 1000.0));
triggerEvent(CLOCK_DUMP, newTime.tv_sec, subsecondMs);
return returnvalue::OK;
}
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
@ -33,13 +43,14 @@ ReturnValue_t Service9TimeManagement::setTime() {
return result;
}
// TODO maybe switch to getClock_usecs to report more meaningful data
uint32_t formerUptime = Clock::getUptime_ms();
timeval time;
Clock::getClock_timeval(&time);
result = Clock::setClock(&timeToSet);
if (result == returnvalue::OK) {
uint32_t newUptime = Clock::getUptime_ms();
triggerEvent(CLOCK_SET, newUptime, formerUptime);
timeval newTime;
Clock::getClock_timeval(&newTime);
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
return returnvalue::OK;
} else {
triggerEvent(CLOCK_SET_FAILURE, result, 0);

View File

@ -6,10 +6,13 @@
class Service9TimeManagement : public PusServiceBase {
public:
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
static constexpr Event CLOCK_SET =
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
static constexpr Event CLOCK_SET_FAILURE =
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
//!< Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
//!< Clock dump event. P1: timeval seconds P2: timeval milliseconds.
static constexpr Event CLOCK_DUMP = MAKE_EVENT(1, severity::INFO);
//!< Clock could not be set. P1: Returncode.
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
@ -30,8 +33,9 @@ class Service9TimeManagement : public PusServiceBase {
virtual ReturnValue_t setTime();
private:
enum SUBSERVICE {
SET_TIME = 128 //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
enum Subservice {
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
DUMP_TIME = 129,
};
};

View File

@ -69,7 +69,7 @@ class FailureReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6
return result;
}
virtual size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const {
size_t size = 0;
size += SerializeAdapter::getSerializedSize(&packetId);
size += sizeof(packetSequenceControl);

View File

@ -33,7 +33,7 @@
* @author baetz
* @ingroup serialize
*/
template <typename T, typename count_t = size_t>
template <typename T, typename count_t = uint8_t>
class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
public:
SerialLinkedListAdapter(typename LinkedElement<T>::Iterator start, bool printCount = false)

View File

@ -109,8 +109,7 @@ ReturnValue_t LocalPool::deleteData(uint8_t* ptr, size_t size, store_address_t*
ReturnValue_t result = ILLEGAL_ADDRESS;
for (uint16_t n = 0; n < NUMBER_OF_SUBPOOLS; n++) {
// Not sure if new allocates all stores in order. so better be careful.
if ((store[n].data() <= ptr) and
(&store[n][numberOfElements[n] * elementSizes[n] - 1] >= ptr)) {
if ((store[n].data() <= ptr) and (&store[n][numberOfElements[n] * elementSizes[n]] > ptr)) {
localId.poolIndex = n;
uint32_t deltaAddress = ptr - store[n].data();
// Getting any data from the right "block" is ok.

View File

@ -91,10 +91,11 @@ void Subsystem::performChildOperation() {
}
if (currentSequenceIterator->getWaitSeconds() != 0) {
if (uptimeStartTable == 0) {
uptimeStartTable = Clock::getUptime_ms();
Clock::getUptime(&uptimeStartTable);
return;
} else {
uint32_t uptimeNow = Clock::getUptime_ms();
uint32_t uptimeNow;
Clock::getUptime(&uptimeNow);
if ((uptimeNow - uptimeStartTable) < (currentSequenceIterator->getWaitSeconds() * 1000)) {
return;
}
@ -585,12 +586,7 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, SerializeIF
return;
}
for (uint8_t i = 0; i < count; i++) {
result = elements[i]->serialize(&storeBuffer, &size, maxSize, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
replyToCommand(result, 0);
IPCStore->deleteData(address);
return;
}
elements[i]->serialize(&storeBuffer, &size, maxSize, SerializeIF::Endianness::BIG);
}
CommandMessage reply;
ModeSequenceMessage::setModeSequenceMessage(&reply, command, address);

View File

@ -9,6 +9,7 @@ class FixedTimeslotTaskBase : public FixedTimeslotTaskIF {
public:
explicit FixedTimeslotTaskBase(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc = nullptr);
~FixedTimeslotTaskBase() override = default;
;
protected:
/**

View File

@ -196,11 +196,12 @@ void Heater::setSwitch(uint8_t number, ReturnValue_t state, uint32_t* uptimeOfSw
if (powerSwitcher->getSwitchState(number) == state) {
*uptimeOfSwitching = INVALID_UPTIME;
} else {
if (*uptimeOfSwitching == INVALID_UPTIME) {
if ((*uptimeOfSwitching == INVALID_UPTIME)) {
powerSwitcher->sendSwitchCommand(number, state);
*uptimeOfSwitching = Clock::getUptime_ms();
Clock::getUptime(uptimeOfSwitching);
} else {
uint32_t currentUptime = Clock::getUptime_ms();
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
if (currentUptime - *uptimeOfSwitching > powerSwitcher->getSwitchDelayMs()) {
*uptimeOfSwitching = INVALID_UPTIME;
if (healthHelper.healthTable->isHealthy(getObjectId())) {

View File

@ -552,7 +552,10 @@ ReturnValue_t CCSDSTime::convertFromCDS(timeval* to, const CCSDSTime::CDS_short*
if (to == nullptr or from == nullptr) {
return returnvalue::FAILED;
}
int32_t days = (from->dayMSB << 8) + from->dayLSB;
uint16_t days = (from->dayMSB << 8) + from->dayLSB;
if (days <= DAYS_CCSDS_TO_UNIX_EPOCH) {
return INVALID_TIME_FORMAT;
}
days -= DAYS_CCSDS_TO_UNIX_EPOCH;
to->tv_sec = days * SECONDS_PER_DAY;
uint32_t msDay =

View File

@ -1,9 +1,4 @@
target_sources(
${LIB_FSFW_NAME}
PRIVATE CCSDSTime.cpp
Countdown.cpp
Stopwatch.cpp
TimeMessage.cpp
CdsShortTimeStamper.cpp
ClockCommon.cpp
boost_timegm.cpp)
PRIVATE CCSDSTime.cpp Countdown.cpp Stopwatch.cpp TimeMessage.cpp
CdsShortTimeStamper.cpp ClockCommon.cpp)

View File

@ -4,6 +4,8 @@
#include "fsfw/timemanager/Clock.h"
CdsShortTimeStamper::CdsShortTimeStamper() : SystemObject(0, false) {}
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,

View File

@ -18,6 +18,7 @@
class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject {
public:
static constexpr size_t TIMESTAMP_LEN = 7;
CdsShortTimeStamper();
/**
* @brief Default constructor which also registers the time stamper as a
* system object so it can be found with the #objectManager.

View File

@ -16,7 +16,6 @@
class Clock {
public:
// https://xkcd.com/927/
typedef struct {
uint32_t year; //!< Year, A.D.
uint32_t month; //!< Month, 1 .. 12.
@ -27,6 +26,14 @@ class Clock {
uint32_t usecond; //!< Microseconds, 0 .. 999999
} TimeOfDay_t;
/**
* This method returns the number of clock ticks per second.
* In RTEMS, this is typically 1000.
* @return The number of ticks.
*
* @deprecated, we should not worry about ticks, but only time
*/
static uint32_t getTicksPerSecond();
/**
* This system call sets the system time.
* To set the time, it uses a TimeOfDay_t struct.
@ -54,8 +61,13 @@ class Clock {
/**
* Get the time since boot in a timeval struct
*
* @return a timeval struct where the uptime is stored
* @param[out] time A pointer to a timeval struct where the uptime is stored.
* @return @c returnvalue::OK on success. Otherwise, the OS failure code is returned.
*
* @deprecated, I do not think this should be able to fail, use timeval getUptime()
*/
static ReturnValue_t getUptime(timeval *uptime);
static timeval getUptime();
/**
@ -67,7 +79,7 @@ class Clock {
* @param ms uptime in ms
* @return returnvalue::OK on success. Otherwise, the OS failure code is returned.
*/
static uint32_t getUptime_ms();
static ReturnValue_t getUptime(uint32_t *uptimeMs);
/**
* Returns the time in microseconds since an OS-defined epoch.
@ -78,7 +90,6 @@ class Clock {
* - Otherwise, the OS failure code is returned.
*/
static ReturnValue_t getClock_usecs(uint64_t *time);
/**
* Returns the time in a TimeOfDay_t struct.
* @param time A pointer to a TimeOfDay_t struct.
@ -95,7 +106,6 @@ class Clock {
* @return
*/
static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to);
/**
* Converts a time of day struct to POSIX seconds.
* @param time The time of day as input

View File

@ -1,7 +1,5 @@
#include <cstdlib>
#include <ctime>
#include "boost_timegm.h"
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/timemanager/Clock.h"
@ -55,58 +53,34 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
}
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
struct tm time_tm;
// WINDOWS does not provide gmtime_r, but gmtime_s
#ifdef _MSC_VER
time_t seconds = from->tv_sec;
errno_t result = gmtime_s(&time_tm, &seconds);
if (result != 0) {
return returnvalue::FAILED;
struct tm* timeInfo;
// According to https://en.cppreference.com/w/c/chrono/gmtime, the implementation of gmtime_s
// in the Windows CRT is incompatible with the C standard but this should not be an issue for
// this implementation
ReturnValue_t result = checkOrCreateClockMutex();
if (result != returnvalue::OK) {
return result;
}
// gmtime writes its output in a global buffer which is not Thread Safe
// Therefore we have to use a Mutex here
MutexGuard helper(timeMutex);
#ifdef PLATFORM_WIN
time_t time;
time = from->tv_sec;
timeInfo = gmtime(&time);
#else
void* result = gmtime_r(&from->tv_sec, &time_tm);
if (result == nullptr) {
return returnvalue::FAILED;
}
timeInfo = gmtime(&from->tv_sec);
#endif
to->year = time_tm.tm_year + 1900;
to->month = time_tm.tm_mon + 1;
to->day = time_tm.tm_mday;
to->hour = time_tm.tm_hour;
to->minute = time_tm.tm_min;
to->second = time_tm.tm_sec;
to->year = timeInfo->tm_year + 1900;
to->month = timeInfo->tm_mon + 1;
to->day = timeInfo->tm_mday;
to->hour = timeInfo->tm_hour;
to->minute = timeInfo->tm_min;
to->second = timeInfo->tm_sec;
to->usecond = from->tv_usec;
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
struct tm time_tm = {};
time_tm.tm_year = from->year - 1900;
time_tm.tm_mon = from->month - 1;
time_tm.tm_mday = from->day;
time_tm.tm_hour = from->hour;
time_tm.tm_min = from->minute;
time_tm.tm_sec = from->second;
time_tm.tm_isdst = 0;
time_t seconds = internal_timegm(&time_tm);
to->tv_sec = seconds;
to->tv_usec = from->usecond;
return returnvalue::OK;
}
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
return returnvalue::OK;
}
ReturnValue_t Clock::checkOrCreateClockMutex() {
if (timeMutex == nullptr) {
MutexFactory* mutexFactory = MutexFactory::instance();
@ -120,37 +94,3 @@ ReturnValue_t Clock::checkOrCreateClockMutex() {
}
return returnvalue::OK;
}
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
timeval time_timeval;
ReturnValue_t result = getClock_timeval(&time_timeval);
if (result != returnvalue::OK) {
return result;
}
return convertTimevalToTimeOfDay(&time_timeval, time);
}
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
timeval timeVal{};
ReturnValue_t result = getClock_timeval(&timeVal);
if (result != returnvalue::OK) {
return result;
}
*time = static_cast<uint64_t>(timeVal.tv_sec) * 1e6 + timeVal.tv_usec;
return returnvalue::OK;
}
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
timeval timeTimeval{};
ReturnValue_t result = convertTimeOfDayToTimeval(time, &timeTimeval);
if (result != returnvalue::OK) {
return result;
}
return setClock(&timeTimeval);
}
uint32_t Clock::getUptime_ms() {
timeval uptime = getUptime();
// TODO verify that overflow is correct
return uptime.tv_sec * 1e3 + uptime.tv_usec / 1e3;
}

View File

@ -7,9 +7,9 @@ Countdown::Countdown(uint32_t initialTimeout) : timeout(initialTimeout) {
Countdown::~Countdown() {}
ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) {
startTime = Clock::getUptime_ms();
ReturnValue_t returnValue = Clock::getUptime(&startTime);
timeout = milliseconds;
return returnvalue::OK;
return returnValue;
}
bool Countdown::hasTimedOut() const {
@ -38,4 +38,8 @@ uint32_t Countdown::getRemainingMillis() const {
}
}
uint32_t Countdown::getCurrentTime() const { return Clock::getUptime_ms(); }
uint32_t Countdown::getCurrentTime() const {
uint32_t currentTime;
Clock::getUptime(&currentTime);
return currentTime;
}

View File

@ -9,10 +9,10 @@
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
// Measures start time on initialization.
startTime = Clock::getUptime();
Clock::getUptime(&startTime);
}
void Stopwatch::start() { startTime = Clock::getUptime(); }
void Stopwatch::start() { Clock::getUptime(&startTime); }
dur_millis_t Stopwatch::stop(bool display) {
stopInternal();
@ -62,6 +62,7 @@ void Stopwatch::setDisplayMode(StopwatchDisplayMode displayMode) {
StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
void Stopwatch::stopInternal() {
timeval endTime = Clock::getUptime();
timeval endTime;
Clock::getUptime(&endTime);
elapsedTime = endTime - startTime;
}

View File

@ -3,17 +3,12 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include "fsfw/platform.h"
#ifdef PLATFORM_WIN
// wtf? Required for timeval!
// Thanks, windows
// clang-format off
#include <winsock2.h>
#include <winsock.h>
// clang-format off
#endif
#include "TimeStampIF.h"

View File

@ -1,66 +0,0 @@
// (C) Copyright Howard Hinnant
// (C) Copyright 2010-2011 Vicente J. Botet Escriba
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//===-------------------------- locale ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This code was adapted by Vicente from Howard Hinnant's experimental work
// on chrono i/o to Boost and some functions from libc++/locale to emulate the missing
// time_get::get()
#include "boost_timegm.h"
#include <cstdint>
int32_t is_leap(int32_t year) {
if (year % 400 == 0) return 1;
if (year % 100 == 0) return 0;
if (year % 4 == 0) return 1;
return 0;
}
int32_t days_from_0(int32_t year) {
year--;
return 365 * year + (year / 400) - (year / 100) + (year / 4);
}
int32_t days_from_1970(int32_t year) {
static const int32_t days_from_0_to_1970 = days_from_0(1970);
return days_from_0(year) - days_from_0_to_1970;
}
int32_t days_from_1jan(int32_t year, int32_t month, int32_t day) {
static const int32_t days[2][12] = {{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}};
return days[is_leap(year)][month - 1] + day - 1;
}
time_t internal_timegm(std::tm const *t) {
int year = t->tm_year + 1900;
int month = t->tm_mon;
if (month > 11) {
year += month / 12;
month %= 12;
} else if (month < 0) {
int years_diff = (-month + 11) / 12;
year -= years_diff;
month += 12 * years_diff;
}
month++;
int day = t->tm_mday;
int day_of_year = days_from_1jan(year, month, day);
int days_since_epoch = days_from_1970(year) + day_of_year;
time_t seconds_in_day = 3600 * 24;
time_t result =
seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
return result;
}

View File

@ -1,3 +0,0 @@
#include <ctime>
time_t internal_timegm(std::tm const *t);

View File

@ -100,5 +100,6 @@ ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializa
void PusTcCreator::setup() {
spCreator.setPacketType(ccsds::PacketType::TC);
spCreator.setSecHeaderFlag();
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
updateSpLengthField();
}

View File

@ -119,6 +119,7 @@ void PusTmCreator::setup() {
updateSpLengthField();
spCreator.setPacketType(ccsds::PacketType::TM);
spCreator.setSecHeaderFlag();
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
}
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {

View File

@ -348,7 +348,7 @@ void CommandingServiceBase::startExecution(store_address_t storeId, CommandMapIt
sendResult = commandQueue->sendMessage(iter.value->first, &command);
}
if (sendResult == returnvalue::OK) {
iter->second.uptimeOfStart = Clock::getUptime_ms();
Clock::getUptime(&iter->second.uptimeOfStart);
iter->second.step = 0;
iter->second.subservice = tcReader.getSubService();
iter->second.command = command.getCommand();
@ -434,7 +434,8 @@ inline void CommandingServiceBase::doPeriodicOperation() {}
MessageQueueId_t CommandingServiceBase::getCommandQueue() { return commandQueue->getId(); }
void CommandingServiceBase::checkTimeout() {
uint32_t uptime = Clock::getUptime_ms();
uint32_t uptime;
Clock::getUptime(&uptime);
CommandMapIter iter;
for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) {
if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) {

View File

@ -16,7 +16,9 @@ TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDes
tcDestination(tcDestination)
{
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
}
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
@ -35,7 +37,7 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerC
}
}
ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored) {
ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored) {
if (maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) {
this->maxNumberOfPacketsStored = maxNumberOfPacketsStored;
return returnvalue::OK;
@ -143,13 +145,17 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
storeDownlinkData(&message);
ReturnValue_t result = storeDownlinkData(&message);
if (result != returnvalue::OK) {
tmStore->deleteData(message.getStorageId());
}
continue;
}
result = tmStore->getData(message.getStorageId(), &data, &size);
if (result != returnvalue::OK) {
status = result;
tmStore->deleteData(message.getStorageId());
continue;
}
@ -157,9 +163,9 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
if (result != returnvalue::OK) {
status = result;
} else {
tmStore->deleteData(message.getStorageId());
packetSentCounter++;
}
tmStore->deleteData(message.getStorageId());
}
return status;
}
@ -171,15 +177,18 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
}
if (tmFifo->full()) {
if (warningSwitch) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!"
<< std::endl;
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!"
<< std::endl;
#else
sif::printWarning(
"TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!\n");
sif::printWarning(
"TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!\n");
#endif
warningSwitch = false;
}
if (overwriteOld) {
tmFifo->retrieve(&storeId);
tmStore->deleteData(storeId);
@ -221,6 +230,7 @@ ReturnValue_t TmTcBridge::handleStoredTm() {
packetSentCounter++;
if (tmFifo->empty()) {
warningSwitch = true;
tmStored = false;
}
tmStore->deleteData(storeId);

View File

@ -17,7 +17,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
public:
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200;
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 500;
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
@ -42,7 +42,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
* @return -@c returnvalue::OK if value was set successfully
* -@c returnvalue::FAILED otherwise, stored value stays the same
*/
ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored);
ReturnValue_t setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored);
/**
* This will set up the bridge to overwrite old data in the FIFO.
@ -91,6 +91,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
//! by default, so telemetry will be handled immediately.
bool communicationLinkUp = true;
bool tmStored = false;
bool warningSwitch = true;
bool overwriteOld = true;
uint8_t packetSentCounter = 0;
@ -152,7 +153,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
*/
DynamicFIFO<store_address_t>* tmFifo = nullptr;
uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE;
uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED;
unsigned int maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED;
};
#endif /* FSFW_TMTCSERVICES_TMTCBRIDGE_H_ */

View File

@ -1,7 +1,7 @@
#include <stdbool.h>
#include <stdio.h>
void printChar(const char* character, bool errStream) {
void __attribute__((weak)) printChar(const char* character, bool errStream) {
if (errStream) {
fprintf(stderr, "%c", *character);
} else {

View File

@ -72,7 +72,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
uint32_t transitionDelay;
// Single SPI command has 2 bytes, first for adress, second for content
// size_t singleComandSize = 2;
size_t singleComandSize = 2;
// Has the size for all adresses of the lis3mdl + the continous write bit
uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1];
@ -87,7 +87,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
*/
uint8_t registers[MGMLIS3MDL::NR_OF_CTRL_REGISTERS];
// uint8_t statusRegister = 0;
uint8_t statusRegister = 0;
bool goToNormalMode = false;
enum class InternalState {

View File

@ -325,7 +325,7 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
// trickery here to calculate the raw values first
int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8;
int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8;
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8;
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[9] << 8)) >> 8;
// Now scale to physical value in microtesla
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;

View File

@ -72,7 +72,7 @@ class MgmRM3100Handler : public DeviceHandlerBase {
RM3100::Rm3100PrimaryDataset primaryDataset;
uint8_t commandBuffer[10];
// uint8_t commandBufferLen = 0;
uint8_t commandBufferLen = 0;
uint8_t cmmRegValue = RM3100::CMM_VALUE;
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;

View File

@ -67,7 +67,7 @@ void CommandExecutor::printLastError(std::string funcName) const {
sif::warning << funcName << " pclose failed with code " << lastError << ": "
<< strerror(lastError) << std::endl;
#else
sif::printError("%s pclose failed with code %d: %s\n", funcName.c_str(), lastError,
sif::printError("%s pclose failed with code %d: %s\n", funcName, lastError,
strerror(lastError));
#endif
}
@ -119,7 +119,7 @@ ReturnValue_t CommandExecutor::check(bool& replyReceived) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << currentCmd << " | " << readVec.data();
#else
sif::printInfo("%s | %s", currentCmd.c_str(), readVec.data());
sif::printInfo("%s | %s", currentCmd, readVec.data());
#endif
}
if (ringBuffer != nullptr) {
@ -188,7 +188,7 @@ ReturnValue_t CommandExecutor::executeBlocking() {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << currentCmd << " | " << output;
#else
sif::printInfo("%s | %s", currentCmd.c_str(), output.c_str());
sif::printInfo("%s | %s", currentCmd, output);
#endif
}
if (ringBuffer != nullptr) {

View File

@ -180,10 +180,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
}
#else
#endif
#endif
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
<< " bytes" << std::endl;
#endif
return returnvalue::FAILED;
}

View File

@ -146,9 +146,8 @@ ReturnValue_t testserialize::test_autoserialization() {
}
// These epsilon values were just guessed.. It appears to work though.
if (std::abs(tv_float - tv::tv_float) > 0.0001 or std::abs(tv_double - tv::tv_double) > 0.01 or
std::abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or
std::abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
if (abs(tv_float - tv::tv_float) > 0.0001 or abs(tv_double - tv::tv_double) > 0.01 or
abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
return unitt::put_error(id);
}

View File

@ -20,9 +20,7 @@ add_subdirectory(globalfunctions)
add_subdirectory(timemanager)
add_subdirectory(tmtcpacket)
add_subdirectory(cfdp)
if(NOT FSFW_OSAL MATCHES "rtems")
add_subdirectory(hal)
endif()
add_subdirectory(hal)
add_subdirectory(internalerror)
add_subdirectory(devicehandler)
add_subdirectory(tmtcservices)

Some files were not shown because too many files have changed in this diff Show More