Merge remote-tracking branch 'origin/develop' into mueller/rw-ass
EIVE/eive-obsw/pipeline/pr-develop This commit looks good Details

This commit is contained in:
Robin Müller 2022-04-28 18:26:34 +02:00
commit 1527b60fd6
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
33 changed files with 898 additions and 869 deletions

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "etl"]
path = thirdparty/etl
url = https://github.com/ETLCPP/etl.git
[submodule "arduino"]
path = arduino
url = https://egit.irs.uni-stuttgart.de/eive/eive_arduino_interface.git

View File

@ -19,10 +19,12 @@ list yields a list of all related PRs for each release.
## Changed
- PCDU handler only called once in PST, but can handle multiple messages now
- Update rootfs base of Linux, all related OBSW changes
- Use gpsd version 3.17 now. Includes API changes
- Add `/usr/local/bin` to PATH. All shell scripts are there now
- Rename GPS device to `/dev/gps0`
- Add Syrlinks and TMP devices to Software by default
# [v1.10.1]

View File

@ -9,27 +9,19 @@
################################################################################
cmake_minimum_required(VERSION 3.13)
# set(CMAKE_VERBOSE TRUE)
set(OBSW_VERSION_MAJOR_IF_GIT_FAILS 0)
set(OBSW_VERSION_MINOR_IF_GIT_FAILS 0)
set(OBSW_VERSION_REVISION_IF_GIT_FAILS 0)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# set(CMAKE_VERBOSE TRUE)
option(EIVE_ADD_ETL_LIB "Add ETL library" ON)
option(EIVE_ADD_JSON_LIB "Add JSON library" ON)
option(EIVE_HARDCODED_TOOLCHAIN_FILE "\
For Linux Board Target BSPs, a default toolchain file will be set. Should be set to OFF \
if a different toolchain file is set externally" ON
)
option(EIVE_SYSROOT_MAGIC "Perform sysroot magic which might not be necessary" OFF)
option(EIVE_CREATE_UNIQUE_OBSW_BIN "Append username to generated binary name" ON)
set(OBSW_ADD_STAR_TRACKER 0)
set(OBSW_DEBUG_STARTRACKER 0)
if(NOT FSFW_OSAL)
set(FSFW_OSAL linux CACHE STRING "OS for the FSFW.")
set(FSFW_OSAL linux CACHE STRING "OS for the FSFW.")
endif()
if(TGT_BSP)
@ -39,13 +31,35 @@ if(TGT_BSP)
elseif(TGT_BSP MATCHES "arm/q7s")
option(EIVE_BUILD_GPSD_GPS_HANDLER "Build GPSD dependent GPS Handler" ON)
endif()
option(EIVE_CREATE_UNIQUE_OBSW_BIN "Append username to generated binary name" ON)
else()
option(EIVE_CREATE_UNIQUE_OBSW_BIN "Append username to generated binary name" OFF)
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Perform steps like loading toolchain files where applicable.
include(PreProjectConfig)
include(EiveHelpers)
pre_project_config()
# Project Name
project(eive-obsw)
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
include(EiveHelpers)
option(EIVE_ADD_ETL_LIB "Add ETL library" ON)
option(EIVE_ADD_JSON_LIB "Add JSON library" ON)
set(OBSW_ADD_STAR_TRACKER 0)
set(OBSW_DEBUG_STARTRACKER 0)
################################################################################
# Pre-Sources preparation
################################################################################
# Version handling
set(GIT_VER_HANDLING_OK FALSE)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
@ -77,21 +91,6 @@ if(NOT GIT_VER_HANDLING_OK)
set(OBSW_VERSION_REVISION ${OBSW_VERSION_REVISION_IF_GIT_FAILS})
endif()
# Check whether the user has already installed Catch2 first. This has to come before
# the project call. We could also exclude doing this when the Q7S primary OBSW is built..
find_package(Catch2 3 CONFIG QUIET)
# Project Name
project(eive-obsw)
################################################################################
# Pre-Sources preparation
################################################################################
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Set names and variables
set(OBSW_NAME ${CMAKE_PROJECT_NAME})
set(WATCHDOG_NAME eive-watchdog)
@ -250,30 +249,8 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
endif()
if (NOT(TGT_BSP MATCHES "arm/te0720-1cfa") AND NOT(TGT_BSP MATCHES "arm/q7s"))
# Not installed, so use FetchContent to download and provide Catch2
if(NOT Catch2_FOUND)
message(STATUS "Did not find a valid Catch2 installation. Using FetchContent to install it")
include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.0.0-preview4
)
FetchContent_MakeAvailable(Catch2)
#fixes regression -preview4, to be confirmed in later releases
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
set_target_properties(Catch2 PROPERTIES EXCLUDE_FROM_ALL "true")
set_target_properties(Catch2WithMain PROPERTIES EXCLUDE_FROM_ALL "true")
endif()
endif()
add_library(${LIB_EIVE_MISSION})
# Add main executable
add_executable(${OBSW_NAME})
if(EIVE_CREATE_UNIQUE_OBSW_BIN)
@ -298,14 +275,15 @@ target_include_directories(${WATCHDOG_NAME} PUBLIC
${CMAKE_BINARY_DIR}
)
#unittests
# unittests
add_executable(${UNITTEST_NAME} EXCLUDE_FROM_ALL)
if(EIVE_ADD_ETL_LIB)
endif()
if(EIVE_ADD_JSON_LIB)
add_subdirectory(${LIB_JSON_PATH})
endif()
if(EIVE_ADD_LINUX_FILES)
add_subdirectory(${LIB_ARCSEC_PATH})
@ -316,26 +294,52 @@ if(ADD_CSP_LIB)
add_subdirectory(${LIB_CSP_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})
add_subdirectory(${UNITTEST_PATH})
# This should have already been downloaded by the FSFW
# Still include it to be safe
include(FetchContent)
FetchContent_Declare(
etl
GIT_REPOSITORY https://github.com/ETLCPP/etl
GIT_TAG ${FSFW_ETL_LIB_VERSION}
)
FetchContent_MakeAvailable(etl)
# Use same Catch2 version as framework
if (NOT(TGT_BSP MATCHES "arm/te0720-1cfa") AND NOT(TGT_BSP MATCHES "arm/q7s"))
# Check whether the user has already installed Catch2 first
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} CONFIG QUIET)
# Not installed, so use FetchContent to download and provide Catch2
if(NOT Catch2_FOUND)
message(STATUS "${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent")
include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG ${FSFW_CATCH2_LIB_VERSION}
)
FetchContent_MakeAvailable(Catch2)
#fixes regression -preview4, to be confirmed in later releases
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
set_target_properties(Catch2 PROPERTIES EXCLUDE_FROM_ALL "true")
set_target_properties(Catch2WithMain PROPERTIES EXCLUDE_FROM_ALL "true")
endif()
endif()
################################################################################
# Post-Sources preparation
################################################################################
# Add libraries
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_FSFW_NAME}
@ -374,7 +378,7 @@ endif()
if(EIVE_ADD_ETL_LIB)
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC
${LIB_ETL_NAME}
etl
)
endif()

