Compare commits

..

46 Commits

Author SHA1 Message Date
c1a9678abb fixing merge again
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-06-02 12:08:06 +02:00
1f4ad10dff fixing merge
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-06-02 11:50:09 +02:00
17ed22039e Merge remote-tracking branch 'origin/development' into mohr/windows
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-06-02 11:41:28 +02:00
b1160cfb2e fixing setsockopt for windows
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-09 14:56:40 +01:00
99896f2695 tweaking cmake toolchains layout
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-02-09 13:43:35 +01:00
45b686a028 Merge remote-tracking branch 'origin/development' into mohr/windows 2023-02-08 22:08:55 +01:00
329e80e7ee enabling win unittests
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-08 14:08:09 +01:00
3772db4753 group id conflict
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-08 11:46:39 +01:00
3d13ead275 moved to newer wine
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-07 21:56:06 +01:00
e7e9ce4baf one more warning suppressed in MSVC 2023-02-07 13:25:13 +01:00
e4c11f8107 fixing problem which causes a looooooong hang in CI by illegaly overrideing internal CMake Variable
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-07 12:26:44 +01:00
270622a5f1 no coverage with clang so far; using correct path to push coverage data
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-06 22:49:37 +01:00
4b52e5bec4 windows and clang builds in CI
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-02-06 22:45:00 +01:00
efc2773f84 docker update for windows
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-06 16:29:53 +01:00
87bb29a66a compiler parameter tuning
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-02-06 13:10:50 +01:00
45963b2064 tuning win build
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-27 17:26:03 +01:00
bc312243df clang -Weverything -Wno-gnu-anonymous-struct
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-27 00:50:10 +01:00
9589d702dd windows unittests succeed
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-26 18:14:35 +01:00
c66fab90f9 filesystem stuff works on linux/host
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-26 17:05:25 +01:00
3e8446ba8b windows building again 2023-01-26 15:30:23 +01:00
e37af4fe70 format
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-26 13:40:44 +01:00
941bf61f28 constant number of assertions in unittests
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-26 13:26:11 +01:00
70fd9ff3e5 fixed impact of windows fixes on other builds
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-26 12:33:39 +01:00
81c5b2ec95 Merge branch 'mohr/rtems' into windows
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-01-26 11:55:16 +01:00
7426e10f82 clocks suck a little less
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-26 11:33:40 +01:00
uli
123c81777a clocks suck 2023-01-26 00:01:40 +01:00
dcc28622a5 windows compiles, some unittests give exceptions
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-01-25 23:54:46 +01:00
6d85fa155e cleaning up unittest build
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-20 16:05:04 +01:00
e6af6200ae updating CI
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-19 17:32:23 +01:00
5ca3e83934 working on rtems CI build
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-19 16:46:43 +01:00
6adabb059a fixing rtems cmake config
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-19 16:27:10 +01:00
5d0a5cd201 exiting qemu nonzero when tests fail 2023-01-19 14:47:40 +01:00
adb8483bb0 unittests for rtems working
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-19 14:24:33 +01:00
fdfdce2fb0 compiling, crashing when run
All checks were successful
fsfw/fsfw/pipeline/head This commit looks good
2023-01-18 00:25:25 +01:00
90efb132d0 fixing rebase error
Some checks failed
fsfw/fsfw/pipeline/pr-development There was a failure building this commit
fsfw/fsfw/pipeline/head This commit looks good
2023-01-16 12:41:23 +01:00
fe9804d922 format
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-01-16 12:35:14 +01:00
a0eae66c35 checking if this helps docker build
Some checks failed
fsfw/fsfw/pipeline/head There was a failure building this commit
2023-01-16 12:32:16 +01:00
e131480d5f two errors found by valgrind 2023-01-16 12:32:15 +01:00
90bafbb6de typos in Jenkinsfile 2023-01-16 12:31:54 +01:00
47d85fb61c finished freertos unittests, valgrind not happy yet 2023-01-16 12:31:53 +01:00
39dad5f45b unittests running but failing 2023-01-16 12:31:53 +01:00
a993c4e0d4 adding linux ci and fixing problems 2023-01-16 12:31:53 +01:00
fe9cc20d00 make get const 2023-01-16 12:31:53 +01:00
552a12a6ad updates for source sequence counter 2023-01-16 12:31:47 +01:00
13639feec6 FreeRTOS unittests building (but not running) 2023-01-16 12:30:36 +01:00
654de0f586 WIP 2023-01-16 12:30:36 +01:00
127 changed files with 1165 additions and 932 deletions

3
.gitmodules vendored
View File

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

View File

