From 0e3b67383df70be94a816ac77d2ffed38681f778 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 15:29:15 +0200 Subject: [PATCH 01/19] arcsec_star_tracker --- thirdparty/arcsec_star_tracker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/arcsec_star_tracker b/thirdparty/arcsec_star_tracker index f596c533..65dfee81 160000 --- a/thirdparty/arcsec_star_tracker +++ b/thirdparty/arcsec_star_tracker @@ -1 +1 @@ -Subproject commit f596c53315f1f81facb28faec3150612a5ad2ca0 +Subproject commit 65dfee8191cd0254d4988b08c9607024389e2b08 From 733a89a97aa6577735951237d204dc63572fa7a5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 15:30:34 +0200 Subject: [PATCH 02/19] arcsec star tracker update --- thirdparty/arcsec_star_tracker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/arcsec_star_tracker b/thirdparty/arcsec_star_tracker index 65dfee81..c468400a 160000 --- a/thirdparty/arcsec_star_tracker +++ b/thirdparty/arcsec_star_tracker @@ -1 +1 @@ -Subproject commit 65dfee8191cd0254d4988b08c9607024389e2b08 +Subproject commit c468400aaf8470a31e393f53c858d2bf2c361273 From 07f531a044fdb2b7cd9f018ab0e859921de99863 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 17:08:26 +0200 Subject: [PATCH 03/19] update core controller --- bsp_q7s/core/CoreController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index dddc4c97..a46c74f1 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -269,7 +269,8 @@ ReturnValue_t CoreController::incrementAllocationFailureCount() { ReturnValue_t CoreController::versionFileInit() { std::string unameFileName = "/tmp/uname_version.txt"; - std::string unameCmd = "uname -a > " + unameFileName; + // TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters + std::string unameCmd = "uname -mnrso > " + unameFileName; int result = std::system(unameCmd.c_str()); if(result != 0) { utility::handleSystemError(result, "CoreController::versionFileInit"); From bbc8a3eeefde8e9bf3139705bfbab5a9624bc005 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 17:20:39 +0200 Subject: [PATCH 04/19] README update --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26adb303..89e2514a 100644 --- a/README.md +++ b/README.md @@ -773,7 +773,10 @@ EIVE implementation - Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir` - Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir` - Folder `scripts` in `/home/root` folder. -- `scripts` folder currently contains `update_main_components.sh` script +- `scripts` folder currently contains a few shell helper scripts +- Folder `profile.d` in `/etc` folder which contains the `path-set.sh` script + which is sourced at software startup +- Library `libwire.so` in `/usr/lib` folder ### SD Cards From 9b2ab66c0a608c08eabbb9f337822ea0966e4d6f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 00:42:33 +0200 Subject: [PATCH 05/19] readme update --- README.md | 600 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 354 insertions(+), 246 deletions(-) diff --git a/README.md b/README.md index 89e2514a..21ee5e40 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,23 @@ EIVE On-Board Software ====== -# General information +# Index + +1. [General](#general) +2. [Prerequisites](#prereq) +3. [Building the Software](#build) +4. [Useful and Common Host Commands](#host-commands) +5. [Setting up Prerequisites](#set-up-prereq) +6. [Remote Debugging](#remote-debugging) +7. [Direct Debugging](#direct-debugging) +8. [Transfering Files to the Q7S](#file-transfer) +9. [Q7S OBC](#q7s) +10. [Static Code Analysis](#static-code-analysis) +11. [Eclipse](#eclipse) +12. [Running the OBSW on a Raspberry Pi](#rpi) +13. [FSFW](#fsfw) + +# General information Target systems: @@ -36,16 +52,169 @@ The CMake build system can be used to generate build systems as well (see helper - Linux Host: Uses the `bsp_hosted` BSP folder and the CMake Unix Makefiles generator. - Windows Host: Uses the `bsp_hosted` BSP folder, the CMake MinGW Makefiles generator and MSYS2. -# Setting up development environment +# Prerequisites -## Installing Vivado the the Xilinx development tools +There is a separate [prerequisites](#set-up-prereq) which specifies how to set up all +prerequisites. + +## Building the OBSW and flashing it on the Q7S + +1. ARM cross-compiler installed, either as part of [Vivado 2018.2 installation](#vivado) or + as a [separate download](#arm-toolchain) +2. [Q7S sysroot](#q7s-sysroot) on local development machine +3. Recommended: Eclipse or [Vivado 2018.2 SDK](#vivado) for OBSW development +3. [TCF agent] running on Q7S + +## Hardware Design + +1. [Vivado 2018.2](#vivado) for programmable logic design + +# Building the software + +## CMake + +When using Windows, run theses steps in MSYS2. + +1. Clone the repository with + + ```sh + git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git + ``` + +2. Update all the submodules + + ```sh + git submodule init + git submodule sync + git submodule update + ``` + +3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`. + It is recommended to set up a shell script which takes care of setting up the environment + for convenience or to set up the + [PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path) + in the `.profile` file. + +4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder. + Add `-G "MinGW Makefiles` in MinGW64 on Windows. + + ```sh + mkdir build-Debug-Q7S && cd build-Debug-Q7S + cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DOS_FSFW=linux .. + cmake --build . -j + ``` + + You can also use provided shell scripts to perform these commands + + ```sh + cd cmake/scripts/Q7S + ./make_debug_cfg.sh + cd ../../.. + ``` + + This will invoke a Python script which in turn invokes CMake with the correct + arguments to configure CMake for Q7S cross-compilation. + + You can build the hosted variant of the OBSW by replacing `-DOS_FSFW=linux` with + `-DOS_FSFW=host`. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi + or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`. + +5. Build the software with + ```sh + cd build-Debug-Q7S + cmake --build . -j + ``` + +## Building in Xilinx SDK 2018.2 + +1. Open Xilinx SDK 2018.2 +2. Import project + * File → Import → C/C++ → Existing Code as Makefile Project +3. Set build command. Replace \ with either debug or release. + * When on Linux right click project → Properties → C/C++ Build → Set build command to `make -j` + * -j causes the compiler to use all available cores + * The target is used to either compile the debug or the optimized release build. + * On windows create a make target additionally (Windows → Show View → Make Target) + * Right click eive_obsw → New + * Target name: all + * Uncheck "Same as the target name" + * Uncheck "Use builder settings" + * As build command type: `cmake --build .` + * In the Behaviour tab, you can enable build acceleration +4. Run build command by double clicking the created target or by right clicking + the project folder and selecting Build Project. + +# Useful and Common Commands (Host) + +## Connect to EIVE flatsat + +### DNS + +```sh +ssh eive@flatsat.eive.absatvirt.lw +``` + +### IPv6 +```sh +ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 +``` + +### IPv4 + +```sh +ssh eive@192.168.199.227 +``` + +## Port forwarding for connection to TCF agent + +This is a required step to connect to the `tcf-agent` on the Q7S, which is required for convenient +remote debugging. Assuming the IPv6 + +```sh +ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +You then need to connect to `localhost` with port `1534`. + +## Port forwarding for file transfers with `scp` + +```sh +ssh -L 1535:192.168.133.10:22 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +You then need to run `scp` with the `-P 1535` flag with `localhost` as the target IP address. + +## Port forwarding for TMTC commanding + +This requires using the TCP on sender side (Python client) and receiver side (OBSW TMTC TCP server). + +```sh +ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +## Set up all port forwarding at once + +You can specify the `-L` option multiple times to set up all port forwarding at once + +```sh +ssh -L 1534:192.168.133.10:1534 \ + -L 1535:192.168.133.10:22 \ + -L 1536:192.168.133.10:7301 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t /bin/bash +``` + +# Setting up prerequisites + +## Installing Vivado the the Xilinx development tools It's also possible to perform debugging with a normal Eclipse installation by installing the TCF plugin and downloading the cross-compiler as specified in the section below. However, if you want to generate the `*.xdi` files necessary to update the firmware, you need to installed Vivado with the SDK core tools. -* Install Vivado 2018.2 and Xilinx SDK from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html. +* Install Vivado 2018.2 and + [Xilinx SDK](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html). Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of the updates. It is recommended to use the installer. @@ -85,7 +254,7 @@ For Linux, you can also download a more recent version of the [Linaro 8.3.0 cross-compiler](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads) from [here](https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz?revision=e09a1c45-0ed3-4a8e-b06b-db3978fd8d56&la=en&hash=93ED4444B8B3A812B893373B490B90BBB28FD2E3) -## Installing toolchain without Vivado +## Installing toolchain without Vivado You can download the toolchains for Windows and Linux [from the EIVE cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files?dir=/EIVE_IRS/Software/tools&fileid=831898). @@ -136,7 +305,7 @@ wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/2Fp2ag6NGnbtAsK/downloa sudo apt-get install cmake ```` -## Getting the Q7S system root +## Getting the Q7S system root It is necessary to copy the Q7S system root to your local development machine for libraries like `libgpio`. You can find the system root for the Q7S, the Raspberry Pi and the @@ -151,102 +320,58 @@ wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/agnJGYeRf6fw2ci/downloa Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path. -# Building the software with CMake +## Setting up UNIX environment for real-time functionalities -When using Windows, run theses steps in MSYS2. +Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities +used by the UNIX pthread module are restricted, which will lead to permission errors when creating +these tasks and configuring real-time properites like scheduling priorities. -1. Clone the repository with +To solve this issues, try following steps: + +1. Edit the /etc/security/limits.conf +file and add following lines at the end: +```sh + hard rtprio 99 + soft rtprio 99 +``` +The soft limit can also be set in the console with `ulimit -Sr` if the hard +limit has been increased, but it is recommended to add it to the file as well for convenience. +If adding the second line is not desired for security reasons, +the soft limit needs to be set for each session. If using an IDE like eclipse +in that case, the IDE needs to be started from the console after setting +the soft limit higher there. After adding the two lines to the file, +the computer needs to be restarted. + +It is also recommended to perform the following change so that the unlockRealtime +script does not need to be run anymore each time. The following steps +raise the maximum allowed message queue length to a higher number permanently, which is +required for some framework components. The recommended values for the new message +length is 130. + +2. Edit the /etc/sysctl.conf file ```sh - git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git + sudo nano /etc/sysctl.conf ``` -2. Update all the submodules - + Append at end: ```sh - git submodule init - git submodule sync - git submodule update - ``` - -3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`. - It is recommended to run the shell script `win_path_helper_xilinx_tools.sh` in `cmake/scripts/Q7S` - or to set up the [PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path) - in the `.profile` file. - -4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder. - Add `-G "MinGW Makefiles` in MinGW64 on Windows. - - ```sh - mkdir build-Debug-Q7S && cd build-Debug-Q7S - cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DOS_FSFW=linux .. - cmake --build . -j - ``` - - You can also use provided shell scripts to perform these commands - - ```sh - cd cmake/scripts/Q7S - ./make_debug_cfg.sh - cd ../../.. - ``` - - This will invoke a Python script which in turn invokes CMake with the correct - arguments to configure CMake for Q7S cross-compilation. - - You can build the hosted variant of the OBSW by replacing `-DOS_FSFW=linux` with - `-DOS_FSFW=host`. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi - or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`. - -5. Build the software with - ```sh - cd Debug - cmake --build . -j + fs/mqueue/msg_max = ``` -## Setting up default Eclipse for Q7S projects - TCF agent + Apply changes with: + ```sh + sudo sysctl -p + ``` -The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debugging on the Q7S. + A possible solution which only persists for the current session is + ```sh + echo | sudo tee /proc/sys/fs/mqueue/msg_max + ``` -1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help → Install New Software and use the download page, for example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. +## TCF-Agent -2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. - Here, the Q7S should show up if the local port forwarding was set up as explained previously. Please note that you have to connect to `localhost` and port `1534` with port forwaring set up. - -3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. Alternatively: - - - Create a new **TCF Remote Application** by pressing the cogs button at the top or going to Run → Debug Configurations → Remote Application and creating a new one there. - - - Set up the correct image in the main tab (it might be necessary to send the image to the Q7S manually once) and file transfer properties - - - It is also recommended to link the correct Eclipse project. - -After that, comfortable remote debugging should be possible with the Debug button. - -A build configuration and a shell helper script has been provided to set up the path variables and -build the Q7S binary on Windows, but a launch configuration needs to be newly created because the -IP address and path settings differ from machine to machine. - -## Building in Xilinx SDK 2018.2 - -1. Open Xilinx SDK 2018.2 -2. Import project - * File → Import → C/C++ → Existing Code as Makefile Project -3. Set build command. Replace \ with either debug or release. - * When on Linux right click project → Properties → C/C++ Build → Set build command to `make -j` - * -j causes the compiler to use all available cores - * The target is used to either compile the debug or the optimized release build. - * On windows create a make target additionally (Windows → Show View → Make Target) - * Right click eive_obsw → New - * Target name: all - * Uncheck "Same as the target name" - * Uncheck "Use builder settings" - * As build command type: `cmake --build .` - * In the Behaviour tab, you can enable build acceleration -4. Run build command by double clicking the created target or by right clicking - the project folder and selecting Build Project. - -## TCF-Agent +Most of the steps specified here were already automated 1. On reboot, some steps have to be taken on the Q7S. Set static IP address and netmask @@ -264,7 +389,7 @@ IP address and path settings differ from machine to machine. You can run it manually there. To perform auto-start on boot, have a look at the start-up application section. -# Debugging the software via Flatsat PC +# Remote Debugging Open SSH connection to flatsat PC: @@ -298,6 +423,7 @@ console of the Q7S like this to set it picocom -b 115200 /dev/ttyUSB0 ``` +The flatsat has the aliases and shell scripts `q7s_ssh` and `q7s_serial` for this task as well. If the serial port is blocked for some reason, you can kill the process using it with `q7s_kill`. @@ -325,13 +451,68 @@ ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t bash ``` This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address -192.168.133.10. -This needs to be done every time, so it is recommended to create an alias to do this quickly. +192.168.133.10. This needs to be done every time, so it is recommended to create an +alias or shell script to do this quickly. Note: When now setting up a debug session in the Xilinx SDK or Eclipse, the host must be set to localhost instead of the IP address of the Q7S. -# Transfering files via SCP +# Direct Debugging + +1. Assign static IP address to Q7S + * Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user + manual chapter 10.3) + * Baudrate 115200 + * Login to Q7S: + * user: root + * pw: root + +2. Connect Q7S to workstation via ethernet +3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S + * When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation + is 192.168.133.2 + +4. Run tcf-agent on Q7S + + * Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually + + ```sh + git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git + cd org.eclipse.tcf.agent/agent + make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1 + ``` + + * Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S + + ```sh + cd obj/GNU/Linux/arm/Debug + scp agent root@192.168.133.10:/tmp + ``` + + * On Q7S + ```sh + cd /tmp + chmod +x agent + ``` + + * Run agent + ```sh + ./agent + ``` + +5. In Xilinx SDK 2018.2 right click on project → Debug As → Debug Configurations +6. Right click Xilinx C/C++ applicaton (System Debugger) → New → +7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent +8. Click New +9. Give connection a name +10. Set Host to static IP address of Q7S. e.g. 192.168.133.10 +11. Test connection (This ensures the TCF Agent is running on the Q7S) +12. Select Application tab + * Project Name: eive_obsw + * Local File Path: Path to eiveobsw-linux.elf (in `_bin\linux\devel`) + * Remote File Path: `/tmp/eive_obsw.elf` + +# Transfering Files to the Q7S To transfer files from the local machine to the Q7S, use port forwarding @@ -355,7 +536,11 @@ From a windows machine files can be copied with putty tools (note: use IPv4 addr pscp -scp -P 22 eive@192.168.199.227:/example-file ```` -# Launching an application at start-up +More detailed information about the used q7s commands can be found in the Q7S user manual. + +# Q7S + +## Launching an application at start-up Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images). Note: It is not possible to modify the currently loaded root partition, e.g. @@ -420,58 +605,7 @@ creating directories. To do this, the parition needs to be mounted. systemctl status example ``` -More detailed information about the used q7s commands can be found in the Q7S user manual. - -## Setting up UNIX environment for real-time functionalities - -Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities -used by the UNIX pthread module are restricted, which will lead to permission errors when creating -these tasks and configuring real-time properites like scheduling priorities. - -To solve this issues, try following steps: - -1. Edit the /etc/security/limits.conf -file and add following lines at the end: -```sh - hard rtprio 99 - soft rtprio 99 -``` -The soft limit can also be set in the console with `ulimit -Sr` if the hard -limit has been increased, but it is recommended to add it to the file as well for convenience. -If adding the second line is not desired for security reasons, -the soft limit needs to be set for each session. If using an IDE like eclipse -in that case, the IDE needs to be started from the console after setting -the soft limit higher there. After adding the two lines to the file, -the computer needs to be restarted. - -It is also recommended to perform the following change so that the unlockRealtime -script does not need to be run anymore each time. The following steps -raise the maximum allowed message queue length to a higher number permanently, which is -required for some framework components. The recommended values for the new message -length is 130. - -2. Edit the /etc/sysctl.conf file - - ```sh - sudo nano /etc/sysctl.conf - ``` - - Append at end: - ```sh - fs/mqueue/msg_max = - ``` - - Apply changes with: - ```sh - sudo sysctl -p - ``` - - A possible solution which only persists for the current session is - ```sh - echo | sudo tee /proc/sys/fs/mqueue/msg_max - ``` - -# PCDU +## PCDU Connect to serial console of P60 Dock ```` @@ -496,102 +630,6 @@ p60-dock # param get out_en[0] GET out_en[0] = 1 ```` -# Debugging the software (when workstation is directly conncected to Q7S) - -1. Assign static IP address to Q7S - * Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user - manual chapter 10.3) - * Baudrate 115200 - * Login to Q7S: - * user: root - * pw: root - -2. Connect Q7S to workstation via ethernet -3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S - * When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation - is 192.168.133.2 - -4. Run tcf-agent on Q7S - - * Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually - - ```sh - git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git - cd org.eclipse.tcf.agent/agent - make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1 - ``` - - * Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S - - ```sh - cd obj/GNU/Linux/arm/Debug - scp agent root@192.168.133.10:/tmp - ``` - - * On Q7S - ```sh - cd /tmp - chmod +x agent - ``` - - * Run agent - ```sh - ./agent - ``` - -5. In Xilinx SDK 2018.2 right click on project → Debug As → Debug Configurations -6. Right click Xilinx C/C++ applicaton (System Debugger) → New → -7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent -8. Click New -9. Give connection a name -10. Set Host to static IP address of Q7S. e.g. 192.168.133.10 -11. Test connection (This ensures the TCF Agent is running on the Q7S) -12. Select Application tab - * Project Name: eive_obsw - * Local File Path: Path to eiveobsw-linux.elf (in `_bin\linux\devel`) - * Remote File Path: `/tmp/eive_obsw.elf` - -# Running cppcheck on the Software - -Static code analysis can be useful to find bugs. -`cppcheck` can be used for this purpose. On Windows you can use MinGW64 to do this. - -```sh -pacman -S mingw-w64-x86_64-cppcheck -``` - -On Ubuntu, install with - -```sh -sudo apt-get install cppcheck -``` - -You can use the Eclipse integration or you can perform the scanning manually from the command line. -CMake will be used for this. - -Run the CMake build generation commands specified above but supply -`-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to the build generation. Invoking the build command will -generate a `compile_commands.json` file which can be used by cppcheck. - -```sh -cppcheck --project=compile_commands.json --xml 2> report.xml -``` - -Finally, you can convert the generated `.xml` file to HTML with the following command - -```sh -cppcheck-htmlreport --file=report.xml --report-dir=cppcheck --source-dir=.. -``` - -# Special notes on Eclipse - -When using Eclipse, there are two special build variables in the project properties -→ C/C++ Build → Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set -the sysroot path in those variables to get any additional includes like `gpiod.h` in the -Eclipse indexer. - -# Q7S Utilities and Troubleshooting - ## Core commands Display currently running image: @@ -786,7 +824,76 @@ EIVE implementation - Folder `tm` for telemetry - Folder `xdi` for XDI components (e.g. for firmware or device tree updates) -# Running the EIVE OBSW on a Raspberry Pi +# Running cppcheck on the Software + +Static code analysis can be useful to find bugs. +`cppcheck` can be used for this purpose. On Windows you can use MinGW64 to do this. + +```sh +pacman -S mingw-w64-x86_64-cppcheck +``` + +On Ubuntu, install with + +```sh +sudo apt-get install cppcheck +``` + +You can use the Eclipse integration or you can perform the scanning manually from the command line. +CMake will be used for this. + +Run the CMake build generation commands specified above but supply +`-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to the build generation. Invoking the build command will +generate a `compile_commands.json` file which can be used by cppcheck. + +```sh +cppcheck --project=compile_commands.json --xml 2> report.xml +``` + +Finally, you can convert the generated `.xml` file to HTML with the following command + +```sh +cppcheck-htmlreport --file=report.xml --report-dir=cppcheck --source-dir=.. +``` + +# Eclipse + +When using Eclipse, there are two special build variables in the project properties +→ C/C++ Build → Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set +the sysroot path in those variables to get any additional includes like `gpiod.h` in the +Eclipse indexer. + +## Setting up default Eclipse for Q7S projects - TCF agent + +The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debugging on the Q7S. + +1. Install the TCF agent plugin in Eclipse from + the [releases](https://www.eclipse.org/tcf/downloads.php). Go to + Help → Install New Software and use the download page, for + example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. + +2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. + Here, the Q7S should show up if the local port forwarding was set up as explained previously. + Please note that you have to connect to `localhost` and port `1534` with port forwaring set up. + +3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. + Alternatively: + + - Create a new **TCF Remote Application** by pressing the cogs button at the top or going to + Run → Debug Configurations → Remote Application and creating a new one there. + + - Set up the correct image in the main tab (it might be necessary to send the image to the + Q7S manually once) and file transfer properties + + - It is also recommended to link the correct Eclipse project. + +After that, comfortable remote debugging should be possible with the Debug button. + +A build configuration and a shell helper script has been provided to set up the path variables and +build the Q7S binary on Windows, but a launch configuration needs to be newly created because the +IP address and path settings differ from machine to machine. + +# Running the EIVE OBSW on a Raspberry Pi Special section for running the EIVE OBSW on the Raspberry Pi. The Raspberry Pi build uses the `bsp_rpi` BSP folder, and a very similar cross-compiler. @@ -802,7 +909,7 @@ sudo apt-get install gpiod libgpiod-dev to install the required GPIO libraries before cloning the system root folder. -# Flight Software Framework (FSFW) +# Flight Software Framework (FSFW) An EIVE fork of the FSFW is submodules into this repository. To add the master upstream branch and merge changes and updates from it @@ -819,4 +926,5 @@ After that, an update can be merged by running git merge upstream/master ``` -Alternatively, changes from other upstreams (forks) and branches can be merged like that in the same way. +Alternatively, changes from other upstreams (forks) and branches can be merged like that +in the same way. From 4b4b75085cc3bb902d0078faf9e680d011a2d7ec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 00:45:52 +0200 Subject: [PATCH 06/19] added helper script --- q7s-port.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 q7s-port.sh diff --git a/q7s-port.sh b/q7s-port.sh new file mode 100755 index 00000000..a4042fd6 --- /dev/null +++ b/q7s-port.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "Setting up all Q7S ports" +echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" +echo "-L 1535:192.168.133.10:22 for file transfers" +echo "-L 1536:192.168.133.10:7301 to TMTC commanding using TCP" + +ssh -L 1534:192.168.133.10:1534 \ + -L 1535:192.168.133.10:22 \ + -L 1536:192.168.133.10:7301 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t /bin/bash From 4645b8d35b9cc45b7679533ada303c8f3f8c5d1e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 00:47:55 +0200 Subject: [PATCH 07/19] added script folder --- q7s-port.sh => scripts/q7s-port.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename q7s-port.sh => scripts/q7s-port.sh (100%) diff --git a/q7s-port.sh b/scripts/q7s-port.sh similarity index 100% rename from q7s-port.sh rename to scripts/q7s-port.sh From 474054f4d83d341939e1d345be4a95316a7fc3bb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 01:21:37 +0200 Subject: [PATCH 08/19] updated cp script --- scripts/q7s-cp.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 scripts/q7s-cp.py diff --git a/scripts/q7s-cp.py b/scripts/q7s-cp.py new file mode 100755 index 00000000..9de9d661 --- /dev/null +++ b/scripts/q7s-cp.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +import argparse +import os + + +def main(): + args = handle_args() + cmd = build_cmd(args) + # Run the command + print(f'Running command: {cmd}') + os.system(cmd) + + +def handle_args(): + help_string = 'This script copies files to the Q7S as long as port forwarding is active.\n' + help_string += 'You can set up port forwarding with ' \ + '"ssh -L 1535:192.168.133.10:22 " -t /bin/bash' + parser = argparse.ArgumentParser( + description=help_string + ) + # Optional arguments + parser.add_argument('-r', '--recursive', dest='recursive', default=False, action='store_true') + parser.add_argument('-t', '--target', help='Target destination', default='/tmp') + parser.add_argument('-P', '--port', help='Target port', default=1535) + # Positional argument(s) + parser.add_argument('source', help='Source files to copy') + return parser.parse_args() + + +def build_cmd(args): + # Build run command + cmd = 'scp ' + if args.recursive: + cmd += '-r ' + cmd += f'-P {args.port} {args.source} root@localhost:' + if args.target: + cmd += args.target + return cmd + + +if __name__ == "__main__": + main() From 0ff837baa14fe2bdd750f4c9987275628d255126 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 10:15:44 +0200 Subject: [PATCH 09/19] updated port script --- scripts/q7s-port.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/q7s-port.sh b/scripts/q7s-port.sh index a4042fd6..4bbf17e9 100755 --- a/scripts/q7s-port.sh +++ b/scripts/q7s-port.sh @@ -8,4 +8,4 @@ ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ - -t /bin/bash + -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' From 7ff133687eeb38e1c6ea8f8fa27d411f8ea40ccd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 10:46:50 +0200 Subject: [PATCH 10/19] README update --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 21ee5e40..512fa7b9 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,34 @@ ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 ssh eive@192.168.199.227 ``` +## Connecting to the serial console or ssh console + +A serial console session is up permanently in a `tmux` session + +### Serial console + +You can check whether the sessions exist with `tmux ls` + +```sh +tmux a -t q7s-serial +``` + +If the session does not exist, you can create it like this + +```sh +tmux new -s q7s-serial +/bin/bash +q7s_serial +``` + +### SSH console + +You can use the following command to connect to the Q7S with `ssh`: + +```sh +q7s_ssh +``` + ## Port forwarding for connection to TCF agent This is a required step to connect to the `tcf-agent` on the Q7S, which is required for convenient From 84ce7d22bf429765227117fb8302cf64badf1590 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:04:56 +0200 Subject: [PATCH 11/19] added logo --- README.md | 2 ++ doc/img/eive-logo.png | Bin 0 -> 106723 bytes 2 files changed, 2 insertions(+) create mode 100644 doc/img/eive-logo.png diff --git a/README.md b/README.md index 512fa7b9..d3fbb0b3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + EIVE On-Board Software ====== diff --git a/doc/img/eive-logo.png b/doc/img/eive-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce27fef6914207f1d5969e7793fbe7a258803d3 GIT binary patch literal 106723 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 Date: Mon, 26 Jul 2021 11:05:43 +0200 Subject: [PATCH 12/19] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3fbb0b3..a7283fb2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + EIVE On-Board Software ====== From 10507904e8f628c5aa75e934812e1a50b030da45 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:07:41 +0200 Subject: [PATCH 13/19] small update --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a7283fb2..f0f759b5 100644 --- a/README.md +++ b/README.md @@ -231,9 +231,11 @@ ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ - -t /bin/bash + -t 'export CONSOLE_PREFIX="[Q7S Tunnel] /bin/bash' ``` +There is also a shell script called `q7s-port.sh` which can be used to achieve the same. + # Setting up prerequisites ## Installing Vivado the the Xilinx development tools From be6ae6b7ae605389e909011a26d26791be6d02c7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:33:38 +0200 Subject: [PATCH 14/19] added TCP support --- bsp_hosted/InitMission.cpp | 4 ++-- bsp_hosted/ObjectFactory.cpp | 6 +++--- bsp_linux_board/InitMission.cpp | 4 ++-- bsp_linux_board/ObjectFactory.cpp | 6 +++--- bsp_q7s/core/InitMission.cpp | 17 +++++++++-------- bsp_q7s/core/ObjectFactory.cpp | 20 ++++++++++++++++---- common/config/commonConfig.h.in | 1 - common/config/commonObjects.h | 4 ++-- linux/fsfwconfig/OBSWConfig.h.in | 5 +++++ scripts/q7s-port-tcp.sh | 11 +++++++++++ scripts/{q7s-port.sh => q7s-port-udp.sh} | 2 +- 11 files changed, 54 insertions(+), 26 deletions(-) create mode 100755 scripts/q7s-port-tcp.sh rename scripts/{q7s-port.sh => q7s-port-udp.sh} (84%) diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 2743aa36..8ef40d06 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -72,13 +72,13 @@ void initmission::initTasks() { /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index acc0be37..0933df5b 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -28,7 +28,7 @@ void Factory::setStaticFrameworkObjectIds(){ CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; // No storage object for now. TmFunnel::storageDestination = objects::NO_OBJECT; @@ -40,7 +40,7 @@ void ObjectFactory::produce(void* args){ Factory::setStaticFrameworkObjectIds(); ObjectFactory::produceGenericObjects(); - new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); } diff --git a/bsp_linux_board/InitMission.cpp b/bsp_linux_board/InitMission.cpp index 9e7abd94..68423216 100644 --- a/bsp_linux_board/InitMission.cpp +++ b/bsp_linux_board/InitMission.cpp @@ -66,13 +66,13 @@ void initmission::initTasks() { /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 4f7dd59a..0d3e8ce5 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -45,7 +45,7 @@ void Factory::setStaticFrameworkObjectIds() { CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; // No storage object for now. TmFunnel::storageDestination = objects::NO_OBJECT; @@ -59,8 +59,8 @@ void ObjectFactory::produce(void* args){ Factory::setStaticFrameworkObjectIds(); ObjectFactory::produceGenericObjects(); - new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); GpioCookie* gpioCookie = nullptr; diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 712cf9c8..a619da5a 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -82,19 +82,20 @@ void initmission::initTasks() { } /* UDP bridge */ - PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); + initmission::printAddObjectError("UDP_BRIDGE", objects::TMTC_BRIDGE); } - PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); + initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK); } + // FS task, task interval does not matter because it runs in permanent loop, priority low // because it is a non-essential background task PeriodicTaskIF* fsTask = factory->createPeriodicTask( @@ -133,8 +134,8 @@ void initmission::initTasks() { sif::info << "Starting tasks.." << std::endl; tmTcDistributor->startTask(); - udpBridgeTask->startTask(); - udpPollingTask->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); coreController->startTask(); taskStarter(pstTasks, "PST task vector"); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 3e36e63d..53da02c5 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -63,9 +63,16 @@ #include "fsfw/tmtcservices/PusServiceBase.h" #include "fsfw/tmtcpacket/pus/tm.h" -/* UDP server includes */ +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 +// UDP server includes #include "fsfw/osal/common/UdpTmTcBridge.h" #include "fsfw/osal/common/UdpTcPollingTask.h" +#else +// TCP server includes +#include "fsfw/osal/common/TcpTmTcBridge.h" +#include "fsfw/osal/common/TcpTmTcServer.h" +#endif + #include "linux/boardtest/SpiTestClass.h" #if TEST_LIBGPIOD == 1 @@ -83,7 +90,7 @@ void Factory::setStaticFrameworkObjectIds() { CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; // No storage object for now. TmFunnel::storageDestination = objects::NO_OBJECT; @@ -131,8 +138,13 @@ void ObjectFactory::produce(void* args){ createReactionWheelComponents(gpioComIF); #endif /* TE7020 != 0 */ - new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 + new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); +#else + new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); +#endif /* Test Task */ #if OBSW_ADD_TEST_CODE == 1 diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index 6c5cb4c4..3d741bcf 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -3,5 +3,4 @@ #define OBSW_ADD_LWGPS_TEST 0 - #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 0505e570..8c9a83b9 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -8,8 +8,8 @@ enum commonObjects: uint32_t { /* First Byte 0x50-0x52 reserved for PUS Services **/ CCSDS_PACKET_DISTRIBUTOR = 0x50000100, PUS_PACKET_DISTRIBUTOR = 0x50000200, - UDP_BRIDGE = 0x50000300, - UDP_POLLING_TASK = 0x50000400, + TMTC_BRIDGE = 0x50000300, + TMTC_POLLING_TASK = 0x50000400, FILE_SYSTEM_HANDLER = 0x50000500, /* 0x43 ('C') for Controllers */ diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index ab55537d..e58261f1 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -17,6 +17,11 @@ /* These defines should be disabled for mission code but are useful for debugging. */ #define OBSW_VERBOSE_LEVEL 1 + +// Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally +// because UDP packets are not allowed in the VPN +#define OBSW_USE_TMTC_TCP_BRIDGE 1 + #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 #define OBSW_ADD_TEST_PST 1 diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh new file mode 100755 index 00000000..9a1cf3cd --- /dev/null +++ b/scripts/q7s-port-tcp.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "Setting up all Q7S ports" +echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" +echo "-L 1535:192.168.133.10:22 for file transfers" +echo "-L 1536:192.168.133.10:7303 to TMTC commanding using TCP" + +ssh -L 1534:192.168.133.10:1534 \ + -L 1535:192.168.133.10:22 \ + -L 1536:192.168.133.10:7303 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port.sh b/scripts/q7s-port-udp.sh similarity index 84% rename from scripts/q7s-port.sh rename to scripts/q7s-port-udp.sh index 4bbf17e9..21393083 100755 --- a/scripts/q7s-port.sh +++ b/scripts/q7s-port-udp.sh @@ -2,7 +2,7 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7301 to TMTC commanding using TCP" +echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ From 2a5f8241615a15a3aeaec82fd99206872eb7eb4f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:47:45 +0200 Subject: [PATCH 15/19] UDP remains default for now --- bsp_q7s/core/CoreController.cpp | 20 +++++++++++++++++++- bsp_q7s/core/CoreController.h | 1 + fsfw | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index a46c74f1..b72bbf62 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1,9 +1,14 @@ #include "CoreController.h" -#include "q7sConfig.h" +#include "OBSWConfig.h" #include "OBSWVersion.h" #include "fsfw/FSFWVersion.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 +#include "fsfw/osal/common/UdpTmTcBridge.h" +#else +#include "fsfw/osal/common/TcpTmTcBridge.h" +#endif #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" @@ -188,6 +193,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; } + initPrint(); return result; } @@ -349,3 +355,15 @@ ReturnValue_t CoreController::versionFileInit() { return HasReturnvaluesIF::RETURN_OK; } + +void CoreController::initPrint() { +#if OBSW_VERBOSE_LEVEL >= 1 +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 + sif::info << "Created UDP server for TMTC commanding with listener port " << + TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; +#else + sif::info << "Created TCP server for TMTC commanding with listener port " << + TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; +#endif +#endif +} diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index d815f302..88415949 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -41,6 +41,7 @@ private: SdCardManager::SdStatusPair& statusPair); ReturnValue_t versionFileInit(); + void initPrint(); }; diff --git a/fsfw b/fsfw index c5b4b013..1f6a5e63 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c5b4b0136217219a4443d858f42c368af9b15f27 +Subproject commit 1f6a5e635fcd6bd812e262cc65a15a8a054f7ecf diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index e58261f1..7a798717 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -20,7 +20,7 @@ debugging. */ // Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally // because UDP packets are not allowed in the VPN -#define OBSW_USE_TMTC_TCP_BRIDGE 1 +#define OBSW_USE_TMTC_TCP_BRIDGE 0 #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 From 3f509ce47258cf825b6872992245050dc417dd17 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:56:39 +0200 Subject: [PATCH 16/19] updated port forwarding scripts --- scripts/q7s-port-tcp.sh | 4 ++-- scripts/q7s-port-udp.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh index 9a1cf3cd..7688380b 100755 --- a/scripts/q7s-port-tcp.sh +++ b/scripts/q7s-port-tcp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7303 to TMTC commanding using TCP" +echo "-L 7303:192.168.133.10:7303 to TMTC commanding using TCP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1536:192.168.133.10:7303 \ + -L 7303:192.168.133.10:7303 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port-udp.sh b/scripts/q7s-port-udp.sh index 21393083..26003c44 100755 --- a/scripts/q7s-port-udp.sh +++ b/scripts/q7s-port-udp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" +echo "-L 7301:192.168.133.10:7301 to TMTC commanding using UDP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1536:192.168.133.10:7301 \ + -L 7301:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' From 4093b2cff22c0e53ae473955b100d52f6ccba907 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:58:28 +0200 Subject: [PATCH 17/19] updating README --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a7283fb2..6deaa770 100644 --- a/README.md +++ b/README.md @@ -216,20 +216,27 @@ You then need to run `scp` with the `-P 1535` flag with `localhost` as the targe ## Port forwarding for TMTC commanding -This requires using the TCP on sender side (Python client) and receiver side (OBSW TMTC TCP server). +If you are using the UDP communication interface, you can use: ```sh -ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 7301:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +For TCP, you can use + +```sh +ssh -L 7303:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` ## Set up all port forwarding at once -You can specify the `-L` option multiple times to set up all port forwarding at once +You can specify the `-L` option multiple times to set up all port forwarding at once. +Example for using the UDP communication interface: ```sh ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1536:192.168.133.10:7301 \ + -L 7301:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t /bin/bash ``` From 5b99199b6c2dd8a873de5194ab0b204febbdc0d5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 12:02:40 +0200 Subject: [PATCH 18/19] changed back some configuration --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7ed6a814..fc218749 100644 --- a/README.md +++ b/README.md @@ -219,15 +219,19 @@ You then need to run `scp` with the `-P 1535` flag with `localhost` as the targe If you are using the UDP communication interface, you can use: ```sh -ssh -L 7301:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` +This forwards UDP TMTC packets on port `1536` of localhost to the TMTC reception port of the Q7S. + For TCP, you can use ```sh -ssh -L 7303:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 1537:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` +This forwards TCP TMTC packets on port `1537` of localhost to the TMTC reception port of the Q7S. + ## Set up all port forwarding at once You can specify the `-L` option multiple times to set up all port forwarding at once. @@ -236,7 +240,7 @@ Example for using the UDP communication interface: ```sh ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 7301:192.168.133.10:7301 \ + -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'export CONSOLE_PREFIX="[Q7S Tunnel] /bin/bash' ``` From 9878b8defcd0ea5a12cda6bb916c2a465baa3f4e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 12:03:17 +0200 Subject: [PATCH 19/19] updated shell scripts --- scripts/q7s-port-tcp.sh | 4 ++-- scripts/q7s-port-udp.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh index 7688380b..9d370670 100755 --- a/scripts/q7s-port-tcp.sh +++ b/scripts/q7s-port-tcp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 7303:192.168.133.10:7303 to TMTC commanding using TCP" +echo "-L 1537:192.168.133.10:7303 to TMTC commanding using TCP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 7303:192.168.133.10:7303 \ + -L 1537:192.168.133.10:7303 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port-udp.sh b/scripts/q7s-port-udp.sh index 26003c44..21393083 100755 --- a/scripts/q7s-port-udp.sh +++ b/scripts/q7s-port-udp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 7301:192.168.133.10:7301 to TMTC commanding using UDP" +echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 7301:192.168.133.10:7301 \ + -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash'