Compare commits
42 Commits
master
...
mohr/warni
Author | SHA1 | Date |
---|---|---|
Ulrich Mohr | 2ca9eb4204 | |
Ulrich Mohr | 45b686a028 | |
Ulrich Mohr | 329e80e7ee | |
Ulrich Mohr | 3772db4753 | |
Ulrich Mohr | 3d13ead275 | |
Ulrich Mohr | e7e9ce4baf | |
Ulrich Mohr | e4c11f8107 | |
Ulrich Mohr | 270622a5f1 | |
Ulrich Mohr | 4b52e5bec4 | |
Ulrich Mohr | efc2773f84 | |
Ulrich Mohr | 87bb29a66a | |
Ulrich Mohr | 45963b2064 | |
Ulrich Mohr | bc312243df | |
Ulrich Mohr | 9589d702dd | |
Ulrich Mohr | c66fab90f9 | |
Ulrich Mohr | 3e8446ba8b | |
Ulrich Mohr | e37af4fe70 | |
Ulrich Mohr | 941bf61f28 | |
Ulrich Mohr | 70fd9ff3e5 | |
Ulrich Mohr | 81c5b2ec95 | |
Ulrich Mohr | 7426e10f82 | |
uli | 123c81777a | |
Ulrich Mohr | dcc28622a5 | |
Ulrich Mohr | 6d85fa155e | |
Ulrich Mohr | e6af6200ae | |
Ulrich Mohr | 5ca3e83934 | |
Ulrich Mohr | 6adabb059a | |
Ulrich Mohr | 5d0a5cd201 | |
Ulrich Mohr | adb8483bb0 | |
Ulrich Mohr | fdfdce2fb0 | |
Ulrich Mohr | 90efb132d0 | |
Ulrich Mohr | fe9804d922 | |
Ulrich Mohr | a0eae66c35 | |
Ulrich Mohr | e131480d5f | |
Ulrich Mohr | 90bafbb6de | |
Ulrich Mohr | 47d85fb61c | |
Ulrich Mohr | 39dad5f45b | |
Ulrich Mohr | a993c4e0d4 | |
Robin Müller | fe9cc20d00 | |
Robin Müller | 552a12a6ad | |
Ulrich Mohr | 13639feec6 | |
Ulrich Mohr | 654de0f586 |
|
@ -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")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
# Manually tweak MSVC to emit (about) the same warnings as clang and gcc on linux
|
||||
# needs to be done here using add_compile_definitions() (as opposed to target_compile_definitions()) to be available for all binaries and libraries
|
||||
add_compile_options("/permissive-" /wd4267 /wd4244 /wd4244 /wd4305 /wd4805 /wd4267 /wd4646 /wd4065 /wd4996 /Dand=&& /Dor=|| /Dnot=!)
|
||||
add_compile_definitions(NOMINMAX)
|
||||
endif()
|
||||
|
||||
set(FSFW_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw")
|
||||
|
||||
set(FSFW_ETL_LIB_NAME etl)
|
||||
|
@ -153,7 +160,7 @@ if(FSFW_BUILD_TESTS)
|
|||
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||
)
|
||||
# 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
|
||||
if(NOT Catch2_FOUND)
|
||||
message(
|
||||
|
@ -174,6 +181,27 @@ if(FSFW_BUILD_TESTS)
|
|||
configure_file(unittests/testcfg/FSFWConfig.h.in FSFWConfig.h)
|
||||
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
||||
|
||||
if(FSFW_OSAL MATCHES "freertos")
|
||||
message(STATUS "${MSG_PREFIX} Downloading FreeRTOS with FetchContent")
|
||||
include(FetchContent)
|
||||
|
||||
set(FreeRTOS_PORT posix)
|
||||
|
||||
FetchContent_Declare(
|
||||
FreeRTOS
|
||||
GIT_REPOSITORY https://egit.irs.uni-stuttgart.de/fsfw/FreeRTOS-LTS
|
||||
GIT_TAG develop
|
||||
GIT_SUBMODULES FreeRTOS/FreeRTOS-Kernel)
|
||||
|
||||
FetchContent_MakeAvailable(FreeRTOS)
|
||||
|
||||
set(LIB_OS_NAME FreeRTOS)
|
||||
target_include_directories(FreeRTOS PUBLIC unittests/testcfg/freertos)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(FreeRTOS PRIVATE ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
project(${FSFW_TEST_TGT} CXX C)
|
||||
add_executable(${FSFW_TEST_TGT})
|
||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||
|
@ -226,6 +254,7 @@ if(FSFW_FETCH_CONTENT_TARGETS)
|
|||
# GitHub issue: https://github.com/catchorg/Catch2/issues/2417
|
||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
set(FSFW_CORE_INC_PATH "inc")
|
||||
|
@ -360,6 +389,9 @@ if(FSFW_BUILD_TESTS)
|
|||
endif()
|
||||
target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2
|
||||
${LIB_FSFW_NAME})
|
||||
if(FSFW_OSAL MATCHES "freertos")
|
||||
target_link_libraries(${FSFW_TEST_TGT} PRIVATE FreeRTOS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. If
|
||||
|
@ -447,8 +479,47 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(COMPILER_FLAGS "/permissive-")
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(FSFW_WARNING_FLAGS
|
||||
-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()
|
||||
|
||||
# Required include paths to compile the FSFW
|
||||
|
|
|
@ -5,7 +5,7 @@ RUN apt-get --yes upgrade
|
|||
|
||||
#tzdata is a dependency, won't install otherwise
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get --yes install 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
|
||||
|
||||
|
@ -21,9 +21,37 @@ RUN git clone https://github.com/ETLCPP/etl.git && \
|
|||
cmake -B build . && \
|
||||
cmake --install build/
|
||||
|
||||
|
||||
# install our own rtems build
|
||||
RUN wget -qO- https://buggy.irs.uni-stuttgart.de/rtems_releases/rtems6-12.2.1.tar.bz2 | tar -xj -C /opt/
|
||||
ENV PATH="$PATH:/opt/rtems/6/bin"
|
||||
|
||||
# install modern wine for MSVC, removing a conflicting file
|
||||
RUN dpkg --add-architecture i386 && \
|
||||
mkdir -pm755 /etc/apt/keyrings && \
|
||||
wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key && \
|
||||
wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/focal/winehq-focal.sources && \
|
||||
apt-get update && \
|
||||
apt-get --yes install winehq-stable
|
||||
# silence wine
|
||||
ENV WINEDEBUG=-all
|
||||
|
||||
|
||||
# install MSVC using https://github.com/mstorsjo/msvc-wine
|
||||
# see msvc-wine/LICENSE.txt
|
||||
COPY msvc-wine/lowercase msvc-wine/fixinclude msvc-wine/install.sh msvc-wine/vsdownload.py ./
|
||||
COPY msvc-wine/wrappers/* ./wrappers/
|
||||
RUN PYTHONUNBUFFERED=1 ./vsdownload.py --accept-license --dest /opt/msvc && \
|
||||
./install.sh /opt/msvc && \
|
||||
rm lowercase fixinclude install.sh vsdownload.py && \
|
||||
rm -rf wrappers
|
||||
RUN wine64 wineboot --init && \
|
||||
while pgrep wineserver > /dev/null; do sleep 1; done
|
||||
|
||||
|
||||
#ssh needs a valid user to work
|
||||
RUN adduser --uid 114 jenkins
|
||||
RUN addgroup -q --gid 117 jenkins && adduser -q --uid 114 --gid 117 jenkins
|
||||
|
||||
#add documentation server to known hosts
|
||||
RUN echo "|1|/LzCV4BuTmTb2wKnD146l9fTKgQ=|NJJtVjvWbtRt8OYqFgcYRnMQyVw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||
RUN echo "|1|CcBvBc3EG03G+XM5rqRHs6gK/Gg=|oGeJQ+1I8NGI2THIkJsW92DpTzs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||
RUN echo "|1|CcBvBc3EG03G+XM5rqRHs6gK/Gg=|oGeJQ+1I8NGI2THIkJsW92DpTzs= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNL8ssTonYtgiR/6RRlSIK9WU1ywOcJmxFTLcEblAwH7oifZzmYq3XRfwXrgfMpylEfMFYfCU8JRqtmi19xc21A=" >> /etc/ssh/ssh_known_hosts
|
||||
|
|
|
@ -2,86 +2,72 @@ pipeline {
|
|||
environment {
|
||||
BUILDDIR_HOST = 'cmake-build-tests-host'
|
||||
BUILDDIR_LINUX = 'cmake-build-tests-linux'
|
||||
BUILDDIR_FREERTOS = 'cmake-build-tests-freertos'
|
||||
BUILDDIR_RTEMS = 'cmake-build-tests-rtems'
|
||||
BUILDDIR_WIN = 'cmake-build-tests-windows'
|
||||
DOCDDIR = 'cmake-build-documentation'
|
||||
}
|
||||
agent {
|
||||
docker {
|
||||
image 'fsfw-ci:d6'
|
||||
image 'fsfw-ci:d9'
|
||||
args '--network host --sysctl fs.mqueue.msg_max=100'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Host') {
|
||||
stages{
|
||||
stage('Clean') {
|
||||
steps {
|
||||
sh 'rm -rf $BUILDDIR_HOST'
|
||||
}
|
||||
}
|
||||
stage('Configure') {
|
||||
steps {
|
||||
dir(BUILDDIR_HOST) {
|
||||
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
dir(BUILDDIR_HOST) {
|
||||
sh 'cmake --build . -j4'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Unittests') {
|
||||
steps {
|
||||
dir(BUILDDIR_HOST) {
|
||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Valgrind') {
|
||||
steps {
|
||||
dir(BUILDDIR_HOST) {
|
||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||
}
|
||||
}
|
||||
stage('Host-clang') {
|
||||
steps {
|
||||
sh 'rm -rf $BUILDDIR_HOST'
|
||||
|
||||
dir(BUILDDIR_HOST) {
|
||||
sh 'CC=clang CXX=clang++ cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||
sh 'cmake --build . -j4'
|
||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Linux') {
|
||||
stages{
|
||||
stage('Clean') {
|
||||
steps {
|
||||
sh 'rm -rf $BUILDDIR_LINUX'
|
||||
}
|
||||
stage('Linux-gcc') {
|
||||
steps {
|
||||
sh 'rm -rf $BUILDDIR_LINUX'
|
||||
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||
sh 'cmake --build . -j4'
|
||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||
}
|
||||
stage('Configure') {
|
||||
steps {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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('Build') {
|
||||
steps {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sh 'cmake --build . -j4'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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('Unittests') {
|
||||
steps {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Valgrind') {
|
||||
steps {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +83,7 @@ pipeline {
|
|||
sh 'rsync -r --delete docs/sphinx/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/development'
|
||||
}
|
||||
}
|
||||
dir(BUILDDIR) {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
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'
|
||||
}
|
||||
}
|
||||
dir(BUILDDIR) {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sshagent(credentials: ['documentation-buildfix']) {
|
||||
sh 'rsync -r --delete fsfw-tests_coverage/* buildfix@documentation.irs.uni-stuttgart.de:/fsfw/coverage/master'
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2d2d7db0b55b0f061eca5f4f1c149608d5501ec6
|
|
@ -21,7 +21,7 @@ struct FileSize : public SerializeIF {
|
|||
this->largeFile = isLarge;
|
||||
return serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
using SerializeIF::serialize;
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
if (not largeFile) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() {
|
||||
cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_t value) : VarLenField() {
|
||||
ReturnValue_t result = this->setValue(width, value);
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
|
@ -20,7 +20,7 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o
|
|||
|
||||
cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; }
|
||||
|
||||
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) {
|
||||
ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, uint64_t value_) {
|
||||
switch (widthInBytes) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
if (value_ > UINT8_MAX) {
|
||||
|
@ -51,7 +51,7 @@ ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_
|
|||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
size_t cfdp::VarLenField::getValue() const {
|
||||
uint64_t cfdp::VarLenField::getValue() const {
|
||||
switch (width) {
|
||||
case (cfdp::WidthInBytes::ONE_BYTE): {
|
||||
return value.oneByte;
|
||||
|
|
|
@ -25,13 +25,13 @@ class VarLenField : public SerializeIF {
|
|||
template <typename T>
|
||||
explicit VarLenField(UnsignedByteField<T> byteField);
|
||||
|
||||
VarLenField(cfdp::WidthInBytes width, size_t value);
|
||||
VarLenField(cfdp::WidthInBytes width, uint64_t value);
|
||||
|
||||
bool operator==(const VarLenField &other) const;
|
||||
bool operator!=(const VarLenField &other) const;
|
||||
bool operator<(const VarLenField &other) const;
|
||||
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, size_t value);
|
||||
ReturnValue_t setValue(cfdp::WidthInBytes, uint64_t value);
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
@ -42,7 +42,7 @@ class VarLenField : public SerializeIF {
|
|||
Endianness streamEndianness);
|
||||
|
||||
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
|
||||
[[nodiscard]] size_t getValue() const;
|
||||
[[nodiscard]] uint64_t getValue() const;
|
||||
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
|
||||
|
@ -53,6 +53,7 @@ class VarLenField : public SerializeIF {
|
|||
#endif
|
||||
|
||||
private:
|
||||
using SerializeIF::deSerialize;
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
#include "fsfw/returnvalues/FwClassIds.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
// Thanks, windows
|
||||
#ifdef NO_ERROR
|
||||
#undef NO_ERROR
|
||||
#endif
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5";
|
||||
|
|
|
@ -68,6 +68,7 @@ class UserBase {
|
|||
|
||||
public:
|
||||
explicit UserBase(HasFileSystemIF& vfs);
|
||||
virtual ~UserBase() = default;
|
||||
|
||||
virtual void transactionIndication(const TransactionId& id) = 0;
|
||||
virtual void eofSentIndication(const TransactionId& id) = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "helpers.h"
|
||||
|
||||
const char* COND_CODE_STRINGS[14] = {"Unknown",
|
||||
static const char* COND_CODE_STRINGS[14] = {"Unknown",
|
||||
"No Error",
|
||||
"Positive ACK Limit Reached",
|
||||
"Keep Alive Limit Reached",
|
||||
|
|
|
@ -42,6 +42,6 @@ size_t EofInfo::getSerializedSize(bool fssLarge) {
|
|||
return size;
|
||||
}
|
||||
|
||||
ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) {
|
||||
ReturnValue_t EofInfo::setFileSize(uint64_t fileSize, bool isLarge) {
|
||||
return this->fileSize.setFileSize(fileSize, isLarge);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ struct EofInfo {
|
|||
void setChecksum(uint32_t checksum);
|
||||
void setConditionCode(cfdp::ConditionCode conditionCode);
|
||||
void setFaultLoc(EntityIdTlv* faultLoc);
|
||||
ReturnValue_t setFileSize(size_t size, bool isLarge);
|
||||
ReturnValue_t setFileSize(uint64_t size, bool isLarge);
|
||||
|
||||
private:
|
||||
cfdp::ConditionCode conditionCode;
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#include "FinishedPduReader.h"
|
||||
|
||||
// Thanks, windows
|
||||
#ifdef NO_ERROR
|
||||
#undef NO_ERROR
|
||||
#endif
|
||||
|
||||
FinishPduReader::FinishPduReader(const uint8_t* pduBuf, size_t maxSize, FinishedInfo& info)
|
||||
: FileDirectiveReader(pduBuf, maxSize), finishedInfo(info) {}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ class EntityIdTlv : public TlvIF {
|
|||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv& tlv, Endianness endianness);
|
||||
|
||||
using SerializeIF::deSerialize;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class FilestoreRequestTlv : public cfdp::FilestoreTlvBase {
|
|||
*/
|
||||
ReturnValue_t deSerialize(cfdp::Tlv &tlv, Endianness endianness);
|
||||
|
||||
using SerializeIF::deSerialize;
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ class FilestoreResponseTlv : public cfdp::FilestoreTlvBase {
|
|||
*/
|
||||
ReturnValue_t deSerialize(const cfdp::Tlv& tlv, Endianness endianness);
|
||||
|
||||
using SerializeIF::deSerialize;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
template <typename Tp>
|
||||
class BinaryNode {
|
||||
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;
|
||||
BinaryNode* left;
|
||||
BinaryNode* right;
|
||||
|
@ -23,31 +23,31 @@ class ExplicitNodeIterator {
|
|||
typedef Tp value_type;
|
||||
typedef Tp* pointer;
|
||||
typedef Tp& reference;
|
||||
ExplicitNodeIterator() : element(NULL) {}
|
||||
ExplicitNodeIterator() : element(nullptr) {}
|
||||
ExplicitNodeIterator(_Node* node) : element(node) {}
|
||||
BinaryNode<Tp>* element;
|
||||
_Self up() { return _Self(element->parent); }
|
||||
_Self left() {
|
||||
if (element != NULL) {
|
||||
if (element != nullptr) {
|
||||
return _Self(element->left);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
return _Self(nullptr);
|
||||
}
|
||||
}
|
||||
_Self right() {
|
||||
if (element != NULL) {
|
||||
if (element != nullptr) {
|
||||
return _Self(element->right);
|
||||
} 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; }
|
||||
pointer operator->() const {
|
||||
if (element != NULL) {
|
||||
if (element != nullptr) {
|
||||
return element->value;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
pointer operator*() const { return this->operator->(); }
|
||||
|
@ -62,13 +62,13 @@ class BinaryTree {
|
|||
typedef ExplicitNodeIterator<Tp> iterator;
|
||||
typedef BinaryNode<Tp> Node;
|
||||
typedef std::pair<iterator, iterator> children;
|
||||
BinaryTree() : rootNode(NULL) {}
|
||||
BinaryTree() : rootNode(nullptr) {}
|
||||
BinaryTree(Node* rootNode) : rootNode(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) {
|
||||
newNode->parent = parentNode.element;
|
||||
if (parentNode.element != NULL) {
|
||||
if (parentNode.element != nullptr) {
|
||||
if (insertLeft) {
|
||||
parentNode.element->left = newNode;
|
||||
} else {
|
||||
|
@ -84,13 +84,13 @@ class BinaryTree {
|
|||
children erase(iterator node) {
|
||||
if (node.element == rootNode) {
|
||||
// We're root node
|
||||
rootNode = NULL;
|
||||
rootNode = nullptr;
|
||||
} else {
|
||||
// Delete parent's reference
|
||||
if (node.up().left() == node) {
|
||||
node.up().element->left = NULL;
|
||||
node.up().element->left = nullptr;
|
||||
} else {
|
||||
node.up().element->right = NULL;
|
||||
node.up().element->right = nullptr;
|
||||
}
|
||||
}
|
||||
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
|
||||
// that, however).
|
||||
thisElement->~T();
|
||||
uint8_t* pointer = (uint8_t*)(thisElement);
|
||||
uint8_t* pointer = static_cast<uint8_t*>(thisElement);
|
||||
return dataBackend->deleteData(pointer, sizeof(T));
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,6 @@ ReturnValue_t LocalDataPoolManager::addUpdateToStore(HousekeepingSnapshot& updat
|
|||
result = updatePacket.serialize(&storePtr, &serializedSize, updatePacketSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
return result;
|
||||
;
|
||||
}
|
||||
|
||||
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,
|
||||
ReturnValue_t errorCode = returnvalue::FAILED,
|
||||
const char* errorPrint = nullptr);
|
||||
|
||||
private:
|
||||
using ProvidesDataPoolSubscriptionIF::subscribeForPeriodicPacket;
|
||||
using ProvidesDataPoolSubscriptionIF::subscribeForUpdatePacket;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
|
|
@ -27,7 +27,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
|
|||
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == NULL) {
|
||||
if (parent == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
parentQueue = parent->getCommandQueue();
|
||||
|
|
|
@ -322,8 +322,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||
if (mode != currentMode) {
|
||||
break;
|
||||
}
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
uint32_t currentUptime = Clock::getUptime_ms();
|
||||
if (currentUptime - timeoutStart >= childTransitionDelay) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1 && FSFW_OBJ_EVENT_TRANSLATION == 0
|
||||
char printout[60];
|
||||
|
@ -347,8 +346,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||
setMode(_MODE_WAIT_ON);
|
||||
break;
|
||||
case _MODE_WAIT_ON: {
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
uint32_t currentUptime = Clock::getUptime_ms();
|
||||
if (powerSwitcher != nullptr and
|
||||
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||
|
@ -367,8 +365,7 @@ void DeviceHandlerBase::doStateMachine() {
|
|||
}
|
||||
} break;
|
||||
case _MODE_WAIT_OFF: {
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
uint32_t currentUptime = Clock::getUptime_ms();
|
||||
|
||||
if (powerSwitcher == nullptr) {
|
||||
setMode(MODE_OFF);
|
||||
|
@ -578,7 +575,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
|||
modeHelper.modeChanged(newMode, newSubmode);
|
||||
announceMode(false);
|
||||
}
|
||||
Clock::getUptime(&timeoutStart);
|
||||
timeoutStart = Clock::getUptime_ms();
|
||||
|
||||
if (mode == MODE_OFF and thermalSet != nullptr) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
|
@ -937,19 +934,14 @@ DeviceHandlerIF::CommunicationAction DeviceHandlerBase::getComAction() {
|
|||
switch (pstStep) {
|
||||
case 0:
|
||||
return CommunicationAction::PERFORM_OPERATION;
|
||||
break;
|
||||
case 1:
|
||||
return CommunicationAction::SEND_WRITE;
|
||||
break;
|
||||
case 2:
|
||||
return CommunicationAction::GET_WRITE;
|
||||
break;
|
||||
case 3:
|
||||
return CommunicationAction::SEND_READ;
|
||||
break;
|
||||
case 4:
|
||||
return CommunicationAction::GET_READ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -965,7 +957,7 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
|
|||
replyReturnvalueToCommand(result, RAW_COMMAND_ID);
|
||||
storedRawData.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
} 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.state = COOKIE_WRITE_READY;
|
||||
}
|
||||
|
|
|
@ -206,9 +206,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||
|
||||
Mode_t getTransitionSourceMode() const;
|
||||
Submode_t getTransitionSourceSubMode() const;
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||
HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
HealthState getHealth() override;
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues,
|
||||
|
@ -1073,7 +1073,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||
bool forceDirectTm = false);
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode);
|
||||
uint32_t *msToReachTheMode) override;
|
||||
|
||||
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ void DeviceHandlerMessage::clear(CommandMessage* message) {
|
|||
ipcStore->deleteData(getStoreAddress(message));
|
||||
}
|
||||
}
|
||||
/* NO BREAK falls through*/
|
||||
[[fallthrough]];
|
||||
case CMD_SWITCH_ADDRESS:
|
||||
case CMD_WIRETAPPING:
|
||||
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);
|
||||
|
||||
MessageQueueId_t getEventReportQueue();
|
||||
MessageQueueId_t getEventReportQueue() override;
|
||||
|
||||
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
|
||||
ReturnValue_t registerListener(MessageQueueId_t listener,
|
||||
bool forwardAllButSelected = false) override;
|
||||
ReturnValue_t unregisterListener(MessageQueueId_t listener) override;
|
||||
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
|
||||
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
|
||||
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) override;
|
||||
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) override;
|
||||
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||
EventId_t idTo = 0, bool idInverted = false,
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object);
|
||||
bool reporterInverted = false) override;
|
||||
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) override;
|
||||
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||
EventId_t idTo = 0, bool idInverted = false,
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
bool reporterInverted = false) override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
protected:
|
||||
MessageQueueIF* eventReportQueue = nullptr;
|
||||
|
|
|
@ -52,6 +52,7 @@ ReturnValue_t DleParser::parseRingBuf(size_t& readSize) {
|
|||
// without skipping the STX
|
||||
readSize = vectorIdx;
|
||||
ErrorInfo info;
|
||||
info.len = vectorIdx;
|
||||
setErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
||||
return POSSIBLE_PACKET_LOSS;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class Type : public SerializeIF {
|
|||
|
||||
template <typename T>
|
||||
struct PodTypeConversion {
|
||||
static_assert(not std::is_same<T, bool>::value,
|
||||
static_assert(!std::is_same<T, bool>::value,
|
||||
"Do not use boolean for the PoolEntry type, use uint8_t "
|
||||
"instead! The ECSS standard defines a boolean as a one bit "
|
||||
"field. Therefore it is preferred to store a boolean as an "
|
||||
|
|
|
@ -37,16 +37,16 @@ void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, bool
|
|||
}
|
||||
}
|
||||
|
||||
void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerLine) {
|
||||
void arrayprinter::printHex(const uint8_t *data, size_t datasize, size_t maxCharPerLine) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if (sif::info.crAdditionEnabled()) {
|
||||
std::cout << "\r" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "hex [" << std::setfill('0') << std::hex;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
for (size_t i = 0; i < datasize; i++) {
|
||||
std::cout << std::setw(2) << static_cast<int>(data[i]);
|
||||
if (i < size - 1) {
|
||||
if (i < datasize - 1) {
|
||||
std::cout << ",";
|
||||
if (i > 0 and (i + 1) % maxCharPerLine == 0) {
|
||||
std::cout << std::endl;
|
||||
|
@ -56,27 +56,11 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerL
|
|||
std::cout << std::dec << std::setfill(' ');
|
||||
std::cout << "]" << std::endl;
|
||||
#else
|
||||
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
||||
// plus line break plus small safety margin.
|
||||
char printBuffer[(size + 1) * 7 + 1] = {};
|
||||
size_t currentPos = 0;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// To avoid buffer overflows.
|
||||
if (sizeof(printBuffer) - currentPos <= 7) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPos += snprintf(printBuffer + currentPos, 6, "%02x", data[i]);
|
||||
if (i < size - 1) {
|
||||
currentPos += sprintf(printBuffer + currentPos, ",");
|
||||
if ((i + 1) % maxCharPerLine == 0) {
|
||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
||||
}
|
||||
}
|
||||
printf("hex [");
|
||||
for (size_t i = 0; i < datasize; i++) {
|
||||
printf("0x%02x ", data[i]);
|
||||
}
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
printf("hex [%s]\n", printBuffer);
|
||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||
printf("]\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -100,26 +84,10 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerL
|
|||
#else
|
||||
// General format: 32,243,-12 so it is number of chars times 4
|
||||
// plus line break plus small safety margin.
|
||||
uint16_t expectedLines = ceil((double)size / maxCharPerLine);
|
||||
char printBuffer[size * 4 + 1 + expectedLines] = {};
|
||||
size_t currentPos = 0;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// To avoid buffer overflows.
|
||||
if (sizeof(printBuffer) - currentPos <= 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentPos += snprintf(printBuffer + currentPos, 4, "%d", data[i]);
|
||||
if (i < size - 1) {
|
||||
currentPos += sprintf(printBuffer + currentPos, ",");
|
||||
if ((i + 1) % maxCharPerLine == 0) {
|
||||
currentPos += sprintf(printBuffer + currentPos, "\n");
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// TODO
|
||||
}
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
printf("dec [%s]\n", printBuffer);
|
||||
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
Endianness streamEndianness) const override {
|
||||
if (timeStamp != nullptr) {
|
||||
/* Endianness will always be MACHINE, so we can simply use memcpy
|
||||
here. */
|
||||
|
@ -70,7 +70,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
virtual size_t getSerializedSize() const override {
|
||||
if (updateData == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class CommandMessage : public MessageQueueMessage, public CommandMessageIF {
|
|||
/**
|
||||
* @brief Default Destructor
|
||||
*/
|
||||
virtual ~CommandMessage() {}
|
||||
~CommandMessage() override {}
|
||||
|
||||
/**
|
||||
* Read the DeviceHandlerCommand_t that is stored in the message,
|
||||
|
|
|
@ -37,7 +37,7 @@ class CommandMessageIF {
|
|||
//! par1 should contain the error code
|
||||
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.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||
|
||||
struct MqArgs {
|
||||
MqArgs(){};
|
||||
MqArgs(){}
|
||||
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
||||
object_id_t objectId = objects::NO_OBJECT;
|
||||
void* args = nullptr;
|
||||
|
|
|
@ -18,7 +18,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
|||
violationEvent(violationEvent),
|
||||
aboveIsViolation(aboveIsViolation) {}
|
||||
virtual ~AbsLimitMonitor() {}
|
||||
virtual ReturnValue_t checkSample(T sample, T *crossedLimit) {
|
||||
ReturnValue_t checkSample(T sample, T *crossedLimit) override {
|
||||
*crossedLimit = limit;
|
||||
if (aboveIsViolation) {
|
||||
if ((std::abs(sample) > limit)) {
|
||||
|
@ -32,9 +32,9 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
|||
return returnvalue::OK; // We're not out of range.
|
||||
}
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) override {
|
||||
ReturnValue_t result = this->MonitorBase<T>::getParameter(
|
||||
domainId, parameterId, parameterWrapper, newValues, startAtIndex);
|
||||
// We'll reuse the DOMAIN_ID of MonitorReporter,
|
||||
|
@ -61,7 +61,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
|||
void setLimit(T value) { limit = value; }
|
||||
|
||||
protected:
|
||||
void sendTransitionEvent(T currentValue, ReturnValue_t state) {
|
||||
void sendTransitionEvent(T currentValue, ReturnValue_t state) override {
|
||||
switch (state) {
|
||||
case MonitoringIF::OUT_OF_RANGE:
|
||||
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.
|
||||
*/
|
||||
virtual ~ObjectManagerIF(void){};
|
||||
virtual ~ObjectManagerIF(void){}
|
||||
/**
|
||||
* @brief With this call, new objects are inserted to the list.
|
||||
* @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.
|
||||
*/
|
||||
virtual ~SystemObject();
|
||||
~SystemObject() override;
|
||||
object_id_t getObjectId() const override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual ReturnValue_t checkObjectConnections() override;
|
||||
|
|
|
@ -36,7 +36,7 @@ class SystemObjectIF : public EventReportingProxyIF {
|
|||
/**
|
||||
* The empty virtual destructor as required for C++ interfaces.
|
||||
*/
|
||||
virtual ~SystemObjectIF() {}
|
||||
~SystemObjectIF() override {}
|
||||
/**
|
||||
* @brief Initializes the object.
|
||||
* There are initialization steps which can also be done in the constructor.
|
||||
|
|
|
@ -24,8 +24,11 @@
|
|||
#else
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
// Thanks, windows
|
||||
// clang-format off
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
// clang-format on
|
||||
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER_SYSTEM LITTLE_ENDIAN
|
||||
#else
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#ifdef PLATFORM_WIN
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
#include <netdb.h>
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
|||
|
||||
ReceptionModes receptionMode;
|
||||
TcpConfig tcpConfig;
|
||||
struct sockaddr tcpAddress = {};
|
||||
// struct sockaddr tcpAddress = {};
|
||||
socket_t listenerTcpSocket = 0;
|
||||
|
||||
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#ifdef PLATFORM_WIN
|
||||
#include <winsock2.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#ifdef PLATFORM_WIN
|
||||
#include <ws2tcpip.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
|
|
@ -40,7 +40,7 @@ class BinarySemaphoreUsingTask : public SemaphoreIF {
|
|||
void refreshTaskHandle();
|
||||
|
||||
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
||||
uint32_t timeoutMs = portMAX_DELAY) override;
|
||||
uint32_t timeoutMs = 0) override;
|
||||
ReturnValue_t release() override;
|
||||
uint8_t getSemaphoreCounter() const override;
|
||||
static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle);
|
||||
|
|
|
@ -51,7 +51,7 @@ class BinarySemaphore : public SemaphoreIF {
|
|||
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
||||
*/
|
||||
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
||||
uint32_t timeoutMs = portMAX_DELAY) override;
|
||||
uint32_t timeoutMs = 0) override;
|
||||
|
||||
/**
|
||||
* Same as lockBinarySemaphore() with timeout in FreeRTOS ticks.
|
||||
|
|
|
@ -11,19 +11,6 @@
|
|||
// TODO sanitize input?
|
||||
// TODO much of this code can be reused for tick-only systems
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) { return 1000; }
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
timeval time_timeval;
|
||||
|
||||
ReturnValue_t result = convertTimeOfDayToTimeval(time, &time_timeval);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return setClock(&time_timeval);
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
timeval uptime = getUptime();
|
||||
|
||||
|
@ -44,81 +31,12 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
*uptime = getUptime();
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
TickType_t ticksSinceStart = xTaskGetTickCount();
|
||||
return Timekeeper::ticksToTimeval(ticksSinceStart);
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
timeval uptime = getUptime();
|
||||
*uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
// uint32_t Clock::getUptimeSeconds() {
|
||||
// timeval uptime = getUptime();
|
||||
// return uptime.tv_sec;
|
||||
// }
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval time_timeval;
|
||||
ReturnValue_t result = getClock_timeval(&time_timeval);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
*time = time_timeval.tv_sec * 1000000 + time_timeval.tv_usec;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
timeval time_timeval;
|
||||
ReturnValue_t result = getClock_timeval(&time_timeval);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
struct tm time_tm;
|
||||
|
||||
gmtime_r(&time_timeval.tv_sec, &time_tm);
|
||||
|
||||
time->year = time_tm.tm_year + 1900;
|
||||
time->month = time_tm.tm_mon + 1;
|
||||
time->day = time_tm.tm_mday;
|
||||
|
||||
time->hour = time_tm.tm_hour;
|
||||
time->minute = time_tm.tm_min;
|
||||
time->second = time_tm.tm_sec;
|
||||
|
||||
time->usecond = time_timeval.tv_usec;
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
||||
struct tm time_tm = {};
|
||||
|
||||
time_tm.tm_year = from->year - 1900;
|
||||
time_tm.tm_mon = from->month - 1;
|
||||
time_tm.tm_mday = from->day;
|
||||
|
||||
time_tm.tm_hour = from->hour;
|
||||
time_tm.tm_min = from->minute;
|
||||
time_tm.tm_sec = from->second;
|
||||
|
||||
time_t seconds = mktime(&time_tm);
|
||||
|
||||
to->tv_sec = seconds;
|
||||
to->tv_usec = from->usecond;
|
||||
// Fails in 2038..
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
||||
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ class CountingSemaphoreUsingTask : public SemaphoreIF {
|
|||
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
||||
*/
|
||||
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
|
||||
uint32_t timeoutMs = portMAX_DELAY) override;
|
||||
uint32_t timeoutMs = 0) override;
|
||||
|
||||
/**
|
||||
* Release a semaphore, increasing the number of available counting
|
||||
|
|
|
@ -56,7 +56,9 @@ ReturnValue_t FixedTimeslotTask::startTask() {
|
|||
// start time for the first entry.
|
||||
auto slotListIter = pollingSeqTable.current;
|
||||
|
||||
pollingSeqTable.intializeSequenceAfterTaskCreation();
|
||||
ReturnValue_t result = pollingSeqTable.intializeSequenceAfterTaskCreation();
|
||||
// Ignore returnvalue for now
|
||||
static_cast<void>(result);
|
||||
|
||||
// The start time for the first entry is read.
|
||||
uint32_t intervalMs = slotListIter->pollingTimeMs;
|
||||
|
|
|
@ -22,7 +22,7 @@ ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
|
|||
return MutexIF::MUTEX_NOT_FOUND;
|
||||
}
|
||||
// If the timeout type is BLOCKING, this will be the correct value.
|
||||
uint32_t timeout = portMAX_DELAY;
|
||||
TickType_t timeout = portMAX_DELAY;
|
||||
if (timeoutType == TimeoutType::POLLING) {
|
||||
timeout = 0;
|
||||
} else if (timeoutType == TimeoutType::WAITING) {
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
void TaskManagement::vRequestContextSwitchFromTask() { vTaskDelay(0); }
|
||||
|
||||
void TaskManagement::requestContextSwitch(CallContext callContext = CallContext::TASK) {
|
||||
if (callContext == CallContext::ISR) {
|
||||
// This function depends on the partmacro.h definition for the specific device
|
||||
vRequestContextSwitchFromISR();
|
||||
} else {
|
||||
vRequestContextSwitchFromTask();
|
||||
}
|
||||
// if (callContext == CallContext::ISR) {
|
||||
// // This function depends on the partmacro.h definition for the specific device
|
||||
// vRequestContextSwitchFromISR();
|
||||
// } else {
|
||||
vRequestContextSwitchFromTask();
|
||||
// }
|
||||
}
|
||||
|
||||
TaskHandle_t TaskManagement::getCurrentTaskHandle() { return xTaskGetCurrentTaskHandle(); }
|
||||
|
||||
size_t TaskManagement::getTaskStackHighWatermark(TaskHandle_t task) {
|
||||
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
|
||||
}
|
||||
// size_t TaskManagement::getTaskStackHighWatermark(TaskHandle_t task) {
|
||||
// return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
|
||||
// }
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* Architecture dependant portmacro.h function call.
|
||||
* Should be implemented in bsp.
|
||||
*/
|
||||
extern "C" void vRequestContextSwitchFromISR();
|
||||
// extern "C" void vRequestContextSwitchFromISR();
|
||||
|
||||
/*!
|
||||
* Used by functions to tell if they are being called from
|
||||
|
@ -53,7 +53,7 @@ TaskHandle_t getCurrentTaskHandle();
|
|||
* @return Smallest value of stack remaining since the task was started in
|
||||
* words.
|
||||
*/
|
||||
size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
|
||||
// size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
|
||||
|
||||
}; // namespace TaskManagement
|
||||
|
||||
|
|
|
@ -15,27 +15,6 @@
|
|||
|
||||
using SystemClock = std::chrono::system_clock;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getTicksPerSecond: Not implemented for host OSAL" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::getTicksPerSecond: Not implemented for host OSAL\n");
|
||||
#endif
|
||||
/* To avoid division by zero */
|
||||
return 1;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
/* I don't know why someone would need to set a clock which is probably perfectly fine on a
|
||||
host system with internet access so this is not implemented for now. */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::setClock: Not implemented for host OSAL" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::setClock: Not implemented for host OSAL\n");
|
||||
#endif
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
/* I don't know why someone would need to set a clock which is probably perfectly fine on a
|
||||
host system with internet access so this is not implemented for now. */
|
||||
|
@ -66,6 +45,7 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||
time->tv_usec = timeUnix.tv_nsec / 1000.0;
|
||||
return returnvalue::OK;
|
||||
#else
|
||||
#warning Clock::getClock_timeval() not implemented for your platform
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getUptime: Not implemented for found OS!" << std::endl;
|
||||
#else
|
||||
|
@ -75,15 +55,6 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||
#endif
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
if (time == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
using namespace std::chrono;
|
||||
*time = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
timeval timeval;
|
||||
#if defined(PLATFORM_WIN)
|
||||
|
@ -100,73 +71,10 @@ timeval Clock::getUptime() {
|
|||
timeval.tv_usec = uptimeSeconds * (double)1e6 - (timeval.tv_sec * 1e6);
|
||||
}
|
||||
#else
|
||||
#warning Clock::getUptime() not implemented for your platform
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
||||
#endif
|
||||
#endif
|
||||
return timeval;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
*uptime = getUptime();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
timeval uptime = getUptime();
|
||||
*uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
/* Do some magic with chrono (C++20!) */
|
||||
/* Right now, the library doesn't have the new features to get the required values yet.
|
||||
so we work around that for now. */
|
||||
auto now = SystemClock::now();
|
||||
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
||||
auto fraction = now - seconds;
|
||||
time_t tt = SystemClock::to_time_t(now);
|
||||
ReturnValue_t result = checkOrCreateClockMutex();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
MutexGuard helper(timeMutex);
|
||||
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||
// Therefore we have to use a Mutex here
|
||||
struct tm* timeInfo;
|
||||
timeInfo = gmtime(&tt);
|
||||
time->year = timeInfo->tm_year + 1900;
|
||||
time->month = timeInfo->tm_mon + 1;
|
||||
time->day = timeInfo->tm_mday;
|
||||
time->hour = timeInfo->tm_hour;
|
||||
time->minute = timeInfo->tm_min;
|
||||
time->second = timeInfo->tm_sec;
|
||||
auto usecond = std::chrono::duration_cast<std::chrono::microseconds>(fraction);
|
||||
time->usecond = usecond.count();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
||||
struct tm time_tm {};
|
||||
|
||||
time_tm.tm_year = from->year - 1900;
|
||||
time_tm.tm_mon = from->month - 1;
|
||||
time_tm.tm_mday = from->day;
|
||||
|
||||
time_tm.tm_hour = from->hour;
|
||||
time_tm.tm_min = from->minute;
|
||||
time_tm.tm_sec = from->second;
|
||||
time_tm.tm_isdst = 0;
|
||||
|
||||
time_t seconds = timegm(&time_tm);
|
||||
|
||||
to->tv_sec = seconds;
|
||||
to->tv_usec = from->usecond;
|
||||
// Fails in 2038..
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
||||
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
#if defined(PLATFORM_WIN)
|
||||
#include <processthreadsapi.h>
|
||||
|
||||
#include "fsfw/osal/windows/winTaskHelpers.h"
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
|
|
|
@ -50,6 +50,6 @@ void TaskFactory::printMissedDeadline() {
|
|||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl;
|
||||
#else
|
||||
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name);
|
||||
sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name.c_str());
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
namespace tasks {
|
||||
|
|
|
@ -10,26 +10,6 @@
|
|||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
uint32_t Clock::getTicksPerSecond() {
|
||||
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||
return ticks;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
timespec timeUnix{};
|
||||
timeval timeTimeval{};
|
||||
convertTimeOfDayToTimeval(time, &timeTimeval);
|
||||
timeUnix.tv_sec = timeTimeval.tv_sec;
|
||||
timeUnix.tv_nsec = (__syscall_slong_t)timeTimeval.tv_usec * 1000;
|
||||
|
||||
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
|
||||
if (status != 0) {
|
||||
// TODO errno
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
timespec timeUnix{};
|
||||
timeUnix.tv_sec = time->tv_sec;
|
||||
|
@ -53,104 +33,12 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval timeVal{};
|
||||
ReturnValue_t result = getClock_timeval(&timeVal);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
*time = static_cast<uint64_t>(timeVal.tv_sec) * 1e6 + timeVal.tv_usec;
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
timeval uptime{};
|
||||
auto result = getUptime(&uptime);
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Clock::getUptime: Error getting uptime" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return uptime;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
// TODO This is not posix compatible and delivers only seconds precision
|
||||
// Linux specific file read but more precise.
|
||||
timeval uptime{0, 0};
|
||||
double uptimeSeconds;
|
||||
if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) {
|
||||
uptime->tv_sec = uptimeSeconds;
|
||||
uptime->tv_usec = uptimeSeconds * (double)1e6 - (uptime->tv_sec * 1e6);
|
||||
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;
|
||||
}
|
||||
return uptime;
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <rtems/rtems/sem.h>
|
||||
|
||||
// TODO
|
||||
|
||||
BinarySemaphore::BinarySemaphore() {}
|
||||
|
||||
BinarySemaphore::~BinarySemaphore() {}
|
||||
|
|
|
@ -6,20 +6,21 @@
|
|||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/osal/rtems/RtemsBasic.h"
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) {
|
||||
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
||||
return static_cast<uint32_t>(ticks_per_second);
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
TimeOfDay_t time_tod;
|
||||
ReturnValue_t result = convertTimevalToTimeOfDay(time, &time_tod);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rtems_time_of_day timeRtems;
|
||||
timeRtems.year = time->year;
|
||||
timeRtems.month = time->month;
|
||||
timeRtems.day = time->day;
|
||||
timeRtems.hour = time->hour;
|
||||
timeRtems.minute = time->minute;
|
||||
timeRtems.second = time->second;
|
||||
timeRtems.ticks = time->usecond * getTicksPerSecond() / 1e6;
|
||||
timeRtems.year = time_tod.year;
|
||||
timeRtems.month = time_tod.month;
|
||||
timeRtems.day = time_tod.day;
|
||||
timeRtems.hour = time_tod.hour;
|
||||
timeRtems.minute = time_tod.minute;
|
||||
timeRtems.second = time_tod.second;
|
||||
timeRtems.ticks =
|
||||
static_cast<uint64_t>(time_tod.usecond) * rtems_clock_get_ticks_per_second() / 1e6;
|
||||
rtems_status_code status = rtems_clock_set(&timeRtems);
|
||||
switch (status) {
|
||||
case RTEMS_SUCCESSFUL:
|
||||
|
@ -33,27 +34,6 @@ ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
|||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
timespec newTime;
|
||||
newTime.tv_sec = time->tv_sec;
|
||||
if (time->tv_usec < 0) {
|
||||
// better returnvalue.
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
newTime.tv_nsec = time->tv_usec * TOD_NANOSECONDS_PER_MICROSECOND;
|
||||
|
||||
ISR_lock_Context context;
|
||||
_TOD_Lock();
|
||||
_TOD_Acquire(&context);
|
||||
Status_Control status = _TOD_Set(&newTime, &context);
|
||||
_TOD_Unlock();
|
||||
if (status == STATUS_SUCCESSFUL) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
// better returnvalue
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
// Callable from ISR
|
||||
rtems_status_code status = rtems_clock_get_tod_timeval(time);
|
||||
|
@ -67,86 +47,13 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
timeval Clock::getUptime() {
|
||||
// According to docs.rtems.org for rtems 5 this method is more accurate than
|
||||
// rtems_clock_get_ticks_since_boot
|
||||
timeval time_timeval;
|
||||
timespec time;
|
||||
rtems_status_code status = rtems_clock_get_uptime(&time);
|
||||
uptime->tv_sec = time.tv_sec;
|
||||
time.tv_nsec = time.tv_nsec / 1000;
|
||||
uptime->tv_usec = time.tv_nsec;
|
||||
switch (status) {
|
||||
case RTEMS_SUCCESSFUL:
|
||||
return returnvalue::OK;
|
||||
default:
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
// This counter overflows after 50 days
|
||||
*uptimeMs = rtems_clock_get_ticks_since_boot();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval temp_time;
|
||||
rtems_status_code returnValue = rtems_clock_get_tod_timeval(&temp_time);
|
||||
*time = ((uint64_t)temp_time.tv_sec * 1000000) + temp_time.tv_usec;
|
||||
switch (returnValue) {
|
||||
case RTEMS_SUCCESSFUL:
|
||||
return returnvalue::OK;
|
||||
default:
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
/* For all but the last field, the struct will be filled with the correct values */
|
||||
rtems_time_of_day timeRtems;
|
||||
rtems_status_code status = rtems_clock_get_tod(&timeRtems);
|
||||
switch (status) {
|
||||
case RTEMS_SUCCESSFUL: {
|
||||
/* The last field now contains the RTEMS ticks of the seconds from 0
|
||||
to rtems_clock_get_ticks_per_second() minus one.
|
||||
We calculate the microseconds accordingly */
|
||||
time->day = timeRtems.day;
|
||||
time->hour = timeRtems.hour;
|
||||
time->minute = timeRtems.minute;
|
||||
time->month = timeRtems.month;
|
||||
time->second = timeRtems.second;
|
||||
time->usecond =
|
||||
static_cast<float>(timeRtems.ticks) / rtems_clock_get_ticks_per_second() * 1e6;
|
||||
time->year = timeRtems.year;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case RTEMS_NOT_DEFINED:
|
||||
/* System date and time is not set */
|
||||
return returnvalue::FAILED;
|
||||
case RTEMS_INVALID_ADDRESS:
|
||||
/* time_buffer is NULL */
|
||||
return returnvalue::FAILED;
|
||||
default:
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
||||
// Fails in 2038..
|
||||
rtems_time_of_day timeRtems;
|
||||
timeRtems.year = from->year;
|
||||
timeRtems.month = from->month;
|
||||
timeRtems.day = from->day;
|
||||
timeRtems.hour = from->hour;
|
||||
timeRtems.minute = from->minute;
|
||||
timeRtems.second = from->second;
|
||||
timeRtems.ticks = from->usecond * getTicksPerSecond() / 1e6;
|
||||
to->tv_sec = _TOD_To_seconds(&timeRtems);
|
||||
to->tv_usec = from->usecond;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
||||
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
time_timeval.tv_sec = time.tv_sec;
|
||||
time_timeval.tv_usec = time.tv_nsec / 1000;
|
||||
return time_timeval;
|
||||
}
|
|
@ -93,8 +93,8 @@ ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size, size_t maxSize
|
|||
streamEndianness);
|
||||
}
|
||||
|
||||
uint32_t CpuUsage::getSerializedSize() const {
|
||||
uint32_t size = 0;
|
||||
size_t CpuUsage::getSerializedSize() const {
|
||||
size_t size = 0;
|
||||
|
||||
size += sizeof(timeSinceLastReset);
|
||||
size += SerialArrayListAdapter<ThreadData>::getSerializedSize(&threadData);
|
||||
|
@ -136,8 +136,8 @@ ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, size_t* size, si
|
|||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
uint32_t CpuUsage::ThreadData::getSerializedSize() const {
|
||||
uint32_t size = 0;
|
||||
size_t CpuUsage::ThreadData::getSerializedSize() const {
|
||||
size_t size = 0;
|
||||
|
||||
size += sizeof(id);
|
||||
size += MAX_LENGTH_OF_THREAD_NAME;
|
||||
|
|
|
@ -35,20 +35,19 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
|
|||
return OUT_OF_PROXIES;
|
||||
case INTERNAL_ERROR_INVALID_GLOBAL_ID:
|
||||
return INVALID_GLOBAL_ID;
|
||||
#ifndef STM32H743ZI_NUCLEO
|
||||
case INTERNAL_ERROR_BAD_STACK_HOOK:
|
||||
return BAD_STACK_HOOK;
|
||||
#endif
|
||||
// case INTERNAL_ERROR_BAD_ATTRIBUTES:
|
||||
// return BAD_ATTRIBUTES;
|
||||
// case INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY:
|
||||
// return IMPLEMENTATION_KEY_CREATE_INCONSISTENCY;
|
||||
// case INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL:
|
||||
// return IMPLEMENTATION_BLOCKING_OPERATION_CANCEL;
|
||||
// case INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE:
|
||||
// return MUTEX_OBTAIN_FROM_BAD_STATE;
|
||||
// case INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0:
|
||||
// return UNLIMITED_AND_MAXIMUM_IS_0;
|
||||
// TODO this one is not there anymore in rtems-6 (5 as well?)
|
||||
// case INTERNAL_ERROR_BAD_STACK_HOOK:
|
||||
// return BAD_STACK_HOOK;
|
||||
// case INTERNAL_ERROR_BAD_ATTRIBUTES:
|
||||
// return BAD_ATTRIBUTES;
|
||||
// case INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY:
|
||||
// return IMPLEMENTATION_KEY_CREATE_INCONSISTENCY;
|
||||
// case INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL:
|
||||
// return IMPLEMENTATION_BLOCKING_OPERATION_CANCEL;
|
||||
// case INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE:
|
||||
// return MUTEX_OBTAIN_FROM_BAD_STATE;
|
||||
// case INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0:
|
||||
// return UNLIMITED_AND_MAXIMUM_IS_0;
|
||||
default:
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#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/tasks/SemaphoreFactory.h"
|
||||
|
@ -18,7 +18,9 @@ SemaphoreFactory* SemaphoreFactory::instance() {
|
|||
}
|
||||
|
||||
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) {
|
||||
return new BinarySemaphore();
|
||||
return nullptr;
|
||||
// TODO
|
||||
// return new BinarySemaphore();
|
||||
}
|
||||
|
||||
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount, uint8_t initCount,
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <minwindef.h>
|
||||
// Thanks, windows
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
// clang-format on
|
||||
|
||||
namespace tasks {
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ class ParameterWrapper : public SerializeIF {
|
|||
|
||||
virtual size_t getSerializedSize() const override;
|
||||
|
||||
using SerializeIF::deSerialize;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
|
|
|
@ -62,13 +62,13 @@ class Fuse : public SystemObject,
|
|||
SerializeIF::Endianness streamEndianness) override;
|
||||
void setAllMonitorsToUnchecked();
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
MessageQueueId_t getCommandQueue() const override;
|
||||
void setDataPoolEntriesInvalid();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
HasHealthIF::HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
|
||||
private:
|
||||
uint8_t oldFuseState;
|
||||
|
|
|
@ -10,15 +10,15 @@ class PowerComponent : public PowerComponentIF {
|
|||
PowerComponent(object_id_t setId, uint8_t moduleId, float minPower, float maxPower,
|
||||
uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF);
|
||||
|
||||
virtual object_id_t getDeviceObjectId();
|
||||
object_id_t getDeviceObjectId() override;
|
||||
|
||||
virtual uint8_t getSwitchId1();
|
||||
virtual uint8_t getSwitchId2();
|
||||
uint8_t getSwitchId1() override;
|
||||
uint8_t getSwitchId2() override;
|
||||
|
||||
bool hasTwoSwitches();
|
||||
bool hasTwoSwitches() override;
|
||||
|
||||
float getMin();
|
||||
float getMax();
|
||||
float getMin() override;
|
||||
float getMax() override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
@ -29,7 +29,7 @@ class PowerComponent : public PowerComponentIF {
|
|||
Endianness streamEndianness) override;
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex);
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
|
||||
|
||||
private:
|
||||
const object_id_t deviceObjectId = objects::NO_OBJECT;
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#include <cstddef>
|
||||
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.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;
|
||||
|
||||
|
@ -180,7 +180,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
|||
if (CRC::crc16ccitt(data, size) != 0) {
|
||||
return CONTAINED_TC_CRC_MISSMATCH;
|
||||
}
|
||||
|
||||
|
||||
// store currentPacket and receive the store address
|
||||
store_address_t addr{};
|
||||
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
||||
|
|
|
@ -13,7 +13,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
|||
uint16_t messageQueueDepth,
|
||||
TimeWriterIF* timeStamper)
|
||||
: SystemObject(objectId),
|
||||
apid(apid),
|
||||
// apid(apid),
|
||||
serviceId(serviceId),
|
||||
targetDestination(targetDestination),
|
||||
storeHelper(apid),
|
||||
|
|
|
@ -72,7 +72,7 @@ class Service1TelecommandVerification : public AcceptsVerifyMessageIF,
|
|||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
uint16_t apid = 0;
|
||||
// uint16_t apid = 0;
|
||||
uint8_t serviceId = 0;
|
||||
|
||||
object_id_t targetDestination = objects::NO_OBJECT;
|
||||
|
|
|
@ -69,7 +69,7 @@ class FailureReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6
|
|||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
virtual size_t getSerializedSize() const override {
|
||||
size_t size = 0;
|
||||
size += SerializeAdapter::getSerializedSize(&packetId);
|
||||
size += sizeof(packetSequenceControl);
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// RMAP command bits
|
||||
//#define RMAP_COMMAND_BIT_INCREMENT 2
|
||||
//#define RMAP_COMMAND_BIT_REPLY 3
|
||||
//#define RMAP_COMMAND_BIT_WRITE 5
|
||||
//#define RMAP_COMMAND_BIT_VERIFY 4
|
||||
//#define RMAP_COMMAND_BIT 6
|
||||
// #define RMAP_COMMAND_BIT_INCREMENT 2
|
||||
// #define RMAP_COMMAND_BIT_REPLY 3
|
||||
// #define RMAP_COMMAND_BIT_WRITE 5
|
||||
// #define RMAP_COMMAND_BIT_VERIFY 4
|
||||
// #define RMAP_COMMAND_BIT 6
|
||||
|
||||
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 =
|
||||
((1 << RMAP_COMMAND_BIT_WRITE) | (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_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))
|
||||
//#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))
|
||||
|
||||
|
@ -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_READ_REPLY_HEADER_LEN = 12;
|
||||
static const uint8_t RMAP_DATA_FOOTER_SIZE = 1; // SIZE OF CRC
|
||||
//#define RMAP_COMMAND_HEADER_LEN 16
|
||||
//#define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||
//#define RMAP_READ_REPLY_HEADER_LEN 12
|
||||
// #define RMAP_COMMAND_HEADER_LEN 16
|
||||
// #define RMAP_WRITE_REPLY_HEADER_LEN 8
|
||||
// #define RMAP_READ_REPLY_HEADER_LEN 12
|
||||
|
||||
} // namespace RMAPIds
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ SerialBufferAdapter<count_t>::SerialBufferAdapter(uint8_t* buffer, count_t buffe
|
|||
buffer(buffer),
|
||||
bufferLength(bufferLength) {}
|
||||
|
||||
template <typename count_t>
|
||||
SerialBufferAdapter<count_t>::~SerialBufferAdapter() = default;
|
||||
|
||||
template <typename count_t>
|
||||
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_, size_t* size,
|
||||
size_t maxSize,
|
||||
|
|
|
@ -41,7 +41,7 @@ class SerialBufferAdapter : public SerializeIF {
|
|||
*/
|
||||
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,
|
||||
Endianness streamEndianness) const override;
|
||||
|
@ -74,4 +74,10 @@ class SerialBufferAdapter : public SerializeIF {
|
|||
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_ */
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* @author baetz
|
||||
* @ingroup serialize
|
||||
*/
|
||||
template <typename T, typename count_t = uint8_t>
|
||||
template <typename T, typename count_t = size_t>
|
||||
class SerialLinkedListAdapter : public SinglyLinkedList<T>, public SerializeIF {
|
||||
public:
|
||||
SerialLinkedListAdapter(typename LinkedElement<T>::Iterator start, bool printCount = false)
|
||||
|
|
|
@ -35,6 +35,12 @@ class SerializeIF {
|
|||
MAKE_RETURN_CODE(3); // !< There are too many elements to be deserialized
|
||||
|
||||
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
|
||||
* 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;
|
||||
for (uint16_t n = 0; n < NUMBER_OF_SUBPOOLS; n++) {
|
||||
// Not sure if new allocates all stores in order. so better be careful.
|
||||
if ((store[n].data() <= ptr) and (&store[n][numberOfElements[n] * elementSizes[n]] > ptr)) {
|
||||
if ((store[n].data() <= ptr) and
|
||||
(&store[n][numberOfElements[n] * elementSizes[n] - 1] >= ptr)) {
|
||||
localId.poolIndex = n;
|
||||
uint32_t deltaAddress = ptr - store[n].data();
|
||||
// Getting any data from the right "block" is ok.
|
||||
|
|
|
@ -22,7 +22,7 @@ union store_address_t {
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -91,11 +91,10 @@ void Subsystem::performChildOperation() {
|
|||
}
|
||||
if (currentSequenceIterator->getWaitSeconds() != 0) {
|
||||
if (uptimeStartTable == 0) {
|
||||
Clock::getUptime(&uptimeStartTable);
|
||||
uptimeStartTable = Clock::getUptime_ms();
|
||||
return;
|
||||
} else {
|
||||
uint32_t uptimeNow;
|
||||
Clock::getUptime(&uptimeNow);
|
||||
uint32_t uptimeNow = Clock::getUptime_ms();
|
||||
if ((uptimeNow - uptimeStartTable) < (currentSequenceIterator->getWaitSeconds() * 1000)) {
|
||||
return;
|
||||
}
|
||||
|
@ -586,7 +585,12 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, SerializeIF
|
|||
return;
|
||||
}
|
||||
for (uint8_t i = 0; i < count; i++) {
|
||||
elements[i]->serialize(&storeBuffer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
result = elements[i]->serialize(&storeBuffer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
replyToCommand(result, 0);
|
||||
IPCStore->deleteData(address);
|
||||
return;
|
||||
}
|
||||
}
|
||||
CommandMessage reply;
|
||||
ModeSequenceMessage::setModeSequenceMessage(&reply, command, address);
|
||||
|
|
|
@ -34,7 +34,7 @@ class ExecutableObjectIF {
|
|||
* a reference to the executing 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
|
||||
|
|
|
@ -9,7 +9,6 @@ class FixedTimeslotTaskBase : public FixedTimeslotTaskIF {
|
|||
public:
|
||||
explicit FixedTimeslotTaskBase(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc = nullptr);
|
||||
~FixedTimeslotTaskBase() override = default;
|
||||
;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
|
|
@ -196,12 +196,11 @@ void Heater::setSwitch(uint8_t number, ReturnValue_t state, uint32_t* uptimeOfSw
|
|||
if (powerSwitcher->getSwitchState(number) == state) {
|
||||
*uptimeOfSwitching = INVALID_UPTIME;
|
||||
} else {
|
||||
if ((*uptimeOfSwitching == INVALID_UPTIME)) {
|
||||
if (*uptimeOfSwitching == INVALID_UPTIME) {
|
||||
powerSwitcher->sendSwitchCommand(number, state);
|
||||
Clock::getUptime(uptimeOfSwitching);
|
||||
*uptimeOfSwitching = Clock::getUptime_ms();
|
||||
} else {
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
uint32_t currentUptime = Clock::getUptime_ms();
|
||||
if (currentUptime - *uptimeOfSwitching > powerSwitcher->getSwitchDelayMs()) {
|
||||
*uptimeOfSwitching = INVALID_UPTIME;
|
||||
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) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
uint16_t days = (from->dayMSB << 8) + from->dayLSB;
|
||||
if (days <= DAYS_CCSDS_TO_UNIX_EPOCH) {
|
||||
return INVALID_TIME_FORMAT;
|
||||
}
|
||||
int32_t days = (from->dayMSB << 8) + from->dayLSB;
|
||||
days -= DAYS_CCSDS_TO_UNIX_EPOCH;
|
||||
to->tv_sec = days * SECONDS_PER_DAY;
|
||||
uint32_t msDay =
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
target_sources(
|
||||
${LIB_FSFW_NAME}
|
||||
PRIVATE CCSDSTime.cpp Countdown.cpp Stopwatch.cpp TimeMessage.cpp
|
||||
CdsShortTimeStamper.cpp ClockCommon.cpp)
|
||||
PRIVATE CCSDSTime.cpp
|
||||
Countdown.cpp
|
||||
Stopwatch.cpp
|
||||
TimeMessage.cpp
|
||||
CdsShortTimeStamper.cpp
|
||||
ClockCommon.cpp
|
||||
boost_timegm.cpp)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
class Clock {
|
||||
public:
|
||||
// https://xkcd.com/927/
|
||||
typedef struct {
|
||||
uint32_t year; //!< Year, A.D.
|
||||
uint32_t month; //!< Month, 1 .. 12.
|
||||
|
@ -26,14 +27,6 @@ class Clock {
|
|||
uint32_t usecond; //!< Microseconds, 0 .. 999999
|
||||
} TimeOfDay_t;
|
||||
|
||||
/**
|
||||
* This method returns the number of clock ticks per second.
|
||||
* In RTEMS, this is typically 1000.
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @deprecated, we should not worry about ticks, but only time
|
||||
*/
|
||||
static uint32_t getTicksPerSecond();
|
||||
/**
|
||||
* This system call sets the system time.
|
||||
* To set the time, it uses a TimeOfDay_t struct.
|
||||
|
@ -61,13 +54,8 @@ class Clock {
|
|||
/**
|
||||
* Get the time since boot in a timeval struct
|
||||
*
|
||||
* @param[out] time A pointer to a timeval struct where the uptime is stored.
|
||||
* @return @c returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
||||
*
|
||||
* @deprecated, I do not think this should be able to fail, use timeval getUptime()
|
||||
* @return a timeval struct where the uptime is stored
|
||||
*/
|
||||
static ReturnValue_t getUptime(timeval *uptime);
|
||||
|
||||
static timeval getUptime();
|
||||
|
||||
/**
|
||||
|
@ -79,7 +67,7 @@ class Clock {
|
|||
* @param ms uptime in ms
|
||||
* @return returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
||||
*/
|
||||
static ReturnValue_t getUptime(uint32_t *uptimeMs);
|
||||
static uint32_t getUptime_ms();
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds since an OS-defined epoch.
|
||||
|
@ -90,6 +78,7 @@ class Clock {
|
|||
* - Otherwise, the OS failure code is returned.
|
||||
*/
|
||||
static ReturnValue_t getClock_usecs(uint64_t *time);
|
||||
|
||||
/**
|
||||
* Returns the time in a TimeOfDay_t struct.
|
||||
* @param time A pointer to a TimeOfDay_t struct.
|
||||
|
@ -106,6 +95,7 @@ class Clock {
|
|||
* @return
|
||||
*/
|
||||
static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to);
|
||||
|
||||
/**
|
||||
* Converts a time of day struct to POSIX seconds.
|
||||
* @param time The time of day as input
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#include "boost_timegm.h"
|
||||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/timemanager/Clock.h"
|
||||
|
||||
|
@ -53,34 +55,58 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
|||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
|
||||
struct tm* timeInfo;
|
||||
// According to https://en.cppreference.com/w/c/chrono/gmtime, the implementation of gmtime_s
|
||||
// in the Windows CRT is incompatible with the C standard but this should not be an issue for
|
||||
// this implementation
|
||||
ReturnValue_t result = checkOrCreateClockMutex();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
struct tm time_tm;
|
||||
// WINDOWS does not provide gmtime_r, but gmtime_s
|
||||
#ifdef _MSC_VER
|
||||
time_t seconds = from->tv_sec;
|
||||
errno_t result = gmtime_s(&time_tm, &seconds);
|
||||
if (result != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||
// Therefore we have to use a Mutex here
|
||||
MutexGuard helper(timeMutex);
|
||||
#ifdef PLATFORM_WIN
|
||||
time_t time;
|
||||
time = from->tv_sec;
|
||||
timeInfo = gmtime(&time);
|
||||
#else
|
||||
timeInfo = gmtime(&from->tv_sec);
|
||||
void* result = gmtime_r(&from->tv_sec, &time_tm);
|
||||
|
||||
if (result == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
#endif
|
||||
to->year = timeInfo->tm_year + 1900;
|
||||
to->month = timeInfo->tm_mon + 1;
|
||||
to->day = timeInfo->tm_mday;
|
||||
to->hour = timeInfo->tm_hour;
|
||||
to->minute = timeInfo->tm_min;
|
||||
to->second = timeInfo->tm_sec;
|
||||
|
||||
to->year = time_tm.tm_year + 1900;
|
||||
to->month = time_tm.tm_mon + 1;
|
||||
to->day = time_tm.tm_mday;
|
||||
to->hour = time_tm.tm_hour;
|
||||
to->minute = time_tm.tm_min;
|
||||
to->second = time_tm.tm_sec;
|
||||
to->usecond = from->tv_usec;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* to) {
|
||||
struct tm time_tm = {};
|
||||
|
||||
time_tm.tm_year = from->year - 1900;
|
||||
time_tm.tm_mon = from->month - 1;
|
||||
time_tm.tm_mday = from->day;
|
||||
|
||||
time_tm.tm_hour = from->hour;
|
||||
time_tm.tm_min = from->minute;
|
||||
time_tm.tm_sec = from->second;
|
||||
|
||||
time_tm.tm_isdst = 0;
|
||||
|
||||
time_t seconds = internal_timegm(&time_tm);
|
||||
|
||||
to->tv_sec = seconds;
|
||||
to->tv_usec = from->usecond;
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
||||
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::checkOrCreateClockMutex() {
|
||||
if (timeMutex == nullptr) {
|
||||
MutexFactory* mutexFactory = MutexFactory::instance();
|
||||
|
@ -94,3 +120,37 @@ ReturnValue_t Clock::checkOrCreateClockMutex() {
|
|||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
timeval time_timeval;
|
||||
ReturnValue_t result = getClock_timeval(&time_timeval);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return convertTimevalToTimeOfDay(&time_timeval, time);
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval timeVal{};
|
||||
ReturnValue_t result = getClock_timeval(&timeVal);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
*time = static_cast<uint64_t>(timeVal.tv_sec) * 1e6 + timeVal.tv_usec;
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
timeval timeTimeval{};
|
||||
ReturnValue_t result = convertTimeOfDayToTimeval(time, &timeTimeval);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return setClock(&timeTimeval);
|
||||
}
|
||||
uint32_t Clock::getUptime_ms() {
|
||||
timeval uptime = getUptime();
|
||||
// TODO verify that overflow is correct
|
||||
return uptime.tv_sec * 1e3 + uptime.tv_usec / 1e3;
|
||||
}
|
|
@ -7,9 +7,9 @@ Countdown::Countdown(uint32_t initialTimeout) : timeout(initialTimeout) {
|
|||
Countdown::~Countdown() {}
|
||||
|
||||
ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) {
|
||||
ReturnValue_t returnValue = Clock::getUptime(&startTime);
|
||||
startTime = Clock::getUptime_ms();
|
||||
timeout = milliseconds;
|
||||
return returnValue;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool Countdown::hasTimedOut() const {
|
||||
|
@ -38,8 +38,4 @@ uint32_t Countdown::getRemainingMillis() const {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t Countdown::getCurrentTime() const {
|
||||
uint32_t currentTime;
|
||||
Clock::getUptime(¤tTime);
|
||||
return currentTime;
|
||||
}
|
||||
uint32_t Countdown::getCurrentTime() const { return Clock::getUptime_ms(); }
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
||||
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
||||
// Measures start time on initialization.
|
||||
Clock::getUptime(&startTime);
|
||||
startTime = Clock::getUptime();
|
||||
}
|
||||
|
||||
void Stopwatch::start() { Clock::getUptime(&startTime); }
|
||||
void Stopwatch::start() { startTime = Clock::getUptime(); }
|
||||
|
||||
dur_millis_t Stopwatch::stop(bool display) {
|
||||
stopInternal();
|
||||
|
@ -62,7 +62,6 @@ void Stopwatch::setDisplayMode(StopwatchDisplayMode displayMode) {
|
|||
StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
||||
|
||||
void Stopwatch::stopInternal() {
|
||||
timeval endTime;
|
||||
Clock::getUptime(&endTime);
|
||||
timeval endTime = Clock::getUptime();
|
||||
elapsedTime = endTime - startTime;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,17 @@
|
|||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#include "fsfw/platform.h"
|
||||
|
||||
#ifdef PLATFORM_WIN
|
||||
// wtf? Required for timeval!
|
||||
// Thanks, windows
|
||||
// clang-format off
|
||||
#include <winsock2.h>
|
||||
#include <winsock.h>
|
||||
// clang-format off
|
||||
#endif
|
||||
|
||||
#include "TimeStampIF.h"
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#include <ctime>
|
||||
|
||||
time_t internal_timegm(std::tm const *t);
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
class RawUserDataReaderIF {
|
||||
public:
|
||||
~RawUserDataReaderIF() = default;
|
||||
virtual ~RawUserDataReaderIF() = default;
|
||||
[[nodiscard]] virtual const uint8_t* getUserData() 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);
|
||||
}
|
||||
if (sendResult == returnvalue::OK) {
|
||||
Clock::getUptime(&iter->second.uptimeOfStart);
|
||||
iter->second.uptimeOfStart = Clock::getUptime_ms();
|
||||
iter->second.step = 0;
|
||||
iter->second.subservice = tcReader.getSubService();
|
||||
iter->second.command = command.getCommand();
|
||||
|
@ -434,8 +434,7 @@ inline void CommandingServiceBase::doPeriodicOperation() {}
|
|||
MessageQueueId_t CommandingServiceBase::getCommandQueue() { return commandQueue->getId(); }
|
||||
|
||||
void CommandingServiceBase::checkTimeout() {
|
||||
uint32_t uptime;
|
||||
Clock::getUptime(&uptime);
|
||||
uint32_t uptime = Clock::getUptime_ms();
|
||||
CommandMapIter iter;
|
||||
for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) {
|
||||
if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void __attribute__((weak)) printChar(const char* character, bool errStream) {
|
||||
void printChar(const char* character, bool errStream) {
|
||||
if (errStream) {
|
||||
fprintf(stderr, "%c", *character);
|
||||
} else {
|
||||
|
|
|
@ -72,7 +72,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
|||
|
||||
uint32_t transitionDelay;
|
||||
// Single SPI command has 2 bytes, first for adress, second for content
|
||||
size_t singleComandSize = 2;
|
||||
// size_t singleComandSize = 2;
|
||||
// Has the size for all adresses of the lis3mdl + the continous write bit
|
||||
uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1];
|
||||
|
||||
|
@ -87,7 +87,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
|||
*/
|
||||
uint8_t registers[MGMLIS3MDL::NR_OF_CTRL_REGISTERS];
|
||||
|
||||
uint8_t statusRegister = 0;
|
||||
// uint8_t statusRegister = 0;
|
||||
bool goToNormalMode = false;
|
||||
|
||||
enum class InternalState {
|
||||
|
|
|
@ -72,7 +72,7 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
|||
RM3100::Rm3100PrimaryDataset primaryDataset;
|
||||
|
||||
uint8_t commandBuffer[10];
|
||||
uint8_t commandBufferLen = 0;
|
||||
// uint8_t commandBufferLen = 0;
|
||||
|
||||
uint8_t cmmRegValue = RM3100::CMM_VALUE;
|
||||
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;
|
||||
|
|
|
@ -67,7 +67,7 @@ void CommandExecutor::printLastError(std::string funcName) const {
|
|||
sif::warning << funcName << " pclose failed with code " << lastError << ": "
|
||||
<< strerror(lastError) << std::endl;
|
||||
#else
|
||||
sif::printError("%s pclose failed with code %d: %s\n", funcName, lastError,
|
||||
sif::printError("%s pclose failed with code %d: %s\n", funcName.c_str(), lastError,
|
||||
strerror(lastError));
|
||||
#endif
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ ReturnValue_t CommandExecutor::check(bool& replyReceived) {
|
|||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << currentCmd << " | " << readVec.data();
|
||||
#else
|
||||
sif::printInfo("%s | %s", currentCmd, readVec.data());
|
||||
sif::printInfo("%s | %s", currentCmd.c_str(), readVec.data());
|
||||
#endif
|
||||
}
|
||||
if (ringBuffer != nullptr) {
|
||||
|
@ -188,7 +188,7 @@ ReturnValue_t CommandExecutor::executeBlocking() {
|
|||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << currentCmd << " | " << output;
|
||||
#else
|
||||
sif::printInfo("%s | %s", currentCmd, output);
|
||||
sif::printInfo("%s | %s", currentCmd.c_str(), output.c_str());
|
||||
#endif
|
||||
}
|
||||
if (ringBuffer != nullptr) {
|
||||
|
|
|
@ -146,8 +146,9 @@ ReturnValue_t testserialize::test_autoserialization() {
|
|||
}
|
||||
|
||||
// These epsilon values were just guessed.. It appears to work though.
|
||||
if (abs(tv_float - tv::tv_float) > 0.0001 or abs(tv_double - tv::tv_double) > 0.01 or
|
||||
abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
|
||||
if (std::abs(tv_float - tv::tv_float) > 0.0001 or std::abs(tv_double - tv::tv_double) > 0.01 or
|
||||
std::abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or
|
||||
std::abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@ add_subdirectory(globalfunctions)
|
|||
add_subdirectory(timemanager)
|
||||
add_subdirectory(tmtcpacket)
|
||||
add_subdirectory(cfdp)
|
||||
add_subdirectory(hal)
|
||||
if(NOT FSFW_OSAL MATCHES "rtems")
|
||||
add_subdirectory(hal)
|
||||
endif()
|
||||
add_subdirectory(internalerror)
|
||||
add_subdirectory(devicehandler)
|
||||
add_subdirectory(tmtcservices)
|
||||
|
|
|
@ -10,16 +10,118 @@
|
|||
|
||||
#define CATCH_CONFIG_COLOUR_WINDOWS
|
||||
|
||||
#include <fsfw/osal/osal.h>
|
||||
|
||||
#include <catch2/catch_session.hpp>
|
||||
|
||||
#ifdef FSFW_OSAL_FREERTOS
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
#include "task.h"
|
||||
#endif
|
||||
|
||||
extern int customSetup();
|
||||
extern int customTeardown();
|
||||
|
||||
#ifdef FSFW_OSAL_FREERTOS
|
||||
struct Taskparameters {
|
||||
int argc;
|
||||
char** argv;
|
||||
TaskHandle_t catchTask;
|
||||
} taskParameters;
|
||||
|
||||
void unittestTaskFunction(void* pvParameters) {
|
||||
Taskparameters* parameters = (Taskparameters*)pvParameters;
|
||||
|
||||
int result = Catch::Session().run(parameters->argc, parameters->argv);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
vTaskSuspendAll();
|
||||
vTaskDelete(parameters->catchTask);
|
||||
customTeardown();
|
||||
exit(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FSFW_OSAL_RTEMS
|
||||
#include <signal.h>
|
||||
|
||||
int sigaltstack(const stack_t* ss, stack_t* old_ss) { return 0; }
|
||||
extern "C" {
|
||||
|
||||
void exit_qemu_failing(int error) {
|
||||
asm(/* 0x20026 == ADP_Stopped_ApplicationExit */
|
||||
"mov x1, #0x26\n\t"
|
||||
"movk x1, #2, lsl #16\n\t"
|
||||
"str x1, [sp,#0]\n\t");
|
||||
|
||||
/* Exit status code. Host QEMU process exits with that status. */
|
||||
asm("mov x0, %[error]\n\t" : : [error] "r"(error));
|
||||
asm("str x0, [sp,#8]\n\t"
|
||||
|
||||
/* x1 contains the address of parameter block.
|
||||
* Any memory address could be used. */
|
||||
"mov x1, sp\n\t"
|
||||
|
||||
/* SYS_EXIT */
|
||||
"mov w0, #0x18\n\t"
|
||||
|
||||
/* Do the semihosting call on A64. */
|
||||
"hlt 0xf000\n\t");
|
||||
}
|
||||
|
||||
#include <rtemsConfig.h>
|
||||
|
||||
void user_handle_fatal(Internal_errors_Source source, bool internal, Internal_errors_t error_code) {
|
||||
if (source == RTEMS_FATAL_SOURCE_EXIT) {
|
||||
if (error_code != 0) {
|
||||
printk("*** EXIT STATUS NOT ZERO ***\n");
|
||||
printk("Quitting qemu with exit code %i\n", error_code);
|
||||
exit_qemu_failing(error_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rtems_task Init(rtems_task_argument ignored) {
|
||||
rtems_time_of_day now;
|
||||
now.year = 2023;
|
||||
now.month = 1;
|
||||
now.day = 15;
|
||||
now.hour = 0;
|
||||
now.minute = 0;
|
||||
now.second = 0;
|
||||
now.ticks = 0;
|
||||
rtems_clock_set(&now);
|
||||
customSetup();
|
||||
const char* argv[] = {"fsfw-test", ""};
|
||||
int result = Catch::Session().run(1, argv);
|
||||
customTeardown();
|
||||
exit(result);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
customSetup();
|
||||
|
||||
int result = 0;
|
||||
|
||||
#ifdef FSFW_OSAL_FREERTOS
|
||||
xTaskCreate(
|
||||
unittestTaskFunction, /* The function that implements the task. */
|
||||
"Unittests", /* The text name assigned to the task - for debug only as it is not used by the
|
||||
kernel. */
|
||||
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||
&taskParameters, /* The parameter passed to the task - not used in this simple case. */
|
||||
1, /* The priority assigned to the task. */
|
||||
&taskParameters.catchTask); /* The task handle is not required, so NULL is passed. */
|
||||
taskParameters.argc = argc;
|
||||
taskParameters.argv = argv;
|
||||
vTaskStartScheduler();
|
||||
#else
|
||||
// Catch internal function call
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
result = Catch::Session().run(argc, argv);
|
||||
#endif
|
||||
|
||||
// global clean-up
|
||||
customTeardown();
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
#include "mocks/cfdp/FaultHandlerMock.h"
|
||||
|
||||
// Thanks, windows
|
||||
#ifdef NO_ERROR
|
||||
#undef NO_ERROR
|
||||
#endif
|
||||
|
||||
TEST_CASE("CFDP Fault Handler", "[cfdp]") {
|
||||
using namespace cfdp;
|
||||
auto fhMock = FaultHandlerMock();
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
#include "fsfw/cfdp/pdu/AckPduReader.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
// Thanks, windows
|
||||
#ifdef NO_ERROR
|
||||
#undef NO_ERROR
|
||||
#endif
|
||||
|
||||
TEST_CASE("ACK PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result;
|
||||
|
|
|
@ -42,7 +42,9 @@ TEST_CASE("EOF PDU", "[cfdp][pdu]") {
|
|||
REQUIRE(sz == 20);
|
||||
|
||||
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;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduCreator(pduConf, eofInfo);
|
||||
|
@ -57,7 +59,7 @@ TEST_CASE("EOF PDU", "[cfdp][pdu]") {
|
|||
uint64_t fileSizeLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeLarge, buf.data() + 16, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fileSizeLarge == 0x10ffffff10);
|
||||
REQUIRE(fileSizeLarge == 0x13fffefd10);
|
||||
REQUIRE(buf[sz - 4] == cfdp::TlvType::ENTITY_ID);
|
||||
// width of entity ID is 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