Compare commits
42 Commits
master
...
mohr/warni
Author | SHA1 | Date | |
---|---|---|---|
2ca9eb4204 | |||
45b686a028 | |||
329e80e7ee | |||
3772db4753 | |||
3d13ead275 | |||
e7e9ce4baf | |||
e4c11f8107 | |||
270622a5f1 | |||
4b52e5bec4 | |||
efc2773f84 | |||
87bb29a66a | |||
45963b2064 | |||
bc312243df | |||
9589d702dd | |||
c66fab90f9 | |||
3e8446ba8b | |||
e37af4fe70 | |||
941bf61f28 | |||
70fd9ff3e5 | |||
81c5b2ec95 | |||
7426e10f82 | |||
|
123c81777a | ||
dcc28622a5 | |||
6d85fa155e | |||
e6af6200ae | |||
5ca3e83934 | |||
6adabb059a | |||
5d0a5cd201 | |||
adb8483bb0 | |||
fdfdce2fb0 | |||
90efb132d0 | |||
fe9804d922 | |||
a0eae66c35 | |||
e131480d5f | |||
90bafbb6de | |||
47d85fb61c | |||
39dad5f45b | |||
a993c4e0d4 | |||
fe9cc20d00 | |||
552a12a6ad | |||
13639feec6 | |||
654de0f586 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "automation/msvc-wine"]
|
||||||
|
path = automation/msvc-wine
|
||||||
|
url = https://github.com/mstorsjo/msvc-wine
|
@ -64,6 +64,13 @@ elseif(${CMAKE_CXX_STANDARD} LESS 17)
|
|||||||
"${MSG_PREFIX} Compiling the FSFW requires a minimum of C++17 support")
|
"${MSG_PREFIX} Compiling the FSFW requires a minimum of C++17 support")
|
||||||
endif()
|
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_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw")
|
||||||
|
|
||||||
set(FSFW_ETL_LIB_NAME etl)
|
set(FSFW_ETL_LIB_NAME etl)
|
||||||
@ -153,7 +160,7 @@ if(FSFW_BUILD_TESTS)
|
|||||||
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||||
)
|
)
|
||||||
# Check whether the user has already installed Catch2 first
|
# Check whether the user has already installed Catch2 first
|
||||||
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION})
|
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} QUIET)
|
||||||
# Not installed, so use FetchContent to download and provide Catch2
|
# Not installed, so use FetchContent to download and provide Catch2
|
||||||
if(NOT Catch2_FOUND)
|
if(NOT Catch2_FOUND)
|
||||||
message(
|
message(
|
||||||
@ -174,6 +181,27 @@ if(FSFW_BUILD_TESTS)
|
|||||||
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
||||||
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.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)
|
project(${FSFW_TEST_TGT} CXX C)
|
||||||
add_executable(${FSFW_TEST_TGT})
|
add_executable(${FSFW_TEST_TGT})
|
||||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
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
|
# GitHub issue: https://github.com/catchorg/Catch2/issues/2417
|
||||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FSFW_CORE_INC_PATH "inc")
|
set(FSFW_CORE_INC_PATH "inc")
|
||||||
@ -360,6 +389,9 @@ if(FSFW_BUILD_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2
|
target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2
|
||||||
${LIB_FSFW_NAME})
|
${LIB_FSFW_NAME})
|
||||||
|
if(FSFW_OSAL MATCHES "freertos")
|
||||||
|
target_link_libraries(${FSFW_TEST_TGT} PRIVATE FreeRTOS)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. If
|
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. If
|
||||||
@ -447,8 +479,47 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(COMPILER_FLAGS "/permissive-")
|
set(FSFW_WARNING_FLAGS
|
||||||
|
-Weverything
|
||||||
|
|
||||||
|
-Wno-gnu-anonymous-struct
|
||||||
|
-Wno-c++98-compat
|
||||||
|
-Wno-c++98-compat-pedantic
|
||||||
|
-Wno-covered-switch-default
|
||||||
|
-Wno-padded
|
||||||
|
-Wno-documentation
|
||||||
|
-Wno-weak-vtables
|
||||||
|
-Wno-c++98-c++11-compat-binary-literal
|
||||||
|
-Wno-documentation-unknown-command
|
||||||
|
-Wno-reserved-macro-identifier
|
||||||
|
-Wno-global-constructors
|
||||||
|
-Wno-reserved-identifier
|
||||||
|
-Wno-switch-enum
|
||||||
|
|
||||||
|
-Werror
|
||||||
|
#WTH?
|
||||||
|
-Wno-ctad-maybe-unsupported
|
||||||
|
#WIP
|
||||||
|
-Wno-undefined-func-template
|
||||||
|
-Wno-suggest-destructor-override
|
||||||
|
-Wno-suggest-override
|
||||||
|
-Wno-inconsistent-missing-destructor-override
|
||||||
|
-Wno-extra-semi
|
||||||
|
#could be useful:
|
||||||
|
-Wno-sign-conversion
|
||||||
|
-Wno-implicit-int-conversion
|
||||||
|
-Wno-shorten-64-to-32
|
||||||
|
-Wno-double-promotion
|
||||||
|
-Wno-float-conversion
|
||||||
|
-Wno-implicit-int-float-conversion
|
||||||
|
-Wno-implicit-float-conversion
|
||||||
|
-Wno-shadow-field-in-constructor
|
||||||
|
-Wno-shadow-field
|
||||||
|
-Wno-shadow
|
||||||
|
-Wno-unused-parameter
|
||||||
|
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Required include paths to compile the FSFW
|
# Required include paths to compile the FSFW
|
||||||
|
@ -5,7 +5,7 @@ RUN apt-get --yes upgrade
|
|||||||
|
|
||||||
#tzdata is a dependency, won't install otherwise
|
#tzdata is a dependency, won't install otherwise
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping 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
|
||||||
|
|
||||||
RUN python3 -m pip install sphinx breathe
|
RUN python3 -m pip install sphinx breathe
|
||||||
|
|
||||||
@ -21,8 +21,36 @@ RUN git clone https://github.com/ETLCPP/etl.git && \
|
|||||||
cmake -B build . && \
|
cmake -B build . && \
|
||||||
cmake --install 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
|
#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
|
#add documentation server to known hosts
|
||||||
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||||
|
100
automation/Jenkinsfile
vendored
100
automation/Jenkinsfile
vendored
@ -2,87 +2,73 @@ pipeline {
|
|||||||
environment {
|
environment {
|
||||||
BUILDDIR_HOST = 'cmake-build-tests-host'
|
BUILDDIR_HOST = 'cmake-build-tests-host'
|
||||||
BUILDDIR_LINUX = 'cmake-build-tests-linux'
|
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'
|
DOCDDIR = 'cmake-build-documentation'
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
image 'fsfw-ci:d6'
|
image 'fsfw-ci:d9'
|
||||||
args '--network host --sysctl fs.mqueue.msg_max=100'
|
args '--network host --sysctl fs.mqueue.msg_max=100'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('Host') {
|
stage('Host-clang') {
|
||||||
stages{
|
|
||||||
stage('Clean') {
|
|
||||||
steps {
|
steps {
|
||||||
sh 'rm -rf $BUILDDIR_HOST'
|
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) {
|
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 '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'
|
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
stage('Linux-gcc') {
|
||||||
}
|
|
||||||
stage('Linux') {
|
|
||||||
stages{
|
|
||||||
stage('Clean') {
|
|
||||||
steps {
|
steps {
|
||||||
sh 'rm -rf $BUILDDIR_LINUX'
|
sh 'rm -rf $BUILDDIR_LINUX'
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Configure') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_LINUX) {
|
dir(BUILDDIR_LINUX) {
|
||||||
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Build') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_LINUX) {
|
|
||||||
sh 'cmake --build . -j4'
|
sh 'cmake --build . -j4'
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Unittests') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_LINUX) {
|
|
||||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Valgrind') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_LINUX) {
|
|
||||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage('FreeRTOS-gcc') {
|
||||||
|
steps {
|
||||||
|
sh 'rm -rf $BUILDDIR_FREERTOS'
|
||||||
|
|
||||||
|
dir(BUILDDIR_FREERTOS) {
|
||||||
|
sh 'cmake -DFSFW_OSAL=freertos -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||||
|
sh 'cmake --build . -j4'
|
||||||
|
sh './fsfw-tests'
|
||||||
|
//sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('rtems-gcc') {
|
||||||
|
steps {
|
||||||
|
sh 'rm -rf $BUILDDIR_RTEMS'
|
||||||
|
|
||||||
|
dir(BUILDDIR_RTEMS) {
|
||||||
|
sh 'cmake -DFSFW_OSAL=rtems -DFSFW_BUILD_TESTS=ON -DFSFW_TESTS_GEN_COV=OFF -DFSFW_CICD_BUILD=ON -DCMAKE_TOOLCHAIN_FILE=../unittests/testcfg/rtems/cmake/aarch64-rtems6-toolchain.cmake ..'
|
||||||
|
sh 'cmake --build . -j4'
|
||||||
|
sh 'qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -semihosting -machine virt,gic-version=3 -cpu cortex-a72 -m 4000 -kernel fsfw-tests'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Host-msvc') {
|
||||||
|
steps {
|
||||||
|
sh 'rm -rf $BUILDDIR_WIN'
|
||||||
|
|
||||||
|
dir(BUILDDIR_WIN) {
|
||||||
|
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_TESTS_GEN_COV=OFF -DFSFW_CICD_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../unittests/testcfg/windows/cmake/x64-windows-toolchain.cmake -GNinja ..'
|
||||||
|
sh 'cmake --build . -j4'
|
||||||
|
sh 'wine64 fsfw-tests.exe'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Documentation') {
|
stage('Documentation') {
|
||||||
@ -97,7 +83,7 @@ pipeline {
|
|||||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
|
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR_LINUX) {
|
||||||
sshagent(credentials: ['documentation-buildfix']) {
|
sshagent(credentials: ['documentation-buildfix']) {
|
||||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
|
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/development'
|
||||||
}
|
}
|
||||||
@ -116,7 +102,7 @@ pipeline {
|
|||||||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
|
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/master'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir(BUILDDIR) {
|
dir(BUILDDIR_LINUX) {
|
||||||
sshagent(credentials: ['documentation-buildfix']) {
|
sshagent(credentials: ['documentation-buildfix']) {
|
||||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
||||||
}
|
}
|
||||||
|
1
automation/msvc-wine
Submodule
1
automation/msvc-wine
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 2d2d7db0b55b0f061eca5f4f1c149608d5501ec6
|
@ -21,7 +21,7 @@ struct FileSize : public SerializeIF {
|
|||||||
this->largeFile = isLarge;
|
this->largeFile = isLarge;
|
||||||
return serialize(buffer, size, maxSize, streamEndianness);
|
return serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
using SerializeIF::serialize;
|
||||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override {
|
Endianness streamEndianness) const override {
|
||||||
if (not largeFile) {
|
if (not largeFile) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface.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);
|
ReturnValue_t result = this->setValue(width, value);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
#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; }
|
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) {
|
switch (widthInBytes) {
|
||||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||||
if (value_ > UINT8_MAX) {
|
if (value_ > UINT8_MAX) {
|
||||||
@ -51,7 +51,7 @@ ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cfdp::VarLenField::getValue() const {
|
uint64_t cfdp::VarLenField::getValue() const {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||||
return value.oneByte;
|
return value.oneByte;
|
||||||
|
@ -25,13 +25,13 @@ class VarLenField : public SerializeIF {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
explicit VarLenField(UnsignedByteField<T> byteField);
|
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;
|
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,
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
@ -42,7 +42,7 @@ class VarLenField : public SerializeIF {
|
|||||||
Endianness streamEndianness);
|
Endianness streamEndianness);
|
||||||
|
|
||||||
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
|
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
|
||||||
[[nodiscard]] size_t getValue() const;
|
[[nodiscard]] uint64_t getValue() const;
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
|
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
|
||||||
@ -53,6 +53,7 @@ class VarLenField : public SerializeIF {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using SerializeIF::deSerialize;
|
||||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
@ -9,6 +9,11 @@
|
|||||||
#include "fsfw/returnvalues/FwClassIds.h"
|
#include "fsfw/returnvalues/FwClassIds.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
// Thanks, windows
|
||||||
|
#ifdef NO_ERROR
|
||||||
|
#undef NO_ERROR
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
|
|
||||||
static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";
|
static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";
|
||||||
|
@ -68,6 +68,7 @@ class UserBase {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit UserBase(HasFileSystemIF& vfs);
|
explicit UserBase(HasFileSystemIF& vfs);
|
||||||
|
virtual ~UserBase() = default;
|
||||||
|
|
||||||
virtual void transactionIndication(const TransactionId& id) = 0;
|
virtual void transactionIndication(const TransactionId& id) = 0;
|
||||||
virtual void eofSentIndication(const TransactionId& id) = 0;
|
virtual void eofSentIndication(const TransactionId& id) = 0;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
const char* COND_CODE_STRINGS[14] = {"Unknown",
|
static const char* COND_CODE_STRINGS[14] = {"Unknown",
|
||||||
"No Error",
|
"No Error",
|
||||||
"Positive ACK Limit Reached",
|
"Positive ACK Limit Reached",
|
||||||
"Keep Alive Limit Reached",
|
"Keep Alive Limit Reached",
|
||||||
|
@ -42,6 +42,6 @@ size_t EofInfo::getSerializedSize(bool fssLarge) {
|
|||||||
return size;
|
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);
|
return this->fileSize.setFileSize(fileSize, isLarge);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ struct EofInfo {
|
|||||||
void setChecksum(uint32_t checksum);
|
void setChecksum(uint32_t checksum);
|
||||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||||
void setFaultLoc(EntityIdTlv* faultLoc);
|
void setFaultLoc(EntityIdTlv* faultLoc);
|
||||||
ReturnValue_t setFileSize(size_t size, bool isLarge);
|
ReturnValue_t setFileSize(uint64_t size, bool isLarge);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cfdp::ConditionCode conditionCode;
|
cfdp::ConditionCode conditionCode;
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
#include "FinishedPduReader.h"
|
#include "FinishedPduReader.h"
|
||||||
|
|
||||||
|
// Thanks, windows
|
||||||
|
#ifdef NO_ERROR
|
||||||
|
#undef NO_ERROR
|
||||||
|
#endif
|
||||||
|
|
||||||
FinishPduReader::FinishPduReader(const uint8_t* pduBuf, size_t maxSize, FinishedInfo& info)
|
FinishPduReader::FinishPduReader(const uint8_t* pduBuf, size_t maxSize, FinishedInfo& info)
|
||||||
: FileDirectiveReader(pduBuf, maxSize), finishedInfo(info) {}
|
: FileDirectiveReader(pduBuf, maxSize), finishedInfo(info) {}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ class EntityIdTlv : public TlvIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||||
|
|
||||||
|
using SerializeIF::deSerialize;
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ class FilestoreRequestTlv : public cfdp::FilestoreTlvBase {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t deSerialize(cfdp::Tlv &tlv, Endianness endianness);
|
ReturnValue_t deSerialize(cfdp::Tlv &tlv, Endianness endianness);
|
||||||
|
|
||||||
|
using SerializeIF::deSerialize;
|
||||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
||||||
|
|
||||||
|
using SerializeIF::deSerialize;
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
template <typename Tp>
|
template <typename Tp>
|
||||||
class BinaryNode {
|
class BinaryNode {
|
||||||
public:
|
public:
|
||||||
BinaryNode(Tp* setValue) : value(setValue), left(NULL), right(NULL), parent(NULL) {}
|
BinaryNode(Tp* setValue) : value(setValue), left(nullptr), right(nullptr), parent(nullptr) {}
|
||||||
Tp* value;
|
Tp* value;
|
||||||
BinaryNode* left;
|
BinaryNode* left;
|
||||||
BinaryNode* right;
|
BinaryNode* right;
|
||||||
@ -23,31 +23,31 @@ class ExplicitNodeIterator {
|
|||||||
typedef Tp value_type;
|
typedef Tp value_type;
|
||||||
typedef Tp* pointer;
|
typedef Tp* pointer;
|
||||||
typedef Tp& reference;
|
typedef Tp& reference;
|
||||||
ExplicitNodeIterator() : element(NULL) {}
|
ExplicitNodeIterator() : element(nullptr) {}
|
||||||
ExplicitNodeIterator(_Node* node) : element(node) {}
|
ExplicitNodeIterator(_Node* node) : element(node) {}
|
||||||
BinaryNode<Tp>* element;
|
BinaryNode<Tp>* element;
|
||||||
_Self up() { return _Self(element->parent); }
|
_Self up() { return _Self(element->parent); }
|
||||||
_Self left() {
|
_Self left() {
|
||||||
if (element != NULL) {
|
if (element != nullptr) {
|
||||||
return _Self(element->left);
|
return _Self(element->left);
|
||||||
} else {
|
} else {
|
||||||
return _Self(NULL);
|
return _Self(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_Self right() {
|
_Self right() {
|
||||||
if (element != NULL) {
|
if (element != nullptr) {
|
||||||
return _Self(element->right);
|
return _Self(element->right);
|
||||||
} else {
|
} else {
|
||||||
return _Self(NULL);
|
return _Self(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool operator==(const _Self& __x) const { return element == __x.element; }
|
bool operator==(const _Self& __x) const { return element == __x.element; }
|
||||||
bool operator!=(const _Self& __x) const { return element != __x.element; }
|
bool operator!=(const _Self& __x) const { return element != __x.element; }
|
||||||
pointer operator->() const {
|
pointer operator->() const {
|
||||||
if (element != NULL) {
|
if (element != nullptr) {
|
||||||
return element->value;
|
return element->value;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pointer operator*() const { return this->operator->(); }
|
pointer operator*() const { return this->operator->(); }
|
||||||
@ -62,13 +62,13 @@ class BinaryTree {
|
|||||||
typedef ExplicitNodeIterator<Tp> iterator;
|
typedef ExplicitNodeIterator<Tp> iterator;
|
||||||
typedef BinaryNode<Tp> Node;
|
typedef BinaryNode<Tp> Node;
|
||||||
typedef std::pair<iterator, iterator> children;
|
typedef std::pair<iterator, iterator> children;
|
||||||
BinaryTree() : rootNode(NULL) {}
|
BinaryTree() : rootNode(nullptr) {}
|
||||||
BinaryTree(Node* rootNode) : rootNode(rootNode) {}
|
BinaryTree(Node* rootNode) : rootNode(rootNode) {}
|
||||||
iterator begin() const { return iterator(rootNode); }
|
iterator begin() const { return iterator(rootNode); }
|
||||||
static iterator end() { return iterator(NULL); }
|
static iterator end() { return iterator(nullptr); }
|
||||||
iterator insert(bool insertLeft, iterator parentNode, Node* newNode) {
|
iterator insert(bool insertLeft, iterator parentNode, Node* newNode) {
|
||||||
newNode->parent = parentNode.element;
|
newNode->parent = parentNode.element;
|
||||||
if (parentNode.element != NULL) {
|
if (parentNode.element != nullptr) {
|
||||||
if (insertLeft) {
|
if (insertLeft) {
|
||||||
parentNode.element->left = newNode;
|
parentNode.element->left = newNode;
|
||||||
} else {
|
} else {
|
||||||
@ -84,13 +84,13 @@ class BinaryTree {
|
|||||||
children erase(iterator node) {
|
children erase(iterator node) {
|
||||||
if (node.element == rootNode) {
|
if (node.element == rootNode) {
|
||||||
// We're root node
|
// We're root node
|
||||||
rootNode = NULL;
|
rootNode = nullptr;
|
||||||
} else {
|
} else {
|
||||||
// Delete parent's reference
|
// Delete parent's reference
|
||||||
if (node.up().left() == node) {
|
if (node.up().left() == node) {
|
||||||
node.up().element->left = NULL;
|
node.up().element->left = nullptr;
|
||||||
} else {
|
} else {
|
||||||
node.up().element->right = NULL;
|
node.up().element->right = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return children(node.element->left, node.element->right);
|
return children(node.element->left, node.element->right);
|
||||||
|
@ -61,7 +61,7 @@ class PlacementFactory {
|
|||||||
// Need to call destructor first, in case something was allocated by the object (shouldn't do
|
// Need to call destructor first, in case something was allocated by the object (shouldn't do
|
||||||
// that, however).
|
// that, however).
|
||||||
thisElement->~T();
|
thisElement->~T();
|
||||||
uint8_t* pointer = (uint8_t*)(thisElement);
|
uint8_t* pointer = static_cast<uint8_t*>(thisElement);
|
||||||
return dataBackend->deleteData(pointer, sizeof(T));
|
return dataBackend->deleteData(pointer, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,6 @@ ReturnValue_t LocalDataPoolManager::addUpdateToStore(HousekeepingSnapshot& updat
|
|||||||
result = updatePacket.serialize(&storePtr, &serializedSize, updatePacketSize,
|
result = updatePacket.serialize(&storePtr, &serializedSize, updatePacketSize,
|
||||||
SerializeIF::Endianness::MACHINE);
|
SerializeIF::Endianness::MACHINE);
|
||||||
return result;
|
return result;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalDataPoolManager::handleChangeResetLogic(DataType type, DataId dataId,
|
void LocalDataPoolManager::handleChangeResetLogic(DataType type, DataId dataId,
|
||||||
|
@ -364,6 +364,10 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
void printWarningOrError(sif::OutputTypes outputType, const char* functionName,
|
void printWarningOrError(sif::OutputTypes outputType, const char* functionName,
|
||||||
ReturnValue_t errorCode = returnvalue::FAILED,
|
ReturnValue_t errorCode = returnvalue::FAILED,
|
||||||
const char* errorPrint = nullptr);
|
const char* errorPrint = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using ProvidesDataPoolSubscriptionIF::subscribeForPeriodicPacket;
|
||||||
|
using ProvidesDataPoolSubscriptionIF::subscribeForUpdatePacket;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -27,7 +27,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
|
|||||||
|
|
||||||
if (parentId != objects::NO_OBJECT) {
|
if (parentId != objects::NO_OBJECT) {
|
||||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||||
if (parent == NULL) {
|
if (parent == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
parentQueue = parent->getCommandQueue();
|
parentQueue = parent->getCommandQueue();
|
||||||
|
@ -322,8 +322,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
if (mode != currentMode) {
|
if (mode != currentMode) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint32_t currentUptime;
|
uint32_t currentUptime = Clock::getUptime_ms();
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
if (currentUptime - timeoutStart >= childTransitionDelay) {
|
if (currentUptime - timeoutStart >= childTransitionDelay) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0
|
#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0
|
||||||
char printout[60];
|
char printout[60];
|
||||||
@ -347,8 +346,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
setMode(_MODE_WAIT_ON);
|
setMode(_MODE_WAIT_ON);
|
||||||
break;
|
break;
|
||||||
case _MODE_WAIT_ON: {
|
case _MODE_WAIT_ON: {
|
||||||
uint32_t currentUptime;
|
uint32_t currentUptime = Clock::getUptime_ms();
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
if (powerSwitcher != nullptr and
|
if (powerSwitcher != nullptr and
|
||||||
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||||
@ -367,8 +365,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case _MODE_WAIT_OFF: {
|
case _MODE_WAIT_OFF: {
|
||||||
uint32_t currentUptime;
|
uint32_t currentUptime = Clock::getUptime_ms();
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
|
|
||||||
if (powerSwitcher == nullptr) {
|
if (powerSwitcher == nullptr) {
|
||||||
setMode(MODE_OFF);
|
setMode(MODE_OFF);
|
||||||
@ -578,7 +575,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
|||||||
modeHelper.modeChanged(newMode, newSubmode);
|
modeHelper.modeChanged(newMode, newSubmode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
}
|
}
|
||||||
Clock::getUptime(&timeoutStart);
|
timeoutStart = Clock::getUptime_ms();
|
||||||
|
|
||||||
if (mode == MODE_OFF and thermalSet != nullptr) {
|
if (mode == MODE_OFF and thermalSet != nullptr) {
|
||||||
ReturnValue_t result = thermalSet->read();
|
ReturnValue_t result = thermalSet->read();
|
||||||
@ -937,19 +934,14 @@ DeviceHandlerIF::CommunicationAction DeviceHandlerBase::getComAction() {
|
|||||||
switch (pstStep) {
|
switch (pstStep) {
|
||||||
case 0:
|
case 0:
|
||||||
return CommunicationAction::PERFORM_OPERATION;
|
return CommunicationAction::PERFORM_OPERATION;
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
return CommunicationAction::SEND_WRITE;
|
return CommunicationAction::SEND_WRITE;
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
return CommunicationAction::GET_WRITE;
|
return CommunicationAction::GET_WRITE;
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
return CommunicationAction::SEND_READ;
|
return CommunicationAction::SEND_READ;
|
||||||
break;
|
|
||||||
case 4:
|
case 4:
|
||||||
return CommunicationAction::GET_READ;
|
return CommunicationAction::GET_READ;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -965,7 +957,7 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
|
|||||||
replyReturnvalueToCommand(result, RAW_COMMAND_ID);
|
replyReturnvalueToCommand(result, RAW_COMMAND_ID);
|
||||||
storedRawData.raw = StorageManagerIF::INVALID_ADDRESS;
|
storedRawData.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||||
} else {
|
} else {
|
||||||
cookieInfo.pendingCommand = deviceCommandMap.find((DeviceCommandId_t)RAW_COMMAND_ID);
|
cookieInfo.pendingCommand = deviceCommandMap.find(static_cast<DeviceCommandId_t>(RAW_COMMAND_ID));
|
||||||
cookieInfo.pendingCommand->second.isExecuting = true;
|
cookieInfo.pendingCommand->second.isExecuting = true;
|
||||||
cookieInfo.state = COOKIE_WRITE_READY;
|
cookieInfo.state = COOKIE_WRITE_READY;
|
||||||
}
|
}
|
||||||
|
@ -206,9 +206,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
|
|
||||||
Mode_t getTransitionSourceMode() const;
|
Mode_t getTransitionSourceMode() const;
|
||||||
Submode_t getTransitionSourceSubMode() const;
|
Submode_t getTransitionSourceSubMode() const;
|
||||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||||
HealthState getHealth();
|
HealthState getHealth() override;
|
||||||
ReturnValue_t setHealth(HealthState health);
|
ReturnValue_t setHealth(HealthState health) override;
|
||||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper,
|
||||||
const ParameterWrapper *newValues,
|
const ParameterWrapper *newValues,
|
||||||
@ -1073,7 +1073,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
bool forceDirectTm = false);
|
bool forceDirectTm = false);
|
||||||
|
|
||||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t *msToReachTheMode);
|
uint32_t *msToReachTheMode) override;
|
||||||
|
|
||||||
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
|
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ void DeviceHandlerMessage::clear(CommandMessage* message) {
|
|||||||
ipcStore->deleteData(getStoreAddress(message));
|
ipcStore->deleteData(getStoreAddress(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* NO BREAK falls through*/
|
[[fallthrough]];
|
||||||
case CMD_SWITCH_ADDRESS:
|
case CMD_SWITCH_ADDRESS:
|
||||||
case CMD_WIRETAPPING:
|
case CMD_WIRETAPPING:
|
||||||
message->setCommand(CommandMessage::CMD_NONE);
|
message->setCommand(CommandMessage::CMD_NONE);
|
||||||
|
@ -28,22 +28,23 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
|
|
||||||
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
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 unregisterListener(MessageQueueId_t listener) override;
|
||||||
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
|
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) override;
|
||||||
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
|
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) override;
|
||||||
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||||
EventId_t idTo = 0, bool idInverted = false,
|
EventId_t idTo = 0, bool idInverted = false,
|
||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false) override;
|
||||||
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object);
|
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) override;
|
||||||
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||||
EventId_t idTo = 0, bool idInverted = false,
|
EventId_t idTo = 0, bool idInverted = false,
|
||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false) override;
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* eventReportQueue = nullptr;
|
MessageQueueIF* eventReportQueue = nullptr;
|
||||||
|
@ -52,6 +52,7 @@ ReturnValue_t DleParser::parseRingBuf(size_t& readSize) {
|
|||||||
// without skipping the STX
|
// without skipping the STX
|
||||||
readSize = vectorIdx;
|
readSize = vectorIdx;
|
||||||
ErrorInfo info;
|
ErrorInfo info;
|
||||||
|
info.len = vectorIdx;
|
||||||
setErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
setErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
||||||
return POSSIBLE_PACKET_LOSS;
|
return POSSIBLE_PACKET_LOSS;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class Type : public SerializeIF {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct PodTypeConversion {
|
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 "
|
"Do not use boolean for the PoolEntry type, use uint8_t "
|
||||||
"instead! The ECSS standard defines a boolean as a one bit "
|
"instead! The ECSS standard defines a boolean as a one bit "
|
||||||
"field. Therefore it is preferred to store a boolean as an "
|
"field. Therefore it is preferred to store a boolean as an "
|
||||||
|
@ -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 FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
if (sif::info.crAdditionEnabled()) {
|
if (sif::info.crAdditionEnabled()) {
|
||||||
std::cout << "\r" << std::endl;
|
std::cout << "\r" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "hex [" << std::setfill('0') << std::hex;
|
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]);
|
std::cout << std::setw(2) << static_cast<int>(data[i]);
|
||||||
if (i < size - 1) {
|
if (i < datasize - 1) {
|
||||||
std::cout << ",";
|
std::cout << ",";
|
||||||
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||||
std::cout << std::endl;
|
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::dec << std::setfill(' ');
|
||||||
std::cout << "]" << std::endl;
|
std::cout << "]" << std::endl;
|
||||||
#else
|
#else
|
||||||
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
printf("hex [");
|
||||||
// plus line break plus small safety margin.
|
for (size_t i = 0; i < datasize; i++) {
|
||||||
char printBuffer[(size + 1) * 7 + 1] = {};
|
printf("0x%02x ", data[i]);
|
||||||
size_t currentPos = 0;
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
// To avoid buffer overflows.
|
|
||||||
if (sizeof(printBuffer) - currentPos <= 7) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
printf("]\n");
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
|
||||||
printf("hex [%s]\n", printBuffer);
|
|
||||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,26 +84,10 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerL
|
|||||||
#else
|
#else
|
||||||
// General format: 32,243,-12 so it is number of chars times 4
|
// General format: 32,243,-12 so it is number of chars times 4
|
||||||
// plus line break plus small safety margin.
|
// 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]);
|
for (size_t i = 0; i < size; i++) {
|
||||||
if (i < size - 1) {
|
// TODO
|
||||||
currentPos += sprintf(printBuffer + currentPos, ",");
|
|
||||||
if ((i + 1) % maxCharPerLine == 0) {
|
|
||||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
|
||||||
printf("dec [%s]\n", printBuffer);
|
|
||||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
||||||
|
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const {
|
Endianness streamEndianness) const override {
|
||||||
if (timeStamp != nullptr) {
|
if (timeStamp != nullptr) {
|
||||||
/* Endianness will always be MACHINE, so we can simply use memcpy
|
/* Endianness will always be MACHINE, so we can simply use memcpy
|
||||||
here. */
|
here. */
|
||||||
@ -70,7 +70,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t getSerializedSize() const {
|
virtual size_t getSerializedSize() const override {
|
||||||
if (updateData == nullptr) {
|
if (updateData == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class CommandMessage : public MessageQueueMessage, public CommandMessageIF {
|
|||||||
/**
|
/**
|
||||||
* @brief Default Destructor
|
* @brief Default Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~CommandMessage() {}
|
~CommandMessage() override {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the DeviceHandlerCommand_t that is stored in the message,
|
* Read the DeviceHandlerCommand_t that is stored in the message,
|
||||||
|
@ -37,7 +37,7 @@ class CommandMessageIF {
|
|||||||
//! par1 should contain the error code
|
//! par1 should contain the error code
|
||||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||||
|
|
||||||
virtual ~CommandMessageIF(){};
|
virtual ~CommandMessageIF() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A command message shall have a uint16_t command ID field.
|
* A command message shall have a uint16_t command ID field.
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||||
|
|
||||||
struct MqArgs {
|
struct MqArgs {
|
||||||
MqArgs(){};
|
MqArgs(){}
|
||||||
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
||||||
object_id_t objectId = objects::NO_OBJECT;
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
void* args = nullptr;
|
void* args = nullptr;
|
||||||
|
@ -18,7 +18,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
|||||||
violationEvent(violationEvent),
|
violationEvent(violationEvent),
|
||||||
aboveIsViolation(aboveIsViolation) {}
|
aboveIsViolation(aboveIsViolation) {}
|
||||||
virtual ~AbsLimitMonitor() {}
|
virtual ~AbsLimitMonitor() {}
|
||||||
virtual ReturnValue_t checkSample(T sample, T *crossedLimit) {
|
ReturnValue_t checkSample(T sample, T *crossedLimit) override {
|
||||||
*crossedLimit = limit;
|
*crossedLimit = limit;
|
||||||
if (aboveIsViolation) {
|
if (aboveIsViolation) {
|
||||||
if ((std::abs(sample) > limit)) {
|
if ((std::abs(sample) > limit)) {
|
||||||
@ -32,9 +32,9 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
|||||||
return returnvalue::OK; // We're not out of range.
|
return returnvalue::OK; // We're not out of range.
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
uint16_t startAtIndex) override {
|
||||||
ReturnValue_t result = this->MonitorBase<T>::getParameter(
|
ReturnValue_t result = this->MonitorBase<T>::getParameter(
|
||||||
domainId, parameterId, parameterWrapper, newValues, startAtIndex);
|
domainId, parameterId, parameterWrapper, newValues, startAtIndex);
|
||||||
// We'll reuse the DOMAIN_ID of MonitorReporter,
|
// We'll reuse the DOMAIN_ID of MonitorReporter,
|
||||||
@ -61,7 +61,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
|||||||
void setLimit(T value) { limit = value; }
|
void setLimit(T value) { limit = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sendTransitionEvent(T currentValue, ReturnValue_t state) {
|
void sendTransitionEvent(T currentValue, ReturnValue_t state) override {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case MonitoringIF::OUT_OF_RANGE:
|
case MonitoringIF::OUT_OF_RANGE:
|
||||||
EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->globalPoolId.objectId,
|
EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->globalPoolId.objectId,
|
||||||
|
@ -40,7 +40,7 @@ class ObjectManagerIF {
|
|||||||
/**
|
/**
|
||||||
* @brief This is the empty virtual destructor as requested by C++ interfaces.
|
* @brief This is the empty virtual destructor as requested by C++ interfaces.
|
||||||
*/
|
*/
|
||||||
virtual ~ObjectManagerIF(void){};
|
virtual ~ObjectManagerIF(void){}
|
||||||
/**
|
/**
|
||||||
* @brief With this call, new objects are inserted to the list.
|
* @brief With this call, new objects are inserted to the list.
|
||||||
* @details The implementation shall return an error code in case the
|
* @details The implementation shall return an error code in case the
|
||||||
|
@ -45,7 +45,7 @@ class SystemObject : public SystemObjectIF {
|
|||||||
/**
|
/**
|
||||||
* @brief On destruction, the object removes itself from the list.
|
* @brief On destruction, the object removes itself from the list.
|
||||||
*/
|
*/
|
||||||
virtual ~SystemObject();
|
~SystemObject() override;
|
||||||
object_id_t getObjectId() const override;
|
object_id_t getObjectId() const override;
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
virtual ReturnValue_t checkObjectConnections() override;
|
virtual ReturnValue_t checkObjectConnections() override;
|
||||||
|
@ -36,7 +36,7 @@ class SystemObjectIF : public EventReportingProxyIF {
|
|||||||
/**
|
/**
|
||||||
* The empty virtual destructor as required for C++ interfaces.
|
* The empty virtual destructor as required for C++ interfaces.
|
||||||
*/
|
*/
|
||||||
virtual ~SystemObjectIF() {}
|
~SystemObjectIF() override {}
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the object.
|
* @brief Initializes the object.
|
||||||
* There are initialization steps which can also be done in the constructor.
|
* There are initialization steps which can also be done in the constructor.
|
||||||
|
@ -24,8 +24,11 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
// Thanks, windows
|
||||||
|
// clang-format off
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
// clang-format on
|
||||||
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
|
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
|
||||||
#define BYTE_ORDER_SYSTEM LITTLE_ENDIAN
|
#define BYTE_ORDER_SYSTEM LITTLE_ENDIAN
|
||||||
#else
|
#else
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
typedef SSIZE_T ssize_t;
|
||||||
#elif defined(PLATFORM_UNIX)
|
#elif defined(PLATFORM_UNIX)
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
|||||||
|
|
||||||
ReceptionModes receptionMode;
|
ReceptionModes receptionMode;
|
||||||
TcpConfig tcpConfig;
|
TcpConfig tcpConfig;
|
||||||
struct sockaddr tcpAddress = {};
|
// struct sockaddr tcpAddress = {};
|
||||||
socket_t listenerTcpSocket = 0;
|
socket_t listenerTcpSocket = 0;
|
||||||
|
|
||||||
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
#elif defined(PLATFORM_UNIX)
|
#elif defined(PLATFORM_UNIX)
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
#elif defined(PLATFORM_UNIX)
|
#elif defined(PLATFORM_UNIX)
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
@ -40,7 +40,7 @@ class BinarySemaphoreUsingTask : public SemaphoreIF {
|
|||||||
void refreshTaskHandle();
|
void refreshTaskHandle();
|
||||||
|
|
||||||
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
||||||
uint32_t timeoutMs = portMAX_DELAY) override;
|
uint32_t timeoutMs = 0) override;
|
||||||
ReturnValue_t release() override;
|
ReturnValue_t release() override;
|
||||||
uint8_t getSemaphoreCounter() const override;
|
uint8_t getSemaphoreCounter() const override;
|
||||||
static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle);
|
static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle);
|
||||||
|
@ -51,7 +51,7 @@ class BinarySemaphore : public SemaphoreIF {
|
|||||||
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
||||||
*/
|
*/
|
||||||
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
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.
|
* Same as lockBinarySemaphore() with timeout in FreeRTOS ticks.
|
||||||
|
@ -11,19 +11,6 @@
|
|||||||
// TODO sanitize input?
|
// TODO sanitize input?
|
||||||
// TODO much of this code can be reused for tick-only systems
|
// TODO much of this code can be reused for tick-only systems
|
||||||
|
|
||||||
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) {
|
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||||
timeval uptime = getUptime();
|
timeval uptime = getUptime();
|
||||||
|
|
||||||
@ -44,81 +31,12 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
|
||||||
*uptime = getUptime();
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeval Clock::getUptime() {
|
timeval Clock::getUptime() {
|
||||||
TickType_t ticksSinceStart = xTaskGetTickCount();
|
TickType_t ticksSinceStart = xTaskGetTickCount();
|
||||||
return Timekeeper::ticksToTimeval(ticksSinceStart);
|
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() {
|
// uint32_t Clock::getUptimeSeconds() {
|
||||||
// timeval uptime = getUptime();
|
// timeval uptime = getUptime();
|
||||||
// return uptime.tv_sec;
|
// 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;
|
|
||||||
}
|
|
||||||
|
@ -34,7 +34,7 @@ class CountingSemaphoreUsingTask : public SemaphoreIF {
|
|||||||
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
||||||
*/
|
*/
|
||||||
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
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
|
* Release a semaphore, increasing the number of available counting
|
||||||
|
@ -56,7 +56,9 @@ ReturnValue_t FixedTimeslotTask::startTask() {
|
|||||||
// start time for the first entry.
|
// start time for the first entry.
|
||||||
auto slotListIter = pollingSeqTable.current;
|
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.
|
// The start time for the first entry is read.
|
||||||
uint32_t intervalMs = slotListIter->pollingTimeMs;
|
uint32_t intervalMs = slotListIter->pollingTimeMs;
|
||||||
|
@ -22,7 +22,7 @@ ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
|
|||||||
return MutexIF::MUTEX_NOT_FOUND;
|
return MutexIF::MUTEX_NOT_FOUND;
|
||||||
}
|
}
|
||||||
// If the timeout type is BLOCKING, this will be the correct value.
|
// 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) {
|
if (timeoutType == TimeoutType::POLLING) {
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
} else if (timeoutType == TimeoutType::WAITING) {
|
} else if (timeoutType == TimeoutType::WAITING) {
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
void TaskManagement::vRequestContextSwitchFromTask() { vTaskDelay(0); }
|
void TaskManagement::vRequestContextSwitchFromTask() { vTaskDelay(0); }
|
||||||
|
|
||||||
void TaskManagement::requestContextSwitch(CallContext callContext = CallContext::TASK) {
|
void TaskManagement::requestContextSwitch(CallContext callContext = CallContext::TASK) {
|
||||||
if (callContext == CallContext::ISR) {
|
// if (callContext == CallContext::ISR) {
|
||||||
// This function depends on the partmacro.h definition for the specific device
|
// // This function depends on the partmacro.h definition for the specific device
|
||||||
vRequestContextSwitchFromISR();
|
// vRequestContextSwitchFromISR();
|
||||||
} else {
|
// } else {
|
||||||
vRequestContextSwitchFromTask();
|
vRequestContextSwitchFromTask();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskHandle_t TaskManagement::getCurrentTaskHandle() { return xTaskGetCurrentTaskHandle(); }
|
TaskHandle_t TaskManagement::getCurrentTaskHandle() { return xTaskGetCurrentTaskHandle(); }
|
||||||
|
|
||||||
size_t TaskManagement::getTaskStackHighWatermark(TaskHandle_t task) {
|
// size_t TaskManagement::getTaskStackHighWatermark(TaskHandle_t task) {
|
||||||
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
|
// return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
|
||||||
}
|
// }
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* Architecture dependant portmacro.h function call.
|
* Architecture dependant portmacro.h function call.
|
||||||
* Should be implemented in bsp.
|
* Should be implemented in bsp.
|
||||||
*/
|
*/
|
||||||
extern "C" void vRequestContextSwitchFromISR();
|
// extern "C" void vRequestContextSwitchFromISR();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Used by functions to tell if they are being called from
|
* 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
|
* @return Smallest value of stack remaining since the task was started in
|
||||||
* words.
|
* words.
|
||||||
*/
|
*/
|
||||||
size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
|
// size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
|
||||||
|
|
||||||
}; // namespace TaskManagement
|
}; // namespace TaskManagement
|
||||||
|
|
||||||
|
@ -15,27 +15,6 @@
|
|||||||
|
|
||||||
using SystemClock = std::chrono::system_clock;
|
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) {
|
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
|
/* 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. */
|
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;
|
time->tv_usec = timeUnix.tv_nsec / 1000.0;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
#else
|
#else
|
||||||
|
#warning Clock::getClock_timeval() not implemented for your platform
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::getUptime: Not implemented for found OS!" << std::endl;
|
sif::warning << "Clock::getUptime: Not implemented for found OS!" << std::endl;
|
||||||
#else
|
#else
|
||||||
@ -75,15 +55,6 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||||||
#endif
|
#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 Clock::getUptime() {
|
||||||
timeval timeval;
|
timeval timeval;
|
||||||
#if defined(PLATFORM_WIN)
|
#if defined(PLATFORM_WIN)
|
||||||
@ -100,73 +71,10 @@ timeval Clock::getUptime() {
|
|||||||
timeval.tv_usec = uptimeSeconds * (double)1e6 - (timeval.tv_sec * 1e6);
|
timeval.tv_usec = uptimeSeconds * (double)1e6 - (timeval.tv_sec * 1e6);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#warning Clock::getUptime() not implemented for your platform
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return timeval;
|
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;
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
#if defined(PLATFORM_WIN)
|
#if defined(PLATFORM_WIN)
|
||||||
#include <processthreadsapi.h>
|
|
||||||
|
|
||||||
#include "fsfw/osal/windows/winTaskHelpers.h"
|
#include "fsfw/osal/windows/winTaskHelpers.h"
|
||||||
#elif defined(PLATFORM_UNIX)
|
#elif defined(PLATFORM_UNIX)
|
||||||
|
@ -50,6 +50,6 @@ void TaskFactory::printMissedDeadline() {
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl;
|
sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name);
|
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name.c_str());
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <fsfw/returnvalues/returnvalue.h>
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace tasks {
|
namespace tasks {
|
||||||
|
@ -10,26 +10,6 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.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) {
|
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||||
timespec timeUnix{};
|
timespec timeUnix{};
|
||||||
timeUnix.tv_sec = time->tv_sec;
|
timeUnix.tv_sec = time->tv_sec;
|
||||||
@ -53,104 +33,12 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||||||
return returnvalue::OK;
|
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 Clock::getUptime() {
|
||||||
timeval uptime{};
|
timeval uptime{0, 0};
|
||||||
auto result = getUptime(&uptime);
|
double uptimeSeconds;
|
||||||
if (result != returnvalue::OK) {
|
if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
uptime.tv_sec = uptimeSeconds;
|
||||||
sif::error << "Clock::getUptime: Error getting uptime" << std::endl;
|
uptime.tv_usec = uptimeSeconds * (double)1e6 - (uptime.tv_sec * 1e6);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return uptime;
|
return uptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
|
||||||
// TODO This is not posix compatible and delivers only seconds precision
|
|
||||||
// Linux specific file read but more precise.
|
|
||||||
double uptimeSeconds;
|
|
||||||
if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) {
|
|
||||||
uptime->tv_sec = uptimeSeconds;
|
|
||||||
uptime->tv_usec = uptimeSeconds * (double)1e6 - (uptime->tv_sec * 1e6);
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for new FSFW Clock function delivering seconds uptime.
|
|
||||||
// uint32_t Clock::getUptimeSeconds() {
|
|
||||||
// //TODO This is not posix compatible and delivers only seconds precision
|
|
||||||
// struct sysinfo sysInfo;
|
|
||||||
// int result = sysinfo(&sysInfo);
|
|
||||||
// if(result != 0){
|
|
||||||
// return returnvalue::FAILED;
|
|
||||||
// }
|
|
||||||
// return sysInfo.uptime;
|
|
||||||
//}
|
|
||||||
|
|
||||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
|
||||||
timeval uptime{};
|
|
||||||
ReturnValue_t result = getUptime(&uptime);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
*uptimeMs = uptime.tv_sec * 1e3 + uptime.tv_usec / 1e3;
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
|
||||||
timespec timeUnix{};
|
|
||||||
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
|
||||||
if (status != 0) {
|
|
||||||
// TODO errno
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
ReturnValue_t result = checkOrCreateClockMutex();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
MutexGuard helper(timeMutex);
|
|
||||||
// gmtime writes its output in a global buffer which is not Thread Safe
|
|
||||||
// Therefore we have to use a Mutex here
|
|
||||||
struct std::tm* timeInfo;
|
|
||||||
timeInfo = gmtime(&timeUnix.tv_sec);
|
|
||||||
time->year = timeInfo->tm_year + 1900;
|
|
||||||
time->month = timeInfo->tm_mon + 1;
|
|
||||||
time->day = timeInfo->tm_mday;
|
|
||||||
time->hour = timeInfo->tm_hour;
|
|
||||||
time->minute = timeInfo->tm_min;
|
|
||||||
time->second = timeInfo->tm_sec;
|
|
||||||
time->usecond = timeUnix.tv_nsec / 1000.0;
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
|
||||||
std::tm fromTm{};
|
|
||||||
// Note: Fails for years before AD
|
|
||||||
fromTm.tm_year = from->year - 1900;
|
|
||||||
fromTm.tm_mon = from->month - 1;
|
|
||||||
fromTm.tm_mday = from->day;
|
|
||||||
fromTm.tm_hour = from->hour;
|
|
||||||
fromTm.tm_min = from->minute;
|
|
||||||
fromTm.tm_sec = from->second;
|
|
||||||
fromTm.tm_isdst = 0;
|
|
||||||
|
|
||||||
to->tv_sec = timegm(&fromTm);
|
|
||||||
to->tv_usec = from->usecond;
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
|
||||||
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <rtems/rtems/sem.h>
|
#include <rtems/rtems/sem.h>
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
BinarySemaphore::BinarySemaphore() {}
|
BinarySemaphore::BinarySemaphore() {}
|
||||||
|
|
||||||
BinarySemaphore::~BinarySemaphore() {}
|
BinarySemaphore::~BinarySemaphore() {}
|
||||||
|
@ -6,20 +6,21 @@
|
|||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/osal/rtems/RtemsBasic.h"
|
#include "fsfw/osal/rtems/RtemsBasic.h"
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void) {
|
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||||
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
TimeOfDay_t time_tod;
|
||||||
return static_cast<uint32_t>(ticks_per_second);
|
ReturnValue_t result = convertTimevalToTimeOfDay(time, &time_tod);
|
||||||
}
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
}
|
||||||
rtems_time_of_day timeRtems;
|
rtems_time_of_day timeRtems;
|
||||||
timeRtems.year = time->year;
|
timeRtems.year = time_tod.year;
|
||||||
timeRtems.month = time->month;
|
timeRtems.month = time_tod.month;
|
||||||
timeRtems.day = time->day;
|
timeRtems.day = time_tod.day;
|
||||||
timeRtems.hour = time->hour;
|
timeRtems.hour = time_tod.hour;
|
||||||
timeRtems.minute = time->minute;
|
timeRtems.minute = time_tod.minute;
|
||||||
timeRtems.second = time->second;
|
timeRtems.second = time_tod.second;
|
||||||
timeRtems.ticks = time->usecond * getTicksPerSecond() / 1e6;
|
timeRtems.ticks =
|
||||||
|
static_cast<uint64_t>(time_tod.usecond) * rtems_clock_get_ticks_per_second() / 1e6;
|
||||||
rtems_status_code status = rtems_clock_set(&timeRtems);
|
rtems_status_code status = rtems_clock_set(&timeRtems);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case RTEMS_SUCCESSFUL:
|
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) {
|
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||||
// Callable from ISR
|
// Callable from ISR
|
||||||
rtems_status_code status = rtems_clock_get_tod_timeval(time);
|
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
|
// According to docs.rtems.org for rtems 5 this method is more accurate than
|
||||||
// rtems_clock_get_ticks_since_boot
|
// rtems_clock_get_ticks_since_boot
|
||||||
|
timeval time_timeval;
|
||||||
timespec time;
|
timespec time;
|
||||||
rtems_status_code status = rtems_clock_get_uptime(&time);
|
rtems_status_code status = rtems_clock_get_uptime(&time);
|
||||||
uptime->tv_sec = time.tv_sec;
|
time_timeval.tv_sec = time.tv_sec;
|
||||||
time.tv_nsec = time.tv_nsec / 1000;
|
time_timeval.tv_usec = time.tv_nsec / 1000;
|
||||||
uptime->tv_usec = time.tv_nsec;
|
return time_timeval;
|
||||||
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;
|
|
||||||
}
|
}
|
@ -93,8 +93,8 @@ ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size, size_t maxSize
|
|||||||
streamEndianness);
|
streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CpuUsage::getSerializedSize() const {
|
size_t CpuUsage::getSerializedSize() const {
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
size += sizeof(timeSinceLastReset);
|
size += sizeof(timeSinceLastReset);
|
||||||
size += SerialArrayListAdapter<ThreadData>::getSerializedSize(&threadData);
|
size += SerialArrayListAdapter<ThreadData>::getSerializedSize(&threadData);
|
||||||
@ -136,8 +136,8 @@ ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, size_t* size, si
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CpuUsage::ThreadData::getSerializedSize() const {
|
size_t CpuUsage::ThreadData::getSerializedSize() const {
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
size += sizeof(id);
|
size += sizeof(id);
|
||||||
size += MAX_LENGTH_OF_THREAD_NAME;
|
size += MAX_LENGTH_OF_THREAD_NAME;
|
||||||
|
@ -35,10 +35,9 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
|
|||||||
return OUT_OF_PROXIES;
|
return OUT_OF_PROXIES;
|
||||||
case INTERNAL_ERROR_INVALID_GLOBAL_ID:
|
case INTERNAL_ERROR_INVALID_GLOBAL_ID:
|
||||||
return INVALID_GLOBAL_ID;
|
return INVALID_GLOBAL_ID;
|
||||||
#ifndef STM32H743ZI_NUCLEO
|
// TODO this one is not there anymore in rtems-6 (5 as well?)
|
||||||
case INTERNAL_ERROR_BAD_STACK_HOOK:
|
// case INTERNAL_ERROR_BAD_STACK_HOOK:
|
||||||
return BAD_STACK_HOOK;
|
// return BAD_STACK_HOOK;
|
||||||
#endif
|
|
||||||
// case INTERNAL_ERROR_BAD_ATTRIBUTES:
|
// case INTERNAL_ERROR_BAD_ATTRIBUTES:
|
||||||
// return BAD_ATTRIBUTES;
|
// return BAD_ATTRIBUTES;
|
||||||
// case INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY:
|
// case INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "fsfw/osal/rtems/BinarySemaphore.h"
|
#include "fsfw/osal/rtems/BinarySemaphore.h"
|
||||||
//#include "fsfw/osal/rtems/CountingSemaphore.h"
|
// #include "fsfw/osal/rtems/CountingSemaphore.h"
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/tasks/SemaphoreFactory.h"
|
#include "fsfw/tasks/SemaphoreFactory.h"
|
||||||
@ -18,7 +18,9 @@ SemaphoreFactory* SemaphoreFactory::instance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) {
|
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) {
|
||||||
return new BinarySemaphore();
|
return nullptr;
|
||||||
|
// TODO
|
||||||
|
// return new BinarySemaphore();
|
||||||
}
|
}
|
||||||
|
|
||||||
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount, uint8_t initCount,
|
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount, uint8_t initCount,
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <minwindef.h>
|
// Thanks, windows
|
||||||
|
// clang-format off
|
||||||
|
#include <windows.h>
|
||||||
|
#include <processthreadsapi.h>
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
namespace tasks {
|
namespace tasks {
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ class ParameterWrapper : public SerializeIF {
|
|||||||
|
|
||||||
virtual size_t getSerializedSize() const override;
|
virtual size_t getSerializedSize() const override;
|
||||||
|
|
||||||
|
using SerializeIF::deSerialize;
|
||||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
@ -62,13 +62,13 @@ class Fuse : public SystemObject,
|
|||||||
SerializeIF::Endianness streamEndianness) override;
|
SerializeIF::Endianness streamEndianness) override;
|
||||||
void setAllMonitorsToUnchecked();
|
void setAllMonitorsToUnchecked();
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode);
|
||||||
MessageQueueId_t getCommandQueue() const;
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
void setDataPoolEntriesInvalid();
|
void setDataPoolEntriesInvalid();
|
||||||
ReturnValue_t setHealth(HealthState health);
|
ReturnValue_t setHealth(HealthState health) override;
|
||||||
HasHealthIF::HealthState getHealth();
|
HasHealthIF::HealthState getHealth() override;
|
||||||
|
|
||||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
|
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:
|
private:
|
||||||
uint8_t oldFuseState;
|
uint8_t oldFuseState;
|
||||||
|
@ -10,15 +10,15 @@ class PowerComponent : public PowerComponentIF {
|
|||||||
PowerComponent(object_id_t setId, uint8_t moduleId, float minPower, float maxPower,
|
PowerComponent(object_id_t setId, uint8_t moduleId, float minPower, float maxPower,
|
||||||
uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF);
|
uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF);
|
||||||
|
|
||||||
virtual object_id_t getDeviceObjectId();
|
object_id_t getDeviceObjectId() override;
|
||||||
|
|
||||||
virtual uint8_t getSwitchId1();
|
uint8_t getSwitchId1() override;
|
||||||
virtual uint8_t getSwitchId2();
|
uint8_t getSwitchId2() override;
|
||||||
|
|
||||||
bool hasTwoSwitches();
|
bool hasTwoSwitches() override;
|
||||||
|
|
||||||
float getMin();
|
float getMin() override;
|
||||||
float getMax();
|
float getMax() override;
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
@ -29,7 +29,7 @@ class PowerComponent : public PowerComponentIF {
|
|||||||
Endianness streamEndianness) override;
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
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:
|
private:
|
||||||
const object_id_t deviceObjectId = objects::NO_OBJECT;
|
const object_id_t deviceObjectId = objects::NO_OBJECT;
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
|
||||||
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
|
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
|
||||||
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
|||||||
uint16_t messageQueueDepth,
|
uint16_t messageQueueDepth,
|
||||||
TimeWriterIF* timeStamper)
|
TimeWriterIF* timeStamper)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
apid(apid),
|
// apid(apid),
|
||||||
serviceId(serviceId),
|
serviceId(serviceId),
|
||||||
targetDestination(targetDestination),
|
targetDestination(targetDestination),
|
||||||
storeHelper(apid),
|
storeHelper(apid),
|
||||||
|
@ -72,7 +72,7 @@ class Service1TelecommandVerification : public AcceptsVerifyMessageIF,
|
|||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t apid = 0;
|
// uint16_t apid = 0;
|
||||||
uint8_t serviceId = 0;
|
uint8_t serviceId = 0;
|
||||||
|
|
||||||
object_id_t targetDestination = objects::NO_OBJECT;
|
object_id_t targetDestination = objects::NO_OBJECT;
|
||||||
|
@ -69,7 +69,7 @@ class FailureReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t getSerializedSize() const {
|
virtual size_t getSerializedSize() const override {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size += SerializeAdapter::getSerializedSize(&packetId);
|
size += SerializeAdapter::getSerializedSize(&packetId);
|
||||||
size += sizeof(packetSequenceControl);
|
size += sizeof(packetSequenceControl);
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
// RMAP command bits
|
// RMAP command bits
|
||||||
//#define RMAP_COMMAND_BIT_INCREMENT 2
|
// #define RMAP_COMMAND_BIT_INCREMENT 2
|
||||||
//#define RMAP_COMMAND_BIT_REPLY 3
|
// #define RMAP_COMMAND_BIT_REPLY 3
|
||||||
//#define RMAP_COMMAND_BIT_WRITE 5
|
// #define RMAP_COMMAND_BIT_WRITE 5
|
||||||
//#define RMAP_COMMAND_BIT_VERIFY 4
|
// #define RMAP_COMMAND_BIT_VERIFY 4
|
||||||
//#define RMAP_COMMAND_BIT 6
|
// #define RMAP_COMMAND_BIT 6
|
||||||
|
|
||||||
namespace RMAPIds {
|
namespace RMAPIds {
|
||||||
|
|
||||||
@ -32,14 +32,14 @@ static const uint8_t RMAP_COMMAND_READ = ((1 << RMAP_COMMAND_BIT) | (1 << RMAP_C
|
|||||||
static const uint8_t RMAP_REPLY_WRITE =
|
static const uint8_t RMAP_REPLY_WRITE =
|
||||||
((1 << RMAP_COMMAND_BIT_WRITE) | (1 << RMAP_COMMAND_BIT_REPLY));
|
((1 << RMAP_COMMAND_BIT_WRITE) | (1 << RMAP_COMMAND_BIT_REPLY));
|
||||||
static const uint8_t RMAP_REPLY_READ = ((1 << RMAP_COMMAND_BIT_REPLY));
|
static const uint8_t RMAP_REPLY_READ = ((1 << RMAP_COMMAND_BIT_REPLY));
|
||||||
//#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
|
// #define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
|
||||||
//| (1<<RMAP_COMMAND_BIT_REPLY)) #define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) |
|
//| (1<<RMAP_COMMAND_BIT_REPLY)) #define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) |
|
||||||
//(1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define
|
//(1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define
|
||||||
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||||
|
|
||||||
//#define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
|
// #define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||||
//(1<<RMAP_COMMAND_BIT_REPLY))
|
//(1<<RMAP_COMMAND_BIT_REPLY))
|
||||||
//#define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) |
|
// #define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||||
//(1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define RMAP_REPLY_READ
|
//(1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define RMAP_REPLY_READ
|
||||||
//((1<<RMAP_COMMAND_BIT_REPLY))
|
//((1<<RMAP_COMMAND_BIT_REPLY))
|
||||||
|
|
||||||
@ -49,9 +49,9 @@ static const uint8_t RMAP_COMMAND_HEADER_LEN = 16;
|
|||||||
static const uint8_t RMAP_WRITE_REPLY_HEADER_LEN = 8;
|
static const uint8_t RMAP_WRITE_REPLY_HEADER_LEN = 8;
|
||||||
static const uint8_t RMAP_READ_REPLY_HEADER_LEN = 12;
|
static const uint8_t RMAP_READ_REPLY_HEADER_LEN = 12;
|
||||||
static const uint8_t RMAP_DATA_FOOTER_SIZE = 1; // SIZE OF CRC
|
static const uint8_t RMAP_DATA_FOOTER_SIZE = 1; // SIZE OF CRC
|
||||||
//#define RMAP_COMMAND_HEADER_LEN 16
|
// #define RMAP_COMMAND_HEADER_LEN 16
|
||||||
//#define RMAP_WRITE_REPLY_HEADER_LEN 8
|
// #define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||||
//#define RMAP_READ_REPLY_HEADER_LEN 12
|
// #define RMAP_READ_REPLY_HEADER_LEN 12
|
||||||
|
|
||||||
} // namespace RMAPIds
|
} // namespace RMAPIds
|
||||||
|
|
||||||
|
@ -20,9 +20,6 @@ SerialBufferAdapter<count_t>::SerialBufferAdapter(uint8_t* buffer, count_t buffe
|
|||||||
buffer(buffer),
|
buffer(buffer),
|
||||||
bufferLength(bufferLength) {}
|
bufferLength(bufferLength) {}
|
||||||
|
|
||||||
template <typename count_t>
|
|
||||||
SerialBufferAdapter<count_t>::~SerialBufferAdapter() = default;
|
|
||||||
|
|
||||||
template <typename count_t>
|
template <typename count_t>
|
||||||
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_, size_t* size,
|
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_, size_t* size,
|
||||||
size_t maxSize,
|
size_t maxSize,
|
||||||
|
@ -41,7 +41,7 @@ class SerialBufferAdapter : public SerializeIF {
|
|||||||
*/
|
*/
|
||||||
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength = false);
|
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength = false);
|
||||||
|
|
||||||
~SerialBufferAdapter() override;
|
~SerialBufferAdapter() override = default;
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
Endianness streamEndianness) const override;
|
Endianness streamEndianness) const override;
|
||||||
@ -74,4 +74,10 @@ class SerialBufferAdapter : public SerializeIF {
|
|||||||
count_t bufferLength = 0;
|
count_t bufferLength = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// declaration of explicit instantiations (which are in the cpp)
|
||||||
|
extern template class SerialBufferAdapter<uint8_t>;
|
||||||
|
extern template class SerialBufferAdapter<uint16_t>;
|
||||||
|
extern template class SerialBufferAdapter<uint32_t>;
|
||||||
|
extern template class SerialBufferAdapter<uint64_t>;
|
||||||
|
|
||||||
#endif /* SERIALBUFFERADAPTER_H_ */
|
#endif /* SERIALBUFFERADAPTER_H_ */
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
* @author baetz
|
* @author baetz
|
||||||
* @ingroup serialize
|
* @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 {
|
class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
|
||||||
public:
|
public:
|
||||||
SerialLinkedListAdapter(typename LinkedElement<T>::Iterator start, bool printCount = false)
|
SerialLinkedListAdapter(typename LinkedElement<T>::Iterator start, bool printCount = false)
|
||||||
|
@ -35,6 +35,12 @@ class SerializeIF {
|
|||||||
MAKE_RETURN_CODE(3); // !< There are too many elements to be deserialized
|
MAKE_RETURN_CODE(3); // !< There are too many elements to be deserialized
|
||||||
|
|
||||||
virtual ~SerializeIF() = default;
|
virtual ~SerializeIF() = default;
|
||||||
|
// C++11 deprecates automatic generation of copy ctor and assignment operator when
|
||||||
|
// a destructor is defined, so we need to explicitely set them to default
|
||||||
|
SerializeIF(const SerializeIF&) = default;
|
||||||
|
SerializeIF() = default;
|
||||||
|
SerializeIF& operator= ( const SerializeIF & ) = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Function to serialize the object into a buffer with maxSize. Size represents the written
|
* Function to serialize the object into a buffer with maxSize. Size represents the written
|
||||||
|
@ -109,7 +109,8 @@ ReturnValue_t LocalPool::deleteData(uint8_t* ptr, size_t size, store_address_t*
|
|||||||
ReturnValue_t result = ILLEGAL_ADDRESS;
|
ReturnValue_t result = ILLEGAL_ADDRESS;
|
||||||
for (uint16_t n = 0; n < NUMBER_OF_SUBPOOLS; n++) {
|
for (uint16_t n = 0; n < NUMBER_OF_SUBPOOLS; n++) {
|
||||||
// Not sure if new allocates all stores in order. so better be careful.
|
// 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;
|
localId.poolIndex = n;
|
||||||
uint32_t deltaAddress = ptr - store[n].data();
|
uint32_t deltaAddress = ptr - store[n].data();
|
||||||
// Getting any data from the right "block" is ok.
|
// Getting any data from the right "block" is ok.
|
||||||
|
@ -22,7 +22,7 @@ union store_address_t {
|
|||||||
*/
|
*/
|
||||||
explicit store_address_t(uint32_t rawAddress) : raw(rawAddress) {}
|
explicit store_address_t(uint32_t rawAddress) : raw(rawAddress) {}
|
||||||
|
|
||||||
static store_address_t invalid() { return {}; };
|
static store_address_t invalid() { return {}; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to create an address object using pool
|
* Constructor to create an address object using pool
|
||||||
|
@ -91,11 +91,10 @@ void Subsystem::performChildOperation() {
|
|||||||
}
|
}
|
||||||
if (currentSequenceIterator->getWaitSeconds() != 0) {
|
if (currentSequenceIterator->getWaitSeconds() != 0) {
|
||||||
if (uptimeStartTable == 0) {
|
if (uptimeStartTable == 0) {
|
||||||
Clock::getUptime(&uptimeStartTable);
|
uptimeStartTable = Clock::getUptime_ms();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
uint32_t uptimeNow;
|
uint32_t uptimeNow = Clock::getUptime_ms();
|
||||||
Clock::getUptime(&uptimeNow);
|
|
||||||
if ((uptimeNow - uptimeStartTable) < (currentSequenceIterator->getWaitSeconds() * 1000)) {
|
if ((uptimeNow - uptimeStartTable) < (currentSequenceIterator->getWaitSeconds() * 1000)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -586,7 +585,12 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, SerializeIF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < count; i++) {
|
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;
|
CommandMessage reply;
|
||||||
ModeSequenceMessage::setModeSequenceMessage(&reply, command, address);
|
ModeSequenceMessage::setModeSequenceMessage(&reply, command, address);
|
||||||
|
@ -34,7 +34,7 @@ class ExecutableObjectIF {
|
|||||||
* a reference to the executing task
|
* a reference to the executing task
|
||||||
* @param task_ Pointer to the taskIF of this task
|
* @param task_ Pointer to the taskIF of this task
|
||||||
*/
|
*/
|
||||||
virtual void setTaskIF(PeriodicTaskIF* task_){};
|
virtual void setTaskIF(PeriodicTaskIF* task_){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should be called after the object was assigned to a
|
* This function should be called after the object was assigned to a
|
||||||
|
@ -9,7 +9,6 @@ class FixedTimeslotTaskBase : public FixedTimeslotTaskIF {
|
|||||||
public:
|
public:
|
||||||
explicit FixedTimeslotTaskBase(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc = nullptr);
|
explicit FixedTimeslotTaskBase(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc = nullptr);
|
||||||
~FixedTimeslotTaskBase() override = default;
|
~FixedTimeslotTaskBase() override = default;
|
||||||
;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -196,12 +196,11 @@ void Heater::setSwitch(uint8_t number, ReturnValue_t state, uint32_t* uptimeOfSw
|
|||||||
if (powerSwitcher->getSwitchState(number) == state) {
|
if (powerSwitcher->getSwitchState(number) == state) {
|
||||||
*uptimeOfSwitching = INVALID_UPTIME;
|
*uptimeOfSwitching = INVALID_UPTIME;
|
||||||
} else {
|
} else {
|
||||||
if ((*uptimeOfSwitching == INVALID_UPTIME)) {
|
if (*uptimeOfSwitching == INVALID_UPTIME) {
|
||||||
powerSwitcher->sendSwitchCommand(number, state);
|
powerSwitcher->sendSwitchCommand(number, state);
|
||||||
Clock::getUptime(uptimeOfSwitching);
|
*uptimeOfSwitching = Clock::getUptime_ms();
|
||||||
} else {
|
} else {
|
||||||
uint32_t currentUptime;
|
uint32_t currentUptime = Clock::getUptime_ms();
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
if (currentUptime - *uptimeOfSwitching > powerSwitcher->getSwitchDelayMs()) {
|
if (currentUptime - *uptimeOfSwitching > powerSwitcher->getSwitchDelayMs()) {
|
||||||
*uptimeOfSwitching = INVALID_UPTIME;
|
*uptimeOfSwitching = INVALID_UPTIME;
|
||||||
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||||
|
@ -552,10 +552,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(timeval* to, const CCSDSTime::CDS_short*
|
|||||||
if (to == nullptr or from == nullptr) {
|
if (to == nullptr or from == nullptr) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
uint16_t days = (from->dayMSB << 8) + from->dayLSB;
|
int32_t days = (from->dayMSB << 8) + from->dayLSB;
|
||||||
if (days <= DAYS_CCSDS_TO_UNIX_EPOCH) {
|
|
||||||
return INVALID_TIME_FORMAT;
|
|
||||||
}
|
|
||||||
days -= DAYS_CCSDS_TO_UNIX_EPOCH;
|
days -= DAYS_CCSDS_TO_UNIX_EPOCH;
|
||||||
to->tv_sec = days * SECONDS_PER_DAY;
|
to->tv_sec = days * SECONDS_PER_DAY;
|
||||||
uint32_t msDay =
|
uint32_t msDay =
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
${LIB_FSFW_NAME}
|
${LIB_FSFW_NAME}
|
||||||
PRIVATE CCSDSTime.cpp Countdown.cpp Stopwatch.cpp TimeMessage.cpp
|
PRIVATE CCSDSTime.cpp
|
||||||
CdsShortTimeStamper.cpp ClockCommon.cpp)
|
Countdown.cpp
|
||||||
|
Stopwatch.cpp
|
||||||
|
TimeMessage.cpp
|
||||||
|
CdsShortTimeStamper.cpp
|
||||||
|
ClockCommon.cpp
|
||||||
|
boost_timegm.cpp)
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
class Clock {
|
class Clock {
|
||||||
public:
|
public:
|
||||||
|
// https://xkcd.com/927/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t year; //!< Year, A.D.
|
uint32_t year; //!< Year, A.D.
|
||||||
uint32_t month; //!< Month, 1 .. 12.
|
uint32_t month; //!< Month, 1 .. 12.
|
||||||
@ -26,14 +27,6 @@ class Clock {
|
|||||||
uint32_t usecond; //!< Microseconds, 0 .. 999999
|
uint32_t usecond; //!< Microseconds, 0 .. 999999
|
||||||
} TimeOfDay_t;
|
} 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.
|
* This system call sets the system time.
|
||||||
* To set the time, it uses a TimeOfDay_t struct.
|
* 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
|
* Get the time since boot in a timeval struct
|
||||||
*
|
*
|
||||||
* @param[out] time A pointer to a timeval struct where the uptime is stored.
|
* @return a timeval struct where the uptime is stored
|
||||||
* @return @c returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
|
||||||
*
|
|
||||||
* @deprecated, I do not think this should be able to fail, use timeval getUptime()
|
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t getUptime(timeval *uptime);
|
|
||||||
|
|
||||||
static timeval getUptime();
|
static timeval getUptime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +67,7 @@ class Clock {
|
|||||||
* @param ms uptime in ms
|
* @param ms uptime in ms
|
||||||
* @return returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
* @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.
|
* Returns the time in microseconds since an OS-defined epoch.
|
||||||
@ -90,6 +78,7 @@ class Clock {
|
|||||||
* - Otherwise, the OS failure code is returned.
|
* - Otherwise, the OS failure code is returned.
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t getClock_usecs(uint64_t *time);
|
static ReturnValue_t getClock_usecs(uint64_t *time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the time in a TimeOfDay_t struct.
|
* Returns the time in a TimeOfDay_t struct.
|
||||||
* @param time A pointer to a TimeOfDay_t struct.
|
* @param time A pointer to a TimeOfDay_t struct.
|
||||||
@ -106,6 +95,7 @@ class Clock {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to);
|
static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a time of day struct to POSIX seconds.
|
* Converts a time of day struct to POSIX seconds.
|
||||||
* @param time The time of day as input
|
* @param time The time of day as input
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "boost_timegm.h"
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
#include "fsfw/timemanager/Clock.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) {
|
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
|
||||||
struct tm* timeInfo;
|
struct tm time_tm;
|
||||||
// According to https://en.cppreference.com/w/c/chrono/gmtime, the implementation of gmtime_s
|
// WINDOWS does not provide gmtime_r, but gmtime_s
|
||||||
// in the Windows CRT is incompatible with the C standard but this should not be an issue for
|
#ifdef _MSC_VER
|
||||||
// this implementation
|
time_t seconds = from->tv_sec;
|
||||||
ReturnValue_t result = checkOrCreateClockMutex();
|
errno_t result = gmtime_s(&time_tm, &seconds);
|
||||||
if (result != returnvalue::OK) {
|
if (result != 0) {
|
||||||
return result;
|
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
|
#else
|
||||||
timeInfo = gmtime(&from->tv_sec);
|
void* result = gmtime_r(&from->tv_sec, &time_tm);
|
||||||
|
|
||||||
|
if (result == nullptr) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
to->year = timeInfo->tm_year + 1900;
|
|
||||||
to->month = timeInfo->tm_mon + 1;
|
to->year = time_tm.tm_year + 1900;
|
||||||
to->day = timeInfo->tm_mday;
|
to->month = time_tm.tm_mon + 1;
|
||||||
to->hour = timeInfo->tm_hour;
|
to->day = time_tm.tm_mday;
|
||||||
to->minute = timeInfo->tm_min;
|
to->hour = time_tm.tm_hour;
|
||||||
to->second = timeInfo->tm_sec;
|
to->minute = time_tm.tm_min;
|
||||||
|
to->second = time_tm.tm_sec;
|
||||||
to->usecond = from->tv_usec;
|
to->usecond = from->tv_usec;
|
||||||
return returnvalue::OK;
|
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() {
|
ReturnValue_t Clock::checkOrCreateClockMutex() {
|
||||||
if (timeMutex == nullptr) {
|
if (timeMutex == nullptr) {
|
||||||
MutexFactory* mutexFactory = MutexFactory::instance();
|
MutexFactory* mutexFactory = MutexFactory::instance();
|
||||||
@ -94,3 +120,37 @@ ReturnValue_t Clock::checkOrCreateClockMutex() {
|
|||||||
}
|
}
|
||||||
return returnvalue::OK;
|
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;
|
||||||
|
}
|
@ -7,9 +7,9 @@ Countdown::Countdown(uint32_t initialTimeout) : timeout(initialTimeout) {
|
|||||||
Countdown::~Countdown() {}
|
Countdown::~Countdown() {}
|
||||||
|
|
||||||
ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) {
|
ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) {
|
||||||
ReturnValue_t returnValue = Clock::getUptime(&startTime);
|
startTime = Clock::getUptime_ms();
|
||||||
timeout = milliseconds;
|
timeout = milliseconds;
|
||||||
return returnValue;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Countdown::hasTimedOut() const {
|
bool Countdown::hasTimedOut() const {
|
||||||
@ -38,8 +38,4 @@ uint32_t Countdown::getRemainingMillis() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Countdown::getCurrentTime() const {
|
uint32_t Countdown::getCurrentTime() const { return Clock::getUptime_ms(); }
|
||||||
uint32_t currentTime;
|
|
||||||
Clock::getUptime(¤tTime);
|
|
||||||
return currentTime;
|
|
||||||
}
|
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
||||||
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
||||||
// Measures start time on initialization.
|
// 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) {
|
dur_millis_t Stopwatch::stop(bool display) {
|
||||||
stopInternal();
|
stopInternal();
|
||||||
@ -62,7 +62,6 @@ void Stopwatch::setDisplayMode(StopwatchDisplayMode displayMode) {
|
|||||||
StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
||||||
|
|
||||||
void Stopwatch::stopInternal() {
|
void Stopwatch::stopInternal() {
|
||||||
timeval endTime;
|
timeval endTime = Clock::getUptime();
|
||||||
Clock::getUptime(&endTime);
|
|
||||||
elapsedTime = endTime - startTime;
|
elapsedTime = endTime - startTime;
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,17 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN
|
#ifdef PLATFORM_WIN
|
||||||
// wtf? Required for timeval!
|
// wtf? Required for timeval!
|
||||||
|
// Thanks, windows
|
||||||
|
// clang-format off
|
||||||
|
#include <winsock2.h>
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
|
// clang-format off
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "TimeStampIF.h"
|
#include "TimeStampIF.h"
|
||||||
|
66
src/fsfw/timemanager/boost_timegm.cpp
Normal file
66
src/fsfw/timemanager/boost_timegm.cpp
Normal 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;
|
||||||
|
}
|
3
src/fsfw/timemanager/boost_timegm.h
Normal file
3
src/fsfw/timemanager/boost_timegm.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
time_t internal_timegm(std::tm const *t);
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
class RawUserDataReaderIF {
|
class RawUserDataReaderIF {
|
||||||
public:
|
public:
|
||||||
~RawUserDataReaderIF() = default;
|
virtual ~RawUserDataReaderIF() = default;
|
||||||
[[nodiscard]] virtual const uint8_t* getUserData() const = 0;
|
[[nodiscard]] virtual const uint8_t* getUserData() const = 0;
|
||||||
[[nodiscard]] virtual size_t getUserDataLen() const = 0;
|
[[nodiscard]] virtual size_t getUserDataLen() const = 0;
|
||||||
};
|
};
|
||||||
|
@ -348,7 +348,7 @@ void CommandingServiceBase::startExecution(store_address_t storeId, CommandMapIt
|
|||||||
sendResult = commandQueue->sendMessage(iter.value->first, &command);
|
sendResult = commandQueue->sendMessage(iter.value->first, &command);
|
||||||
}
|
}
|
||||||
if (sendResult == returnvalue::OK) {
|
if (sendResult == returnvalue::OK) {
|
||||||
Clock::getUptime(&iter->second.uptimeOfStart);
|
iter->second.uptimeOfStart = Clock::getUptime_ms();
|
||||||
iter->second.step = 0;
|
iter->second.step = 0;
|
||||||
iter->second.subservice = tcReader.getSubService();
|
iter->second.subservice = tcReader.getSubService();
|
||||||
iter->second.command = command.getCommand();
|
iter->second.command = command.getCommand();
|
||||||
@ -434,8 +434,7 @@ inline void CommandingServiceBase::doPeriodicOperation() {}
|
|||||||
MessageQueueId_t CommandingServiceBase::getCommandQueue() { return commandQueue->getId(); }
|
MessageQueueId_t CommandingServiceBase::getCommandQueue() { return commandQueue->getId(); }
|
||||||
|
|
||||||
void CommandingServiceBase::checkTimeout() {
|
void CommandingServiceBase::checkTimeout() {
|
||||||
uint32_t uptime;
|
uint32_t uptime = Clock::getUptime_ms();
|
||||||
Clock::getUptime(&uptime);
|
|
||||||
CommandMapIter iter;
|
CommandMapIter iter;
|
||||||
for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) {
|
for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) {
|
||||||
if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) {
|
if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void __attribute__((weak)) printChar(const char* character, bool errStream) {
|
void printChar(const char* character, bool errStream) {
|
||||||
if (errStream) {
|
if (errStream) {
|
||||||
fprintf(stderr, "%c", *character);
|
fprintf(stderr, "%c", *character);
|
||||||
} else {
|
} else {
|
||||||
|
@ -72,7 +72,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
uint32_t transitionDelay;
|
uint32_t transitionDelay;
|
||||||
// Single SPI command has 2 bytes, first for adress, second for content
|
// 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
|
// Has the size for all adresses of the lis3mdl + the continous write bit
|
||||||
uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1];
|
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 registers[MGMLIS3MDL::NR_OF_CTRL_REGISTERS];
|
||||||
|
|
||||||
uint8_t statusRegister = 0;
|
// uint8_t statusRegister = 0;
|
||||||
bool goToNormalMode = false;
|
bool goToNormalMode = false;
|
||||||
|
|
||||||
enum class InternalState {
|
enum class InternalState {
|
||||||
|
@ -72,7 +72,7 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
|||||||
RM3100::Rm3100PrimaryDataset primaryDataset;
|
RM3100::Rm3100PrimaryDataset primaryDataset;
|
||||||
|
|
||||||
uint8_t commandBuffer[10];
|
uint8_t commandBuffer[10];
|
||||||
uint8_t commandBufferLen = 0;
|
// uint8_t commandBufferLen = 0;
|
||||||
|
|
||||||
uint8_t cmmRegValue = RM3100::CMM_VALUE;
|
uint8_t cmmRegValue = RM3100::CMM_VALUE;
|
||||||
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;
|
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;
|
||||||
|
@ -67,7 +67,7 @@ void CommandExecutor::printLastError(std::string funcName) const {
|
|||||||
sif::warning << funcName << " pclose failed with code " << lastError << ": "
|
sif::warning << funcName << " pclose failed with code " << lastError << ": "
|
||||||
<< strerror(lastError) << std::endl;
|
<< strerror(lastError) << std::endl;
|
||||||
#else
|
#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));
|
strerror(lastError));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ ReturnValue_t CommandExecutor::check(bool& replyReceived) {
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << currentCmd << " | " << readVec.data();
|
sif::info << currentCmd << " | " << readVec.data();
|
||||||
#else
|
#else
|
||||||
sif::printInfo("%s | %s", currentCmd, readVec.data());
|
sif::printInfo("%s | %s", currentCmd.c_str(), readVec.data());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (ringBuffer != nullptr) {
|
if (ringBuffer != nullptr) {
|
||||||
@ -188,7 +188,7 @@ ReturnValue_t CommandExecutor::executeBlocking() {
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << currentCmd << " | " << output;
|
sif::info << currentCmd << " | " << output;
|
||||||
#else
|
#else
|
||||||
sif::printInfo("%s | %s", currentCmd, output);
|
sif::printInfo("%s | %s", currentCmd.c_str(), output.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (ringBuffer != nullptr) {
|
if (ringBuffer != nullptr) {
|
||||||
|
@ -146,8 +146,9 @@ ReturnValue_t testserialize::test_autoserialization() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// These epsilon values were just guessed.. It appears to work though.
|
// 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
|
if (std::abs(tv_float - tv::tv_float) > 0.0001 or std::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) {
|
std::abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or
|
||||||
|
std::abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
|
||||||
return unitt::put_error(id);
|
return unitt::put_error(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,9 @@ add_subdirectory(globalfunctions)
|
|||||||
add_subdirectory(timemanager)
|
add_subdirectory(timemanager)
|
||||||
add_subdirectory(tmtcpacket)
|
add_subdirectory(tmtcpacket)
|
||||||
add_subdirectory(cfdp)
|
add_subdirectory(cfdp)
|
||||||
add_subdirectory(hal)
|
if(NOT FSFW_OSAL MATCHES "rtems")
|
||||||
|
add_subdirectory(hal)
|
||||||
|
endif()
|
||||||
add_subdirectory(internalerror)
|
add_subdirectory(internalerror)
|
||||||
add_subdirectory(devicehandler)
|
add_subdirectory(devicehandler)
|
||||||
add_subdirectory(tmtcservices)
|
add_subdirectory(tmtcservices)
|
||||||
|
@ -10,16 +10,118 @@
|
|||||||
|
|
||||||
#define CATCH_CONFIG_COLOUR_WINDOWS
|
#define CATCH_CONFIG_COLOUR_WINDOWS
|
||||||
|
|
||||||
|
#include <fsfw/osal/osal.h>
|
||||||
|
|
||||||
#include <catch2/catch_session.hpp>
|
#include <catch2/catch_session.hpp>
|
||||||
|
|
||||||
|
#ifdef FSFW_OSAL_FREERTOS
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
|
||||||
|
#include "task.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int customSetup();
|
extern int customSetup();
|
||||||
extern int customTeardown();
|
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[]) {
|
int main(int argc, char* argv[]) {
|
||||||
customSetup();
|
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
|
// Catch internal function call
|
||||||
int result = Catch::Session().run(argc, argv);
|
result = Catch::Session().run(argc, argv);
|
||||||
|
#endif
|
||||||
|
|
||||||
// global clean-up
|
// global clean-up
|
||||||
customTeardown();
|
customTeardown();
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
#include "mocks/cfdp/FaultHandlerMock.h"
|
#include "mocks/cfdp/FaultHandlerMock.h"
|
||||||
|
|
||||||
|
// Thanks, windows
|
||||||
|
#ifdef NO_ERROR
|
||||||
|
#undef NO_ERROR
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("CFDP Fault Handler", "[cfdp]") {
|
TEST_CASE("CFDP Fault Handler", "[cfdp]") {
|
||||||
using namespace cfdp;
|
using namespace cfdp;
|
||||||
auto fhMock = FaultHandlerMock();
|
auto fhMock = FaultHandlerMock();
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
#include "fsfw/cfdp/pdu/AckPduReader.h"
|
#include "fsfw/cfdp/pdu/AckPduReader.h"
|
||||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||||
|
|
||||||
|
// Thanks, windows
|
||||||
|
#ifdef NO_ERROR
|
||||||
|
#undef NO_ERROR
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("ACK PDU", "[cfdp][pdu]") {
|
TEST_CASE("ACK PDU", "[cfdp][pdu]") {
|
||||||
using namespace cfdp;
|
using namespace cfdp;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
@ -42,7 +42,9 @@ TEST_CASE("EOF PDU", "[cfdp][pdu]") {
|
|||||||
REQUIRE(sz == 20);
|
REQUIRE(sz == 20);
|
||||||
|
|
||||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||||
eofInfo.setFileSize(0x10ffffff10, true);
|
uint64_t value = 0x13ffffffff;
|
||||||
|
size_t vlaue1 = value;
|
||||||
|
eofInfo.setFileSize(0x13fffefd10, true);
|
||||||
pduConf.largeFile = true;
|
pduConf.largeFile = true;
|
||||||
// Should serialize with fault location now
|
// Should serialize with fault location now
|
||||||
auto serializeWithFaultLocation = EofPduCreator(pduConf, eofInfo);
|
auto serializeWithFaultLocation = EofPduCreator(pduConf, eofInfo);
|
||||||
@ -57,7 +59,7 @@ TEST_CASE("EOF PDU", "[cfdp][pdu]") {
|
|||||||
uint64_t fileSizeLarge = 0;
|
uint64_t fileSizeLarge = 0;
|
||||||
result = SerializeAdapter::deSerialize(&fileSizeLarge, buf.data() + 16, nullptr,
|
result = SerializeAdapter::deSerialize(&fileSizeLarge, buf.data() + 16, nullptr,
|
||||||
SerializeIF::Endianness::NETWORK);
|
SerializeIF::Endianness::NETWORK);
|
||||||
REQUIRE(fileSizeLarge == 0x10ffffff10);
|
REQUIRE(fileSizeLarge == 0x13fffefd10);
|
||||||
REQUIRE(buf[sz - 4] == cfdp::TlvType::ENTITY_ID);
|
REQUIRE(buf[sz - 4] == cfdp::TlvType::ENTITY_ID);
|
||||||
// width of entity ID is 2
|
// width of entity ID is 2
|
||||||
REQUIRE(buf[sz - 3] == 2);
|
REQUIRE(buf[sz - 3] == 2);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user