Merge branch 'mohr/startracker' into meier/startracker

This commit is contained in:
Jakob Meier 2022-02-21 10:04:15 +01:00
commit 7d01aa463b
54 changed files with 400 additions and 431 deletions

3
.gitignore vendored
View File

@ -8,6 +8,9 @@
!misc/eclipse/**/.cproject
!misc/eclipse/**/.project
#vscode
.vscode
# Python
__pycache__
.idea

View File

@ -13,18 +13,13 @@ cmake_minimum_required(VERSION 3.13)
set(CMAKE_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(TGT_BSP MATCHES "arm/q7s")
option(EIVE_BUILD_WATCHDOG "Compile the OBSW watchdog instead" OFF)
option(BUILD_Q7S_SIMPLE_MODE OFF "Simple mode with a minimal main function")
endif()
option(EIVE_BUILD_UNITTESTS "Build Catch2 unittests" OFF)
option(EIVE_ADD_ETL_LIB "Add ETL library" ON)
option(EIVE_ADD_JSON_LIB "Add JSON library" ON)
option(EIVE_SYSROOT_MAGIC "Perform sysroot magic which might not be necessary" OFF)
if(NOT FSFW_OSAL)
set(FSFW_OSAL host CACHE STRING "OS for the FSFW.")
set(FSFW_OSAL linux CACHE STRING "OS for the FSFW.")
endif()
if(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack")
@ -35,18 +30,8 @@ endif()
include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake)
pre_project_config()
if(EIVE_BUILD_WATCHDOG)
set(PROJECT_NAME_TO_SET eive-watchdog)
elseif(EIVE_BUILD_UNITTESTS)
set(PROJECT_NAME_TO_SET eive-unittest)
elseif(TGT_BSP MATCHES "arm/q7s")
set(PROJECT_NAME_TO_SET eive-obsw-$ENV{USERNAME})
else()
set(PROJECT_NAME_TO_SET eive-obsw)
endif()
# Project Name
project(${PROJECT_NAME_TO_SET} ASM C CXX)
project(eive-obsw ASM C CXX)
################################################################################
# Pre-Sources preparation
@ -57,8 +42,11 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Set names and variables
set(TARGET_NAME ${CMAKE_PROJECT_NAME})
set(OBSW_NAME ${CMAKE_PROJECT_NAME})
set(WATCHDOG_NAME eive-watchdog)
set(SIMPLE_OBSW_NAME eive-simple)
set(LIB_FSFW_NAME fsfw)
set(LIB_EIVE_MISSION eive-mission)
set(LIB_ETL_NAME etl)
set(LIB_CSP_NAME libcsp)
set(LIB_LWGPS_NAME lwgps)
@ -71,7 +59,6 @@ set(LIB_JSON_NAME nlohmann_json::nlohmann_json)
# Set path names
set(FSFW_PATH fsfw)
set(MISSION_PATH mission)
set(TEST_PATH test/testtasks)
set(UNITTEST_PATH unittest)
set(LINUX_PATH linux)
@ -80,6 +67,7 @@ set(WATCHDOG_PATH watchdog)
set(COMMON_CONFIG_PATH ${COMMON_PATH}/config)
set(UNITTEST_CFG_PATH ${UNITTEST_PATH}/testcfg)
set(LIB_EIVE_MISSION_PATH mission)
set(LIB_CSP_PATH ${THIRD_PARTY_FOLDER}/libcsp)
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
@ -146,18 +134,17 @@ if(EIVE_BUILD_UNITTESTS)
endif()
# Configuration files
if(NOT EIVE_BUILD_WATCHDOG)
configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h)
configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h)
configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h)
if(TGT_BSP MATCHES "arm/q7s")
configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h)
elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse")
configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h)
endif()
configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h)
configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h)
configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h)
if(TGT_BSP MATCHES "arm/q7s")
configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h)
elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse")
configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h)
endif()
configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h)
# Set common config path for FSFW
@ -170,8 +157,48 @@ set(FSFW_ADDITIONAL_INC_PATHS
# Executable and Sources
################################################################################
#global compiler options need to be set before adding executables
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(
"-Wall"
"-Wextra"
"-Wimplicit-fallthrough=1"
"-Wno-unused-parameter"
"-Wno-psabi"
)
message(STATUS "goes here")
# Remove unused sections.
add_compile_options(
"-ffunction-sections"
"-fdata-sections"
)
# Removed unused sections.
add_link_options(
"-Wl,--gc-sections"
)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
endif()
add_library(${LIB_EIVE_MISSION})
# Add executable
add_executable(${TARGET_NAME})
add_executable(${OBSW_NAME})
#watchdog
add_executable(${WATCHDOG_NAME} EXCLUDE_FROM_ALL)
add_subdirectory(${WATCHDOG_PATH})
target_link_libraries(${WATCHDOG_NAME} PUBLIC
${LIB_CXX_FS}
)
target_include_directories(${WATCHDOG_NAME} PUBLIC
${CMAKE_BINARY_DIR}
)
if(EIVE_ADD_ETL_LIB)
add_subdirectory(${LIB_ETL_PATH})
@ -181,75 +208,78 @@ if(EIVE_ADD_JSON_LIB)
add_subdirectory(${LIB_JSON_PATH})
endif()
if(NOT EIVE_BUILD_WATCHDOG)
if(NOT EIVE_BUILD_UNITTESTS)
if(EIVE_ADD_LINUX_FILES)
add_subdirectory(${LIB_ARCSEC_PATH})
add_subdirectory(${LINUX_PATH})
endif()
add_subdirectory(${BSP_PATH})
if(ADD_CSP_LIB)
add_subdirectory(${LIB_CSP_PATH})
endif()
if(NOT EIVE_BUILD_UNITTESTS)
if(EIVE_ADD_LINUX_FILES)
add_subdirectory(${LIB_ARCSEC_PATH})
add_subdirectory(${LINUX_PATH})
endif()
add_subdirectory(${BSP_PATH})
if(ADD_CSP_LIB)
add_subdirectory(${LIB_CSP_PATH})
endif()
add_subdirectory(${COMMON_PATH})
endif()
if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG))
add_subdirectory(${LIB_LWGPS_PATH})
add_subdirectory(${FSFW_PATH})
add_subdirectory(${MISSION_PATH})
add_subdirectory(${TEST_PATH})
endif()
add_subdirectory(${COMMON_PATH})
add_subdirectory(${LIB_LWGPS_PATH})
add_subdirectory(${FSFW_PATH})
add_subdirectory(${LIB_EIVE_MISSION_PATH})
add_subdirectory(${TEST_PATH})
if(EIVE_BUILD_UNITTESTS)
# add_subdirectory(${LIB_CATCH2_PATH})
add_subdirectory(${UNITTEST_PATH})
endif()
if(EIVE_BUILD_WATCHDOG)
add_subdirectory(${WATCHDOG_PATH})
endif()
################################################################################
# Post-Sources preparation
################################################################################
set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux)
if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG))
# Add libraries for all sources.
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_FSFW_NAME}
${LIB_OS_NAME}
${LIB_LWGPS_NAME}
# Add libraries
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_FSFW_NAME}
${LIB_LWGPS_NAME}
${LIB_OS_NAME}
)
target_link_libraries(${OBSW_NAME} PRIVATE
${LIB_EIVE_MISSION}
)
if(TGT_BSP MATCHES "arm/q7s")
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_ARCSEC}
${LIB_GPS}
)
if(TGT_BSP MATCHES "arm/q7s")
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_ARCSEC}
${LIB_GPS}
)
endif()
endif()
if(NOT EIVE_BUILD_WATCHDOG)
if(ADD_CSP_LIB)
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_CSP_NAME}
)
endif()
if(TGT_BSP MATCHES "arm/egse")
target_link_libraries(${OBSW_NAME} PRIVATE
${LIB_ARCSEC}
)
endif()
if(ADD_CSP_LIB)
target_link_libraries(${OBSW_NAME} PRIVATE
${LIB_CSP_NAME}
)
endif()
if(EIVE_ADD_ETL_LIB)
target_link_libraries(${TARGET_NAME} PRIVATE
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_ETL_NAME}
)
endif()
if(EIVE_ADD_JSON_LIB)
target_link_libraries(${TARGET_NAME} PRIVATE
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_JSON_NAME}
)
endif()
@ -260,18 +290,12 @@ if(EIVE_BUILD_UNITTESTS)
)
endif()
target_link_libraries(${TARGET_NAME} PRIVATE
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_CXX_FS}
)
if(TGT_BSP MATCHES "arm/egse")
target_link_libraries(${TARGET_NAME} PRIVATE
${LIB_ARCSEC}
)
endif()
# Add include paths for all sources.
target_include_directories(${TARGET_NAME} PRIVATE
target_include_directories(${LIB_EIVE_MISSION} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${FSFW_CONFIG_PATH}
${CMAKE_CURRENT_BINARY_DIR}
@ -279,44 +303,16 @@ target_include_directories(${TARGET_NAME} PRIVATE
)
if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/egse")
target_include_directories(${TARGET_NAME} PRIVATE
target_include_directories(${LIB_EIVE_MISSION} PUBLIC
${ARCSEC_LIB_PATH}
)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(WARNING_FLAGS
-Wall
-Wextra
-Wimplicit-fallthrough=1
-Wno-unused-parameter
-Wno-psabi
)
# Remove unused sections.
target_compile_options(${TARGET_NAME} PRIVATE
"-ffunction-sections"
"-fdata-sections"
)
# Removed unused sections.
target_link_options(${TARGET_NAME} PRIVATE
"-Wl,--gc-sections"
)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
endif()
if(CMAKE_VERBOSE)
message(STATUS "Warning flags: ${WARNING_FLAGS}")
endif()
# Compile options for all sources.
target_compile_options(${TARGET_NAME} PRIVATE
${WARNING_FLAGS}
)
if(${CMAKE_CROSSCOMPILING})
include (${CMAKE_SCRIPT_PATH}/HardwareOsPostConfig.cmake)
@ -348,9 +344,9 @@ string(CONCAT POST_BUILD_COMMENT
)
add_custom_command(
TARGET ${TARGET_NAME}
TARGET ${OBSW_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${TARGET_NAME}${FILE_SUFFIX}
COMMAND ${CMAKE_SIZE} ${OBSW_NAME}${FILE_SUFFIX}
COMMENT ${POST_BUILD_COMMENT}
)

View File

@ -107,7 +107,7 @@ When using Windows, run theses steps in MSYS2.
```sh
mkdir build-Debug-Q7S && cd build-Debug-Q7S
cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DOS_FSFW=linux ..
cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j
```
@ -122,8 +122,7 @@ When using Windows, run theses steps in MSYS2.
This will invoke a Python script which in turn invokes CMake with the correct
arguments to configure CMake for Q7S cross-compilation.
You can build the hosted variant of the OBSW by replacing `-DOS_FSFW=linux` with
`-DOS_FSFW=host`. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi
There are also different values for `-DTGT_BSP` to build for the Raspberry Pi
or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`.
5. Build the software with
@ -162,38 +161,45 @@ automatically.
### Q7S OBSW
The EIVE OBSW is the default target if no target is specified.
```sh
mkdir build-Debug-Q7S && cd build-Debug-Q7S
cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DCMAKE_BUILD_TYPE=Debug ..
cmake -DTGT_BSP=arm/q7s -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j
```
### Q7S Watchdog
To build the EIVE watchdog, the corresponding target must be specified in the build command.
The configure steps do not need to be repeated if the folder has already been configured.
```sh
mkdir build-Debug-Q7S && cd build-Debug-Q7S
cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DEIVE_BUILD_WATCHDOG=ON -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j
cmake -DTGT_BSP=arm/q7s -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . --target eive-watchdog -j
```
### Hosted
You can also replace `linux` by `host` for this command to build on Windows or for generic OSes
You can also use the FSFW OSAL `host` to build on Windows or for generic OSes.
Note: Currently this is not supported.
```sh
mkdir build-Debug-Host && cd build-Debug-Host
cmake -DFSFW_OSAL=linux -DCMAKE_BUILD_TYPE=Debug ..
cmake -DFSFW_OSAL=host -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j
```
### Unittests
You can also replace `linux` by `host` for this command to build on Windows
To build the unittests, the corresponding target must be specified in the build command.
The configure steps do not need to be repeated if the folder has already been configured.
```sh
mkdir build-Debug-Unittest && cd build-Debug-Unittest
cmake -DFSFW_OSAL=linux -DEIVE_BUILD_UNITTESTS=ON ..
cmake --build . -j
cmake ..
cmake --build . --target eive-unittests -j
```
## Connect to EIVE flatsat

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${OBSW_NAME} PUBLIC
InitMission.cpp
main.cpp
ObjectFactory.cpp

View File

@ -1,7 +1,7 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
print.c
)
target_include_directories(${TARGET_NAME} PUBLIC
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${OBSW_NAME} PUBLIC
InitMission.cpp
main.cpp
ObjectFactory.cpp

View File

@ -1,8 +1,8 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
print.c
)
target_include_directories(${TARGET_NAME} PUBLIC
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,21 +1,21 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
ipc/MissionMessageTypes.cpp
)
target_include_directories(${TARGET_NAME} PUBLIC
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
# If a special translation file for object IDs exists, compile it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp")
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
objects/translateObjects.cpp
)
endif()
# If a special translation file for events exists, compile it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp")
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
events/translateEvents.cpp
)
endif()

View File

@ -1,17 +1,29 @@
target_sources(${TARGET_NAME} PUBLIC
#simple mode
add_executable(${SIMPLE_OBSW_NAME} EXCLUDE_FROM_ALL)
target_compile_definitions(${SIMPLE_OBSW_NAME} PRIVATE "Q7S_SIMPLE_MODE")
target_sources(${SIMPLE_OBSW_NAME} PUBLIC
main.cpp
)
#I think this is unintentional? (produces linker errors for stuff in /linux)
target_link_libraries(${SIMPLE_OBSW_NAME} PUBLIC
${LIB_FSFW_NAME}
)
target_compile_definitions(${SIMPLE_OBSW_NAME} PRIVATE "Q7S_SIMPLE_MODE")
add_subdirectory(simple)
target_sources(${OBSW_NAME} PUBLIC
main.cpp
)
add_subdirectory(boardtest)
if(Q7S_SIMPLE_MODE)
add_subdirectory(simple)
else()
add_subdirectory(boardconfig)
add_subdirectory(comIF)
add_subdirectory(gpio)
add_subdirectory(core)
add_subdirectory(memory)
add_subdirectory(callbacks)
add_subdirectory(devices)
endif()
add_subdirectory(boardconfig)
add_subdirectory(comIF)
add_subdirectory(gpio)
add_subdirectory(core)
add_subdirectory(memory)
add_subdirectory(callbacks)
add_subdirectory(devices)

View File

@ -1,7 +1,12 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
print.c
)
target_include_directories(${TARGET_NAME} PUBLIC
target_sources(${SIMPLE_OBSW_NAME} PRIVATE
print.c
)
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -3,8 +3,6 @@
#include <cstdint>
#cmakedefine01 Q7S_SIMPLE_MODE
/*******************************************************************/
/** All of the following flags should be enabled for mission code */
/*******************************************************************/

View File

@ -1,8 +1,10 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
FileSystemTest.cpp
Q7STestTask.cpp
)
if(EIVE_BUILD_Q7S_SIMPLE_MODE)
target_sources(${SIMPLE_OBSW_NAME} PRIVATE
FileSystemTest.cpp
)
endif()

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
rwSpiCallback.cpp
gnssCallback.cpp
pcduSwitchCb.cpp

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
)

View File

@ -1,6 +1,10 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
CoreController.cpp
obsw.cpp
InitMission.cpp
ObjectFactory.cpp
)
target_sources(${SIMPLE_OBSW_NAME} PRIVATE
InitMission.cpp
)

View File

@ -350,18 +350,17 @@ void initmission::createPusTasks(TaskFactory& factory,
void initmission::createTestTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*>& taskVec) {
#if OBSW_ADD_TEST_TASK == 1 || OBSW_ADD_SPI_TEST_CODE == 1 || OBSW_ADD_I2C_TEST_CODE == 1 || \
(BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1)
#if OBSW_ADD_TEST_TASK == 1 && OBSW_ADD_TEST_CODE == 1
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
#endif
static_cast<void>(result); // supress warning in case it is not used
PeriodicTaskIF* testTask = factory.createPeriodicTask(
"TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
#if OBSW_ADD_TEST_TASK == 1
result = testTask->addComponent(objects::TEST_TASK);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
}
#endif /* OBSW_ADD_TEST_TASK == 1 */
#if OBSW_ADD_SPI_TEST_CODE == 1
result = testTask->addComponent(objects::SPI_TEST);
@ -375,6 +374,13 @@ void initmission::createTestTasks(TaskFactory& factory,
initmission::printAddObjectError("I2C_TEST", objects::I2C_TEST);
}
#endif
#if OBSW_ADD_UART_TEST_CODE == 1
result = testTask->addComponent(objects::UART_TEST);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("UART_TEST", objects::UART_TEST);
}
#endif
#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1
result = testTask->addComponent(objects::LIBGPIOD_TEST);
if (result != HasReturnvaluesIF::RETURN_OK) {
@ -382,4 +388,6 @@ void initmission::createTestTasks(TaskFactory& factory,
}
#endif /* BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 */
taskVec.push_back(testTask);
#endif // OBSW_ADD_TEST_TASK == 1 && OBSW_ADD_TEST_CODE == 1
}

View File

@ -1,6 +1,7 @@
#include "ObjectFactory.h"
#include <linux/boardtest/I2cTestClass.h>
#include <linux/boardtest/UartTestClass.h>
#include <sstream>
@ -1135,4 +1136,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
#if OBSW_ADD_I2C_TEST_CODE == 1
new I2cTestClass(objects::I2C_TEST, q7s::I2C_DEFAULT_DEV);
#endif
#if OBSW_ADD_UART_TEST_CODE == 1
new UartTestClass(objects::UART_TEST);
#endif
}

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
PlocSupervisorHandler.cpp
PlocUpdater.cpp
PlocMemoryDumper.cpp

View File

@ -1,3 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
gpioCallbacks.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
FileSystemHandler.cpp
SdCardManager.cpp
scratchApi.cpp

View File

@ -1,3 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${SIMPLE_OBSW_NAME} PRIVATE
simple.cpp
)

View File

@ -1,5 +1,7 @@
#include "simple.h"
#include "iostream"
#include "q7sConfig.h"
#if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1
@ -7,7 +9,7 @@
#endif
int simple::simple() {
cout << "-- Q7S Simple Application --" << endl;
std::cout << "-- Q7S Simple Application --" << std::endl;
#if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1
{ FileSystemTest fileSystemTest; }
#endif

View File

@ -3,7 +3,7 @@ function(post_source_hw_os_config)
if(LINK_LWIP)
message(STATUS "Linking against ${LIB_LWIP_NAME} lwIP library")
if(LIB_LWIP_NAME)
target_link_libraries(${TARGET_NAME} PUBLIC
target_link_libraries(${OBSW_NAME} PUBLIC
${LIB_LWIP_NAME}
)
else()
@ -12,7 +12,7 @@ if(LINK_LWIP)
endif()
if(LINKER_SCRIPT)
target_link_options(${TARGET_NAME} PRIVATE
add_link_options(
-T${LINKER_SCRIPT}
)
endif()
@ -35,20 +35,20 @@ if(CMAKE_VERBOSE)
endif()
# Generator expression. Can be used to set different C, CXX and ASM flags.
target_compile_options(${TARGET_NAME} PRIVATE
add_compile_options(
$<$<COMPILE_LANGUAGE:C>:${C_DEFS} ${C_FLAGS}>
$<$<COMPILE_LANGUAGE:CXX>:${CXX_DEFS} ${CXX_FLAGS}>
$<$<COMPILE_LANGUAGE:ASM>:${ASM_FLAGS}>
)
set(STRIPPED_TARGET_NAME ${TARGET_NAME}-stripped)
set(STRIPPED_OBSW_NAME ${OBSW_NAME}-stripped)
add_custom_command(
TARGET ${TARGET_NAME}
TARGET ${OBSW_NAME}
POST_BUILD
COMMAND ${CMAKE_STRIP} --strip-all ${TARGET_NAME} -o ${STRIPPED_TARGET_NAME}
BYPRODUCTS ${STRIPPED_TARGET_NAME}
COMMENT "Generating stripped executable ${STRIPPED_TARGET_NAME}.."
COMMAND ${CMAKE_STRIP} --strip-all ${OBSW_NAME} -o ${STRIPPED_OBSW_NAME}
BYPRODUCTS ${STRIPPED_OBSW_NAME}
COMMENT "Generating stripped executable ${STRIPPED_OBSW_NAME}.."
)
endfunction()

View File

@ -9,6 +9,7 @@ if(DEFINED TGT_BSP)
endif()
endif()
# Disable compiler checks for cross-compiling.
if(FSFW_OSAL MATCHES linux AND TGT_BSP)
if(TGT_BSP MATCHES "arm/q7s")

View File

@ -1,36 +0,0 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Simple-Q7S"
build_generator=""
definitions="BUILD_Q7S_SIMPLE_MODE=On"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
python="py"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-l "${build_dir}" -d "${definitions}"
# set +x

View File

@ -1,35 +0,0 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Simple-Q7S"
build_generator="Ninja"
definitions="BUILD_Q7S_SIMPLE_MODE=On"
if [ "${OS}" = "Windows_NT" ]; then
python="py"
# Could be other OS but this works for now.
else
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-l "${build_dir}" -d "${definitions}"
# set +x

View File

@ -1,37 +0,0 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Debug-Watchdog"
build_generator=""
definitions="EIVE_BUILD_WATCHDOG=ON"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
python="py"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-d "${definitions}" -l"${build_dir}"
# set +x

View File

@ -1,36 +0,0 @@
#!/bin/sh
counter=0
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f "cmake_build_config.py" ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "cmake_build_config.py not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Release-Watchdog"
build_generator=""
definitions="EIVE_BUILD_WATCHDOG=ON"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
python="py"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \
-d "${definitions} -l"${build_dir}"
# set +x

View File

@ -1,35 +0,0 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Debug-Watchdog"
build_generator="Ninja"
definitions="EIVE_BUILD_WATCHDOG=ON"
if [ "${OS}" = "Windows_NT" ]; then
python="py"
# Could be other OS but this works for now.
else
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-d "${definitions}" -l "${build_dir}"
# set +x

View File

@ -1,35 +0,0 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/q7s"
build_dir="build-Release-Watchdog"
build_generator="Ninja"
definitions="EIVE_BUILD_WATCHDOG=ON"
if [ "${OS}" = "Windows_NT" ]; then
python="py"
# Could be other OS but this works for now.
else
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \
-d "${definitions}" -l"${build_dir}"
# set +x

View File

@ -1,7 +1,7 @@
target_include_directories(${TARGET_NAME} PRIVATE
target_include_directories(${OBSW_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
commonConfig.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
LibgpiodTest.cpp
I2cTestClass.cpp
SpiTestClass.cpp

View File

@ -1,4 +1,6 @@
#include "UartTestClass.h"
#include <fsfw/tasks/TaskFactory.h>
#if defined(RASPBERRY_PI)
#include "rpiConfig.h"
#elif defined(XIPHOS_Q7S)
@ -9,18 +11,22 @@
#include <fcntl.h> // Contains file controls like O_RDWR
#include <unistd.h> // write(), read(), close()
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "lwgps/lwgps.h"
#include "fsfw/globalfunctions/CRC.h"
#include "fsfw/globalfunctions/DleEncoder.h"
#include "fsfw/globalfunctions/arrayprinter.h"
#include "fsfw/serviceinterface.h"
#include "mission/devices/devicedefinitions/SCEXDefinitions.h"
#define GPS_REPLY_WIRETAPPING 0
UartTestClass::UartTestClass(object_id_t objectId) : TestTask(objectId) {}
UartTestClass::UartTestClass(object_id_t objectId) : TestTask(objectId) { mode = TestModes::SCEX; }
ReturnValue_t UartTestClass::initialize() {
if (mode == TestModes::GPS) {
gpsInit();
} else if (mode == TestModes::SCEX) {
scexInit();
}
return HasReturnvaluesIF::RETURN_OK;
}
@ -29,6 +35,8 @@ ReturnValue_t UartTestClass::performOneShotAction() { return HasReturnvaluesIF::
ReturnValue_t UartTestClass::performPeriodicAction() {
if (mode == TestModes::GPS) {
gpsPeriodic();
} else if (mode == TestModes::SCEX) {
scexPeriodic();
}
return HasReturnvaluesIF::RETURN_OK;
}
@ -118,3 +126,96 @@ void UartTestClass::gpsPeriodic() {
} while (bytesRead > 0);
#endif
}
void UartTestClass::scexInit() {
#if defined(RASPBERRY_PI)
std::string devname = "/dev/ttyUSB1";
#else
std::string devname = "/dev/ul-scex";
#endif
/* Get file descriptor */
serialPort = open(devname.c_str(), O_RDWR);
if (serialPort < 0) {
sif::warning << "open call failed with error [" << errno << ", " << strerror(errno)
<< std::endl;
return;
}
// Setting up UART parameters
tty.c_cflag &= ~PARENB; // Clear parity bit
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
tty.c_cflag &= ~CSIZE; // Clear all the size bits
tty.c_cflag |= CS8; // 8 bits per byte
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
// Use non-canonical mode and clear echo flag
tty.c_lflag &= ~(ICANON | ECHO);
// Non-blocking mode, read until either line is 0.1 second idle or maximum of 255 bytes are
// received in one go
tty.c_cc[VTIME] = 1; // In units of 0.1 seconds
tty.c_cc[VMIN] = 255; // Read up to 255 bytes
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
sif::warning << "tcsetattr call failed with error [" << errno << ", " << strerror(errno)
<< std::endl;
}
// Flush received and unread data
tcflush(serialPort, TCIFLUSH);
}
void UartTestClass::scexPeriodic() {
auto dleEncoder = DleEncoder();
std::array<uint8_t, 128> tmpCmdBuf = {};
// Send ping command
tmpCmdBuf[0] = scex::CMD_PING;
// These two fields are the packet counter and the total packet count. Those are 1 and 1 for each
// telecommand so far
tmpCmdBuf[1] = 1;
tmpCmdBuf[2] = 1;
uint16_t userDataLen = 0;
tmpCmdBuf[3] = (userDataLen >> 8) & 0xff;
tmpCmdBuf[4] = userDataLen & 0xff;
uint16_t crc = CRC::crc16ccitt(tmpCmdBuf.data(), 5);
tmpCmdBuf[5] = (crc >> 8) & 0xff;
tmpCmdBuf[6] = crc & 0xff;
size_t encodedLen = 0;
ReturnValue_t result =
dleEncoder.encode(tmpCmdBuf.data(), 7, cmdBuf.data(), cmdBuf.size(), &encodedLen, true);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "UartTestClass::scexInit: Encoding failed" << std::endl;
return;
}
arrayprinter::print(cmdBuf.data(), 9);
size_t bytesWritten = write(serialPort, cmdBuf.data(), encodedLen);
if (bytesWritten != encodedLen) {
sif::warning << "Sending ping command to solar experiment failed" << std::endl;
}
TaskFactory::delayTask(20);
bytesWritten = write(serialPort, cmdBuf.data(), encodedLen);
if (bytesWritten != encodedLen) {
sif::warning << "Sending ping command to solar experiment failed" << std::endl;
}
// Read back reply immediately
int bytesRead = 0;
do {
bytesRead = read(serialPort, reinterpret_cast<void*>(recBuf.data()),
static_cast<unsigned int>(recBuf.size()));
if (bytesRead < 0) {
sif::warning << "UartTestClass::performPeriodicAction: read call failed with error [" << errno
<< ", " << strerror(errno) << "]" << std::endl;
break;
} else if (bytesRead >= static_cast<int>(recBuf.size())) {
sif::debug << "UartTestClass::performPeriodicAction: "
"recv buffer might not be large enough"
<< std::endl;
} else if (bytesRead > 0) {
sif::info << "Received " << bytesRead << " from the Solar Cell Experiment:" << std::endl;
arrayprinter::print(recBuf.data(), bytesRead);
}
} while (bytesRead > 0);
}

View File

@ -20,16 +20,20 @@ class UartTestClass : public TestTask {
enum TestModes {
GPS,
// Solar Cell Experiment
SCE
SCEX
};
void gpsInit();
void gpsPeriodic();
void scexInit();
void scexPeriodic();
TestModes mode = TestModes::GPS;
lwgps_t gpsData = {};
struct termios tty = {};
int serialPort = 0;
std::array<uint8_t, 512> recBuf;
std::array<uint8_t, 64> cmdBuf = {};
std::array<uint8_t, 4096> recBuf = {};
uint8_t recvCnt = 0;
};

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${OBSW_NAME} PUBLIC
CspComIF.cpp
CspCookie.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
SolarArrayDeploymentHandler.cpp
SusHandler.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
StarTrackerHandler.cpp
StarTrackerJsonCommands.cpp
ArcsecDatalinkLayer.cpp

View File

@ -1,22 +1,22 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
ipc/MissionMessageTypes.cpp
pollingsequence/pollingSequenceFactory.cpp
)
target_include_directories(${TARGET_NAME} PUBLIC
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
# If a special translation file for object IDs exists, compile it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp")
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
objects/translateObjects.cpp
)
endif()
# If a special translation file for events exists, compile it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp")
target_sources(${TARGET_NAME} PRIVATE
target_sources(${OBSW_NAME} PRIVATE
events/translateEvents.cpp
)
endif()

View File

@ -75,12 +75,14 @@ debugging. */
#define OBSW_SYRLINKS_SIMULATED 1
#define OBSW_ADD_TEST_CODE 0
#define OBSW_ADD_TEST_TASK 0
#define OBSW_ADD_TEST_PST 0
// If this is enabled, all other SPI code should be disabled
#define OBSW_ADD_SPI_TEST_CODE 0
// If this is enabled, all other I2C code should be disabled
#define OBSW_ADD_I2C_TEST_CODE 0
#define OBSW_ADD_TEST_PST 0
#define OBSW_ADD_TEST_TASK 0
#define OBSW_ADD_UART_TEST_CODE 0
#define OBSW_TEST_LIBGPIOD 0
#define OBSW_TEST_RADIATION_SENSOR_HANDLER 0
#define OBSW_TEST_SUS_HANDLER 0

View File

@ -3,6 +3,6 @@
#include "fsfw/events/Event.h"
const char * translateEvents(Event event);
const char* translateEvents(Event event);
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${OBSW_NAME} PUBLIC
PapbVcInterface.cpp
Ptme.cpp
PdecHandler.cpp

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${OBSW_NAME} PUBLIC
utility.cpp
)

View File

@ -3,3 +3,5 @@ add_subdirectory(devices)
add_subdirectory(utility)
add_subdirectory(memory)
add_subdirectory(tmtc)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${LIB_EIVE_MISSION} PRIVATE
GenericFactory.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${LIB_EIVE_MISSION} PRIVATE
GPSHyperionLinuxController.cpp
GomspaceDeviceHandler.cpp
BpxBatteryHandler.cpp

View File

@ -67,7 +67,9 @@ ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
#if OBSW_ENABLE_PERIODIC_HK == 1
poolManager.subscribeForPeriodicPacket(gpsSet.getSid(), true, 2.0, false);
#endif
return HasReturnvaluesIF::RETURN_OK;
}
@ -160,7 +162,6 @@ void GPSHyperionLinuxController::readGpsDataFromGpsd() {
gpsSet.hours = timeOfDay.hour;
gpsSet.minutes = timeOfDay.minute;
gpsSet.seconds = timeOfDay.second;
debugHyperionGps = true;
if (debugHyperionGps) {
sif::info << "-- Hyperion GPS Data --" << std::endl;
time_t timeRaw = gps->fix.time.tv_sec;

View File

@ -0,0 +1,13 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_
#include <cstdint>
// Definitions for the Solar Cell Experiment
namespace scex {
static constexpr uint8_t CMD_PING = 0x4e;
}
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_SCEXDEFINITIONS_H_ */

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${LIB_EIVE_MISSION} PRIVATE
NVMParameterBase.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${LIB_EIVE_MISSION} PRIVATE
CCSDSHandler.cpp
VirtualChannel.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${LIB_EIVE_MISSION} PRIVATE
TmFunnel.cpp
Timestamp.cpp
)

View File

@ -49,6 +49,13 @@ def handle_args():
action="store_true",
help="Copy from Q7S to host instead. Always copies to current directory.",
)
parser.add_argument(
"-f",
"--flatsat",
default=False,
action="store_true",
help="Copy to flatsat instead"
)
# Positional argument(s)
parser.add_argument(
"source", help="Source files to copy or target files to copy back to host"
@ -61,17 +68,28 @@ def build_cmd(args):
cmd = "scp "
if args.recursive:
cmd += "-r "
address = ""
port_args = ""
target = args.target
if args.invert and target == "":
target = "."
elif target == "":
target = f"/tmp"
if args.invert:
cmd += f"-P {args.port} root@localhost:{args.source} {target}"
if args.flatsat:
address = "eive@flatsat.eive.absatvirt.lw"
else:
cmd += f"-P {args.port} {args.source} root@localhost:{target}"
if args.target:
cmd += args.target
address = "root@localhost"
port_args=f"-P {args.port}"
if args.invert:
if target == "":
target = "."
else:
target = args.target
else:
if target == "":
target = f"/tmp"
else:
target = args.target
if args.invert:
cmd += f"{port_args} {address}:{args.source} {target}"
else:
cmd += f"{port_args} {args.source} {address}:{target}"
return cmd

View File

@ -1,7 +1,7 @@
target_sources(${TARGET_NAME} PUBLIC
target_sources(${OBSW_NAME} PUBLIC
TestTask.cpp
)
target_include_directories(${TARGET_NAME} PUBLIC
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${WATCHDOG_NAME} PRIVATE
main.cpp
Watchdog.cpp
)

View File

@ -2,7 +2,8 @@
#define WATCHDOG_WATCHDOG_H_
#include <array>
#include <cstdint>
#include <string>
class WatchdogTask {
public: