Compare commits

...

69 Commits

Author SHA1 Message Date
Steffen Gaisser 4e61855d79 Merge pull request 'Another Update Package Yaaay' (#9) from mueller/yet-another-update-package-nice into master
Reviewed-on: #9
2021-05-25 14:55:42 +02:00
Steffen Gaisser 677a2f3d30 Merge branch 'master' into mueller/yet-another-update-package-nice 2021-05-25 14:55:36 +02:00
Robin Müller edc49d9e41 fsfw update 2021-05-25 14:37:57 +02:00
Steffen Gaisser d3026bbf62 Merge pull request 'Update Package' (#8) from mueller/update-package into master
Reviewed-on: #8
2021-05-25 14:31:57 +02:00
Robin Müller 834c376202 small fix 2021-05-24 15:15:17 +02:00
Robin Müller d97fcef444 updated RPi readme 2021-05-24 14:47:38 +02:00
Robin Müller bc6d4d846d hal and modgen update 2021-05-24 14:42:09 +02:00
Robin Müller 5c4a0809e0
node from alpine added 2021-05-21 19:46:28 +02:00
Robin Müller e95ba333a5
some more improvements 2021-05-21 19:31:05 +02:00
Robin Müller 985151c3ed
multi-stage build for toolchain installation 2021-05-21 19:25:40 +02:00
Robin Müller 4a7ea4b727
some fixes, docker compose update 2021-05-21 18:24:46 +02:00
Robin Müller 143ded24de
version is now arg 2021-05-21 18:19:08 +02:00
Robin Müller 3a92588e37
use ubuntu now 2021-05-21 18:16:04 +02:00
Robin Müller 190fabc081
updated all dockerfiles 2021-05-21 17:56:46 +02:00
Robin Müller 93a0ad6af3
updated dockerignore 2021-05-21 17:08:52 +02:00
Robin Müller 90edbe2968
using alpine image now 2021-05-21 16:36:58 +02:00
Robin Müller ff5f3b2aae
one run command now 2021-05-21 13:57:15 +02:00
Robin Müller f6d4e2141e
small fix 2021-05-21 13:55:56 +02:00
Robin Müller e0baf17c83
added compose 2021-05-20 23:30:57 +02:00
Robin Müller 53c420cf69
important fix 2021-05-20 23:07:55 +02:00
Robin Müller 0b81b25587
simple and works 2021-05-20 20:53:59 +02:00
Robin Müller 9462246861
dockerfile update 2021-05-20 19:43:24 +02:00
Robin Müller e2d40a474b
continued dockerfile and added dockerignore 2021-05-20 19:31:11 +02:00
Robin Müller dca08e63ab
fsfw update 2021-05-17 15:54:52 +02:00
Robin Müller e4b0ccdcc9
updated fsfw 2021-05-17 15:53:41 +02:00
Robin Müller 4268b29d19
tmtccmd update 2021-05-17 15:51:22 +02:00
Robin Müller fea2e77b0a
some inspector tweaks 2021-05-17 15:40:51 +02:00
Robin Müller bdbd9fa3c8
updated tmtccmd 2021-05-17 15:32:51 +02:00
Robin Müller 0a6db776ae
updated service 3 run configs 2021-05-17 15:27:31 +02:00
Robin Müller 2f32a81b47
updated run configs 2021-05-17 15:24:59 +02:00
Robin Müller bd35acead0
update to new tmtccmd version 2021-05-17 15:23:54 +02:00
Robin Müller a4ea0680fe
update submodules 2021-05-17 14:57:23 +02:00
Robin Müller acee256b1c Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public into mueller/master 2021-05-17 13:28:58 +02:00
Robin Müller f655889e7f
updated even generator 2021-05-14 11:51:52 +02:00
Robin Müller f138950670
updated modgen 2021-05-14 11:45:35 +02:00
Robin Müller 804f2f2448
fixed linux launch file 2021-05-12 18:42:51 +02:00
Robin Müller a6fbe4af6e fsfw update 2021-05-07 00:23:47 +02:00
Robin Müller 63608b0da1 updated tmtccmd 2021-05-06 20:20:04 +02:00
Robin Müller 7f24f26f85 fsfw hal update 2021-05-05 21:31:21 +02:00
Robin Müller 8502b7ad26 submodule update, obj factory update, cmake form 2021-05-05 19:43:03 +02:00
Robin Müller 5f4b1520d5 updated release config launch file 2021-05-04 18:39:49 +02:00
Robin Müller fe50ea388c updated launch config 2021-05-04 18:37:53 +02:00
Robin Müller f889812b39 updated .cproject file 2021-05-04 18:37:05 +02:00
Robin Müller c68e3c6e6d updated tmtccmd 2021-05-04 18:32:36 +02:00
Robin Müller 590db280ba merge origin master 2021-05-04 15:22:21 +02:00
Steffen Gaisser f9c3bc0a4d Merge pull request 'BBB x-compile guide added' (#7) from mueller/bbb-guide into master
Reviewed-on: #7
2021-05-04 15:16:28 +02:00
Steffen Gaisser 08d71aa6d2 Merge remote-tracking branch 'origin/master' into mueller/bbb-guide 2021-05-04 15:15:47 +02:00
Steffen Gaisser 5eabea96c2 Merge pull request 'Update to PUS C' (#6) from mueller/update-pus-c into master
Reviewed-on: #6
2021-05-04 15:11:34 +02:00
Robin Müller ab2f7fe9ec fsfw and modgen udpate 2021-05-04 15:09:33 +02:00
Robin Müller 4bddaf4832 fsfw update 2021-05-04 14:10:30 +02:00
Robin Müller 895193c9a6 typos 2021-05-02 15:13:33 +02:00
Robin Müller 5dda86a9da bbb support complete 2021-05-02 15:09:17 +02:00
Robin Müller c6c75c92dc updating READMEs for bbb and rpi 2021-05-02 14:53:02 +02:00
Robin Müller a3fb7974ba readme bbb update for linux and windows 2021-05-02 13:21:32 +02:00
Robin Müller 891d9e1822 updated READMEs 2021-05-02 13:05:04 +02:00
Robin Müller f967fd71a2 generic troubleshooting sections 2021-05-01 19:12:07 +02:00
Robin Müller d8a377ec9a Merge branch 'mueller/master' into mueller/bbb-guide 2021-05-01 18:45:37 +02:00
Robin Müller 85d9ff1c8c updated BBB readme 2021-05-01 18:30:59 +02:00
Robin Müller 8364ec3499 use new bbb x-compifle file 2021-05-01 18:06:40 +02:00
Robin Müller 1aa9918370 added BBB x-compile file 2021-05-01 18:03:55 +02:00
Robin Müller 34ccf96308 ref bbb doc 2021-05-01 17:52:01 +02:00
Robin Müller f5f33fd194 added bbb guide and updated rpi guide 2021-05-01 17:48:08 +02:00
Robin Müller 9f7aca0be5 updated project file 2021-05-01 16:49:49 +02:00
Robin Müller fb6703d8e1 fsfw update 2021-04-30 23:59:56 +02:00
Robin Müller db8f635bb5 modgen update 2021-04-30 11:41:00 +02:00
Robin Müller 52a1efc660 fsfw update 2021-04-29 20:25:16 +02:00
Robin Müller 168449f37e fsfw update 2021-04-29 20:21:57 +02:00
Robin Müller 2f73e80930 Merge remote-tracking branch 'origin/master' into mueller/master 2021-04-29 20:20:55 +02:00
Robin Müller 1e90f954c1 updated submodule 2021-04-29 19:35:54 +02:00
62 changed files with 1553 additions and 678 deletions

6
.dockerignore Normal file
View File

@ -0,0 +1,6 @@
/build*
generators
misc
tmtc
doc

View File

@ -27,6 +27,7 @@ the TMTC capabilities of the FSFW (currently, using the ECSS PUS packet standard
[Getting started with the Host OSAL](doc/README-host.md#top)<br>
[Getting started with the FreeRTOS OSAL on a STM32](doc/README-stm32-freertos.md#top)<br>
[Getting started with the Raspberry Pi](doc/README-rpi.md#top)<br>
[Getting started with the Beagle Bone Black](doc/README-bbb.md#top)<br>
[Getting started with the RTEMS OSAL on a STM32](doc/README-stm32-rtems.md#top)<br>
[Getting started with Eclipse for C/C++](doc/README-eclipse.md#top)<br>
[Getting started with CMake](doc/README-cmake.md#top)<br>

18
bsp_hosted/Dockerfile Normal file
View File

@ -0,0 +1,18 @@
FROM ubuntu:latest
# FROM alpine:latest
RUN apt-get update && apt-get install -y cmake g++
# RUN apk add cmake make g++
WORKDIR /usr/src/app
COPY . .
RUN set -ex; \
rm -rf build-hosted; \
mkdir build-hosted; \
cd build-hosted; \
cmake -DCMAKE_BUILD_TYPE=Release -DOS_FSFW=host ..;
ENTRYPOINT ["cmake", "--build", "build-hosted"]
CMD ["-j"]
# CMD ["bash"]

View File

@ -47,8 +47,7 @@ void ObjectFactory::produce(){
}
/* TMTC Reception via UDP socket */
auto tmtcBridge = new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE);
auto tmtcBridge = new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_DISTRIBUTOR);
tmtcBridge->setMaxNumberOfPacketsStored(20);
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);

View File

@ -17,7 +17,7 @@
#define FSFW_DISABLE_PRINTOUT 0
#endif
#define FSFW_USE_PUS_C_TELEMETRY 0
#define FSFW_USE_PUS_C_TELEMETRY 1
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1

View File

@ -0,0 +1,249 @@
/**
* @brief Auto-generated event translation file. Contains 78 translations.
* @details
* Generated on: 2021-05-14 11:51:26
*/
#include "translateEvents.h"
const char *STORE_SEND_WRITE_FAILED_STRING = "STORE_SEND_WRITE_FAILED";
const char *STORE_WRITE_FAILED_STRING = "STORE_WRITE_FAILED";
const char *STORE_SEND_READ_FAILED_STRING = "STORE_SEND_READ_FAILED";
const char *STORE_READ_FAILED_STRING = "STORE_READ_FAILED";
const char *UNEXPECTED_MSG_STRING = "UNEXPECTED_MSG";
const char *STORING_FAILED_STRING = "STORING_FAILED";
const char *TM_DUMP_FAILED_STRING = "TM_DUMP_FAILED";
const char *STORE_INIT_FAILED_STRING = "STORE_INIT_FAILED";
const char *STORE_INIT_EMPTY_STRING = "STORE_INIT_EMPTY";
const char *STORE_CONTENT_CORRUPTED_STRING = "STORE_CONTENT_CORRUPTED";
const char *STORE_INITIALIZE_STRING = "STORE_INITIALIZE";
const char *INIT_DONE_STRING = "INIT_DONE";
const char *DUMP_FINISHED_STRING = "DUMP_FINISHED";
const char *DELETION_FINISHED_STRING = "DELETION_FINISHED";
const char *DELETION_FAILED_STRING = "DELETION_FAILED";
const char *AUTO_CATALOGS_SENDING_FAILED_STRING = "AUTO_CATALOGS_SENDING_FAILED";
const char *GET_DATA_FAILED_STRING = "GET_DATA_FAILED";
const char *STORE_DATA_FAILED_STRING = "STORE_DATA_FAILED";
const char *DEVICE_BUILDING_COMMAND_FAILED_STRING = "DEVICE_BUILDING_COMMAND_FAILED";
const char *DEVICE_SENDING_COMMAND_FAILED_STRING = "DEVICE_SENDING_COMMAND_FAILED";
const char *DEVICE_REQUESTING_REPLY_FAILED_STRING = "DEVICE_REQUESTING_REPLY_FAILED";
const char *DEVICE_READING_REPLY_FAILED_STRING = "DEVICE_READING_REPLY_FAILED";
const char *DEVICE_INTERPRETING_REPLY_FAILED_STRING = "DEVICE_INTERPRETING_REPLY_FAILED";
const char *DEVICE_MISSED_REPLY_STRING = "DEVICE_MISSED_REPLY";
const char *DEVICE_UNKNOWN_REPLY_STRING = "DEVICE_UNKNOWN_REPLY";
const char *DEVICE_UNREQUESTED_REPLY_STRING = "DEVICE_UNREQUESTED_REPLY";
const char *INVALID_DEVICE_COMMAND_STRING = "INVALID_DEVICE_COMMAND";
const char *MONITORING_LIMIT_EXCEEDED_STRING = "MONITORING_LIMIT_EXCEEDED";
const char *MONITORING_AMBIGUOUS_STRING = "MONITORING_AMBIGUOUS";
const char *FUSE_CURRENT_HIGH_STRING = "FUSE_CURRENT_HIGH";
const char *FUSE_WENT_OFF_STRING = "FUSE_WENT_OFF";
const char *POWER_ABOVE_HIGH_LIMIT_STRING = "POWER_ABOVE_HIGH_LIMIT";
const char *POWER_BELOW_LOW_LIMIT_STRING = "POWER_BELOW_LOW_LIMIT";
const char *SWITCH_WENT_OFF_STRING = "SWITCH_WENT_OFF";
const char *HEATER_ON_STRING = "HEATER_ON";
const char *HEATER_OFF_STRING = "HEATER_OFF";
const char *HEATER_TIMEOUT_STRING = "HEATER_TIMEOUT";
const char *HEATER_STAYED_ON_STRING = "HEATER_STAYED_ON";
const char *HEATER_STAYED_OFF_STRING = "HEATER_STAYED_OFF";
const char *TEMP_SENSOR_HIGH_STRING = "TEMP_SENSOR_HIGH";
const char *TEMP_SENSOR_LOW_STRING = "TEMP_SENSOR_LOW";
const char *TEMP_SENSOR_GRADIENT_STRING = "TEMP_SENSOR_GRADIENT";
const char *COMPONENT_TEMP_LOW_STRING = "COMPONENT_TEMP_LOW";
const char *COMPONENT_TEMP_HIGH_STRING = "COMPONENT_TEMP_HIGH";
const char *COMPONENT_TEMP_OOL_LOW_STRING = "COMPONENT_TEMP_OOL_LOW";
const char *COMPONENT_TEMP_OOL_HIGH_STRING = "COMPONENT_TEMP_OOL_HIGH";
const char *TEMP_NOT_IN_OP_RANGE_STRING = "TEMP_NOT_IN_OP_RANGE";
const char *FDIR_CHANGED_STATE_STRING = "FDIR_CHANGED_STATE";
const char *FDIR_STARTS_RECOVERY_STRING = "FDIR_STARTS_RECOVERY";
const char *FDIR_TURNS_OFF_DEVICE_STRING = "FDIR_TURNS_OFF_DEVICE";
const char *MONITOR_CHANGED_STATE_STRING = "MONITOR_CHANGED_STATE";
const char *VALUE_BELOW_LOW_LIMIT_STRING = "VALUE_BELOW_LOW_LIMIT";
const char *VALUE_ABOVE_HIGH_LIMIT_STRING = "VALUE_ABOVE_HIGH_LIMIT";
const char *VALUE_OUT_OF_RANGE_STRING = "VALUE_OUT_OF_RANGE";
const char *SWITCHING_TM_FAILED_STRING = "SWITCHING_TM_FAILED";
const char *CHANGING_MODE_STRING = "CHANGING_MODE";
const char *MODE_INFO_STRING = "MODE_INFO";
const char *FALLBACK_FAILED_STRING = "FALLBACK_FAILED";
const char *MODE_TRANSITION_FAILED_STRING = "MODE_TRANSITION_FAILED";
const char *CANT_KEEP_MODE_STRING = "CANT_KEEP_MODE";
const char *OBJECT_IN_INVALID_MODE_STRING = "OBJECT_IN_INVALID_MODE";
const char *FORCING_MODE_STRING = "FORCING_MODE";
const char *MODE_CMD_REJECTED_STRING = "MODE_CMD_REJECTED";
const char *HEALTH_INFO_STRING = "HEALTH_INFO";
const char *CHILD_CHANGED_HEALTH_STRING = "CHILD_CHANGED_HEALTH";
const char *CHILD_PROBLEMS_STRING = "CHILD_PROBLEMS";
const char *OVERWRITING_HEALTH_STRING = "OVERWRITING_HEALTH";
const char *TRYING_RECOVERY_STRING = "TRYING_RECOVERY";
const char *RECOVERY_STEP_STRING = "RECOVERY_STEP";
const char *RECOVERY_DONE_STRING = "RECOVERY_DONE";
const char *RF_AVAILABLE_STRING = "RF_AVAILABLE";
const char *RF_LOST_STRING = "RF_LOST";
const char *BIT_LOCK_STRING = "BIT_LOCK";
const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST";
const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED";
const char *CLOCK_SET_STRING = "CLOCK_SET";
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
const char *TEST_STRING = "TEST";
const char * translateEvents(Event event) {
switch( (event & 0xffff) ) {
case(2200):
return STORE_SEND_WRITE_FAILED_STRING;
case(2201):
return STORE_WRITE_FAILED_STRING;
case(2202):
return STORE_SEND_READ_FAILED_STRING;
case(2203):
return STORE_READ_FAILED_STRING;
case(2204):
return UNEXPECTED_MSG_STRING;
case(2205):
return STORING_FAILED_STRING;
case(2206):
return TM_DUMP_FAILED_STRING;
case(2207):
return STORE_INIT_FAILED_STRING;
case(2208):
return STORE_INIT_EMPTY_STRING;
case(2209):
return STORE_CONTENT_CORRUPTED_STRING;
case(2210):
return STORE_INITIALIZE_STRING;
case(2211):
return INIT_DONE_STRING;
case(2212):
return DUMP_FINISHED_STRING;
case(2213):
return DELETION_FINISHED_STRING;
case(2214):
return DELETION_FAILED_STRING;
case(2215):
return AUTO_CATALOGS_SENDING_FAILED_STRING;
case(2600):
return GET_DATA_FAILED_STRING;
case(2601):
return STORE_DATA_FAILED_STRING;
case(2800):
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
case(2801):
return DEVICE_SENDING_COMMAND_FAILED_STRING;
case(2802):
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
case(2803):
return DEVICE_READING_REPLY_FAILED_STRING;
case(2804):
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
case(2805):
return DEVICE_MISSED_REPLY_STRING;
case(2806):
return DEVICE_UNKNOWN_REPLY_STRING;
case(2807):
return DEVICE_UNREQUESTED_REPLY_STRING;
case(2808):
return INVALID_DEVICE_COMMAND_STRING;
case(2809):
return MONITORING_LIMIT_EXCEEDED_STRING;
case(2810):
return MONITORING_AMBIGUOUS_STRING;
case(4201):
return FUSE_CURRENT_HIGH_STRING;
case(4202):
return FUSE_WENT_OFF_STRING;
case(4204):
return POWER_ABOVE_HIGH_LIMIT_STRING;
case(4205):
return POWER_BELOW_LOW_LIMIT_STRING;
case(4300):
return SWITCH_WENT_OFF_STRING;
case(5000):
return HEATER_ON_STRING;
case(5001):
return HEATER_OFF_STRING;
case(5002):
return HEATER_TIMEOUT_STRING;
case(5003):
return HEATER_STAYED_ON_STRING;
case(5004):
return HEATER_STAYED_OFF_STRING;
case(5200):
return TEMP_SENSOR_HIGH_STRING;
case(5201):
return TEMP_SENSOR_LOW_STRING;
case(5202):
return TEMP_SENSOR_GRADIENT_STRING;
case(5901):
return COMPONENT_TEMP_LOW_STRING;
case(5902):
return COMPONENT_TEMP_HIGH_STRING;
case(5903):
return COMPONENT_TEMP_OOL_LOW_STRING;
case(5904):
return COMPONENT_TEMP_OOL_HIGH_STRING;
case(5905):
return TEMP_NOT_IN_OP_RANGE_STRING;
case(7101):
return FDIR_CHANGED_STATE_STRING;
case(7102):
return FDIR_STARTS_RECOVERY_STRING;
case(7103):
return FDIR_TURNS_OFF_DEVICE_STRING;
case(7201):
return MONITOR_CHANGED_STATE_STRING;
case(7202):
return VALUE_BELOW_LOW_LIMIT_STRING;
case(7203):
return VALUE_ABOVE_HIGH_LIMIT_STRING;
case(7204):
return VALUE_OUT_OF_RANGE_STRING;
case(7301):
return SWITCHING_TM_FAILED_STRING;
case(7400):
return CHANGING_MODE_STRING;
case(7401):
return MODE_INFO_STRING;
case(7402):
return FALLBACK_FAILED_STRING;
case(7403):
return MODE_TRANSITION_FAILED_STRING;
case(7404):
return CANT_KEEP_MODE_STRING;
case(7405):
return OBJECT_IN_INVALID_MODE_STRING;
case(7406):
return FORCING_MODE_STRING;
case(7407):
return MODE_CMD_REJECTED_STRING;
case(7506):
return HEALTH_INFO_STRING;
case(7507):
return CHILD_CHANGED_HEALTH_STRING;
case(7508):
return CHILD_PROBLEMS_STRING;
case(7509):
return OVERWRITING_HEALTH_STRING;
case(7510):
return TRYING_RECOVERY_STRING;
case(7511):
return RECOVERY_STEP_STRING;
case(7512):
return RECOVERY_DONE_STRING;
case(7900):
return RF_AVAILABLE_STRING;
case(7901):
return RF_LOST_STRING;
case(7902):
return BIT_LOCK_STRING;
case(7903):
return BIT_LOCK_LOST_STRING;
case(7905):
return FRAME_PROCESSING_FAILED_STRING;
case(8900):
return CLOCK_SET_STRING;
case(8901):
return CLOCK_SET_FAILURE_STRING;
case(9700):
return TEST_STRING;
default:
return "UNKNOWN_EVENT";
}
return 0;
}

View File

@ -0,0 +1,8 @@
#ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_
#define FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_
#include <fsfw/events/Event.h>
const char * translateEvents(Event event);
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */

18
bsp_linux/Dockerfile Normal file
View File

@ -0,0 +1,18 @@
FROM ubuntu:latest
# FROM alpine:latest
RUN apt-get update && apt-get install -y cmake g++
# RUN apk add cmake make g++
WORKDIR /usr/src/app
COPY . .
RUN set -ex; \
rm -rf build-linux; \
mkdir build-linux; \
cd build-linux; \
cmake -DCMAKE_BUILD_TYPE=Release -DOS_FSFW=linux ..;
ENTRYPOINT ["cmake", "--build", "build-linux"]
CMD ["-j"]
# CMD ["bash"]

View File

@ -48,8 +48,7 @@ void ObjectFactory::produce() {
}
/* TMTC Reception via UDP socket */
auto tmtcBridge = new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE);
auto tmtcBridge = new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_DISTRIBUTOR);
tmtcBridge->setMaxNumberOfPacketsStored(20);
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
#endif /* OBSW_ADD_CORE_COMPONENTS == 1 */

View File

@ -0,0 +1,41 @@
# Specify the cross compiler version
# See: https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack
ARG XPM_ARM_XCOMPILER_VERSION_DEFAULT="10.2.1-1.1.2"
# Stage 0
# FROM node:current-alpine3.13
FROM node:latest
# Issues with XPM cross-compiler on alpine..
ARG XPM_ARM_XCOMPILER_VERSION_DEFAULT
ENV XPM_ARM_XCOMPILER_VERSION=$XPM_ARM_XCOMPILER_VERSION_DEFAULT
RUN npm install --global xpm@latest; \
xpm install --global @xpack-dev-tools/arm-none-eabi-gcc@${XPM_ARM_XCOMPILER_VERSION}
# Stage 1
FROM ubuntu:latest
# FROM alpine:latest
COPY --from=0 /root/.local/xPacks/@xpack-dev-tools /usr/tools/
ARG XPM_ARM_XCOMPILER_VERSION_DEFAULT
ENV XPM_ARM_XCOMPILER_VERSION=$XPM_ARM_XCOMPILER_VERSION_DEFAULT
RUN echo ${XPM_ARM_XCOMPILER_VERSION}
RUN apt-get update && apt-get install -y cmake g++
# RUN apk add cmake make g++
ENV PATH="/usr/tools/arm-none-eabi-gcc/${XPM_ARM_XCOMPILER_VERSION}/.content/bin:${PATH}"
WORKDIR /usr/src/app
COPY . .
RUN set -ex; \
rm -rf build-freertos; \
mkdir build-freertos; \
cd build-freertos; \
cmake -DCMAKE_BUILD_TYPE=Release -DOS_FSFW=freertos -DTGT_BSP=arm/stm32h743zi-nucleo ..;
ENTRYPOINT ["cmake", "--build", "build-freertos"]
CMD ["-j"]
# CMD ["bash"]

View File

@ -0,0 +1,98 @@
# BBB_ROOTFS should point to the local directory which contains all the
# libraries and includes from the target raspi.
# The following command can be used to do this, replace <ip-address> and the
# local <rootfs-path> accordingly:
# rsync -vR --progress -rl --delete-after --safe-links pi@<ip-address>:/{lib,usr,opt/vc/lib} <rootfs-path>
# RASPBIAN_ROOTFS needs to be passed to the CMake command or defined in the
# application CMakeLists.txt before loading the toolchain file.
# CROSS_COMPILE also needs to be set accordingly or passed to the CMake command
if(NOT DEFINED ENV{BBB_ROOTFS})
message(FATAL_ERROR
"Define the BBB_ROOTFS variable to point to the Beagle Bone Black rootfs."
)
else()
set(SYSROOT_PATH "$ENV{BBB_ROOTFS}")
message(STATUS "Beagle Bone Black sysroot: ${SYSROOT_PATH}")
endif()
if(NOT DEFINED ENV{CROSS_COMPILE})
set(CROSS_COMPILE "arm-linux-gnueabihf")
message(STATUS
"No CROSS_COMPILE environmental variable set, using default ARM linux "
"cross compiler name ${CROSS_COMPILE}"
)
else()
set(CROSS_COMPILE "$ENV{CROSS_COMPILE}")
message(STATUS
"Using environmental variable CROSS_COMPILE as cross-compiler: "
"$ENV{CROSS_COMPILE}"
)
endif()
message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc")
set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++")
set(CROSS_COMPILE_LD "${CROSS_COMPILE}-ld")
set(CROSS_COMPILE_AR "${CROSS_COMPILE}-ar")
set(CROSS_COMPILE_RANLIB "${CROSS_COMPILE}-ranlib")
set(CROSS_COMPILE_STRIP "${CROSS_COMPILE}-strip")
set(CROSS_COMPILE_NM "${CROSS_COMPILE}-nm")
set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy")
set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size")
# At the very least, cross compile gcc and g++ have to be set!
find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED)
find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED)
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
# Define name of the target system
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Define the compiler
set(CMAKE_C_COMPILER ${CROSS_COMPILE_CC})
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX})
# List of library dirs where LD has to look. Pass them directly through gcc.
# LD_LIBRARY_PATH is not evaluated by arm-*-ld
set(LIB_DIRS
"${SYSROOT_PATH}/lib/${CROSS_COMPILE}"
"${SYSROOT_PATH}/usr/local/lib"
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
"${SYSROOT_PATH}/usr/lib"
)
# You can additionally check the linker paths if you add the
# flags ' -Xlinker --verbose'
set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/include")
foreach(LIB ${LIB_DIRS})
set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}")
endforeach()
set(CMAKE_PREFIX_PATH
"${CMAKE_PREFIX_PATH}"
"${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
)
set(CMAKE_C_FLAGS
"-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard ${COMMON_FLAGS}"
CACHE STRING "Flags for Beagle Bone Black"
)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}"
CACHE STRING "Flags for Beagle Bone Black"
)
set(CMAKE_FIND_ROOT_PATH
"${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH};${CMAKE_SYSROOT}"
)
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -110,15 +110,19 @@ elseif(${OS_FSFW} STREQUAL linux AND TGT_BSP)
"$ENV{RASPBERRY_VERSION}"
)
endif()
if(LINUX_CROSS_COMPILE)
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_SCRIPT_PATH}/RPiCrossCompileConfig.cmake"
PARENT_SCOPE
)
endif()
elseif(${TGT_BSP} MATCHES "arm/beagleboneblack")
if(LINUX_CROSS_COMPILE)
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_SCRIPT_PATH}/RPiCrossCompileConfig.cmake"
PARENT_SCOPE
)
endif()
elseif(${TGT_BSP} MATCHES "arm/beagleboneblack")
if(LINUX_CROSS_COMPILE)
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_SCRIPT_PATH}/BBBCrossCompileConfig.cmake"
PARENT_SCOPE
)
endif()
else()
message(WARNING "Target BSP (TGT_BSP) ${TGT_BSP} unknown!")
endif()