127
README.md
View File

@ -39,12 +39,14 @@ Target systems:
the [Xiphos Traq Platform](https://trac2.xiphos.ca/eive-q7). Press on index to find all
relevant pages. The most recent datasheet can be found
[here](https://trac2.xiphos.ca/manual/wiki/Q7RevB/UserManual).
* Linux OS built with Yocto 2.5
* Linux OS built with Yocto 2.5. SDK and root filesystem can be rebuilt with
[yocto](https://egit.irs.uni-stuttgart.de/eive/q7s-yocto)
* [Linux Kernel](https://github.com/XiphosSystemsCorp/linux-xlnx.git) . EIVE version can be found
[here](https://github.com/spacefisch/linux-xlnx) . Pre-compiled files can be
found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/q7s-linux-components&fileid=777299).
* Q7S base project can be found [here](https://egit.irs.uni-stuttgart.de/eive/q7s-base)
* Minimal base project files can be found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/xiphos-q7s-sdk&fileid=510908)
* Minimal base project files and Xiphos SDK can be found
[here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/xiphos-q7s-sdk&fileid=510908)
* Host System
* Generic software components which are not dependant on hardware can also
be run on a host system. All host code is contained in the `bsp_hosted` folder
@ -55,7 +57,8 @@ Target systems:
The steps in the primary README are related to the main OBC target Q7S.
The CMake build system can be used to generate build systems as well (see helper scripts in `cmake/scripts`:
- Linux (Raspberry Pi): See special section below.
- Linux Raspberry Pi: See special section below. Uses the `bsp_linux_board` folder
- Linux Trenz TE7020_1CFA: Uses the `bsp_te0720_1cfa` folder
- Linux Host: Uses the `bsp_hosted` BSP folder and the CMake Unix Makefiles generator.
- Windows Host: Uses the `bsp_hosted` BSP folder, the CMake MinGW Makefiles generator and MSYS2.
@ -68,7 +71,7 @@ prerequisites.
1. ARM cross-compiler installed, either as part of [Vivado 2018.2 installation](#vivado) or
as a [separate download](#arm-toolchain)
2. [Q7S sysroot](#q7s-sysroot) on local development machine
2. [Q7S sysroot](#sysroot) on local development machine
3. Recommended: Eclipse or [Vivado 2018.2 SDK](#vivado) for OBSW development
3. [TCF agent](https://wiki.eclipse.org/TCF) running on Q7S
@ -96,11 +99,9 @@ When using Windows, run theses steps in MSYS2.
git submodule update
```
3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`.
It is recommended to set up a shell script which takes care of setting up the environment
for convenience or to set up the
[PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path)
in the `.profile` file.
3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version` and that
the sysroot environmental variables have been set like specified in the
[root filesystem chapter](#sysroot).
4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder.
Add `-G "MinGW Makefiles` in MinGW64 on Windows.
@ -230,18 +231,19 @@ A serial console session is up permanently in a `tmux` session
### Serial console
You can check whether the sessions exist with `tmux ls`
You can check whether the sessions exist with `tmux ls`.
This is the command to connect to the serial interface of the FM using the
RS422 interface of the flight preparation panel:
```sh
tmux a -t q7s-serial
tmux a -t q7s-fm-fpp
```
If the session does not exist, you can create it like this
```sh
tmux new -s q7s-serial
/bin/bash
q7s_serial
tmux new -s q7s-fm-fpp -t /bin/bash
launch-q7s-fpp
```
Other useful tmux commands:
@ -261,55 +263,50 @@ Other useful tmux commands:
You can use the following command to connect to the Q7S with `ssh`:
```sh
q7s_ssh
q7s-fm-ssh
```
## Port forwarding for connection to TCF agent
This is a required step to connect to the `tcf-agent` on the Q7S, which is required for convenient
remote debugging. Assuming the IPv6
```sh
ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash
```
You then need to connect to `localhost` with port `1534`.
## Port forwarding for file transfers with `scp`
```sh
ssh -L 1535:192.168.133.10:22 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash
```
You then need to run `scp` with the `-P 1535` flag with `localhost` as the target IP address.
## Port forwarding for TMTC commanding
You can enable port forwarding for TMTC commanding with the following command:
```sh
ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash
```
This forwards TMTC packets on port `1536` of localhost to the TMTC reception port of the Q7S.
## Set up all port forwarding at once
Port forwarding is necessary for remote-debugging using the `tcf-agent`, copying files
with `scp` & `q7s-cp.py` and sending TMTC commands.
You can specify the `-L` option multiple times to set up all port forwarding at once.
Example for using the UDP communication interface:
```sh
ssh -L 1534:192.168.133.10:1534 \
-L 1535:192.168.133.10:22 \
-L 1536:192.168.133.10:7301 \
ssh -L 1534:192.168.155.55:1534 \
-L 1535:192.168.155.55:22 \
-L 1536:192.168.155.55:7301 \
-L 1537:127.0.0.1:7100 \
-L 1538:192.168.133.10:1534 \
-L 1539:192.168.133.10:22 \
-L 1540:192.168.133.10:7301 \
eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \
-t 'export CONSOLE_PREFIX="[Q7S Tunnel] /bin/bash'
-t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash'
```
There is also a shell script called `q7s-port.sh` which can be used to achieve the same.
# <a id="set-up-prereq"></a> Setting up prerequisites
## <a id="sysroot"></a> Getting system root for Linux cross-compilation
Cross-compiling any program for an embedded Linux board generally required parts of the target root
file system on the development/host computer. For the Q7S, you can install the cross-compilation
root file system by simply installing the SDK. You can find the most recent SDK
[here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/xiphos-q7s-sdk).
If you are compiling for the Q7S or the TE7020, the `ZYNQ_7020_SYSROOT` environment variable
must be set to the location of the SDK compile sysroot. Here is an example on how to do this
in Ubuntu, assuming the SDK was installed in the default location
```sh
export ZYNQ_7020_SYSROOT="/opt/xiphos/sdk/ark/sysroots/cortexa9hf-neon-xiphos-linux-gnueabi"
```
If you are comiling for the Raspberry Pi, you have to set the `LINUX_ROOTFS` environmental
variable instead. You can find a base root filesystem for the Raspberry Pi
[here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/rootfs).
## <a id="vivado"></a> Installing Vivado the the Xilinx development tools
It's also possible to perform debugging with a normal Eclipse installation by installing
@ -348,7 +345,9 @@ twice) and generate this list manually with the following commands, according to
sudo apt install libncurses5
```
2. ```sh
2. Execute the following command
```sh
sudo <installRoot>/Vivado/2018.2/bin/vivado -nolog -nojournal -mode batch -source
<installRoot>/.xinstall/Vivado_2018.2/scripts/xlpartinfo.tcl -tclargs
<installRoot>/Vivado/2018.2/data/parts/installed_devices.txt
@ -422,21 +421,6 @@ You can download the toolchains for Windows and Linux
```sh
sudo apt-get install cmake
````
## <a id="q7s-sysroot"></a> Getting the Q7S system root
It is necessary to copy the Q7S system root to your local development machine for libraries
like `libgpio`. You can find the system root for the Q7S, the Raspberry Pi and the
Beagle Bone Black for download here
[here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/rootfs&fileid=831849).
Download it and unzip it somewhere in the Xilinx installation folder.
You can use the following command if `wget` can be used or for CI/CD:
```sh
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
```
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
### Updating system root for CI
@ -727,7 +711,10 @@ More detailed information about the used q7s commands can be found in the Q7S us
# <a id="q7s"></a> Q7S OBC
## Launching an application at start-up
## Launching an application at start-up - deprecated
This way to enable auto-startup is deprecated. It is instead recommended to tweak the yocto
recipes file for the related `systemd` service to enable auto-startup with `SYSTEMD_AUTO_ENABLE`.
You can also do the steps performed here on a host computer inside the `q7s-rootfs` directory
of the [Q7S base repository](https://egit.irs.uni-stuttgart.de/eive/q7s-base). This might
@ -829,10 +816,9 @@ If a timeout occurs, this special file will be deleted as well.
The watchdog and its configuration will be directly integrated into this repostory, which
makes adaptions easy.
### `tcfagent`
### `tcf-agent`
This starts the `/usr/bin/agent` program to allows remote debugging. Might not be part of
the mission code
This starts the `/usr/bin/tcf-agent` program to allows remote debugging
### `eive-early-config`
@ -1196,8 +1182,11 @@ Alternatively, changes from other upstreams (forks) and branches can be merged l
in the same way.
# <a id="coding-style"></a> Coding Style
* the formatting is based on the clang-format tools
## Setting up eclipse auto-fromatter with clang-format
1. Help &rarr; Install New Software &rarr; Add
2. In location insert the link http://www.cppstyle.com/luna
3. The software package CppStyle should now be available for installation

View File

@ -8,11 +8,13 @@
#include "commonConfig.h"
#define OBSW_ADD_TEST_CODE 1
#define OBSW_PRINT_MISSED_DEADLINES 1
#define OBSW_ADD_TEST_CODE 1
/* These defines should be disabled for mission code but are useful for
debugging. */
#define OBSW_VEBOSE_LEVEL 1
#define OBSW_VEBOSE_LEVEL 1
#define OBSW_USE_CCSDS_IP_CORE 0
// Set to 1 if all telemetry should be sent to the PTME IP Core
@ -20,6 +22,12 @@ debugging. */
// Set to 1 if telecommands are received via the PDEC IP Core
#define OBSW_TC_FROM_PDEC 0
#define OBSW_SYRLINKS_SIMULATED 0
#define OBSW_INITIALIZE_SWITCHES 0
#define OBSW_TCP_SERVER_WIRETAPPING 0
#ifdef __cplusplus
#include "objects/systemObjectList.h"

View File

@ -1,7 +1,7 @@
#include <iostream>
#include "InitMission.h"
#include "OBSWVersion.h"
#include "commonConfig.h"
#include "fsfw/FSFWVersion.h"
#include "fsfw/tasks/TaskFactory.h"
#ifdef WIN32
@ -19,9 +19,9 @@ static const char* COMPILE_PRINTOUT = "unknown OS";
int main(void) {
std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for " << COMPILE_PRINTOUT << " --" << std::endl;
std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "."
<< SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "."
<< FSFW_REVISION << "--" << std::endl;
std::cout << "-- OBSW "
<< " v" << common::OBSW_VERSION << " | FSFW v" << fsfw::FSFW_VERSION << " --"
<< std::endl;
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
initmission::initMission();

View File

@ -34,5 +34,6 @@ SOFTWARE.
#define ETL_CPP11_SUPPORTED 1
#define ETL_NO_NULLPTR_SUPPORT 0
#define ETL_HAS_ERROR_ON_STRING_TRUNCATION 1
#endif

View File

@ -1,5 +1,7 @@
#include "ObjectFactory.h"
#include <_deps/etl-src/include/etl/utility.h>
#include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h"
#include "bsp_q7s/callbacks/gnssCallback.h"
@ -45,6 +47,8 @@
#include "tmtc/apid.h"
#include "tmtc/pusIds.h"
using etl::pair;
#if OBSW_TEST_LIBGPIOD == 1
#include "linux/boardtest/LibgpiodTest.h"
#endif
@ -152,7 +156,7 @@ void ObjectFactory::produce(void* args) {
createSolarArrayDeploymentComponents();
createPlPcduComponents(gpioComIF, spiComIF, pwrSwitcher);
#if OBSW_ADD_SYRLINKS == 1
createSyrlinksComponents();
createSyrlinksComponents(pwrSwitcher);
#endif /* OBSW_ADD_SYRLINKS == 1 */
createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher);
createPayloadComponents(gpioComIF);
@ -168,6 +172,9 @@ void ObjectFactory::produce(void* args) {
imtqHandler->setStartUpImmediately();
imtqHandler->setToGoToNormal(true);
#endif
#if OBSW_DEBUG_IMTQ == 1
imtqHandler->setDebugMode(true);
#endif
#endif
createReactionWheelComponents(gpioComIF);
@ -177,6 +184,9 @@ void ObjectFactory::produce(void* args) {
new BpxBatteryHandler(objects::BPX_BATT_HANDLER, objects::I2C_COM_IF, bpxI2cCookie);
bpxHandler->setStartUpImmediately();
bpxHandler->setToGoToNormalMode(true);
#if OBSW_DEBUG_BPX_BATT == 1
bpxHandler->setDebugMode(true);
#endif
#endif
new FileSystemHandler(objects::FILE_SYSTEM_HANDLER);
@ -266,6 +276,12 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
if (pwrSwitcher != nullptr) {
*pwrSwitcher = pcduHandler;
}
#if OBSW_DEBUG_P60DOCK == 1
p60dockhandler->setDebugMode(true);
#endif
#if OBSW_DEBUG_ACU == 1
acuhandler->setDebugMode(true);
#endif
}
void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
@ -632,6 +648,9 @@ void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) {
auto syrlinksHandler = new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF,
syrlinksUartCookie, pcdu::PDU1_CH1_SYRLINKS_12V);
syrlinksHandler->setPowerSwitcher(pwrSwitcher);
#if OBSW_DEBUG_SYRLINKS == 1
syrlinksHandler->setDebugMode(true);
#endif
}
void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF) {
@ -717,47 +736,31 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) {
gpioComIF->addGpios(gpioCookieRw);
#if OBSW_ADD_RW == 1
auto rw1SpiCookie =
new SpiCookie(addresses::RW1, gpioIds::CS_RW1, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE,
spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr);
auto rw2SpiCookie =
new SpiCookie(addresses::RW2, gpioIds::CS_RW2, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE,
spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr);
auto rw3SpiCookie =
new SpiCookie(addresses::RW3, gpioIds::CS_RW3, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE,
spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr);
auto rw4SpiCookie =
new SpiCookie(addresses::RW4, gpioIds::CS_RW4, q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE,
spi::RW_MODE, spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr);
auto rwHandler1 =
new RwHandler(objects::RW1, objects::SPI_COM_IF, rw1SpiCookie, gpioComIF, gpioIds::EN_RW1);
std::array<std::pair<address_t, gpioId_t>, 4> rwCookieParams = {
{{addresses::RW1, gpioIds::CS_RW1},
{addresses::RW2, gpioIds::CS_RW2},
{addresses::RW3, gpioIds::CS_RW3},
{addresses::RW4, gpioIds::CS_RW4}}};
std::array<SpiCookie*, 4> rwCookies = {};
std::array<std::pair<object_id_t, gpioId_t>, 4> rwDevParams = {{{objects::RW1, gpioIds::EN_RW1},
{objects::RW2, gpioIds::EN_RW2},
{objects::RW3, gpioIds::EN_RW3},
{objects::RW4, gpioIds::EN_RW4}}};
std::array<RwHandler*, 4> rws = {};
for (uint8_t idx = 0; idx < rwCookies.size(); idx++) {
rwCookies[idx] = new SpiCookie(rwCookieParams[idx].first, rwCookieParams[idx].second,
q7s::SPI_RW_DEV, RwDefinitions::MAX_REPLY_SIZE, spi::RW_MODE,
spi::RW_SPEED, &rwSpiCallback::spiCallback, nullptr);
rws[idx] = new RwHandler(rwDevParams[idx].first, objects::SPI_COM_IF, rwCookies[idx], gpioComIF,
rwDevParams[idx].second);
rwCookies[idx]->setCallbackArgs(rws[idx]);
#if OBSW_TEST_RW == 1
rwHandler1->setStartUpImmediately();
rws[idx]->setStartUpImmediately();
#endif
rw1SpiCookie->setCallbackArgs(rwHandler1);
auto rwHandler2 =
new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, gpioIds::EN_RW2);
#if OBSW_TEST_RW == 1
rwHandler2->setStartUpImmediately();
#if OBSW_DEBUG_RW == 1
rws[idx]->setDebugMode(true);
#endif
rw2SpiCookie->setCallbackArgs(rwHandler2);
auto rwHandler3 =
new RwHandler(objects::RW3, objects::SPI_COM_IF, rw3SpiCookie, gpioComIF, gpioIds::EN_RW3);
#if OBSW_TEST_RW == 1
rwHandler3->setStartUpImmediately();
#endif
rw3SpiCookie->setCallbackArgs(rwHandler3);
auto rwHandler4 =
new RwHandler(objects::RW4, objects::SPI_COM_IF, rw4SpiCookie, gpioComIF, gpioIds::EN_RW4);
#if OBSW_TEST_RW == 1
rwHandler4->setStartUpImmediately();
#endif
rw4SpiCookie->setCallbackArgs(rwHandler4);
}
#endif /* OBSW_ADD_RW == 1 */
}

View File

@ -4,16 +4,20 @@
#include <cstdint>
#include "fsfw/version.h"
#define OBSW_ADD_LWGPS_TEST 0
/* These defines should be disabled for mission code but are useful for
debugging. */
#define OBSW_VERBOSE_LEVEL 1
#define OBSW_ADD_LWGPS_TEST 0
// Disable this for mission code. It allows exchanging TMTC packets via the Ethernet port
#define OBSW_ADD_TCPIP_BRIDGE 1
#define OBSW_ADD_TCPIP_BRIDGE 1
// Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally
// because UDP packets are not allowed in the VPN
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
// CCSDS IP Cores.
#define OBSW_USE_TMTC_TCP_BRIDGE 1
#define OBSW_USE_TMTC_TCP_BRIDGE 1
namespace common {

@ -1 +1 @@
Subproject commit 2a408e8c7dd2ebe974b9699fb5aee0889aa86392
Subproject commit 5ad9fb94af3312d29863527106396395f7b808a5

View File

@ -267,6 +267,9 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
rtdFdir = new RtdFdir(rtdIds[idx]);
rtds[idx]->setCustomFdir(rtdFdir);
rtds[idx]->setDeviceIdx(idx + 3);
#if OBSW_DEBUG_RTD == 1
rtds[idx]->setDebugMode(true);
#endif
}
#if OBSW_TEST_RTD == 1

View File

@ -14,10 +14,6 @@
#include "commonConfig.h"
#include "OBSWVersion.h"
/* These defines should be disabled for mission code but are useful for
debugging. */
#define OBSW_VERBOSE_LEVEL 1
#define Q7S_EM 0
@ -47,12 +43,12 @@ debugging. */
#define OBSW_ADD_SUS_BOARD_ASS 1
#define OBSW_ADD_ACS_BOARD 1
#define OBSW_ADD_ACS_HANDLERS 1
#define OBSW_ADD_RW 0
#define OBSW_ADD_RW 1
#define OBSW_ADD_RTD_DEVICES 1
#define OBSW_ADD_TMP_DEVICES 0
#define OBSW_ADD_TMP_DEVICES 1
#define OBSW_ADD_RAD_SENSORS 1
#define OBSW_ADD_PL_PCDU 1
#define OBSW_ADD_SYRLINKS 0
#define OBSW_ADD_SYRLINKS 1
#define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0
#define OBSW_STAR_TRACKER_GROUND_CONFIG 1
@ -147,7 +143,7 @@ debugging. */
#define OBSW_DEBUG_GPS 0
#define OBSW_DEBUG_ACU 0
#define OBSW_DEBUG_SYRLINKS 0
#define OBSW_DEBUG_RW 0
#define OBSW_DEBUG_PDEC_HANDLER 0
#ifdef TE0720_1CFA
@ -187,7 +183,7 @@ debugging. */
#endif // RASPBERRY_PI
#define TCP_SERVER_WIRETAPPING 0
#define OBSW_TCP_SERVER_WIRETAPPING 0
/*******************************************************************/
/** CMake Defines */

View File

@ -514,7 +514,6 @@ ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) {
#if Q7S_EM != 1
// PCDU handlers receives two messages and both must be handled
thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);

View File

@ -111,9 +111,9 @@ void ObjectFactory::produceGenericObjects() {
tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID});
sif::info << "Created TCP server for TMTC commanding with listener port "
<< tcpServer->getTcpPort() << std::endl;
#if TCP_SERVER_WIRETAPPING == 1
#if OBSW_TCP_SERVER_WIRETAPPING == 1
tcpServer->enableWiretapping(true);
#endif /* TCP_SERVER_WIRETAPPING == 1 */
#endif /* OBSW_TCP_SERVER_WIRETAPPING == 1 */
#endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */
tmtcBridge->setMaxNumberOfPacketsStored(70);
#endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */

View File

@ -23,20 +23,22 @@ void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pack
parseHkTableReply(packet);
handleDeviceTM(&acuHkTableDataset, id, true);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_ACU == 1
acuHkTableDataset.read();
float temperatureC_1 = acuHkTableDataset.temperature1.value * 0.1;
float temperatureC_2 = acuHkTableDataset.temperature2.value * 0.1;
float temperatureC_3 = acuHkTableDataset.temperature3.value * 0.1;
sif::info << "ACU: Temperature 1: " << temperatureC_1 << " °C" << std::endl;
sif::info << "ACU: Temperature 2: " << temperatureC_2 << " °C" << std::endl;
sif::info << "ACU: Temperature 3: " << temperatureC_3 << " °C" << std::endl;
sif::info << "ACU: Ground Watchdog Timer Count: " << acuHkTableDataset.wdtCntGnd.value
<< std::endl;
sif::info << "ACU: Ground watchdog timer, seconds left before reboot: "
<< acuHkTableDataset.wdtGndLeft.value << std::endl;
acuHkTableDataset.commit();
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
acuHkTableDataset.read();
float temperatureC_1 = acuHkTableDataset.temperature1.value * 0.1;
float temperatureC_2 = acuHkTableDataset.temperature2.value * 0.1;
float temperatureC_3 = acuHkTableDataset.temperature3.value * 0.1;
sif::info << "ACU: Temperature 1: " << temperatureC_1 << " °C" << std::endl;
sif::info << "ACU: Temperature 2: " << temperatureC_2 << " °C" << std::endl;
sif::info << "ACU: Temperature 3: " << temperatureC_3 << " °C" << std::endl;
sif::info << "ACU: Ground Watchdog Timer Count: " << acuHkTableDataset.wdtCntGnd.value
<< std::endl;
sif::info << "ACU: Ground watchdog timer, seconds left before reboot: "
<< acuHkTableDataset.wdtGndLeft.value << std::endl;
acuHkTableDataset.commit();
#endif
}
}
LocalPoolDataSetBase *ACUHandler::getDataSetHandle(sid_t sid) {
@ -317,3 +319,5 @@ void ACUHandler::printChannelStats() {
<< static_cast<unsigned int>(acuHkTableDataset.currentInChannel5.value) << std::setw(15)
<< std::right << acuHkTableDataset.voltageInChannel5.value << std::endl;
}
void ACUHandler::setDebugMode(bool enable) { this->debugMode = enable; }

View File

@ -15,6 +15,8 @@ class ACUHandler : public GomspaceDeviceHandler {
ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie);
virtual ~ACUHandler();
void setDebugMode(bool enable);
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
@ -37,6 +39,7 @@ class ACUHandler : public GomspaceDeviceHandler {
static const DeviceCommandId_t PRINT_CHANNEL_STATS = 51;
ACU::HkTableDataset acuHkTableDataset;
bool debugMode = false;
/**
* @brief Function extracts the hk table information from the received csp packet and stores

View File

@ -197,19 +197,19 @@ ReturnValue_t BpxBatteryHandler::interpretDeviceReply(DeviceCommandId_t id, cons
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
#if OBSW_DEBUG_BPX_BATT == 1
sif::info << "BPX Battery HK output:" << std::endl;
sif::info << "Charge current [mA]: " << hkSet.chargeCurrent << std::endl;
sif::info << "Discharge current [mA]: " << hkSet.dischargeCurrent << std::endl;
sif::info << "Heater current [mA]: " << hkSet.heaterCurrent << std::endl;
sif::info << "Battery voltage [mV]: " << hkSet.battVoltage << std::endl;
sif::info << "Battery Temperature 1 [C]: " << hkSet.battTemp1 << std::endl;
sif::info << "Battery Temperature 2 [C]: " << hkSet.battTemp2 << std::endl;
sif::info << "Battery Temperature 3 [C]: " << hkSet.battTemp3 << std::endl;
sif::info << "Battery Temperature 4 [C]: " << hkSet.battTemp4 << std::endl;
sif::info << "Battery Reboot Counter: " << hkSet.rebootCounter << std::endl;
sif::info << "Battery Boot Cause: " << static_cast<int>(hkSet.bootcause.value) << std::endl;
#endif
if (debugMode) {
sif::info << "BPX Battery HK output:" << std::endl;
sif::info << "Charge current [mA]: " << hkSet.chargeCurrent << std::endl;
sif::info << "Discharge current [mA]: " << hkSet.dischargeCurrent << std::endl;
sif::info << "Heater current [mA]: " << hkSet.heaterCurrent << std::endl;
sif::info << "Battery voltage [mV]: " << hkSet.battVoltage << std::endl;
sif::info << "Battery Temperature 1 [C]: " << hkSet.battTemp1 << std::endl;
sif::info << "Battery Temperature 2 [C]: " << hkSet.battTemp2 << std::endl;
sif::info << "Battery Temperature 3 [C]: " << hkSet.battTemp3 << std::endl;
sif::info << "Battery Temperature 4 [C]: " << hkSet.battTemp4 << std::endl;
sif::info << "Battery Reboot Counter: " << hkSet.rebootCounter << std::endl;
sif::info << "Battery Boot Cause: " << static_cast<int>(hkSet.bootcause.value) << std::endl;
}
break;
}
case (BpxBattery::PING): {
@ -277,3 +277,5 @@ ReturnValue_t BpxBatteryHandler::initializeLocalDataPool(localpool::DataPool& lo
void BpxBatteryHandler::setToGoToNormalMode(bool enable) {
this->goToNormalModeImmediately = enable;
}
void BpxBatteryHandler::setDebugMode(bool enable) { this->debugMode = enable; }

View File

@ -11,6 +11,7 @@ class BpxBatteryHandler : public DeviceHandlerBase {
virtual ~BpxBatteryHandler();
void setToGoToNormalMode(bool enable);
void setDebugMode(bool enable);
protected:
enum class States {
@ -20,6 +21,7 @@ class BpxBatteryHandler : public DeviceHandlerBase {
States state = States::CHECK_COM;
bool commandExecuted = false;
bool debugMode = false;
bool goToNormalModeImmediately = false;
uint8_t sentPingByte = BpxBattery::DEFAULT_PING_SENT_BYTE;
BpxBatteryHk hkSet;

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@ class IMTQHandler : public DeviceHandlerBase {
*/
void setToGoToNormal(bool enable);
void setDebugMode(bool enable);
protected:
void doStartUp() override;
void doShutDown() override;
@ -99,6 +101,7 @@ class IMTQHandler : public DeviceHandlerBase {
uint8_t commandBuffer[IMTQ::MAX_COMMAND_SIZE];
bool goToNormalMode = false;
bool debugMode = false;
enum class CommunicationStep {
GET_ENG_HK_DATA,

View File

@ -399,20 +399,21 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
// calculate approximation
float approxTemp = adcCode / 32.0 - 256.0;
#if OBSW_DEBUG_RTD == 1
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
if (debugDivider->checkAndIncrement()) {
if (debugDivider->checkAndIncrement()) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Max31865: ObjID " << std::hex << this->getObjectId() << " | RTD " << std::dec
<< static_cast<int>(deviceIdx) << ": R[Ohm] " << rtdValue
<< " Ohms | Approx T[C]: " << approxTemp << std::endl;
sif::info << "Max31865: ObjID " << std::hex << this->getObjectId() << " | RTD "
<< std::dec << static_cast<int>(deviceIdx) << ": R[Ohm] " << rtdValue
<< " Ohms | Approx T[C]: " << approxTemp << std::endl;
#else
sif::printInfo("Max31685: Measured resistance is %f Ohms\n", rtdValue);
sif::printInfo("Approximated temperature is %f C\n", approxTemp);
sif::printInfo("Max31685: Measured resistance is %f Ohms\n", rtdValue);
sif::printInfo("Approximated temperature is %f C\n", approxTemp);
#endif
}
#endif
}
#endif
#endif
PoolReadGuard pg(&sensorDataset);
if (pg.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
// Configuration error
@ -530,3 +531,5 @@ void Max31865PT1000Handler::modeChanged() {
}
void Max31865PT1000Handler::setDeviceIdx(uint8_t idx) { deviceIdx = idx; }
void Max31865PT1000Handler::setDebugMode(bool enable) { this->debugMode = enable; }

View File

@ -33,6 +33,8 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
Max31865PT1000Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie);
virtual ~Max31865PT1000Handler();
void setDebugMode(bool enable);
// Configuration in 8 digit code:
// 1. 1 for V_BIAS enabled, 0 for disabled
// 2. 1 for Auto-conversion, 0 for off
@ -85,6 +87,7 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
private:
uint8_t switchId = 0;
bool instantNormal = false;
bool debugMode = false;
bool warningSwitch = true;
enum class InternalState {

View File

@ -24,50 +24,6 @@ void P60DockHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *
* P60DockHandler itself.
*/
handleDeviceTM(&coreHk, id, true);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_P60DOCK == 1
p60dockHkTableDataset.read();
sif::info << "P60 Dock: ACU VCC switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateAcuVcc.value)
<< std::endl;
sif::info << "P60 Dock: PDU1 VCC switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu1Vcc.value)
<< std::endl;
sif::info << "P60 Dock: PDU2 VCC switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu2Vcc.value)
<< std::endl;
sif::info << "P60 Dock: ACU VBAT switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateAcuVbat.value)
<< std::endl;
sif::info << "P60 Dock: PDU1 VBAT switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu1Vbat.value)
<< std::endl;
sif::info << "P60 Dock: PDU2 VBAT switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStatePdu2Vbat.value)
<< std::endl;
sif::info << "P60 Dock: Stack VBAT switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateStackVbat.value)
<< std::endl;
sif::info << "P60 Dock: Stack 3V3 switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateStack3V3.value)
<< std::endl;
sif::info << "P60 Dock: Stack 5V switch: "
<< static_cast<unsigned int>(p60dockHkTableDataset.outputEnableStateStack5V.value)
<< std::endl;
float temperatureC = p60dockHkTableDataset.temperature1.value * 0.1;
sif::info << "P60 Dock: Temperature 1: " << temperatureC << " °C" << std::endl;
temperatureC = p60dockHkTableDataset.temperature2.value * 0.1;
sif::info << "P60 Dock: Temperature 2: " << temperatureC << " °C" << std::endl;
sif::info << "P60 Dock: Watchdog Timer seconds left before reboot: "
<< p60dockHkTableDataset.wdtGndLeft << " seconds" << std::endl;
sif::info << "P60 Dock: CSP 1, pings left before reboot: "
<< (int)p60dockHkTableDataset.wdtCspLeft1.value << std::endl;
sif::info << "P60 Dock: CSP 2, pings left before reboot: "
<< (int)p60dockHkTableDataset.wdtCspLeft1.value << std::endl;
p60dockHkTableDataset.commit();
#endif
}
void P60DockHandler::parseHkTableReply(const uint8_t *packet) {
@ -362,3 +318,5 @@ void P60DockHandler::printHkTableLatchups() {
genericPrintoutHandler("X3 VBAT", hk::X3_IDLE_VBAT);
genericPrintoutHandler("X3 VCC", hk::X3_IDLE_VCC);
}
void P60DockHandler::setDebugMode(bool enable) { this->debugMode = enable; }

View File

@ -24,6 +24,8 @@ class P60DockHandler : public GomspaceDeviceHandler {
P60DockHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie);
virtual ~P60DockHandler();
void setDebugMode(bool enable);
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
@ -50,6 +52,7 @@ class P60DockHandler : public GomspaceDeviceHandler {
P60Dock::CoreHkSet coreHk;
P60Dock::HkTableDataset auxHk;
bool firstHk = true;
bool debugMode = false;
static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 16;
PoolEntry<int16_t> hkCurrents = PoolEntry<int16_t>(P60Dock::hk::CHNLS_LEN);

View File

@ -95,17 +95,20 @@ void PCDUHandler::initializeSwitchStates() {
}
void PCDUHandler::readCommandQueue() {
ReturnValue_t result;
ReturnValue_t result = RETURN_OK;
CommandMessage command;
result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
result = commandQueue->receiveMessage(&command)) {
result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
result = poolManager.handleHousekeepingMessage(&command);
if (result == RETURN_OK) {
return;
result = poolManager.handleHousekeepingMessage(&command);
if (result == RETURN_OK) {
return;
}
}
}

View File

@ -2,7 +2,9 @@
#include <fsfw/src/fsfw/datapool/PoolReadGuard.h>
#ifdef FSFW_OSAL_LINUX
#include "OBSWConfig.h"
#ifdef XIPHOS_Q7S
#include <fsfw_hal/linux/UnixFileGuard.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
#include <fsfw_hal/linux/spi/SpiCookie.h>
@ -663,7 +665,7 @@ ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
return params.writeJsonFile();
}
#ifdef FSFW_OSAL_LINUX
#ifdef XIPHOS_Q7S
ReturnValue_t PayloadPcduHandler::extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie,
const uint8_t* sendData, size_t sendLen,
void* args) {

View File

@ -68,10 +68,9 @@ class PayloadPcduHandler : public DeviceHandlerBase {
void setToGoToNormalModeImmediately(bool enable);
void enablePeriodicPrintout(bool enable, uint8_t divider);
#ifdef XIPHOS_Q7S
static ReturnValue_t extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie,
const uint8_t* sendData, size_t sendLen, void* args);
#ifdef FSFW_OSAL_LINUX
static ReturnValue_t transferAsTwo(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData,
size_t sendLen, bool tempOnly);
#endif

View File

@ -1,10 +1,11 @@
#include "RwHandler.h"
#include "OBSWConfig.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/CRC.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include "OBSWConfig.h"
RwHandler::RwHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
GpioIF* gpioComIF, gpioId_t enableGpio)
: DeviceHandlerBase(objectId, comIF, comCookie),
@ -341,12 +342,15 @@ void RwHandler::handleResetStatusReply(const uint8_t* packet) {
lastResetStatusSet.lastResetStatus = resetStatus;
}
lastResetStatusSet.currentResetStatus = resetStatus;
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleResetStatusReply: Last reset status: "
<< static_cast<unsigned int>(lastResetStatusSet.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleResetStatusReply: Current reset status: "
<< static_cast<unsigned int>(lastResetStatusSet.currentResetStatus.value) << std::endl;
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "RwHandler::handleResetStatusReply: Last reset status: "
<< static_cast<unsigned int>(lastResetStatusSet.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleResetStatusReply: Current reset status: "
<< static_cast<unsigned int>(lastResetStatusSet.currentResetStatus.value)
<< std::endl;
#endif
}
}
void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
@ -371,16 +375,18 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
sif::error << "RwHandler::handleGetRwStatusReply: Reaction wheel in error state" << std::endl;
}
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleGetRwStatusReply: Current speed is: " << statusSet.currSpeed
<< " * 0.1 RPM" << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: Reference speed is: " << statusSet.referenceSpeed
<< " * 0.1 RPM" << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: State is: "
<< (unsigned int)statusSet.state.value << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: clc mode is: "
<< (unsigned int)statusSet.clcMode.value << std::endl;
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "RwHandler::handleGetRwStatusReply: Current speed is: " << statusSet.currSpeed
<< " * 0.1 RPM" << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: Reference speed is: "
<< statusSet.referenceSpeed << " * 0.1 RPM" << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: State is: "
<< (unsigned int)statusSet.state.value << std::endl;
sif::info << "RwHandler::handleGetRwStatusReply: clc mode is: "
<< (unsigned int)statusSet.clcMode.value << std::endl;
#endif
}
}
void RwHandler::handleTemperatureReply(const uint8_t* packet) {
@ -388,10 +394,12 @@ void RwHandler::handleTemperatureReply(const uint8_t* packet) {
uint8_t offset = 2;
temperatureSet.temperatureCelcius = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 |
*(packet + offset + 1) << 8 | *(packet + offset);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleTemperatureReply: Temperature: "
<< temperatureSet.temperatureCelcius << " °C" << std::endl;
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "RwHandler::handleTemperatureReply: Temperature: "
<< temperatureSet.temperatureCelcius << " °C" << std::endl;
#endif
}
}
void RwHandler::handleGetTelemetryReply(const uint8_t* packet) {
@ -468,53 +476,57 @@ void RwHandler::handleGetTelemetryReply(const uint8_t* packet) {
offset += 4;
tmDataset.spiTotalNumOfErrors = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 |
*(packet + offset + 1) << 8 | *(packet + offset);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_RW == 1
sif::info << "RwHandler::handleGetTelemetryReply: Last reset status: "
<< static_cast<unsigned int>(tmDataset.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: MCU temperature: " << tmDataset.mcuTemperature
<< std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Pressure sensor temperature: "
<< tmDataset.pressureSensorTemperature << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Pressure " << tmDataset.pressure << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: State: "
<< static_cast<unsigned int>(tmDataset.rwState.value) << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: CLC mode: "
<< static_cast<unsigned int>(tmDataset.rwClcMode.value) << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Current speed: " << tmDataset.rwCurrSpeed
<< std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Reference speed: " << tmDataset.rwRefSpeed
<< std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid CRC packets: "
<< tmDataset.numOfInvalidCrcPackets << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid length packets: "
<< tmDataset.numOfInvalidLenPackets << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid command packets: "
<< tmDataset.numOfInvalidCmdPackets << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of command executed replies: "
<< tmDataset.numOfCmdExecutedReplies << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of command replies: "
<< tmDataset.numOfCmdReplies << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of bytes written: "
<< tmDataset.uartNumOfBytesWritten << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of bytes read: "
<< tmDataset.uartNumOfBytesRead << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of parity errors: "
<< tmDataset.uartNumOfParityErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of noise errors: "
<< tmDataset.uartNumOfNoiseErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of frame errors: "
<< tmDataset.uartNumOfFrameErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of register overrun errors: "
<< tmDataset.uartNumOfRegisterOverrunErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of total errors: "
<< tmDataset.uartTotalNumOfErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of bytes written: "
<< tmDataset.spiNumOfBytesWritten << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of bytes read: "
<< tmDataset.spiNumOfBytesRead << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of register overrun errors: "
<< tmDataset.spiNumOfRegisterOverrunErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of register total errors: "
<< tmDataset.spiTotalNumOfErrors << std::endl;
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "RwHandler::handleGetTelemetryReply: Last reset status: "
<< static_cast<unsigned int>(tmDataset.lastResetStatus.value) << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: MCU temperature: " << tmDataset.mcuTemperature
<< std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Pressure sensor temperature: "
<< tmDataset.pressureSensorTemperature << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Pressure " << tmDataset.pressure << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: State: "
<< static_cast<unsigned int>(tmDataset.rwState.value) << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: CLC mode: "
<< static_cast<unsigned int>(tmDataset.rwClcMode.value) << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Current speed: " << tmDataset.rwCurrSpeed
<< std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Reference speed: " << tmDataset.rwRefSpeed
<< std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid CRC packets: "
<< tmDataset.numOfInvalidCrcPackets << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid length packets: "
<< tmDataset.numOfInvalidLenPackets << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of invalid command packets: "
<< tmDataset.numOfInvalidCmdPackets << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of command executed replies: "
<< tmDataset.numOfCmdExecutedReplies << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: Number of command replies: "
<< tmDataset.numOfCmdReplies << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of bytes written: "
<< tmDataset.uartNumOfBytesWritten << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of bytes read: "
<< tmDataset.uartNumOfBytesRead << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of parity errors: "
<< tmDataset.uartNumOfParityErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of noise errors: "
<< tmDataset.uartNumOfNoiseErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of frame errors: "
<< tmDataset.uartNumOfFrameErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of register overrun errors: "
<< tmDataset.uartNumOfRegisterOverrunErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: UART number of total errors: "
<< tmDataset.uartTotalNumOfErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of bytes written: "
<< tmDataset.spiNumOfBytesWritten << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of bytes read: "
<< tmDataset.spiNumOfBytesRead << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of register overrun errors: "
<< tmDataset.spiNumOfRegisterOverrunErrors << std::endl;
sif::info << "RwHandler::handleGetTelemetryReply: SPI number of register total errors: "
<< tmDataset.spiTotalNumOfErrors << std::endl;
#endif
}
}
void RwHandler::setDebugMode(bool enable) { this->debugMode = enable; }

View File

@ -32,6 +32,9 @@ class RwHandler : public DeviceHandlerBase {
*/
RwHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, GpioIF* gpioComIF,
gpioId_t enableGpio);
void setDebugMode(bool enable);
virtual ~RwHandler();
static const uint8_t INTERFACE_ID = CLASS_ID::RW_HANDLER;
@ -88,6 +91,7 @@ class RwHandler : public DeviceHandlerBase {
GpioIF* gpioComIF = nullptr;
gpioId_t enableGpio = gpio::NO_GPIO;
bool debugMode = false;
RwDefinitions::TemperatureSet temperatureSet;
RwDefinitions::StatusSet statusSet;

View File

@ -166,12 +166,12 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic
return RETURN_OK;
}
case (syrlinks::ENABLE_DEBUG): {
debug = true;
debugMode = true;
rawPacketLen = 0;
return RETURN_OK;
}
case (syrlinks::DISABLE_DEBUG): {
debug = false;
debugMode = false;
rawPacketLen = 0;
return RETURN_OK;
}
@ -363,7 +363,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons
tempBasebandBoard = calcTempVal(rawTempBasebandBoard);
temperatureSet.temperatureBasebandBoard = tempBasebandBoard;
PoolReadGuard rg(&temperatureSet);
if (debug) {
if (debugMode) {
sif::info << "Syrlinks temperature baseband board: " << tempBasebandBoard << " °C"
<< std::endl;
}
@ -394,7 +394,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons
tempPowerAmplifier = calcTempVal(rawTempPowerAmplifier);
PoolReadGuard rg(&temperatureSet);
temperatureSet.temperaturePowerAmplifier = tempPowerAmplifier;
if (debug) {
if (debugMode) {
sif::info << "Syrlinks temperature power amplifier board: " << tempPowerAmplifier << " °C"
<< std::endl;
}
@ -540,8 +540,8 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) {
offset += 6;
rxDataset.rxDataRate = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SYRLINKS == 1
if (debug) {
if (debugMode) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Syrlinks RX Status: 0x" << std::hex << (unsigned int)rxDataset.rxStatus.value
<< std::endl;
sif::info << "Syrlinks RX Sensitivity: " << std::dec << rxDataset.rxSensitivity << std::endl;
@ -551,14 +551,14 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) {
sif::info << "Syrlinks RX Demod Eb: " << rxDataset.rxDemodEb << std::endl;
sif::info << "Syrlinks RX Demod N0: " << rxDataset.rxDemodN0 << std::endl;
sif::info << "Syrlinks RX Datarate: " << (unsigned int)rxDataset.rxDataRate.value << std::endl;
}
#endif
}
}
void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) {
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
uint8_t lclConfig = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
if (debug) {
if (debugMode) {
sif::info << "SyrlinksHkHandler::parseRxStatusRegistersReply: Lcl config: "
<< static_cast<unsigned int>(lclConfig) << std::endl;
}
@ -568,24 +568,20 @@ void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
txDataset.txStatus = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_DEBUG_SYRLINKS == 1
if (debug) {
if (debugMode) {
sif::info << "Syrlinks TX Status: 0x" << std::hex << (unsigned int)txDataset.txStatus.value
<< std::endl;
}
#endif
}
void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) {
PoolReadGuard readHelper(&txDataset);
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
txDataset.txWaveform = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_DEBUG_SYRLINKS == 1
if (debug) {
if (debugMode) {
sif::info << "Syrlinks TX Waveform: 0x" << std::hex << (unsigned int)txDataset.txWaveform.value
<< std::endl;
}
#endif
}
void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) {
@ -593,11 +589,9 @@ void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) {
uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE;
txDataset.txAgcValue = agcValueHighByte << 8 |
convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
#if OBSW_DEBUG_SYRLINKS == 1
if (debug) {
if (debugMode) {
sif::info << "Syrlinks TX AGC Value: " << txDataset.txAgcValue << std::endl;
}
#endif
}
void SyrlinksHkHandler::parseAgcHighByte(const uint8_t* packet) {
@ -654,3 +648,5 @@ void SyrlinksHkHandler::prepareCommand(std::string command, DeviceCommandId_t co
rememberCommandId = commandId;
rawPacket = commandBuffer;
}
void SyrlinksHkHandler::setDebugMode(bool enable) { this->debugMode = enable; }

View File

@ -28,6 +28,8 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
*/
void setModeNormal();
void setDebugMode(bool enable);
protected:
void doStartUp() override;
void doShutDown() override;
@ -95,6 +97,7 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
const power::Switch_t powerSwitch = power::NO_SWITCH;
bool debugMode = false;
uint8_t agcValueHighByte = 0;
uint16_t rawTempPowerAmplifier = 0;
uint16_t rawTempBasebandBoard = 0;
@ -107,8 +110,6 @@ class SyrlinksHkHandler : public DeviceHandlerBase {
StartupState startupState = StartupState::OFF;
bool debug = false;
/**
* This object is used to store the id of the next command to execute. This controls the
* read out of multiple registers which can not be fetched with one single command.

1
thirdparty/etl vendored

@ -1 +0,0 @@
Subproject commit c308dc427b7a34e54f33860fb2e244564b2740b4

View File

@ -77,7 +77,10 @@ static int csp_bytesize(char *buf, int len, unsigned long int n) {
postfix = 'B';
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
return snprintf(buf, len, "%.1f%c", size, postfix);
#pragma GCC diagnostic pop
}
void csp_iflist_print(void) {