@ -10,11 +10,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Fixes
- The `PusTmCreator` API only accepted 255 bytes of source data. It can now accept source
data with a size limited only by the size of `size_t`.
- Important bugfix in CFDP PDU header format: The entity length field and the transaction sequence
number fields stored the actual length of the field instead of the length minus 1 like specified
in the CFDP standard.
- PUS Health Service: Size check for set health command.
Perform operation completion for announce health command.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/746
@ -22,17 +17,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/745
- Small tweak for version getter
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/744
- Important bugfix for `LocalPool::delete` function, where an overflow could possibly lead to UB.
## Added
- add CFDP subsystem ID
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
- New object ID for persistent TM store PUS 15
- `EventManager`: Add function to print all listeners.
## Changed
- Bump ETL version to 20.35.14
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/748
- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`.
@ -41,8 +32,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
- Assert that `FixedArrayList` is larger than 0 at compile time.
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/740
## Added
- `EventManager`: Add function to print all listeners.
## Changed
- `EventManager`: Queue depth is configurable now
- `ActionHelper`: Allow execution of actions without additional data
# [v6.0.0] 2023-02-10

View File

@ -64,6 +64,13 @@ 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)
@ -72,7 +79,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION
20
CACHE STRING "ETL library major version requirement")
set(FSFW_ETL_LIB_VERSION
${FSFW_ETL_LIB_MAJOR_VERSION}.36.0
${FSFW_ETL_LIB_MAJOR_VERSION}.35.14
CACHE STRING "ETL library exact version requirement")
set(FSFW_ETL_LINK_TARGET etl::etl)
@ -80,7 +87,7 @@ set(FSFW_CATCH2_LIB_MAJOR_VERSION
3
CACHE STRING "Catch2 library major version requirement")
set(FSFW_CATCH2_LIB_VERSION
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.3.2
v${FSFW_CATCH2_LIB_MAJOR_VERSION}.1.0
CACHE STRING "Catch2 library exact version requirement")
# Keep this off by default for now. See PR:
@ -174,6 +181,27 @@ 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)
@ -226,6 +254,7 @@ 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")
@ -360,6 +389,9 @@ 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
@ -447,8 +479,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(FSFW_WARNING_FLAGS -Wall -Wno-gnu-anonymous-struct)
endif()
# Required include paths to compile the FSFW

View File

@ -5,11 +5,9 @@ RUN apt-get --yes upgrade
#tzdata is a dependency, won't install otherwise
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping python3 pip doxygen graphviz rsync
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
# This should also install Sphinx
RUN python3 -m pip install -r docs/requirements.txt
RUN python3 -m pip install breathe
RUN python3 -m pip install sphinx breathe
RUN git clone https://github.com/catchorg/Catch2.git && \
cd Catch2 && \
@ -23,8 +21,36 @@ 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 adduser --uid 114 jenkins
RUN addgroup -q --gid 117 jenkins && adduser -q --uid 114 --gid 117 jenkins
#add documentation server to known hosts
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts

136
automation/Jenkinsfile vendored
View File

@ -2,129 +2,109 @@ 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:d6'
image 'fsfw-ci:d9'
args '--network host --sysctl fs.mqueue.msg_max=100'
}
}
stages {
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('x64-linux-clang-host') {
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('Linux') {
stages{
stage('Clean') {
steps {
sh 'rm -rf $BUILDDIR_LINUX'
}
stage('x64-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('Configure') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
}
}
}
}
stage('x64-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('Build') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake --build . -j4'
}
}
}
}
stage('aarch64-rtems6-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=../cmake/aarch64-rtems6-gcc.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('Unittests') {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake --build . -- fsfw-tests_coverage -j4'
}
}
}
stage('Valgrind') {
steps {
dir(BUILDDIR_LINUX) {
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
}
}
}
}
stage('x64-windows-msvc-host') {
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=../cmake/x64-windows-msvc.cmake -GNinja ..'
sh 'cmake --build . -j4'
sh 'wine64 fsfw-tests.exe'
}
}
}
stage('Documentation') {
when {
anyOf {
branch 'development';
branch pattern: 'development-doc*'
}
branch 'development'
}
steps {
dir(DOCDDIR) {
sh 'cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..'
sh 'make Sphinx'
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/development'
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
}
}
dir(BUILDDIR_LINUX) {
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/coverage/development'
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
}
}
}
}
stage('Master Documentation') {
when {
anyOf {
branch 'master';
branch pattern: 'master-doc*'
}
branch 'master'
}
steps {
dir(DOCDDIR) {
sh 'cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..'
sh 'make Sphinx'
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/master'
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
}
}
dir(BUILDDIR_LINUX) {
sshagent(credentials: ['documentation-buildfix']) {
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/projects/fsfw/coverage/master'
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
}
}
}

1
automation/msvc-wine Submodule

Submodule automation/msvc-wine added at 2d2d7db0b5

View File

@ -0,0 +1,3 @@
add_compile_options("-mcpu=cortex-a72" "-I/opt/rtems/6/aarch64-rtems6/a72_lp64_qemu/lib/include")
add_link_options("-B/opt/rtems/6/aarch64-rtems6/a72_lp64_qemu/lib" "-qrtems")

View File

@ -0,0 +1,33 @@
## the name of the target operating system
set(CMAKE_SYSTEM_NAME a72_lp64_qemu)
set(CMAKE_SYSTEM_PROCESSOR a72)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER aarch64-rtems6-gcc)
set(CMAKE_CXX_COMPILER aarch64-rtems6-g++)
# built in tests fail
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# ignore host installed libraries
# makes find_package() ignore the <package>Config.cmake files
set(CMAKE_IGNORE_PATH /usr/local)
# supress errors
add_compile_definitions("__STDC_VERSION__")
# make newlib behave like glib with an intercepted cmath
add_compile_options("-I${CMAKE_SOURCE_DIR}/unittests/testcfg/rtems/include")

View File

@ -0,0 +1,27 @@
set(CMAKE_SYSTEM_NAME Windows)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER /opt/msvc/bin/x64/cl)
set(CMAKE_CXX_COMPILER /opt/msvc/bin/x64/cl)
# built in tests fail
set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)
# fails somewhere caused by wine
# overriding internal variable DO NOT TRY THIS AT HOME!
set(CMAKE_C_ABI_COMPILED ON)
set(CMAKE_CXX_ABI_COMPILED ON)
# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# ignore host installed libraries
# makes find_package() ignore the <package>Config.cmake files
set(CMAKE_IGNORE_PATH /usr/local)

View File

@ -21,7 +21,6 @@ project = "Flight Software Framework"
copyright = "2021, Institute of Space Systems (IRS)"
author = "Institute of Space Systems (IRS)"
# TODO: Should try to read this from CMakeLists.txt automatically..
# The full version, including alpha/beta/rc tags
release = "5.0.0"
@ -49,7 +48,7 @@ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
html_theme = "alabaster"
html_theme_options = {
"extra_nav_links": {"Impressum" : "https://www.uni-stuttgart.de/impressum", "Datenschutz": "https://info.irs.uni-stuttgart.de/datenschutz/datenschutzWebmit.html"}

View File

@ -1 +0,0 @@
sphinx-rtd-theme==1.3.0

View File

@ -59,24 +59,17 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress) {
bool hasAdditionalData = false;
const uint8_t* dataPtr = nullptr;
size_t size = 0;
ReturnValue_t result;
if (dataAddress != store_address_t::invalid()) {
hasAdditionalData = true;
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != returnvalue::OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
if (result != returnvalue::OK) {
CommandMessage reply;
ActionMessage::setStepReply(&reply, actionId, 0, result);
queueToUse->sendMessage(commandedBy, &reply);
return;
}
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
if (hasAdditionalData) {
ipcStore->deleteData(dataAddress);
}
ipcStore->deleteData(dataAddress);
if (result == HasActionsIF::EXECUTION_FINISHED) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, actionId, true, result);

View File

@ -16,8 +16,8 @@ class CommandActionHelper {
public:
explicit CommandActionHelper(CommandsActionsIF* owner);
virtual ~CommandActionHelper();
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
const uint8_t* data = nullptr, uint32_t size = 0);
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
uint32_t size);
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
ReturnValue_t initialize();
ReturnValue_t handleReply(CommandMessage* reply);

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, size_t value) : VarLenField() {
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_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, size_t value_) {
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, uint64_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, size_
return returnvalue::OK;
}
size_t cfdp::VarLenField::getValue() const {
uint64_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, size_t value);
VarLenField(cfdp::WidthInBytes width, uint64_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, size_t value);
ReturnValue_t setValue(cfdp::WidthInBytes, uint64_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]] size_t getValue() const;
[[nodiscard]] uint64_t getValue() const;
#if FSFW_CPP_OSTREAM_ENABLED == 1
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
@ -51,9 +51,9 @@ class VarLenField : public SerializeIF {
return os;
}
#endif
private:
using SerializeIF::deSerialize; // we overloaded above, so this is needed to uncofuse the
// compiler
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;

View File

@ -9,6 +9,11 @@
#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(size_t fileSize, bool isLarge) {
ReturnValue_t EofInfo::setFileSize(uint64_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(size_t size, bool isLarge);
ReturnValue_t setFileSize(uint64_t size, bool isLarge);
private:
cfdp::ConditionCode conditionCode;

View File

@ -1,5 +1,10 @@
#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

@ -24,8 +24,8 @@ ReturnValue_t HeaderCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
*buffer += 1;
**buffer = pduDataFieldLen & 0x00ff;
*buffer += 1;
**buffer = segmentationCtrl << 7 | ((pduConf.sourceId.getWidth() - 1) << 4) |
segmentMetadataFlag << 3 | (pduConf.seqNum.getWidth() - 1);
**buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 | segmentMetadataFlag << 3 |
pduConf.seqNum.getWidth();
*buffer += 1;
*size += 4;
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);

View File

@ -78,11 +78,11 @@ cfdp::SegmentationControl PduHeaderReader::getSegmentationControl() const {
}
cfdp::WidthInBytes PduHeaderReader::getLenEntityIds() const {
return static_cast<cfdp::WidthInBytes>(((pointers.fixedHeader->fourthByte >> 4) & 0b111) + 1);
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte >> 4) & 0x07);
}
cfdp::WidthInBytes PduHeaderReader::getLenSeqNum() const {
return static_cast<cfdp::WidthInBytes>((pointers.fixedHeader->fourthByte & 0b111) + 1);
return static_cast<cfdp::WidthInBytes>(pointers.fixedHeader->fourthByte & 0x07);
}
cfdp::SegmentMetadataFlag PduHeaderReader::getSegmentMetadataFlag() const {

View File

@ -23,8 +23,7 @@ class EntityIdTlv : public TlvIF {
*/
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
// the compiler
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;

View File

@ -26,6 +26,7 @@ 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,8 +29,7 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
*/
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
// the compiler
using SerializeIF::deSerialize;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;

View File

@ -155,8 +155,8 @@ class FixedMap : public SerializeIF {
uint32_t maxSize() const { return theMap.maxSize(); }
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const {
ReturnValue_t result =
SerializeAdapter::serialize(&this->_size, buffer, size, maxSize, streamEndianness);
uint32_t i = 0;
@ -170,7 +170,7 @@ class FixedMap : public SerializeIF {
return result;
}
size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const {
uint32_t printSize = sizeof(_size);
uint32_t i = 0;
@ -182,8 +182,8 @@ class FixedMap : public SerializeIF {
return printSize;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
ReturnValue_t result =
SerializeAdapter::deSerialize(&this->_size, buffer, size, streamEndianness);
if (this->_size > theMap.maxSize()) {

View File

@ -64,8 +64,8 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
* commit() in between
*/
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
/**
* @brief The commit call initializes writing back the registered variables.
* @details
@ -84,15 +84,15 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
* - @c COMMITING_WITHOUT_READING if set was not read yet and
* contains non write-only variables
*/
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t lockTimeout = 20) override;
/**
* Register the passed pool variable instance into the data set.
* @param variable
* @return
*/
ReturnValue_t registerVariable(PoolVariableIF* variable) override;
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) override;
/**
* Provides the means to lock the underlying data structure to ensure

View File

@ -364,6 +364,10 @@ 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

@ -87,9 +87,9 @@ class LocalPoolVariable : public LocalPoolObjectBase {
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
/**
* @brief This is a call to read the array's values

View File

@ -98,11 +98,11 @@ class LocalPoolVector : public LocalPoolObjectBase {
T& operator[](size_t i);
const T& operator[](size_t i) const;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndiannes) const override;
size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndiannes) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
/**
* @brief This is a call to read the array's values

View File

@ -322,8 +322,7 @@ void DeviceHandlerBase::doStateMachine() {
if (mode != currentMode) {
break;
}
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
uint32_t currentUptime = Clock::getUptime_ms();
if (currentUptime - timeoutStart >= childTransitionDelay) {
#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0
char printout[60];
@ -347,8 +346,7 @@ void DeviceHandlerBase::doStateMachine() {
setMode(_MODE_WAIT_ON);
break;
case _MODE_WAIT_ON: {
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
uint32_t currentUptime = Clock::getUptime_ms();
if (powerSwitcher != nullptr and
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
@ -367,8 +365,7 @@ void DeviceHandlerBase::doStateMachine() {
}
} break;
case _MODE_WAIT_OFF: {
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
uint32_t currentUptime = Clock::getUptime_ms();
if (powerSwitcher == nullptr) {
setMode(MODE_OFF);
@ -578,7 +575,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
modeHelper.modeChanged(newMode, newSubmode);
announceMode(false);
}
Clock::getUptime(&timeoutStart);
timeoutStart = Clock::getUptime_ms();
if (mode == MODE_OFF and thermalSet != nullptr) {
ReturnValue_t result = thermalSet->read();

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);
HealthState getHealth();
ReturnValue_t setHealth(HealthState health);
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
HealthState getHealth() override;
ReturnValue_t setHealth(HealthState health) override;
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);
uint32_t *msToReachTheMode) override;
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);

View File

@ -21,29 +21,33 @@ extern const char* translateEvents(Event event);
class EventManager : public EventManagerIF, public ExecutableObjectIF, public SystemObject {
public:
EventManager(object_id_t setObjectId, uint32_t eventQueueDepth);
virtual ~EventManager();
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
MessageQueueId_t getEventReportQueue();
MessageQueueId_t getEventReportQueue() override;
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
ReturnValue_t registerListener(MessageQueueId_t listener,
bool forwardAllButSelected = false) override;
ReturnValue_t unregisterListener(MessageQueueId_t listener) override;
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) override;
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) override;
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);
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object);
bool reporterInverted = false) override;
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) override;
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
EventId_t idTo = 0, bool idInverted = false,
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
bool reporterInverted = false);
ReturnValue_t performOperation(uint8_t opCode);
bool reporterInverted = false) override;
ReturnValue_t performOperation(uint8_t opCode) override;
void printListeners();
protected:
MessageQueueIF* eventReportQueue = nullptr;

View File

@ -52,6 +52,7 @@ 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

@ -44,13 +44,13 @@ class Type : public SerializeIF {
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
size_t getSerializedSize() const override;
virtual size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
private:
ActualType_t actualType;
@ -58,7 +58,7 @@ class Type : public SerializeIF {
template <typename T>
struct PodTypeConversion {
static_assert(not std::is_same<T, bool>::value,
static_assert(!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 size, size_t maxCharPerLine) {
void arrayprinter::printHex(const uint8_t *data, size_t datasize, 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 < size; i++) {
for (size_t i = 0; i < datasize; i++) {
std::cout << std::setw(2) << static_cast<int>(data[i]);
if (i < size - 1) {
if (i < datasize - 1) {
std::cout << ",";
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
std::cout << std::endl;
@ -56,27 +56,11 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerL
std::cout << std::dec << std::setfill(' ');
std::cout << "]" << std::endl;
#else
// 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("hex [");
for (size_t i = 0; i < datasize; i++) {
printf("0x%02x ", data[i]);
}
#if FSFW_DISABLE_PRINTOUT == 0
printf("hex [%s]\n", printBuffer);
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
printf("]\n");
#endif
}
@ -100,26 +84,10 @@ 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++) {
// 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");
}
}
for (size_t i = 0; i < size; i++) {
// TODO
}
#if FSFW_DISABLE_PRINTOUT == 0
printf("dec [%s]\n", printBuffer);
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
#endif
}

View File

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

View File

@ -18,7 +18,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
violationEvent(violationEvent),
aboveIsViolation(aboveIsViolation) {}
virtual ~AbsLimitMonitor() {}
virtual ReturnValue_t checkSample(T sample, T *crossedLimit) {
ReturnValue_t checkSample(T sample, T *crossedLimit) override {
*crossedLimit = limit;
if (aboveIsViolation) {
if ((std::abs(sample) > limit)) {
@ -61,7 +61,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
void setLimit(T value) { limit = value; }
protected:
void sendTransitionEvent(T currentValue, ReturnValue_t state) {
void sendTransitionEvent(T currentValue, ReturnValue_t state) override {
switch (state) {
case MonitoringIF::OUT_OF_RANGE:
EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->globalPoolId.objectId,

View File

@ -13,7 +13,6 @@ class MonitoringMessage : public CommandMessage {
static const Command_t LIMIT_VIOLATION_REPORT = MAKE_COMMAND_ID(10);
virtual ~MonitoringMessage();
static void setLimitViolationReport(CommandMessage* message, store_address_t storeId);
using CommandMessage::clear;
static void clear(CommandMessage* message);
static store_address_t getStoreId(const CommandMessage* message);
static void setTypicalMessage(CommandMessage* message, Command_t type, store_address_t storeId);

View File

@ -15,7 +15,6 @@ enum framework_objects : object_id_t {
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
PUS_SERVICE_15_TM_STORAGE = 0x53000015,
PUS_SERVICE_17_TEST = 0x53000017,
PUS_SERVICE_20_PARAMETERS = 0x53000020,
PUS_SERVICE_200_MODE_MGMT = 0x53000200,

View File

@ -24,8 +24,11 @@
#else
#ifdef WIN32
#include <windows.h>
// Thanks, windows
// clang-format off
#include <winsock2.h>
#include <windows.h>
// clang-format on
#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>
#include <ws2tcpip.h>
typedef SSIZE_T ssize_t;
#elif defined(PLATFORM_UNIX)
#include <netdb.h>
@ -92,12 +92,22 @@ ReturnValue_t TcpTmTcServer::initialize() {
}
if (tcpConfig.reuseAddr) {
#ifdef PLATFORM_WIN
DWORD enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&enable),
sizeof(enable));
#elif defined(PLATFORM_UNIX)
unsigned int enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
#endif
}
if (tcpConfig.reusePort) {
// Not supported in windows
#ifdef PLATFORM_UNIX
unsigned int enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
#endif
}
// Bind to the address found by getaddrinfo

View File

@ -130,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,6 +8,7 @@
#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,6 +7,7 @@
#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 = portMAX_DELAY) override;
uint32_t timeoutMs = 0) 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 = portMAX_DELAY) override;
uint32_t timeoutMs = 0) override;
/**
* Same as lockBinarySemaphore() with timeout in FreeRTOS ticks.

View File

@ -11,19 +11,6 @@
// 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();
@ -44,81 +31,12 @@ 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 = portMAX_DELAY) override;
uint32_t timeoutMs = 0) override;
/**
* Release a semaphore, increasing the number of available counting

View File

@ -56,7 +56,9 @@ ReturnValue_t FixedTimeslotTask::startTask() {
// start time for the first entry.
auto slotListIter = pollingSeqTable.current;
pollingSeqTable.intializeSequenceAfterTaskCreation();
ReturnValue_t result = pollingSeqTable.intializeSequenceAfterTaskCreation();
// Ignore returnvalue for now
static_cast<void>(result);
// 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.
uint32_t timeout = portMAX_DELAY;
TickType_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,27 +15,6 @@
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. */
@ -66,6 +45,7 @@ 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
@ -75,15 +55,6 @@ 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)
@ -100,73 +71,10 @@ 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

@ -5,7 +5,6 @@
#include <condition_variable>
#include <thread>
#include <vector>
#include <string>
#include "fsfw/objectmanager/ObjectManagerIF.h"
#include "fsfw/tasks/FixedSlotSequence.h"

View File

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

View File

@ -5,7 +5,6 @@
#include <condition_variable>
#include <thread>
#include <vector>
#include <string>
#include "fsfw/objectmanager/ObjectManagerIF.h"
#include "fsfw/tasks/PeriodicTaskBase.h"

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);
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name.c_str());
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
}

View File

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

View File

@ -10,26 +10,6 @@
#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;
@ -53,107 +33,22 @@ 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{};
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) {
double uptimeSeconds;
std::ifstream ifile("/proc/uptime");
if (ifile.bad()) {
return returnvalue::FAILED;
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Clock::getUptime: Error getting uptime" << std::endl;
#endif
return uptime;
}
if (ifile >> uptimeSeconds) {
uptime->tv_sec = uptimeSeconds;
uptime->tv_usec = uptimeSeconds * (double)1e6 - (uptime->tv_sec * 1e6);
return returnvalue::OK;
uptime.tv_sec = uptimeSeconds;
uptime.tv_usec = (uptimeSeconds - uptime.tv_sec) * (double)1e6;
}
return returnvalue::FAILED;
}
// 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;
return uptime;
}

View File

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

View File

@ -6,20 +6,21 @@
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/osal/rtems/RtemsBasic.h"
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) {
ReturnValue_t Clock::setClock(const timeval* time) {
TimeOfDay_t time_tod;
ReturnValue_t result = convertTimevalToTimeOfDay(time, &time_tod);
if (result != returnvalue::OK) {
return result;
}
rtems_time_of_day timeRtems;
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;
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;
rtems_status_code status = rtems_clock_set(&timeRtems);
switch (status) {
case RTEMS_SUCCESSFUL:
@ -33,27 +34,6 @@ ReturnValue_t Clock::setClock(const TimeOfDay_t* 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);
@ -67,86 +47,13 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
}
}
ReturnValue_t Clock::getUptime(timeval* uptime) {
timeval Clock::getUptime() {
// 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);
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;
}
time_timeval.tv_sec = time.tv_sec;
time_timeval.tv_usec = time.tv_nsec / 1000;
return time_timeval;
}

View File

@ -93,8 +93,8 @@ ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size, size_t maxSize
streamEndianness);
}
uint32_t CpuUsage::getSerializedSize() const {
uint32_t size = 0;
size_t CpuUsage::getSerializedSize() const {
size_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;
}
uint32_t CpuUsage::ThreadData::getSerializedSize() const {
uint32_t size = 0;
size_t CpuUsage::ThreadData::getSerializedSize() const {
size_t size = 0;
size += sizeof(id);
size += MAX_LENGTH_OF_THREAD_NAME;

View File

@ -19,13 +19,13 @@ class CpuUsage : public SerializeIF {
float timeRunning;
float percentUsage;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
size_t getSerializedSize() const override;
virtual size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;
};
CpuUsage();

View File

@ -35,20 +35,19 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
return OUT_OF_PROXIES;
case INTERNAL_ERROR_INVALID_GLOBAL_ID:
return INVALID_GLOBAL_ID;
#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;
// 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;
default:
return returnvalue::FAILED;
}

View File

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

View File

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

View File

@ -40,15 +40,14 @@ class ParameterWrapper : public SerializeIF {
ParameterWrapper(Type type, uint8_t rows, uint8_t columns, const void *data);
virtual ~ParameterWrapper();
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
size_t getSerializedSize() const override;
virtual size_t getSerializedSize() const override;
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
// the compiler
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
using SerializeIF::deSerialize;
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness, uint16_t startWritingAtIndex = 0);

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;
MessageQueueId_t getCommandQueue() const override;
void setDataPoolEntriesInvalid();
ReturnValue_t setHealth(HealthState health);
HasHealthIF::HealthState getHealth();
ReturnValue_t setHealth(HealthState health) override;
HasHealthIF::HealthState getHealth() override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex);
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
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);
virtual object_id_t getDeviceObjectId();
object_id_t getDeviceObjectId() override;
virtual uint8_t getSwitchId1();
virtual uint8_t getSwitchId2();
uint8_t getSwitchId1() override;
uint8_t getSwitchId2() override;
bool hasTwoSwitches();
bool hasTwoSwitches() override;
float getMin();
float getMax();
float getMin() override;
float getMax() override;
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);
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
private:
const object_id_t deviceObjectId = objects::NO_OBJECT;

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

View File

@ -24,8 +24,8 @@ class EventReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3,
parameter1(parameter1_),
parameter2(parameter2_) {}
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override {
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override {
ReturnValue_t result =
SerializeAdapter::serialize(&reportId, buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
@ -46,7 +46,7 @@ class EventReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3,
return result;
}
size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const override {
uint32_t size = 0;
size += SerializeAdapter::getSerializedSize(&reportId);
size += SerializeAdapter::getSerializedSize(&objectId);
@ -55,8 +55,8 @@ class EventReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3,
return size;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override {
return returnvalue::FAILED;
}

View File

@ -16,10 +16,8 @@ class SerialArrayListAdapter : public SerializeIF {
public:
SerialArrayListAdapter(ArrayList<T, count_t>* adaptee) : adaptee(adaptee) {}
using SerializeIF::serialize; // we overload this function as well, so this is needed to uncofuse
// the compiler
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const {
return serialize(adaptee, buffer, size, maxSize, streamEndianness);
}
@ -36,7 +34,7 @@ class SerialArrayListAdapter : public SerializeIF {
return result;
}
size_t getSerializedSize() const override { return getSerializedSize(adaptee); }
virtual size_t getSerializedSize() const { return getSerializedSize(adaptee); }
static uint32_t getSerializedSize(const ArrayList<T, count_t>* list) {
uint32_t printSize = sizeof(count_t);
@ -49,10 +47,8 @@ class SerialArrayListAdapter : public SerializeIF {
return printSize;
}
using SerializeIF::deSerialize; // we overload this function as well, so this is needed to
// uncofuse the compiler
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return deSerialize(adaptee, buffer, size, streamEndianness);
}

View File

@ -33,7 +33,7 @@
* @author baetz
* @ingroup serialize
*/
template <typename T, typename count_t = uint8_t>
template <typename T, typename count_t = size_t>
class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
public:
SerialLinkedListAdapter(typename LinkedElement<T>::Iterator start, bool printCount = false)
@ -45,10 +45,8 @@ class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
SerialLinkedListAdapter(bool printCount = false)
: SinglyLinkedList<T>(), printCount(printCount) {}
using SerializeIF::serialize; // we overloaded this function, so this is needed to unconfuse the
// compiler
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
if (printCount) {
count_t mySize = SinglyLinkedList<T>::getSize();
ReturnValue_t result =
@ -70,7 +68,7 @@ class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
return result;
}
size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const override {
if (printCount) {
return SerialLinkedListAdapter<T>::getSerializedSize() + sizeof(count_t);
} else {
@ -78,8 +76,6 @@ class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
}
}
using SerializeIF::deSerialize; // we overloaded this function, so this is needed to unconfuse
// the compiler
static size_t getSerializedSize(const LinkedElement<T>* element) {
size_t size = 0;
while (element != nullptr) {
@ -89,8 +85,8 @@ class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
return size;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
return deSerialize(SinglyLinkedList<T>::start, buffer, size, streamEndianness);
}

View File

@ -32,8 +32,8 @@ class SerializeElement : public SerializeIF, public LinkedElement<SerializeIF> {
size_t getSerializedSize() const override { return SerializeAdapter::getSerializedSize(&entry); }
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override {
return SerializeAdapter::deSerialize(&entry, buffer, size, streamEndianness);
}

View File

@ -89,7 +89,7 @@ ReturnValue_t LocalPool::deleteData(store_address_t storeId) {
ReturnValue_t status = returnvalue::OK;
size_type pageSize = getSubpoolElementSize(storeId.poolIndex);
if ((pageSize != 0) and (storeId.packetIndex < numberOfElements[storeId.poolIndex])) {
size_type packetPosition = getRawPosition(storeId);
uint16_t packetPosition = getRawPosition(storeId);
uint8_t* ptr = &store[storeId.poolIndex][packetPosition];
std::memset(ptr, 0, pageSize);
// Set free list
@ -109,7 +109,8 @@ 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]] > ptr)) {
if ((store[n].data() <= ptr) and
(&store[n][numberOfElements[n] * elementSizes[n] - 1] >= ptr)) {
localId.poolIndex = n;
uint32_t deltaAddress = ptr - store[n].data();
// Getting any data from the right "block" is ok.

View File

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

View File

@ -15,8 +15,8 @@ class ModeListEntry : public SerializeIF, public LinkedElement<ModeListEntry> {
uint8_t value3 = 0;
uint8_t value4 = 0;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const {
ReturnValue_t result;
result = SerializeAdapter::serialize(&value1, buffer, size, maxSize, streamEndianness);
@ -40,12 +40,12 @@ class ModeListEntry : public SerializeIF, public LinkedElement<ModeListEntry> {
return result;
}
size_t getSerializedSize() const override {
virtual size_t getSerializedSize() const {
return sizeof(value1) + sizeof(value2) + sizeof(value3) + sizeof(value4);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
ReturnValue_t result;
result = SerializeAdapter::deSerialize(&value1, buffer, size, streamEndianness);

View File

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

View File

@ -196,12 +196,11 @@ 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);
Clock::getUptime(uptimeOfSwitching);
*uptimeOfSwitching = Clock::getUptime_ms();
} else {
uint32_t currentUptime;
Clock::getUptime(&currentUptime);
uint32_t currentUptime = Clock::getUptime_ms();
if (currentUptime - *uptimeOfSwitching > powerSwitcher->getSwitchDelayMs()) {
*uptimeOfSwitching = INVALID_UPTIME;
if (healthHelper.healthTable->isHealthy(getObjectId())) {

View File

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

View File

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

View File

@ -16,6 +16,7 @@
class Clock {
public:
// https://xkcd.com/927/
typedef struct {
uint32_t year; //!< Year, A.D.
uint32_t month; //!< Month, 1 .. 12.
@ -26,14 +27,6 @@ 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.
@ -61,13 +54,8 @@ class Clock {
/**
* Get the time since boot in a timeval struct
*
* @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()
* @return a timeval struct where the uptime is stored
*/
static ReturnValue_t getUptime(timeval *uptime);
static timeval getUptime();
/**
@ -79,7 +67,7 @@ class Clock {
* @param ms uptime in ms
* @return returnvalue::OK on success. Otherwise, the OS failure code is returned.
*/
static ReturnValue_t getUptime(uint32_t *uptimeMs);
static uint32_t getUptime_ms();
/**
* Returns the time in microseconds since an OS-defined epoch.
@ -90,6 +78,7 @@ 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.
@ -106,6 +95,7 @@ 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,5 +1,7 @@
#include <cstdlib>
#include <ctime>
#include "boost_timegm.h"
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/timemanager/Clock.h"
@ -53,34 +55,58 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
}
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
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;
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;
}
// 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
timeInfo = gmtime(&from->tv_sec);
void* result = gmtime_r(&from->tv_sec, &time_tm);
if (result == nullptr) {
return returnvalue::FAILED;
}
#endif
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->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->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();
@ -94,3 +120,37 @@ 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) {
ReturnValue_t returnValue = Clock::getUptime(&startTime);
startTime = Clock::getUptime_ms();
timeout = milliseconds;
return returnValue;
return returnvalue::OK;
}
bool Countdown::hasTimedOut() const {
@ -38,8 +38,4 @@ uint32_t Countdown::getRemainingMillis() const {
}
}
uint32_t Countdown::getCurrentTime() const {
uint32_t currentTime;
Clock::getUptime(&currentTime);
return currentTime;
}
uint32_t Countdown::getCurrentTime() const { return Clock::getUptime_ms(); }

View File

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

View File

@ -3,12 +3,17 @@
#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

@ -0,0 +1,66 @@
// (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

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

View File

@ -40,7 +40,7 @@ struct PusTmParams {
size_t dataLen)
: secHeader(service, subservice, timeStamper), adapter(data, dataLen), sourceData(&adapter) {}
PusTmSecHeader secHeader;
SerialBufferAdapter<size_t> adapter;
SerialBufferAdapter<uint8_t> adapter;
const SerializeIF* sourceData = nullptr;
};

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) {
Clock::getUptime(&iter->second.uptimeOfStart);
iter->second.uptimeOfStart = Clock::getUptime_ms();
iter->second.step = 0;
iter->second.subservice = tcReader.getSubService();
iter->second.command = command.getCommand();
@ -434,8 +434,7 @@ inline void CommandingServiceBase::doPeriodicOperation() {}
MessageQueueId_t CommandingServiceBase::getCommandQueue() { return commandQueue->getId(); }
void CommandingServiceBase::checkTimeout() {
uint32_t uptime;
Clock::getUptime(&uptime);
uint32_t uptime = Clock::getUptime_ms();
CommandMapIter iter;
for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) {
if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) {

View File

@ -1,7 +1,7 @@
#include <stdbool.h>
#include <stdio.h>
void __attribute__((weak)) printChar(const char* character, bool errStream) {
void 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

@ -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, lastError,
sif::printError("%s pclose failed with code %d: %s\n", funcName.c_str(), 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, readVec.data());
sif::printInfo("%s | %s", currentCmd.c_str(), 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, output);
sif::printInfo("%s | %s", currentCmd.c_str(), output.c_str());
#endif
}
if (ringBuffer != nullptr) {

View File

@ -146,8 +146,9 @@ ReturnValue_t testserialize::test_autoserialization() {
}
// These epsilon values were just guessed.. It appears to work though.
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) {
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) {
return unitt::put_error(id);
}

View File

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

View File

@ -10,16 +10,118 @@
#define CATCH_CONFIG_COLOUR_WINDOWS
#include <fsfw/osal/osal.h>
#include <catch2/catch_session.hpp>
#ifdef FSFW_OSAL_FREERTOS
#include <FreeRTOS.h>
#include "task.h"
#endif
extern int customSetup();
extern int customTeardown();
#ifdef FSFW_OSAL_FREERTOS
struct Taskparameters {
int argc;
char** argv;
TaskHandle_t catchTask;
} taskParameters;
void unittestTaskFunction(void* pvParameters) {
Taskparameters* parameters = (Taskparameters*)pvParameters;
int result = Catch::Session().run(parameters->argc, parameters->argv);
vTaskDelay(pdMS_TO_TICKS(10));
vTaskSuspendAll();
vTaskDelete(parameters->catchTask);
customTeardown();
exit(result);
}
#endif
#ifdef FSFW_OSAL_RTEMS
#include <signal.h>
int sigaltstack(const stack_t* ss, stack_t* old_ss) { return 0; }
extern "C" {
void exit_qemu_failing(int error) {
asm(/* 0x20026 == ADP_Stopped_ApplicationExit */
"mov x1, #0x26\n\t"
"movk x1, #2, lsl #16\n\t"
"str x1, [sp,#0]\n\t");
/* Exit status code. Host QEMU process exits with that status. */
asm("mov x0, %[error]\n\t" : : [error] "r"(error));
asm("str x0, [sp,#8]\n\t"
/* x1 contains the address of parameter block.
* Any memory address could be used. */
"mov x1, sp\n\t"
/* SYS_EXIT */
"mov w0, #0x18\n\t"
/* Do the semihosting call on A64. */
"hlt 0xf000\n\t");
}
#include <rtemsConfig.h>
void user_handle_fatal(Internal_errors_Source source, bool internal, Internal_errors_t error_code) {
if (source == RTEMS_FATAL_SOURCE_EXIT) {
if (error_code != 0) {
printk("*** EXIT STATUS NOT ZERO ***\n");
printk("Quitting qemu with exit code %i\n", error_code);
exit_qemu_failing(error_code);
}
}
}
rtems_task Init(rtems_task_argument ignored) {
rtems_time_of_day now;
now.year = 2023;
now.month = 1;
now.day = 15;
now.hour = 0;
now.minute = 0;
now.second = 0;
now.ticks = 0;
rtems_clock_set(&now);
customSetup();
const char* argv[] = {"fsfw-test", ""};
int result = Catch::Session().run(1, argv);
customTeardown();
exit(result);
}
}
#endif
int main(int argc, char* argv[]) {
customSetup();
int result = 0;
#ifdef FSFW_OSAL_FREERTOS
xTaskCreate(
unittestTaskFunction, /* The function that implements the task. */
"Unittests", /* The text name assigned to the task - for debug only as it is not used by the
kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
&taskParameters, /* The parameter passed to the task - not used in this simple case. */
1, /* The priority assigned to the task. */
&taskParameters.catchTask); /* The task handle is not required, so NULL is passed. */
taskParameters.argc = argc;
taskParameters.argv = argv;
vTaskStartScheduler();
#else
// Catch internal function call
int result = Catch::Session().run(argc, argv);
result = Catch::Session().run(argc, argv);
#endif
// global clean-up
customTeardown();

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