View File

@ -0,0 +1,3 @@
export PATH=$PATH:"$HOME/beaglebone/<cross_compiler_path>/bin"
export CROSS_COMPILE="arm-linux-gnueabihf"
export BBB_ROOTFS="${HOME}/raspberrypi/rootfs"

View File

@ -0,0 +1,30 @@
#!/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/beagleboneblack"
build_generator=""
builddir="build-Debug-BBB"
defines="LINUX_CROSS_COMPILE=ON"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-l "${builddir}" -d "${defines}"

View File

@ -0,0 +1,30 @@
#!/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/beagleboneblack"
build_generator=""
builddir="build-Release-BBB"
defines="LINUX_CROSS_COMPILE=ON"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-l "${builddir}" -d "${defines}"

View File

@ -0,0 +1,30 @@
#!/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/beagleboneblack"
build_generator=""
builddir="build-Release-BBB"
defines="LINUX_CROSS_COMPILE=ON"
if [ "${OS}" = "Windows_NT" ]; then
build_generator="MinGW Makefiles"
# Could be other OS but this works for now.
else
build_generator="Unix Makefiles"
fi
python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-l "${builddir}" -d "${defines}"

View File

411
doc/README-bbb.md Normal file
View File

@ -0,0 +1,411 @@
<img align="center" src="./images/bbb/beagleboard-logo.png" width="30%">
<sub><sup>Image taken from [Beagle Board website](https://beagleboard.org/logo) and used in
accordance with their trademark rules.</sup></sub>
# Getting started on the Beagle Bone Black
The FSFW can be run on a Beagle Bone Black with the Linux OSAL, using
an ARM linux (cross) compiler. Instructions will be provided on how to do this.
## General Information
The following instructions will show how to build the example on the Beagle Bone Black directly.
It will also show how to cross-compile on a host machine and mirror the Beagle Bone sysroot folder
on the host machine so that the same libraries and headers used on the BBB are used
for the cross-compilation process.
Some Eclipse project files were provided as well to help with setting up the indexer in Eclipse
more quickly.
## Prerequisites for direct compilation and cross-compiling
1. SSH connection to the Beagle Bone Black working
2. Beagle Bone Black linux environment set up properly
3. `CMake` installed
## Setting up general prerequisites for Linux systems
1. Install CMake and rsync
```sh
sudo apt-get install cmake rsync
```
2. Configure the Beagle Bone Black Linux environment. The last section of the
[Linux README](README-linux.md#top) specifies how to set up a UNIX environment for the FSFW and
is also applicable to the Beagle Bone Black. SSH into the BBB and
follow the instructions in that section.
3. Install the `gpiod` library
```sh
sudo apt-get install gpiod libgpiod-dev
```
## Getting started on the Beagle Bone Black
Make sure to follow the steps above. Now you should be able to build the software on
the Beagle Bone Black. A ssh connection to the Raspberry Pi is assumed here
You can build the software with the following commands
```sh
mkdir build-Debug-BBB
cd build-Debug-BBB
cmake -DOS_FSFW=linux -DTGT_BSP=arm/beagleboneblack -DLINUX_CROSS_COMPILE=OFF -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j2
```
## Prerequisites for cross-compiling
These prerequisites are valid for Linux as well as Windows hosts.
1. ARM Linux cross compiler installed
2. Beagle Bone Black sysroot folder mirrored on the host machine, using `rsync`
3. gdb-multiarch installed on host for remote debugging or `tcf-agent` running on the BBB
## Cross-Compiling on a Linux Host
### Setting up prerequisites for cross-compiling
1. Install `CMake` and `rsync`
```
sudo apt-get install cmake rsync
```
2. Configure the Beagle Bone Black linux environment. The last section of the
[Linux REAMDE](README-linux.md#top) specifies how to set up a UNIX environment
for the FSFW and isalso applicable to the Raspberry Pi. SSH into the
Beagle Bone Black and follow the instructions in that section.
3. Install the correct [ARM Linux cross-compile toolchain](https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/).
provided by Linaro.
Test the toolchain by running:
```sh
arm-linux-gnueabihf-gcc --version
```
4. Set up a sysroot folder on the local host machine. Make sure the SSH connection to
the BBB is working without issues. Then perform the following steps
```sh
cd $HOME
mkdir beaglebone
cd beaglebone
mkdir rootfs
cd rootfs
pwd
```
Store the result of `pwd`, it is going to be used by `rsync` later.
Now use `rsync` to clone the BBB sysroot to the local host machine.
You can replace `<ip-address>` with `beaglebone.local` to use DNS.
Use the rootfs location stored from the previous steps as `<rootfs-path>`.
```sh
rsync -avHAXR --delete-after --info=progress2 --numeric-ids <user_name>@<ip_address>:/{usr,lib} <rootfs_path>
```
On Linux, it is recommended to repair some symlinks which can be problematic:
Navigate to the folder containing the symlinks first:
```sh
cd <rootfs_path>/usr/lib/arm-linux-gnueabihf
```
You can now use
```sh
readlink libpthread.so
```
which will show an absolute location of a shared library the symlinks points to. This location
needs to be converted into a relative path.
Run the following command to create a relative symlinks instead of an absolute ones. The pointed
to location might change to check it with `readlink` first before removing the symlinks:
```sh
rm libpthread.so
rm librt.so
ln -s ../../../lib/arm-linux-gnueabihf/libpthread.so.0 libpthread.so
ln -s ../../../lib/arm-linux-gnueabihf/librt.so.1 librt.so
```
For more information on issues which can occur when cloning the root filesystem,
see the [troubleshooting](#troubleshooting) section.
5. It is recommended to install `gdb-multiarch`. This tool will allow remote debugging on the host
computer. This is not required if the `tcf-agent` is used.
```sh
sudo apt-get install multiarch
```
6. Perform the steps [in the following chapter](#cross-test) to build the
software for the BBB and test it.
## Cross-Compiling on a Windows Host
### Additional Prerequites
1. [MSYS2](https://www.msys2.org/) installed. All command line steps shown here
were performed in the MSYS2 MinGW64 shell (not the default MSYS2, use MinGW64!).
Replace `<UserName>` with respectively. It is recommended to set up
aliases in the `.bashrc` file to allow quick navigation to the `fsfw_example`
repository and to run `git config --global core.autocrlf true` for git in
MinGW64.
### Setting up prerequisites for Windows
1. Install CMake and rsync in MinGW64 after installing MSYS2
```
pacman -S mingw-w64-x86_64-cmake rsync
```
2. Configure the Beagle Bone Black linux environment. The last section of the
[Linux REAMDE](README-linux.md#top) specifies how to set up a UNIX environment
for the FSFW and isalso applicable to the Raspberry Pi. SSH into the
Beagle Bone Black and follow the instructions in that section.
3. Install the correct [ARM Linux cross-compile toolchain](https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/).
provided by Linaro.
Test the toolchain by running:
```sh
arm-linux-gnueabihf-gcc --version
```
4. Set up a sysroot folder on the local host machine. Make sure the SSH connection to
the BBB is working without issues. Then perform the following steps
```sh
cd /c/Users/<UserName>
mkdir beaglebone
cd beaglebone
mkdir rootfs
cd rootfs
pwd
```
Store the result of `pwd`, it is going to be used by `rsync` later.
Now use rsync to clone the BBB sysroot to the local host machine.
You can replace `<ip-address>` with `beaglebone.local` to use DNS.
Use the rootfs location stored from the previous steps as `<rootfs-path>`.
```sh
rsync -avHAXR --numeric-ids --info=progress2 <username>@<ip-address>:/{lib,usr} <rootfs-path>
```
Please note that `rsync` sometimes does not copy shared libraries or symlinks properly,
which might result in errors when cross-compiling and cross-linking. It is recommended to run
the following commands in addition to the `rsync` command on Windows:
```sh
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/{libc.so.6,ld-linux-armhf.so.3,libm.so.6} <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/{libpthread.so,libc.so,librt.so} <rootfs_path>/usr/lib/arm-linux-gnueabihf
```
For more information on issues which can occur when cloning the root filesystem,
see the [troubleshooting](#troubleshooting) section.
5. It is recommended to install `gdb-multiarch`. This tool will allow remote debugging on the host
computer. Replace `x86_64` with the correct processor architecture for other architectures.
This is not required if the `tcf-agent` is used.
```sh
pacman -S mingw-w64-x86_64-gdb-multiarch
```
6. Perform the steps [in the following chapter](#cross-test) to build the
software for the BBB and test it.
## <a id="cross-test"></a> Testing the cross-compilation
It is recommended to set the following environmental variables for the CMake build:
- `CROSS_COMPILE`: Explicitely specify the name of the cross compiler
- `BBB_ROOTFS`: Explicitely set the path to the local BBB rootfs
For example with the following commands
```sh
export CROSS_COMPILE="arm-linux-gnueabihf"
```
It is recommended to test whether the environmental variables were set correctly,
for example by running
```sh
echo $BBB_ROOTFS
```
These variables can either be set every time before a debugging session to
keep the environment clean (should be done before starting Eclipse)
or permanently by adding the `export` commands to system files.
A helper script has been provided in `cmake/scripts/BBB` to perform
setting up the environment. The scripts need to be `source`d instead of
being run like regular shell scripts.
You can also set up the environmental variables permanently by adding the
export commands to the `.profile` or `.bashrc` file in the `$HOME` folder.
On Windows, MinGW64 was used to set up the build system, so you can use the
MinGW64 `.bashrc` file to do this. If you are using Eclipse to build
the software, Eclipse will have the system variables from Windows,
so it is recommended to either permanently set the three environmental
variables in the Windows system environmental variables or add them in
Eclipse. See the [Eclipse README](README-eclipse.md#top) for more information.
Now we can test whether everything was set up properly by compiling the example
and running it on the BBB via command line. Navigate into the `fsfw_example` folder first.
1. Build the software locally to test the cross-compilation process.
A debug build directory is created first.
```sh
mkdir build-Debug-BBB
cd build-Debug-BBB
```
2. Configure the build system. On Linux, run the following command:
```sh
cmake -G "Unix Makefiles" -DOS_FSFW=linux -DTGT_BSP=arm/beagleboneblack -DLINUX_CROSS_COMPILE=ON -DCMAKE_BUILD_TYPE=Debug ..
```
On Windows, replace `-G "Unix Makefiles"` with `-G "MinGW Makefiles"`.
Alternatively, you can use the helper shell scripts located inside `cmake/scripts/BBB/crosscompile`
or the Python helper script `cmake_build_config.py` inside the `cmake/scripts` folder.
The `BBB` folder also contains template shell files which can be `source`d
to quickly set up the environmental variables if you want to keep the system path clean.
3. Run the binary to test it
```sh
scp fsfw_example <username>@beaglebone.local:/home/fsfw_example
ssh <username>@beaglebone.local
./fsfw_example
```
### Setting up Eclipse for a BBB remote target
It is recommended to use the provided Eclipse project files and
launch configurations to have a starting point. See the specific section in
the [Eclipse README](README-eclipse.md#top) for information how to do this.
#### Windows
There are some additional steps necessary on Windows: The cross-compiler by
default is configured to look for the cross-compiler in `/opt/cross-pi-gcc/bin`.
The toolchain path needs to be corrected, for example like shown in the following image:
<img align="center" src="./images/eclipse/eclipse-cross-compile-win.png" width="50%">
## Setting up the TCF agent on the BBB
It is recommended to set up a [TCF agent](https://wiki.eclipse.org/TCF) for comfortable
Eclipse remote debugging. The following steps show how to setup the TCF agent
on the Raspberry Pi and add it to the auto-startup applications. The steps are taken
from [this guide](https://wiki.eclipse.org/TCF/Raspberry_Pi)
1. Install required packages on the RPi
```sh
sudo apt-get install git uuid uuid-dev libssl-dev
```
2. Clone the repository and perform some preparation steps
```sh
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git
cd org.eclipse.tcf.agent.git/agent
```
3. Build the TCF agent
```sh
make
```
and then test it by running
```sh
obj/GNU/Linux/arm/Debug/agent S
```
4. Finally install the agent for auto-start with the following steps. And set it up for
auto-start.
```sh
cd org.eclipse.tcf.agent/agent
make install
sudo make install INSTALLROOT=
sudo update-rc.d tcf-agent defaults
```
The [Eclipse README](README-eclipse.md#top) specifies how to perform remote
debugging using the TCF agent.
# <a id="troubleshooting"></a> Troubleshooting
## Cloning the root filesystem
There might be some issues with the pthread symbolic links.
Navigate to the folder containing the symlinks
```sh
cd <rootfs_path>/usr/lib/arm-linux-gnueabihf
```
Type `more libpthread`, press `TAB` and check whether the symbolic
link `libpthread.so` is shown. If it is not, we are going to set it up
manually to avoid issues when linking against `pthread` later.
Now you can find out where `libpthread.so` points with `readlink libpthread.so`.
This information is used to convert the absolute symlink to relative ones, for example with:
Run the following command to copy the symlink `libpthread.so.0` if it does not exist yet:
```sh
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/libpthread.so .
```
Alternatively, you can correct the symlinks to use relative paths, for example with:
```sh
ln -s ../../../lib/arm-linux-gnueabihf/libpthread.so.0 libpthread.so
ln -s ../../../lib/arm-linux-gnueabihf/librt.so.1 librt.so
```
Please note that there might also be issues with some symlinks or libraries not being copied
properly, especially on Windows. This has occured with files like `libc.so.6`.
If there are linker issues at a later stage, you can try to copy the symlinks manually from the
Linux board to the sysroot with `scp`.
For example, you can copy `libc.so.6` from the Linux board to the sysroot with
the following command
If there are issues with the cross-compilation process, manually copying the following
symlinks can help:
```sh
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/libc.so <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/libc.a <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/librt.a <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/librt.so <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/librt.so.1 <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/libpthread.so.0 <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/libc.so.6 <rootfs_path>/lib/arm-linux-gnueabihf
```
If any custom libraries are used which rely on symlinks, it might be necessary to copy them
or create them manually as well.

View File

@ -1,41 +1,43 @@
<img align="center" src="./images/rpi/RPi-Logo-Landscape-Reg-PRINT.png" width="30%">
<sub><sup>Image taken from [Raspberry Pi website](https://www.raspberrypi.org/trademark-rules/). Raspberry Pi is a trademark of the Raspberry Pi Foundation</sup></sub>
<sub><sup>Image taken from [Raspberry Pi website](https://www.raspberrypi.org/trademark-rules/).
Raspberry Pi is a trademark of the Raspberry Pi Foundation</sup></sub>
# Getting started on the Raspberry Pi
The FSFW can be run on a Raspberry Pi with the Linux OSAL, using
an ARM linux cross compiler. Instructions will be provided on how
an ARM linux (cross) compiler. Instructions will be provided on how
to do this.
## General Information
The following instructions will show how to install the cross compiler on
a host machine and mirror the Rapsberry Pi sysroot folder on the host machine
so that the same libraries and headers used on the Raspberry Pi are used
for the cross-compilation process. The provided Eclipse project files
and launch configurations also provide a starting point to perform
remote debugging on a Raspberry Pi, using a SSH connection.
The following instructions will show how to build the example on the Raspberry Pi directly.
It will also show how to cross-compile on a host machine and mirror the Raspberry Pi sysroot folder
on the host machine so that the same libraries and headers used on the RPi are used
for the cross-compilation process.
Some Eclipse project files were provided as well to help with setting up the indexer in Eclipse
more quickly.
## Prerequisites for direct compilation and cross-compiling
1. SSH connection to the Raspberry Pi working
2. Raspberry Pi linux environment set up properly
3. CMake and rsync installed
3. `CMake` installed
## Setting up general prerequisites for Linux systems
1. Install CMake and rsync
1. Install `CMake` and `rsync`
```sh
sudo apt-get install cmake rsync
```
2. Configure the Raspberry Pi Linux environment. The last section of the
[Linux REAMDE](README-linux.md#top) specifies how to set up a UNIX environment for the FSFW and is
also applicable to the Raspberry Pi. SSH into the Raspberry Pi and
[Linux README](README-linux.md#top) specifies how to set up a UNIX environment for the FSFW and
is also applicable to the Raspberry Pi. SSH into the Raspberry Pi and
follow the instructions in that section.
3. Install the `gpiod` library
```sh
@ -62,10 +64,8 @@ These prerequisites are valid for Linux as well as Windows hosts.
1. ARM Linux cross compiler installed
2. Raspberry Pi sysroot folder mirrored on the host machine, using `rsync`
3. gdb-multiarch installed on host for remote debugging or TCF agent running on Raspberry Pi
3. gdb-multiarch installed on host for remote debugging or `tcf-agent` running on Raspberry Pi
## Cross-Compiling on a Linux Host
Steps tested for Ubuntu 20.04. Adapt accordingly for used Linux distribution.
@ -76,7 +76,6 @@ based on Debian buster is used. If this is not the case, it is recommended to
follow the steps in the stackoverflow post above and to make sure that the
toolchain binaries are added to the path accordingly.
### Setting up prerequisites for cross-compiling
1. Install the pre-built ARM cross-compile with the following command
@ -84,31 +83,36 @@ toolchain binaries are added to the path accordingly.
```sh
wget https://github.com/Pro/raspi-toolchain/releases/latest/download/raspi-toolchain.tar.gz
```
Please note that this version of the toolchain might become obsolete in the future.
If another toolchain installation is used, it is still recommended to unpack the toolchain in the
`/opt/cross-pi-gcc` folder so that the Eclipse configuration and helper
scripts work without adaptions. Add the folder to the system path. On Linux,
this can generally be done with the following command
```sh
export PATH=$PATH:"/opt/cross-pi-gcc/bin"
```
You can add this line to the `.bashrc` or `.profile` file in the `$HOME` directory
to add environmental variables permanently. More experienced users can
perform this step is a shell script which is `source`d to keep the environment clean.
Test the toolchain with the following command
```sh
arm-linux-gnueabihf-gcc --version
```
Then extract to the opt folder:
```sh
sudo tar xfz raspi-toolchain.tar.gz --strip-components=1 -C /opt
```
Please note that this version of the toolchain might become obsolete in the future.
If another toolchain installation is used, it is still recommended to unpack the toolchain in the
`/opt/cross-pi-gcc` folder so that the Eclipse configuration and helper
scripts work without adaptions. Add the folder to the system path. On Linux,
this can generally be done with the following command
```sh
export PATH=$PATH:"/opt/cross-pi-gcc/bin"
```
You can add this line to the `.bashrc` or `.profile` file in the `$HOME` directory
to add environmental variables permanently. More experienced users can
perform this step is a shell script which is `source`d to keep the environment clean.
Test the toolchain with the following command
```sh
arm-linux-gnueabihf-gcc --version
```
2. Set up a sysroot folder on the local host machine. Make sure the SSH connection to
the Raspberry Pi is working without issues. Then perform the following steps
```sh
cd ~
mkdir raspberrypi
@ -117,39 +121,56 @@ toolchain binaries are added to the path accordingly.
cd rootfs
pwd
```
The result of the `pwd` command will be used later to sync the root file
system of the Raspberry Pi to the host machine.
With a Raspberry Pi 4, you can replace `<ip-address>` with `raspberrypi.local` and
when using the default rootfs path, you can replace `<rootfs-path>` with
`$HOME/raspberrypi/rootfs`.
```sh
rsync -vR --progress -rl --delete-after --safe-links pi@<ip-address>:/{lib,usr,opt/vc/lib} <rootfs-path>
rsync -avHAXR --numeric-ids --info=progress2 <username>@<ip-address>:/{lib,usr,opt/vc/lib} <rootfs-path>
```
Please note that there might be issues with some symlinks or libraries not being copied properly.
This has occured with files like `libc.so.6`. If there are linker issues at a later stage,
you can try to rerun `rsync` without the`--safe-links` flag or copy the shared libraries or
symlinks manually from the Raspberry Pi to the sysroot with `scp`.
For example, you can copy `libc.so.6` from the Raspberry Pi to the sysroot with
the following command
On Linux, it is recommended to repair some symlinks which can be problematic:
Navigate to the folder containing the symlinks first:
```sh
scp pi@<ip-address>:lib/arm-linux-gnueabihf/lib.so.6 <rootfs-path>/lib/arm-linux-gnueabihf
cd <rootfs_path>/usr/lib/arm-linux-gnueabihf
```
You can now use
```sh
readlink libpthread.so
```
which will show an absolute location of a shared library the symlinks points to. This location
needs to be converted into a relative path.
Run the following command to create a relative symlinks instead of an absolute ones. The pointed
to location might change to check it with `readlink` first before removing the symlinks:
```sh
rm libpthread.so
rm librt.so
ln -s ../../../lib/arm-linux-gnueabihf/libpthread.so.0 libpthread.so
ln -s ../../../lib/arm-linux-gnueabihf/librt.so.1 librt.so
```
For more information on issues which can occur when cloning the root filesystem,
see the [troubleshooting](#troubleshooting) section.
3. It is recommended to install `gdb-multiarch`. This tool will allow remote debugging
on the host computer. You don't need to do this if the TCF agent is used.
on the host computer. This step is not required if the `tcf-agent` is used.
```sh
sudo apt-get install gdb-multiarch
```
4. Perform the steps [in the cross-compile section](#cross-test) to build the
software for the Raspberry Pi and test it.
## Cross-Compiling on a Windows Host
### Additional Prerequites
@ -168,7 +189,7 @@ toolchain binaries are added to the path accordingly.
```
pacman -S mingw-w64-x86_64-cmake rsync
```
2. Configure the Raspberry Pi linux environment. The last section of the
[Linux REAMDE](README-linux.md#top) specifies how to set up a UNIX environment
for the FSFW and isalso applicable to the Raspberry Pi. SSH into the
@ -178,14 +199,14 @@ toolchain binaries are added to the path accordingly.
You can find out the distribution release of your Raspberry Pi by running `cat /etc/rpi-issue`.
Test the toolchain by running:
```sh
arm-linux-gnueabihf-gcc --version
```
4. Set up a sysroot folder on the local host machine. Make sure the SSH connection to
the Raspberry Pi is working without issues. Then perform the following steps
```sh
cd /c/Users/<UserName>
mkdir raspberrypi
@ -194,81 +215,62 @@ toolchain binaries are added to the path accordingly.
cd rootfs
pwd
```
Store the result of `pwd`, it is going to be used by `rsync` later.
Now use rsync to clone the Rapsberry Pi sysroot to the local host machine.
With a Raspberry Pi 4, you can replace `<ip-address>` with `raspberrypi.local`.
Use the rootfs location stored from the previous steps as `<rootfs-path>`.
```sh
rsync -vR --progress -rl --delete-after --safe-links pi@<ip-address>:/{lib,usr,opt/vc/lib} <rootfs-path>
```
5. There might be some issues with the pthread symbolic links. Navigate to the folder
containing the symlinks
Please note that `rsync` sometimes does not copy shared libraries or symlinks properly,
which might result in errors when cross-compiling and cross-linking. It is recommended to run
the following commands in addition to the `rsync` command on Windows:
```sh
cd /c/User/<UserName>/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/{libc.so.6,ld-linux-armhf.so.3,libm.so.6} <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/{libpthread.so,libc.so,librt.so} <rootfs_path>/usr/lib/arm-linux-gnueabihf
```
Type `more libpthread`, press `TAB` and check whether the symbolic
link `libpthread.so` is shown. If it is not, we are going to set it up
manually to avoid issues when linking against `pthread` later.
Run the following command to create a symlink to `libpthread.so.0`
```sh
ln -s ../../../lib/arm-linux-gnueabihf/libpthread.so.0 libpthread.so
```
Please note that there might also be issues with some symlinks or libraries not being copied
properly. This has occured with files like `libc.so.6`. If there are linker issues at a later
stage, you can try to rerun `rsync` without `--safe-links` or copy the shared libraries or
symlinks manually from the Raspberry Pi to the sysroot with `scp`.
For example, you can copy `libc.so.6` from the Raspberry Pi to the sysroot with
the following command
```sh
scp pi@<ip-address>:lib/arm-linux-gnueabihf/lib.so.6 <rootfs-path>/lib/arm-linux-gnueabihf
```
6. It is recommended to install `gdb-multiarch`.
This tool will allow remote debugging on the host computer. Replace
`x86_64` with the correct processor architecture for other architectures.
For more information on issues which can occur when cloning the root filesystem,
see the [troubleshooting](#troubleshooting) section.
5. It is recommended to install `gdb-multiarch`. This tool will allow remote debugging on the host
computer. Replace `x86_64` with the correct processor architecture for other architectures.
This is not required if the `tcf-agent` is used.
```sh
pacman -S mingw-w64-x86_64-gdb-multiarch
```
7. Perform the steps [in the following chapter](#cross-test) to build the
6. Perform the steps [in the following chapter](#cross-test) to build the
software for the Raspberry Pi and test it.
## <a id="cross-test"></a> Testing the cross-compilation
It is recommended to set the following environmental variables for the CMake build:
- `CROSS_COMPILE`: Explicitely specify the name of the cross compiler
- `RASPBERRY_VERSION`: Explicitely specify the version of the Raspberry Pi
- `RASPBIAN_ROOTFS`: Explicitely set the path to the local RPi rootfs
For example with the following commands
```sh
export CROSS_COMPILE="arm-linux-gnueabihf"
export RASPBERRY_VERSION="4"
export RASPBIAN_ROOTFS="<pathToRootFS>"
```
It is recommended to test whether the environmental variables were set correctly,
for example by running
```sh
echo $RASPBIAN_ROOTFS
```
These variables can either be set every time before a debugging session to
keep the environment clean (should be done before starting Eclipse)
or permanently by adding the `export` commands to system files.
@ -285,32 +287,32 @@ the software, Eclipse will have the system variables from Windows,
so it is recommended to either permanently set the three environmental
variables in the Windows system environmental variables or add them in
Eclipse. See the [Eclipse README](README-eclipse.md#top) for more information.
Now we can test whether everything was set up properly by compiling the example
and running it on the Raspberry Pi via command line.
Navigate into the `fsfw_example` folder first.
1. Build the software locally to test the cross-compilation process.
We are going to create a Debug build directory first.
```sh
mkdir build-Debug-RPi
cd build-Debug-RPi
```
2. Configure the build system. On Linux, run the following command:
```sh
cmake -G "Unix Makefiles" -DOS_FSFW=linux -DTGT_BSP=arm/raspberrypi -DLINUX_CROSS_COMPILE=ON -DCMAKE_BUILD_TYPE=Debug ..
```
On Windows, replace `-G "Unix Makefiles"` with `-G "MinGW Makefiles"`.
Alternatively, you can use the helper shell scripts located inside `cmake/scripts/RPi/crosscompile`
or the Python helper script `cmake_build_config.py` inside the `cmake/scripts` folder.
The `RPi` folder also contains template shell files which can be `source`d
to quickly set up the environmental variables if you want to keep the system path clean.
3. Run the binary to test it
```sh
@ -318,13 +320,13 @@ Navigate into the `fsfw_example` folder first.
ssh pi@raspberrypi.local
./fsfw_example
```
### Setting up Eclipse for a Raspberry Pi remote target
It is recommended to use the provided Eclipse project files and
launch configurations to have a starting point. See the specific section in
the [Eclipse README](README-eclipse.md#top) for information how to do this.
#### Windows
There are some additional steps necessary on Windows: The cross-compiler by
@ -333,7 +335,6 @@ The toolchain path needs to be corrected, for example like shown in the followin
<img align="center" src="./images/eclipse/eclipse-cross-compile-win.png" width="50%">
## Setting up the TCF agent on the Raspberry Pi
It is recommended to set up a [TCF agent](https://wiki.eclipse.org/TCF) for comfortable
@ -346,28 +347,27 @@ from [this guide](https://wiki.eclipse.org/TCF/Raspberry_Pi)
```sh
sudo apt-get install git uuid uuid-dev libssl-dev
```
2. Clone the repository and perform some preparation steps
```sh
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git
cd org.eclipse.tcf.agent.git/agent
cp -R machine/arm machine/armv6l
```
3. Build the TCF agent
```sh
make
```
and then test it by running
```sh
obj/GNU/Linux/armv6l/Debug/agent S
obj/GNU/Linux/arm/Debug/agent S
```
4. Finally instal lthe agent for auto-start with the following steps. The last step
did not work on a Rapsberry Pi 4, but apparentely was not necessary.
4. Finally instal lthe agent for auto-start with the following steps and set it up for auto-start.
The last step did not work on a Rapsberry Pi 4, but apparentely was not necessary.
```sh
cd org.eclipse.tcf.agent/agent
make install
@ -375,6 +375,63 @@ from [this guide](https://wiki.eclipse.org/TCF/Raspberry_Pi)
sudo update-rc.d tcf-agent defaults
sudo update-rc.d tcf-agent enable 2
```
The [Eclipse README](README-eclipse.md#top) specifies how to perform remote
debugging using the TCF agent.
# <a id="troubleshooting"></a> Troubleshooting
## Cloning the root filesystem
There might be some issues with the pthread symbolic links.
Navigate to the folder containing the symlinks
```sh
cd <rootfs_path>/usr/lib/arm-linux-gnueabihf
```
Type `more libpthread`, press `TAB` and check whether the symbolic
link `libpthread.so` is shown. If it is not, we are going to set it up
manually to avoid issues when linking against `pthread` later.
Now you can find out where `libpthread.so` points with `readlink libpthread.so`.
This information is used to convert the absolute symlink to relative ones, for example with:
Run the following command to copy the symlink `libpthread.so.0` if it does not exist yet:
```sh
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/libpthread.so .
```
Alternatively, you can correct the symlinks to use relative paths, for example with:
```sh
ln -s ../../../lib/arm-linux-gnueabihf/libpthread.so.0 libpthread.so
ln -s ../../../lib/arm-linux-gnueabihf/librt.so.1 librt.so
```
Please note that there might also be issues with some symlinks or libraries not being copied
properly, especially on Windows. This has occured with files like `libc.so.6`.
If there are linker issues at a later stage, you can try to copy the symlinks manually from the
Linux board to the sysroot with `scp`.
For example, you can copy `libc.so.6` from the Linux board to the sysroot with
the following command
If there are issues with the cross-compilation process, manually copying the following
symlinks can help:
```sh
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/libc.so <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/libc.a <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/librt.a <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/usr/lib/arm-linux-gnueabihf/librt.so <rootfs_path>/usr/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/librt.so.1 <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/libpthread.so.0 <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 <rootfs_path>/lib/arm-linux-gnueabihf
scp <user_name>@<ip-address>:/lib/arm-linux-gnueabihf/libc.so.6 <rootfs_path>/lib/arm-linux-gnueabihf
```
If any custom libraries are used which rely on symlinks, it might be necessary to copy them
or create them manually as well.

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

17
docker-compose.yml Normal file
View File

@ -0,0 +1,17 @@
version: "3.8"
services:
build-linux:
build:
context: .
dockerfile: bsp_linux/Dockerfile
build-host:
build:
context: .
dockerfile: bsp_hosted/Dockerfile
build-freertos:
build:
context: .
dockerfile: bsp_stm32_freertos/Dockerfile

2
fsfw

@ -1 +1 @@
Subproject commit 097244bf8b429d1b107343a3dbd77fa537a9c86d
Subproject commit f3d9fb645ea5f4dfdf8b1d8aafe542ff8bbbefd6

@ -1 +1 @@
Subproject commit a4f5e783e1d0452321559c1d612ef0add868d47c
Subproject commit d801319c12713d08cbdbc571ee2a922ce2f0c851

16
generators/definitions.py Normal file
View File

@ -0,0 +1,16 @@
import enum
class BspSelect(enum.Enum):
BSP_HOSTED = enum.auto()
BSP_LINUX = enum.auto()
BSP_STM32_FREERTOS = enum.auto()
BSP_STM32_RTEMS = enum.auto()
BspFolderDict = {
BspSelect.BSP_HOSTED.value: "bsp_hosted",
BspSelect.BSP_LINUX.value: "bsp_linux",
BspSelect.BSP_STM32_FREERTOS.value: "bsp_stm32_freertos",
BspSelect.BSP_STM32_RTEMS.value: "bsp_stm32_rtems",
}

View File

@ -0,0 +1,92 @@
#! /usr/bin/python3
"""
@file event_parser.py
@brief Part of the Mission Information Base Exporter for the SOURCE project by KSat.
@details
Event exporter.
To use MySQLdb, run pip install mysqlclient or install in IDE.
On Windows, Build Tools installation might be necessary
@data 21.11.2019
"""
import datetime
from modgen.events.event_parser import handle_csv_export, handle_cpp_export, SubsystemDefinitionParser, EventParser
from modgen.parserbase.file_list_parser import FileListParser
from modgen.utility.mib_printer import PrettyPrinter
from definitions import BspSelect, BspFolderDict
from utility.mib_file_management import copy_file, move_file
# TODO: Ask from user or store in json file?
BSP_SELECT = BspSelect.BSP_HOSTED.value
BSP_FOLDER = BspFolderDict[BSP_SELECT]
DATE_TODAY = datetime.datetime.now()
DATE_STRING_FULL = DATE_TODAY.strftime("%Y-%m-%d %H:%M:%S")
GENERATE_CPP = True
GENERATE_CPP_H = True
GENERATE_CSV = True
COPY_CPP_FILE = True
COPY_CPP_H_FILE = True
MOVE_CSV_FILE = True
PARSE_HOST_BSP = True
CSV_FILENAME = "mib_events.csv"
CSV_MOVE_DESTINATION = "../"
CPP_FILENAME = "translateEvents.cpp"
CPP_H_FILENAME = "translateEvents.h"
CPP_COPY_DESTINATION = f"../../{BSP_FOLDER}/fsfwconfig/events/"
FILE_SEPARATOR = ";"
SUBSYSTEM_DEFINITION_DESTINATIONS = [
f"../../{BSP_FOLDER}/fsfwconfig/events/subsystemIdRanges.h",
"../../fsfw/events/fwSubsystemIdRanges.h"
]
HEADER_DEFINITION_DESTINATIONS = ["../../mission/", "../../fsfw/", f"../../{BSP_FOLDER}", "../../test/"]
def main():
print("EventParser: Parsing events: ")
event_list = parse_events()
if GENERATE_CSV:
handle_csv_export(file_name=CSV_FILENAME, event_list=event_list, file_separator=FILE_SEPARATOR)
if MOVE_CSV_FILE:
move_file(file_name=CSV_FILENAME, destination=CSV_MOVE_DESTINATION)
if GENERATE_CPP:
handle_cpp_export(
event_list=event_list, date_string=DATE_STRING_FULL, file_name=CPP_FILENAME,
generate_header=GENERATE_CPP_H, header_file_name=CPP_H_FILENAME
)
if COPY_CPP_FILE:
print(f"EventParser: Copying file to {CPP_COPY_DESTINATION}")
copy_file(CPP_FILENAME, CPP_COPY_DESTINATION)
copy_file(CPP_H_FILENAME, CPP_COPY_DESTINATION)
print("")
def parse_events():
subsystem_parser = SubsystemDefinitionParser(SUBSYSTEM_DEFINITION_DESTINATIONS)
subsystem_table = subsystem_parser.parse_files()
print(f"Found {len(subsystem_table)} subsystem definitions.")
PrettyPrinter.pprint(subsystem_table)
event_header_parser = FileListParser(HEADER_DEFINITION_DESTINATIONS)
event_headers = event_header_parser.parse_header_files(
True, "Parsing event header file list:\n", True
)
# PrettyPrinter.pprint(event_headers)
# myEventList = parseHeaderFiles(subsystem_table, event_headers)
event_parser = EventParser(event_headers, subsystem_table)
event_parser.set_moving_window_mode(moving_window_size=7)
event_table = event_parser.parse_files()
list_items = sorted(event_table.items())
print(f"Found {len(list_items)} entries:")
PrettyPrinter.pprint(list_items)
return list_items
if __name__ == "__main__":
main()

View File

@ -1,223 +0,0 @@
#! /usr/bin/python3.8
"""
@file mib_events.py
@brief Part of the Mission Information Base Exporter for the SOURCE project by KSat.
@details
Event exporter.
To use MySQLdb, run pip install mysqlclient or install in IDE.
On Windows, Build Tools installation might be necessary
@data 21.11.2019
"""
import re
import datetime
from parserbase.mib_file_list_parser import FileListParser
from parserbase.mib_parser import FileParser
from utility.mib_printer import PrettyPrinter
from utility.mib_file_management import copy_file, move_file
DATE_TODAY = datetime.datetime.now()
DATE_STRING_FULL = DATE_TODAY.strftime("%Y-%m-%d %H:%M:%S")
GENERATE_CPP = True
GENERATE_CSV = True
COPY_CPP_FILE = True
MOVE_CSV_FILE = True
CSV_FILENAME = "mib_events.csv"
CSV_MOVE_DESTINATION = "../"
CPP_FILENAME = "translateEvents.cpp"
CPP_COPY_DESTINATION = "../../config/events/"
FILE_SEPARATOR = ";"
SUBSYSTEM_DEFINITION_DESTINATIONS = ["../../config/tmtc/subsystemIdRanges.h",
"../../fsfw/events/fwSubsystemIdRanges.h"]
HEADER_DEFINITION_DESTINATIONS = ["../../mission/", "../../fsfw/"]
def main():
print("EventParser: Parsing events: ")
event_list = parse_events()
if GENERATE_CSV:
handle_csv_export(CSV_FILENAME, event_list)
if MOVE_CSV_FILE:
move_file(CSV_FILENAME, CSV_MOVE_DESTINATION)
if GENERATE_CPP:
handle_cpp_export(CPP_FILENAME, event_list)
if COPY_CPP_FILE:
print("EventParser: Copying file to " + CPP_COPY_DESTINATION)
copy_file(CPP_FILENAME, CPP_COPY_DESTINATION)
print("")
def parse_events():
subsystem_parser = SubsystemDefinitionParser(SUBSYSTEM_DEFINITION_DESTINATIONS)
subsystem_table = subsystem_parser.parse_files()
print("Found " + str(len(subsystem_table)) + " subsystem definitions.")
PrettyPrinter.pprint(subsystem_table)
event_header_parser = FileListParser(HEADER_DEFINITION_DESTINATIONS)
event_headers = event_header_parser.parse_header_files(
True, "Parsing event header file list:\n", True)
# g.PP.pprint(event_headers)
# myEventList = parseHeaderFiles(subsystem_table, event_headers)
event_parser = EventParser(event_headers, subsystem_table)
event_table = event_parser.parse_files()
list_items = sorted(event_table.items())
print("Found " + str(len(list_items)) + " entries:")
PrettyPrinter.pprint(list_items)
return list_items
class SubsystemDefinitionParser(FileParser):
def __init__(self, file_list):
super().__init__(file_list)
def _handle_file_parsing(self, file_name: str, *args, **kwargs):
file = open(file_name, "r")
for line in file.readlines():
match = re.search(r'([A-Z0-9_]*) = ([0-9]{1,2})', line)
if match:
self.mib_table.update({match.group(1): [match.group(2)]})
def _post_parsing_operation(self):
pass
class EventParser(FileParser):
def __init__(self, file_list, interface_list):
super().__init__(file_list)
self.interfaces = interface_list
self.count = 0
self.myId = 0
self.currentId = 0
self.last_lines = ["", "", ""]
def _handle_file_parsing(self, file_name: str, *args: any, **kwargs):
try:
file = open(file_name, 'r', encoding='utf-8')
all_lines = file.readlines()
except UnicodeDecodeError:
file = open(file_name, 'r', encoding='cp1252')
all_lines = file.readlines()
total_count = 0
for line in all_lines:
self.__handle_line_reading(line, file_name)
if self.count > 0:
print("File " + file_name + " contained " + str(self.count) + " events.")
total_count += self.count
self.count = 0
def _post_parsing_operation(self):
pass
def __handle_line_reading(self, line, file_name):
if not self.last_lines[0] == '\n':
twolines = self.last_lines[0] + ' ' + line.strip()
else:
twolines = ''
match1 = re.search('SUBSYSTEM_ID[\s]*=[\s]*SUBSYSTEM_ID::([A-Z_0-9]*);', twolines)
if match1:
self.currentId = self.interfaces[match1.group(1)][0]
# print( "Current ID: " + str(currentId) )
self.myId = self.return_number_from_string(self.currentId)
match = re.search(
'(//)?[\t ]*static const(?:expr)? Event[\s]*([A-Z_0-9]*)[\s]*=[\s]*'
'MAKE_EVENT\(([0-9]{1,2}),[\s]*SEVERITY::([A-Z]*)\);[\t ]*(//!<)?([^\n]*)', twolines)
if match:
if match.group(1):
self.last_lines[0] = line
return
description = " "
if match.group(6):
description = self.clean_up_description(match.group(6))
string_to_add = match.group(2)
full_id = (self.myId * 100) + self.return_number_from_string(match.group(3))
severity = match.group(4)
if full_id in self.mib_table:
# print("EventParser: Duplicate Event " + hex(full_id) + " from " + file_name +
# " was already in " + self.mib_table[full_id][3])
pass
self.mib_table.update({full_id: (string_to_add, severity, description, file_name)})
self.count = self.count + 1
self.last_lines[0] = line
def build_checked_string(self, first_part, second_part):
my_str = first_part + self.convert(second_part)
if len(my_str) > 16:
print("EventParser: Entry: " + my_str + " too long. Will truncate.")
my_str = my_str[0:14]
# else:
# print( "Entry: " + myStr + " is all right.")
return my_str
@staticmethod
def return_number_from_string(a_string):
if a_string.startswith('0x'):
return int(a_string, 16)
elif a_string.isdigit():
return int(a_string)
else:
print('EventParser: Illegal number representation: ' + a_string)
return 0
@staticmethod
def convert(name):
single_strings = name.split('_')
new_string = ''
for one_string in single_strings:
one_string = one_string.lower()
one_string = one_string.capitalize()
new_string = new_string + one_string
return new_string
@staticmethod
def clean_up_description(description):
description = description.lstrip('//!<>')
description = description.lstrip()
if description == '':
description = ' '
return description
def export_to_file(filename, list_of_entries):
print("EventParser: Exporting to file: " + filename)
file = open(filename, "w")
for entry in list_of_entries:
file.write(str(entry[0]) + FILE_SEPARATOR + entry[1][0] + FILE_SEPARATOR + entry[1][1]
+ FILE_SEPARATOR + entry[1][2] + FILE_SEPARATOR + entry[1][3] + '\n')
file.close()
return
def write_translation_file(filename, list_of_entries):
outputfile = open(filename, "w")
definitions = ""
function = "const char * translateEvents(Event event){\n\tswitch((event&0xFFFF)){\n"
for entry in list_of_entries:
definitions += "const char *" + entry[1][0] + "_STRING = \"" + entry[1][0] + "\";\n"
function += "\t\tcase " + str(entry[0]) + ":\n\t\t\treturn " + entry[1][0] + "_STRING;\n"
function += '\t\tdefault:\n\t\t\treturn "UNKNOWN_EVENT";\n'
outputfile.write("/**\n * @brief Auto-generated event translation file. "
"Contains " + str(len(list_of_entries)) + " translations.\n"
" * Generated on: " + DATE_STRING_FULL +
" \n */\n")
outputfile.write("#include \"translateEvents.h\"\n\n")
outputfile.write(definitions + "\n" + function + "\t}\n\treturn 0;\n}\n")
outputfile.close()
def handle_csv_export(file_name: str, list_items: list):
"""
Generates the CSV in the same directory as the .py file and copes the CSV to another
directory if specified.
"""
export_to_file(file_name, list_items)
def handle_cpp_export(file_name: str, list_items):
print("EventParser: Generating translation cpp file.")
write_translation_file(file_name, list_items)
if __name__ == "__main__":
main()

View File

@ -1,6 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 78 translations.
* Generated on: 2020-09-30 15:17:26
* @details
* Generated on: 2021-05-14 11:51:26
*/
#include "translateEvents.h"
@ -83,166 +84,166 @@ const char *CLOCK_SET_STRING = "CLOCK_SET";
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
const char *TEST_STRING = "TEST";
const char * translateEvents(Event event){
switch((event&0xFFFF)){
case 2200:
return STORE_SEND_WRITE_FAILED_STRING;
case 2201:
return STORE_WRITE_FAILED_STRING;
case 2202:
return STORE_SEND_READ_FAILED_STRING;
case 2203:
return STORE_READ_FAILED_STRING;
case 2204:
return UNEXPECTED_MSG_STRING;
case 2205:
return STORING_FAILED_STRING;
case 2206:
return TM_DUMP_FAILED_STRING;
case 2207:
return STORE_INIT_FAILED_STRING;
case 2208:
return STORE_INIT_EMPTY_STRING;
case 2209:
return STORE_CONTENT_CORRUPTED_STRING;
case 2210:
return STORE_INITIALIZE_STRING;
case 2211:
return INIT_DONE_STRING;
case 2212:
return DUMP_FINISHED_STRING;
case 2213:
return DELETION_FINISHED_STRING;
case 2214:
return DELETION_FAILED_STRING;
case 2215:
return AUTO_CATALOGS_SENDING_FAILED_STRING;
case 2600:
return GET_DATA_FAILED_STRING;
case 2601:
return STORE_DATA_FAILED_STRING;
case 2800:
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
case 2801:
return DEVICE_SENDING_COMMAND_FAILED_STRING;
case 2802:
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
case 2803:
return DEVICE_READING_REPLY_FAILED_STRING;
case 2804:
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
case 2805:
return DEVICE_MISSED_REPLY_STRING;
case 2806:
return DEVICE_UNKNOWN_REPLY_STRING;
case 2807:
return DEVICE_UNREQUESTED_REPLY_STRING;
case 2808:
return INVALID_DEVICE_COMMAND_STRING;
case 2809:
return MONITORING_LIMIT_EXCEEDED_STRING;
case 2810:
return MONITORING_AMBIGUOUS_STRING;
case 4201:
return FUSE_CURRENT_HIGH_STRING;
case 4202:
return FUSE_WENT_OFF_STRING;
case 4204:
return POWER_ABOVE_HIGH_LIMIT_STRING;
case 4205:
return POWER_BELOW_LOW_LIMIT_STRING;
case 4300:
return SWITCH_WENT_OFF_STRING;
case 5000:
return HEATER_ON_STRING;
case 5001:
return HEATER_OFF_STRING;
case 5002:
return HEATER_TIMEOUT_STRING;
case 5003:
return HEATER_STAYED_ON_STRING;
case 5004:
return HEATER_STAYED_OFF_STRING;
case 5200:
return TEMP_SENSOR_HIGH_STRING;
case 5201:
return TEMP_SENSOR_LOW_STRING;
case 5202:
return TEMP_SENSOR_GRADIENT_STRING;
case 5901:
return COMPONENT_TEMP_LOW_STRING;
case 5902:
return COMPONENT_TEMP_HIGH_STRING;
case 5903:
return COMPONENT_TEMP_OOL_LOW_STRING;
case 5904:
return COMPONENT_TEMP_OOL_HIGH_STRING;
case 5905:
return TEMP_NOT_IN_OP_RANGE_STRING;
case 7101:
return FDIR_CHANGED_STATE_STRING;
case 7102:
return FDIR_STARTS_RECOVERY_STRING;
case 7103:
return FDIR_TURNS_OFF_DEVICE_STRING;
case 7201:
return MONITOR_CHANGED_STATE_STRING;
case 7202:
return VALUE_BELOW_LOW_LIMIT_STRING;
case 7203:
return VALUE_ABOVE_HIGH_LIMIT_STRING;
case 7204:
return VALUE_OUT_OF_RANGE_STRING;
case 7301:
return SWITCHING_TM_FAILED_STRING;
case 7400:
return CHANGING_MODE_STRING;
case 7401:
return MODE_INFO_STRING;
case 7402:
return FALLBACK_FAILED_STRING;
case 7403:
return MODE_TRANSITION_FAILED_STRING;
case 7404:
return CANT_KEEP_MODE_STRING;
case 7405:
return OBJECT_IN_INVALID_MODE_STRING;
case 7406:
return FORCING_MODE_STRING;
case 7407:
return MODE_CMD_REJECTED_STRING;
case 7506:
return HEALTH_INFO_STRING;
case 7507:
return CHILD_CHANGED_HEALTH_STRING;
case 7508:
return CHILD_PROBLEMS_STRING;
case 7509:
return OVERWRITING_HEALTH_STRING;
case 7510:
return TRYING_RECOVERY_STRING;
case 7511:
return RECOVERY_STEP_STRING;
case 7512:
return RECOVERY_DONE_STRING;
case 7900:
return RF_AVAILABLE_STRING;
case 7901:
return RF_LOST_STRING;
case 7902:
return BIT_LOCK_STRING;
case 7903:
return BIT_LOCK_LOST_STRING;
case 7905:
return FRAME_PROCESSING_FAILED_STRING;
case 8900:
return CLOCK_SET_STRING;
case 8901:
return CLOCK_SET_FAILURE_STRING;
case 9700:
return TEST_STRING;
default:
return "UNKNOWN_EVENT";
const char * translateEvents(Event event) {
switch( (event & 0xffff) ) {
case(2200):
return STORE_SEND_WRITE_FAILED_STRING;
case(2201):
return STORE_WRITE_FAILED_STRING;
case(2202):
return STORE_SEND_READ_FAILED_STRING;
case(2203):
return STORE_READ_FAILED_STRING;
case(2204):
return UNEXPECTED_MSG_STRING;
case(2205):
return STORING_FAILED_STRING;
case(2206):
return TM_DUMP_FAILED_STRING;
case(2207):
return STORE_INIT_FAILED_STRING;
case(2208):
return STORE_INIT_EMPTY_STRING;
case(2209):
return STORE_CONTENT_CORRUPTED_STRING;
case(2210):
return STORE_INITIALIZE_STRING;
case(2211):
return INIT_DONE_STRING;
case(2212):
return DUMP_FINISHED_STRING;
case(2213):
return DELETION_FINISHED_STRING;
case(2214):
return DELETION_FAILED_STRING;
case(2215):
return AUTO_CATALOGS_SENDING_FAILED_STRING;
case(2600):
return GET_DATA_FAILED_STRING;
case(2601):
return STORE_DATA_FAILED_STRING;
case(2800):
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
case(2801):
return DEVICE_SENDING_COMMAND_FAILED_STRING;
case(2802):
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
case(2803):
return DEVICE_READING_REPLY_FAILED_STRING;
case(2804):
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
case(2805):
return DEVICE_MISSED_REPLY_STRING;
case(2806):
return DEVICE_UNKNOWN_REPLY_STRING;
case(2807):
return DEVICE_UNREQUESTED_REPLY_STRING;
case(2808):
return INVALID_DEVICE_COMMAND_STRING;
case(2809):
return MONITORING_LIMIT_EXCEEDED_STRING;
case(2810):
return MONITORING_AMBIGUOUS_STRING;
case(4201):
return FUSE_CURRENT_HIGH_STRING;
case(4202):
return FUSE_WENT_OFF_STRING;
case(4204):
return POWER_ABOVE_HIGH_LIMIT_STRING;
case(4205):
return POWER_BELOW_LOW_LIMIT_STRING;
case(4300):
return SWITCH_WENT_OFF_STRING;
case(5000):
return HEATER_ON_STRING;
case(5001):
return HEATER_OFF_STRING;
case(5002):
return HEATER_TIMEOUT_STRING;
case(5003):
return HEATER_STAYED_ON_STRING;
case(5004):
return HEATER_STAYED_OFF_STRING;
case(5200):
return TEMP_SENSOR_HIGH_STRING;
case(5201):
return TEMP_SENSOR_LOW_STRING;
case(5202):
return TEMP_SENSOR_GRADIENT_STRING;
case(5901):
return COMPONENT_TEMP_LOW_STRING;
case(5902):
return COMPONENT_TEMP_HIGH_STRING;
case(5903):
return COMPONENT_TEMP_OOL_LOW_STRING;
case(5904):
return COMPONENT_TEMP_OOL_HIGH_STRING;
case(5905):
return TEMP_NOT_IN_OP_RANGE_STRING;
case(7101):
return FDIR_CHANGED_STATE_STRING;
case(7102):
return FDIR_STARTS_RECOVERY_STRING;
case(7103):
return FDIR_TURNS_OFF_DEVICE_STRING;
case(7201):
return MONITOR_CHANGED_STATE_STRING;
case(7202):
return VALUE_BELOW_LOW_LIMIT_STRING;
case(7203):
return VALUE_ABOVE_HIGH_LIMIT_STRING;
case(7204):
return VALUE_OUT_OF_RANGE_STRING;
case(7301):
return SWITCHING_TM_FAILED_STRING;
case(7400):
return CHANGING_MODE_STRING;
case(7401):
return MODE_INFO_STRING;
case(7402):
return FALLBACK_FAILED_STRING;
case(7403):
return MODE_TRANSITION_FAILED_STRING;
case(7404):
return CANT_KEEP_MODE_STRING;
case(7405):
return OBJECT_IN_INVALID_MODE_STRING;
case(7406):
return FORCING_MODE_STRING;
case(7407):
return MODE_CMD_REJECTED_STRING;
case(7506):
return HEALTH_INFO_STRING;
case(7507):
return CHILD_CHANGED_HEALTH_STRING;
case(7508):
return CHILD_PROBLEMS_STRING;
case(7509):
return OVERWRITING_HEALTH_STRING;
case(7510):
return TRYING_RECOVERY_STRING;
case(7511):
return RECOVERY_STEP_STRING;
case(7512):
return RECOVERY_DONE_STRING;
case(7900):
return RF_AVAILABLE_STRING;
case(7901):
return RF_LOST_STRING;
case(7902):
return BIT_LOCK_STRING;
case(7903):
return BIT_LOCK_LOST_STRING;
case(7905):
return FRAME_PROCESSING_FAILED_STRING;
case(8900):
return CLOCK_SET_STRING;
case(8901):
return CLOCK_SET_FAILURE_STRING;
case(9700):
return TEST_STRING;
default:
return "UNKNOWN_EVENT";
}
return 0;
}

View File

@ -0,0 +1,8 @@
#ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_
#define FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_
#include <fsfw/events/Event.h>
const char * translateEvents(Event event);
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */

View File

@ -1,7 +1,7 @@
#! /usr/bin/python3.8
# -*- coding: utf-8 -*-
"""
@file mib_exporter.py
@file mod_exporter.py
@brief Mission Information Base Exporter for the SOURCE project by KSat.
@details
Parses OBSW which is based on FSFW developed by the Institute of Space Systems (IRS) Stuttgart.
@ -315,7 +315,7 @@ def handle_external_file_running():
TODO: Make this stuff OOP too. Retvals and objects were already refactored
"""
os.chdir("events")
os.system("python mib_events.py")
os.system("python event_parser.py")
os.chdir("..")
print_string = "Exported to file: MIB_Events.csv\r\n"
return print_string

@ -1 +1 @@
Subproject commit 2dd83dbb458e19beec71877b969f287b03387af1
Subproject commit d9beb68bd9d1a1e6015e4979d547a762d199bff7

View File

@ -18,7 +18,7 @@
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.278840997" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.1841242502" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example/build-Debug-Linux}" command="cmake" id="cdt.managedbuild.target.gnu.builder.base.1872525696" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example_public/build-Debug-Linux}" command="cmake" id="cdt.managedbuild.target.gnu.builder.base.1872525696" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1985468037" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1424606859" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.642413900" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
@ -70,7 +70,7 @@
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494.1347848179." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.159290000" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.PE64;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1930506317" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example/build-Release-Linux}" command="cmake" id="cdt.managedbuild.target.gnu.builder.base.1965960475" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example_public/build-Release-Linux}" command="cmake" id="cdt.managedbuild.target.gnu.builder.base.1965960475" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1609672491" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1491459311" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1743900662" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
@ -122,7 +122,7 @@
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494.615695818." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.base.623801143" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.PE64;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.mingw.base.1711871351" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example/build-Debug-Host}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="cdt.managedbuild.builder.gnu.cross.1761965921" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example_public/build-Debug-Host}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="cdt.managedbuild.builder.gnu.cross.1761965921" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.base.13166088" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1629700138" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
@ -174,7 +174,7 @@
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494.615695818.954051921." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.base.1448115319" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.PE64;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.mingw.base.169860740" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example/Release-Host}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="cdt.managedbuild.builder.gnu.cross.1108079754" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example_public/build-Release-Host}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="cdt.managedbuild.builder.gnu.cross.1108079754" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.base.1193239387" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1144625128" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
@ -300,7 +300,7 @@
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.1998715444" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.1164065327" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.859936413" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example/build-Debug-RPi}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnuarmeclipse.managedbuild.cross.builder.510727936" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example_public/build-Debug-RPi}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnuarmeclipse.managedbuild.cross.builder.510727936" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1275243710" name="GNU Arm Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1772374282" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1512175823" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
@ -441,7 +441,7 @@
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.1941954257" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.1643607730" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1156260373" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example/build-Release-RPi}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnuarmeclipse.managedbuild.cross.builder.221137140" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example_public/build-Release-RPi}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnuarmeclipse.managedbuild.cross.builder.221137140" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1050996101" name="GNU Arm Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.577446546" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1908565237" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
@ -587,7 +587,7 @@
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.1229082279" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.1853005011" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.PE64;org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.787378269" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example/build-Debug-STM32H743-RTEMS}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnuarmeclipse.managedbuild.cross.builder.2086445741" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<builder arguments="--build ." autoBuildTarget="all" buildPath="${workspace_loc:/fsfw_example_public/build-Debug-STM32H743-RTEMS}" cleanBuildTarget="clean" command="cmake" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnuarmeclipse.managedbuild.cross.builder.2086445741" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.69591689" name="GNU Arm Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.823743724" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.1507142905" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" valueType="includePath">
@ -747,7 +747,7 @@
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.1883044707" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.1981903948" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.PE64;org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.633957164" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example/build-Release-STM32H743-RTEMS}" command="cmake" id="ilg.gnuarmeclipse.managedbuild.cross.builder.744774495" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example_public/build-Release-STM32H743-RTEMS}" command="cmake" id="ilg.gnuarmeclipse.managedbuild.cross.builder.744774495" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1724462366" name="GNU Arm Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1298708475" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.488497726" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" valueType="includePath">
@ -900,7 +900,7 @@
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.211372987" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.1913468245" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.197500878" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example/build-Debug-STM32H743-FreeRTOS}" command="cmake" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1059796223" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example_public/build-Debug-STM32H743-FreeRTOS}" command="cmake" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1059796223" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.43129417" name="GNU Arm Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.82715789" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.671384657" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" valueType="definedSymbols">
@ -1056,7 +1056,7 @@
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.1424010361" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.213201916" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1241442493" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example/build-Release-STM32H743-FreeRTOS}" command="cmake" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1531059207" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<builder arguments="--build ." buildPath="${workspace_loc:/fsfw_example_public/build-Release-STM32H743-FreeRTOS}" command="cmake" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1531059207" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.672489248" name="GNU Arm Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1922193266" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1784187041" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>fsfw_example</name>
<name>fsfw_example_public</name>
<comment></comment>
<projects>
</projects>

View File

@ -18,11 +18,11 @@
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="build-Debug-Linux/fsfw_example"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="fsfw_example"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="fsfw_example_public"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/fsfw_example"/>
<listEntry value="/fsfw_example_public"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>

View File

@ -19,11 +19,11 @@
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="build-Debug-Host/fsfw_example.exe"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="fsfw_example"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="fsfw_example_public"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494.615695818"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/fsfw_example"/>
<listEntry value="/fsfw_example_public"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>

View File

@ -19,11 +19,11 @@
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="build-Release-Host/fsfw_example.exe"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="fsfw_example"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="fsfw_example_public"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="cdt.managedbuild.toolchain.gnu.base.450259316.1933681494.615695818.954051921"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/fsfw_example"/>
<listEntry value="/fsfw_example_public"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>

View File

@ -1,7 +1,7 @@
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/tmtcpacket/pus/TmPacketBase.h>
#include <fsfw/tmtcpacket/pus/TmPacketPusC.h>
#include <mission/utility/TmFunnel.h>
object_id_t TmFunnel::downlinkDestination = objects::NO_OBJECT;
@ -50,7 +50,7 @@ ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) {
if(result != HasReturnvaluesIF::RETURN_OK){
return result;
}
TmPacketBase packet(packetData);
TmPacketPusC packet(packetData);
packet.setPacketSequenceCount(this->sourceSequenceCount);
sourceSequenceCount++;
sourceSequenceCount = sourceSequenceCount %

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 5 -t 5" />
<option name="PARAMETERS" value="-s 5 -t 5" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 8 -t 4" />
<option name="PARAMETERS" value="-s 8 -t 4" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m onecmd -s 200 -t 4" />
<option name="PARAMETERS" value="-s 200 -t 4" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 17 -t 3" />
<option name="PARAMETERS" value="-s 17 -o 0 -t 3" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 2 -t 4" />
<option name="PARAMETERS" value="-s 2 -t 4" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 3 -o 0 --hk -t 3" />
<option name="PARAMETERS" value="-s 3 -o 0 --hk -t 3" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 3 -o 2 --hk -t 3" />
<option name="PARAMETERS" value="-s 3 -o 2 --hk -t 3" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 3 -o 3 --hk -t 3" />
<option name="PARAMETERS" value="-s 3 -o 3 --hk -t 3" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_client_cli.py" />
<option name="PARAMETERS" value="-m seqcmd -s 3 -o 1 --hk -t 3" />
<option name="PARAMETERS" value="-s 3 -o 1 --hk -t 3" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />

View File

@ -1,24 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Single Command" type="PythonConfigurationType" factoryName="Python" folderName="Service Demos">
<module name="tmtc" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtc_core/tmtcc_runner.py" />
<option name="PARAMETERS" value="-m 0 -c 2" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

View File

@ -6,7 +6,7 @@
import sys
from tmtccmd.core.backend import TmTcHandler
from tmtccmd.utility.tmtcc_logger import get_logger
from tmtccmd.utility.logger import get_logger
LOGGER = get_logger()
@ -15,7 +15,5 @@ def perform_mode_operation_user(tmtc_backend: TmTcHandler, mode: int):
"""
Custom modes can be implemented here
"""
if tmtc_backend:
pass
LOGGER.error(f"Unknown mode {mode}, Configuration error !")
sys.exit()

View File

@ -1,10 +1,9 @@
import argparse
from typing import Dict, Union, Tuple
from tmtccmd.core.hook_base import TmTcHookBase
from tmtccmd.ecss.tc import PusTelecommand
from tmtccmd.config.definitions import ServiceOpCodeDictT
from tmtccmd.config.hook import TmTcHookBase
from tmtccmd.pus_tm.service_3_base import Service3Base
from tmtccmd.ecss.conf import PusVersion
class FsfwHookBase(TmTcHookBase):
@ -18,18 +17,27 @@ class FsfwHookBase(TmTcHookBase):
from config.version import SW_NAME, SW_VERSION, SW_SUBVERSION, SW_SUBSUBVERSION
return f"{SW_NAME} {SW_VERSION}.{SW_SUBVERSION}.{SW_SUBSUBVERSION}"
def get_json_config_file_path(self) -> str:
return "config/tmtc_config.json"
def get_service_op_code_dictionary(self) -> ServiceOpCodeDictT:
from tmtccmd.config.globals import get_default_service_op_code_dict
return get_default_service_op_code_dict()
def add_globals_pre_args_parsing(self, gui: bool = False):
from tmtccmd.defaults.globals_setup import set_default_globals_pre_args_parsing
set_default_globals_pre_args_parsing(gui=gui, apid=0xef, pus_tm_version=PusVersion.PUS_A)
from tmtccmd.config.globals import set_default_globals_pre_args_parsing
set_default_globals_pre_args_parsing(gui=gui, apid=0xef)
def add_globals_post_args_parsing(self, args: argparse.Namespace, json_cfg_path: str = ""):
from tmtccmd.defaults.globals_setup import set_default_globals_post_args_parsing
set_default_globals_post_args_parsing(args=args, json_cfg_path=json_cfg_path)
def add_globals_post_args_parsing(self, args: argparse.Namespace):
from tmtccmd.config.globals import set_default_globals_post_args_parsing
set_default_globals_post_args_parsing(args=args, json_cfg_path=self.get_json_config_file_path())
def assign_communication_interface(self, com_if: int, tmtc_printer: TmTcPrinter) -> \
def assign_communication_interface(self, com_if_key: str, tmtc_printer: TmTcPrinter) -> \
Union[CommunicationInterface, None]:
from tmtccmd.defaults.com_setup import create_communication_interface_default
return create_communication_interface_default(com_if=com_if, tmtc_printer=tmtc_printer)
from tmtccmd.config.com_if import create_communication_interface_default
return create_communication_interface_default(
com_if_key=com_if_key, tmtc_printer=tmtc_printer, json_cfg_path=self.get_json_config_file_path()
)
def perform_mode_operation(self, tmtc_backend: TmTcHandler, mode: int):
print("No custom mode operation implemented")
@ -38,17 +46,13 @@ class FsfwHookBase(TmTcHookBase):
from pus_tc.tc_packing import pack_service_queue_user
pack_service_queue_user(service=service, op_code=op_code, service_queue=service_queue)
def pack_total_service_queue(self) -> Union[None, TcQueueT]:
from pus_tc.tc_packing import create_total_tc_queue_user
return create_total_tc_queue_user()
def tm_user_factory_hook(self, raw_tm_packet: bytearray) -> Union[None, PusTelemetry]:
from pus_tm.factory_hook import tm_user_factory_hook
return tm_user_factory_hook(raw_tm_packet=raw_tm_packet)
def set_object_ids(self) -> Dict[bytes, list]:
from config.object_ids import set_object_ids
return set_object_ids()
def get_object_ids(self) -> Dict[bytes, list]:
from config.object_ids import get_object_ids
return get_object_ids()
@staticmethod
def handle_service_8_telemetry(
@ -61,18 +65,9 @@ class FsfwHookBase(TmTcHookBase):
@staticmethod
def handle_service_3_housekeeping(
object_id: bytearray, set_id: int, hk_data: bytearray, service3_packet: Service3Base
object_id: bytes, set_id: int, hk_data: bytearray, service3_packet: Service3Base
) -> Tuple[list, list, bytearray, int]:
from pus_tm.service_3_hk_handling import service_3_hk_handling
return service_3_hk_handling(
object_id=object_id, set_id=set_id, hk_data=hk_data, service3_packet=service3_packet
)
def command_preparation_hook(self) -> Union[None, PusTelecommand]:
pass
def set_json_config_file_path(self) -> str:
return "config/tmtc_config.json"

View File

@ -3,18 +3,17 @@
@details Template configuration file. Copy this folder to the TMTC commander root and adapt
it to your needs.
"""
from typing import Dict
SERVICE_17_OBJ_ID = bytes([0x53, 0x00, 0x00, 0x17])
TEST_DEVICE_0_OBJ_ID = bytes([0x44, 0x01, 0xAF, 0xFE])
TEST_DEVICE_1_OBJ_ID = bytes([0x44, 0x02, 0xAF, 0xFE])
PUS_SERVICE_17_ID = bytes([0x53, 0x00, 0x00, 0x17])
TEST_DEVICE_0_ID = bytes([0x44, 0x01, 0xAF, 0xFE])
TEST_DEVICE_1_ID = bytes([0x44, 0x02, 0xAF, 0xFE])
def set_object_ids() -> Dict[bytes, list]:
def get_object_ids() -> Dict[bytes, list]:
object_id_dict = {
SERVICE_17_OBJ_ID: ["Service 17"],
TEST_DEVICE_0_OBJ_ID: ["Test Device 0"],
TEST_DEVICE_1_OBJ_ID: ["Test Device 1"],
PUS_SERVICE_17_ID: ["PUS Service 17"],
TEST_DEVICE_0_ID: ["Test Device 0"],
TEST_DEVICE_1_ID: ["Test Device 1"]
}
return object_id_dict

View File

@ -1,4 +1,4 @@
SW_NAME = "fsfw-tmtc"
SW_VERSION = 1
SW_SUBVERSION = 1
SW_SUBVERSION = 2
SW_SUBSUBVERSION = 0

View File

@ -5,12 +5,13 @@
@author R. Mueller
@date 02.05.2020
"""
from config.object_ids import TEST_DEVICE_0_OBJ_ID, TEST_DEVICE_1_OBJ_ID
from tmtccmd.core.definitions import QueueCommands
from tmtccmd.config.definitions import QueueCommands
from tmtccmd.ecss.tc import PusTelecommand
from tmtccmd.pus_tc.packer import TcQueueT
from tmtccmd.pus_tc.service_200_mode import pack_mode_data
from config.object_ids import TEST_DEVICE_0_ID
def pack_service_200_commands_into(tc_queue: TcQueueT, op_code: str):
if op_code == "0":
@ -21,7 +22,7 @@ def pack_service_200_test_into(init_ssc: int, tc_queue: TcQueueT) -> int:
new_ssc = init_ssc
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 200"))
# Object ID: DUMMY Device
object_id = TEST_DEVICE_0_OBJ_ID
object_id = TEST_DEVICE_0_ID
# Set On Mode
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 200: Set Mode On"))
mode_data = pack_mode_data(object_id, 1, 0)

View File

@ -1,18 +1,16 @@
import struct
from tmtccmd.core.definitions import QueueCommands
from tmtccmd.config.definitions import QueueCommands
from tmtccmd.ecss.tc import PusTelecommand
from tmtccmd.pus_tc.definitions import TcQueueT
from tmtccmd.pus_tc.service_20_parameter import pack_type_and_matrix_data, \
pack_parameter_id
from tmtccmd.pus_tc.service_200_mode import pack_mode_data
from tmtccmd.utility.tmtcc_logger import get_logger
from tmtccmd.utility.logger import get_logger
from config.object_ids import TEST_DEVICE_0_OBJ_ID
from config.object_ids import TEST_DEVICE_0_ID
LOGGER = get_logger()
TEST_DEVICE_0_ID = bytearray()
def pack_service20_commands_into(tc_queue: TcQueueT, op_code: str):
@ -23,7 +21,7 @@ def pack_service20_commands_into(tc_queue: TcQueueT, op_code: str):
def pack_service20_test_into(tc_queue: TcQueueT, called_externally: bool = False):
if called_externally is False:
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 20"))
object_id = TEST_DEVICE_0_OBJ_ID
object_id = TEST_DEVICE_0_ID
# set mode normal
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 20: Set Normal Mode"))
@ -40,7 +38,7 @@ def pack_service20_test_into(tc_queue: TcQueueT, called_externally: bool = False
def load_param_0_simple_test_commands(tc_queue: TcQueueT):
object_id = TEST_DEVICE_0_OBJ_ID
object_id = TEST_DEVICE_0_ID
parameter_id_0 = pack_parameter_id(domain_id=0, unique_id=0, linear_index=0)
# test checking Load for uint32_t
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 20: Load uint32_t"))

View File

@ -7,13 +7,13 @@
"""
import struct
from tmtccmd.core.definitions import QueueCommands
from tmtccmd.config.definitions import QueueCommands
from tmtccmd.ecss.tc import PusTelecommand
from tmtccmd.pus_tc.definitions import TcQueueT
from pus_tc.service_200_mode import pack_mode_data
import pus_tc.command_data as cmd_data
from config.object_ids import TEST_DEVICE_0_OBJ_ID, TEST_DEVICE_1_OBJ_ID
from config.object_ids import TEST_DEVICE_0_ID
def pack_service_2_commands_into(tc_queue: TcQueueT, op_code: str):
@ -25,7 +25,7 @@ def pack_service_2_commands_into(tc_queue: TcQueueT, op_code: str):
def pack_generic_service_2_test_into(init_ssc: int, tc_queue: TcQueueT) -> int:
new_ssc = init_ssc
object_id = TEST_DEVICE_0_OBJ_ID # dummy device
object_id = TEST_DEVICE_0_ID # dummy device
# Set Raw Mode
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 2: Setting Raw Mode"))
mode_data = pack_mode_data(object_id, 3, 0)

View File

@ -1,5 +1,4 @@
from tmtccmd.core.definitions import QueueCommands
from tmtccmd.core.object_id_manager import get_object_id
from tmtccmd.config.definitions import QueueCommands
from tmtccmd.pus_tc.service_200_mode import pack_mode_data
from tmtccmd.pus_tc.service_20_parameter import pack_boolean_parameter_command
from tmtccmd.pus_tc.service_3_housekeeping import make_sid, generate_one_hk_command, \
@ -8,8 +7,8 @@ from tmtccmd.ecss.tc import PusTelecommand
from tmtccmd.pus_tc.definitions import TcQueueT
from tmtccmd.pus_tc.service_8_functional_cmd import generate_action_command
from config.object_ids import TEST_DEVICE_0_ID, TEST_DEVICE_1_ID
from config.object_ids import TEST_DEVICE_1_OBJ_ID, TEST_DEVICE_0_OBJ_ID
# Set IDs
TEST_SET_ID = 0
@ -26,9 +25,9 @@ def pack_service_3_commands_into(tc_queue: TcQueueT, op_code: str):
# TODO: Import this from config instead
device_idx = 0
if device_idx == 0:
object_id = TEST_DEVICE_0_OBJ_ID
object_id = TEST_DEVICE_0_ID
else:
object_id = TEST_DEVICE_1_OBJ_ID
object_id = TEST_DEVICE_1_ID
if op_code == "0":
# This will pack all the tests

View File

@ -1,10 +1,11 @@
from tmtccmd.core.definitions import QueueCommands
from tmtccmd.config.definitions import QueueCommands
from tmtccmd.ecss.tc import PusTelecommand
from tmtccmd.pus_tc.definitions import TcQueueT
import pus_tc.command_data as cmd_data
from pus_tc.service_200_mode import pack_mode_data
from config.object_ids import TEST_DEVICE_1_OBJ_ID, TEST_DEVICE_0_OBJ_ID
from config.object_ids import TEST_DEVICE_0_ID
def pack_service_8_commands_into(tc_queue: TcQueueT, op_code: str):
@ -16,7 +17,7 @@ def pack_service_8_commands_into(tc_queue: TcQueueT, op_code: str):
def pack_generic_service_8_test_into(tc_queue: TcQueueT):
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 8"))
object_id = TEST_DEVICE_0_OBJ_ID
object_id = TEST_DEVICE_0_ID
# set mode on
tc_queue.appendleft((QueueCommands.PRINT, "Testing Service 8: Set On Mode"))

View File

@ -6,14 +6,15 @@
import os
from collections import deque
from typing import Union
from pus_tc.service_20_parameters import pack_service20_commands_into
from pus_tc.service_2_raw_cmd import pack_service_2_commands_into
from pus_tc.service_3_housekeeping import pack_service_3_commands_into
from pus_tc.service_8_func_cmd import pack_service_8_commands_into
from tmtccmd.utility.tmtcc_logger import get_logger
from tmtccmd.utility.logger import get_logger
from tmtccmd.pus_tc.definitions import TcQueueT
from tmtccmd.core.definitions import CoreServiceList
from tmtccmd.config.definitions import CoreServiceList
from tmtccmd.pus_tc.service_5_event import pack_generic_service5_test_into
from tmtccmd.pus_tc.service_17_test import pack_generic_service17_test
from pus_tc.service_200_mode import pack_service_200_commands_into
@ -21,20 +22,20 @@ from pus_tc.service_200_mode import pack_service_200_commands_into
LOGGER = get_logger()
def pack_service_queue_user(service: int, op_code: str, service_queue: TcQueueT):
if service == CoreServiceList.SERVICE_2:
def pack_service_queue_user(service: Union[str, int], op_code: str, service_queue: TcQueueT):
if service == CoreServiceList.SERVICE_2.value:
return pack_service_2_commands_into(op_code=op_code, tc_queue=service_queue)
if service == CoreServiceList.SERVICE_3:
if service == CoreServiceList.SERVICE_3.value:
return pack_service_3_commands_into(op_code=op_code, tc_queue=service_queue)
if service == CoreServiceList.SERVICE_5:
if service == CoreServiceList.SERVICE_5.value:
return pack_generic_service5_test_into(tc_queue=service_queue)
if service == CoreServiceList.SERVICE_8:
if service == CoreServiceList.SERVICE_8.value:
return pack_service_8_commands_into(op_code=op_code, tc_queue=service_queue)
if service == CoreServiceList.SERVICE_17:
if service == CoreServiceList.SERVICE_17.value:
return pack_generic_service17_test(init_ssc=1700, tc_queue=service_queue)
if service == CoreServiceList.SERVICE_20:
if service == CoreServiceList.SERVICE_20.value:
return pack_service20_commands_into(tc_queue=service_queue, op_code=op_code)
if service == CoreServiceList.SERVICE_200:
if service == CoreServiceList.SERVICE_200.value:
return pack_service_200_commands_into(tc_queue=service_queue, op_code=op_code)
LOGGER.warning("Invalid Service !")

View File

@ -5,7 +5,7 @@
"""
from tmtccmd.ecss.tm import PusTelemetry
from tmtccmd.utility.tmtcc_logger import get_logger
from tmtccmd.utility.logger import get_logger
from tmtccmd.pus_tm.service_1_verification import Service1TM
from tmtccmd.pus_tm.service_2_raw_cmd import Service2TM
from tmtccmd.pus_tm.service_3_housekeeping import Service3TM

View File

@ -7,33 +7,35 @@
import struct
from typing import Tuple
from tmtccmd.pus_tm.service_3_housekeeping import Service3Base
from tmtccmd.utility.tmtcc_logger import get_logger
from tmtccmd.utility.logger import get_logger
from config.object_ids import TEST_DEVICE_0_OBJ_ID, TEST_DEVICE_1_OBJ_ID
from config.object_ids import TEST_DEVICE_0_ID, TEST_DEVICE_1_ID
LOGGER = get_logger()
def service_3_hk_handling(
object_id: bytearray, set_id: int, hk_data: bytearray, service3_packet: Service3Base
object_id: bytes, set_id: int, hk_data: bytearray, service3_packet: Service3Base
) -> Tuple[list, list, bytearray, int]:
"""
This function is called when a Service 3 Housekeeping packet is received.
:param object_id:
:param set_id:
:param hk_data:
:param service3_packet:
:return: Expects a tuple, consisting of two lists, a bytearray and an integer
Please note that the object IDs should be compared by value because direct comparison of
enumerations does not work in Python. For example use:
if object_id.value == ObjectIds.TEST_OBJECT.value
to test equality based on the object ID list.
@param object_id:
@param set_id:
@param hk_data:
@param service3_packet:
@return: Expects a tuple, consisting of two lists, a bytearray and an integer
The first list contains the header columns, the second list the list with
the corresponding values. The bytearray is the validity buffer, which is usually appended
at the end of the housekeeping packet. The last value is the number of parameters.
"""
if set_id:
pass
if service3_packet:
pass
if object_id == TEST_DEVICE_0_OBJ_ID or \
object_id == TEST_DEVICE_1_OBJ_ID:
if object_id == TEST_DEVICE_0_ID or object_id == TEST_DEVICE_1_ID:
return handle_test_set_deserialization(hk_data=hk_data)
else:
LOGGER.info("Service3TM: Parsing for this SID has not been implemented.")

View File

@ -14,14 +14,6 @@ def custom_service_8_handling(
@param custom_data:
@return:
"""
if object_id:
pass
if action_id:
pass
if custom_data:
pass
header_list = []
content_list = []
return header_list, content_list

View File

@ -39,7 +39,7 @@ except ImportError:
def main():
hook_obj = FsfwHookBase()
initialize_tmtc_commander(hook_object=hook_obj)
run_tmtc_commander(False)
run_tmtc_commander(use_gui=False, app_name="TMTC Commander FSFW")
if __name__ == "__main__":

View File

@ -33,7 +33,7 @@ from tmtccmd.runner import run_tmtc_commander, initialize_tmtc_commander
def main():
hook_obj = FsfwHookBase()
initialize_tmtc_commander(hook_object=hook_obj)
run_tmtc_commander(True)
run_tmtc_commander(use_gui=True, app_name="TMTC Commander FSFW")
if __name__ == "__main__":

@ -1 +1 @@
Subproject commit 0d2450dfd2f34fdd5eb0b0ff55d1fbc0684f852d
Subproject commit 2fe13b2d7183dce67b6b7ec4b89dd7771ee46a2f