merged develop
This commit is contained in:
commit
f0dc1279c4
648
README.md
648
README.md
@ -1,7 +1,25 @@
|
|||||||
|
<img align="center" src="./doc/img/eive-logo.png" width="20%">
|
||||||
|
|
||||||
<a id="top"></a> <a name="linux"></a> EIVE On-Board Software
|
<a id="top"></a> <a name="linux"></a> 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)
|
||||||
|
|
||||||
|
# <a id="general"></a> General information
|
||||||
|
|
||||||
Target systems:
|
Target systems:
|
||||||
|
|
||||||
@ -36,16 +54,210 @@ 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.
|
- 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.
|
- Windows Host: Uses the `bsp_hosted` BSP folder, the CMake MinGW Makefiles generator and MSYS2.
|
||||||
|
|
||||||
# Setting up development environment
|
# <a id="prereq"></a> 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
|
||||||
|
|
||||||
|
# <a id="build"></a> 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 \<target\> with either debug or release.
|
||||||
|
* When on Linux right click project → Properties → C/C++ Build → Set build command to `make <target> -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.
|
||||||
|
|
||||||
|
# <a id="host-commands"></a> 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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
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 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.
|
||||||
|
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 \
|
||||||
|
eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \
|
||||||
|
-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.
|
||||||
|
|
||||||
|
# <a id="set-up-prereq"></a> Setting up prerequisites
|
||||||
|
|
||||||
|
## <a id="vivado"></a> Installing Vivado the the Xilinx development tools
|
||||||
|
|
||||||
It's also possible to perform debugging with a normal Eclipse installation by installing
|
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,
|
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
|
if you want to generate the `*.xdi` files necessary to update the firmware, you need to
|
||||||
installed Vivado with the SDK core tools.
|
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
|
Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of
|
||||||
the updates. It is recommended to use the installer.
|
the updates. It is recommended to use the installer.
|
||||||
|
|
||||||
@ -85,7 +297,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)
|
[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)
|
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
|
## <a id="arm-toolchain"></a> Installing toolchain without Vivado
|
||||||
|
|
||||||
You can download the toolchains for Windows and Linux
|
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).
|
[from the EIVE cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files?dir=/EIVE_IRS/Software/tools&fileid=831898).
|
||||||
@ -136,7 +348,7 @@ wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/2Fp2ag6NGnbtAsK/downloa
|
|||||||
sudo apt-get install cmake
|
sudo apt-get install cmake
|
||||||
````
|
````
|
||||||
|
|
||||||
## Getting the Q7S system root
|
## <a id="q7s-sysroot"></a> Getting the Q7S system root
|
||||||
|
|
||||||
It is necessary to copy the Q7S system root to your local development machine for libraries
|
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
|
like `libgpio`. You can find the system root for the Q7S, the Raspberry Pi and the
|
||||||
@ -151,102 +363,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.
|
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
|
||||||
|
<username> hard rtprio 99
|
||||||
|
<username> 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
|
```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
|
```sh
|
||||||
git submodule init
|
fs/mqueue/msg_max = <newMsgMaxLen>
|
||||||
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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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 <newMsgMax> | 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.
|
## <a id="tcf-agent"></a> TCF-Agent
|
||||||
|
|
||||||
2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**.
|
Most of the steps specified here were already automated
|
||||||
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 \<target\> with either debug or release.
|
|
||||||
* When on Linux right click project → Properties → C/C++ Build → Set build command to `make <target> -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
|
|
||||||
|
|
||||||
1. On reboot, some steps have to be taken on the Q7S. Set static IP address and netmask
|
1. On reboot, some steps have to be taken on the Q7S. Set static IP address and netmask
|
||||||
|
|
||||||
@ -264,7 +432,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
|
You can run it manually there. To perform auto-start on boot, have a look at the start-up
|
||||||
application section.
|
application section.
|
||||||
|
|
||||||
# Debugging the software via Flatsat PC
|
# <a id="remote-debugging"></a> Remote Debugging
|
||||||
|
|
||||||
Open SSH connection to flatsat PC:
|
Open SSH connection to flatsat PC:
|
||||||
|
|
||||||
@ -298,6 +466,7 @@ console of the Q7S like this to set it
|
|||||||
picocom -b 115200 /dev/ttyUSB0
|
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
|
If the serial port is blocked for some reason, you can kill
|
||||||
the process using it with `q7s_kill`.
|
the process using it with `q7s_kill`.
|
||||||
|
|
||||||
@ -325,13 +494,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
|
This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address
|
||||||
192.168.133.10.
|
192.168.133.10. This needs to be done every time, so it is recommended to create an
|
||||||
This needs to be done every time, so it is recommended to create an alias to do this quickly.
|
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
|
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.
|
to localhost instead of the IP address of the Q7S.
|
||||||
|
|
||||||
# Transfering files via SCP
|
# <a id="direct-debugging"></a> 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`
|
||||||
|
|
||||||
|
# <a id="file-transfer"></a> Transfering Files to the Q7S
|
||||||
|
|
||||||
To transfer files from the local machine to the Q7S, use port forwarding
|
To transfer files from the local machine to the Q7S, use port forwarding
|
||||||
|
|
||||||
@ -355,7 +579,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:</directory-to-example-file/>/example-file </windows-machine-path/>
|
pscp -scp -P 22 eive@192.168.199.227:</directory-to-example-file/>/example-file </windows-machine-path/>
|
||||||
````
|
````
|
||||||
|
|
||||||
# Launching an application at start-up
|
More detailed information about the used q7s commands can be found in the Q7S user manual.
|
||||||
|
|
||||||
|
# <a id="q7s"></a> 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
|
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.
|
two xdi images). Note: It is not possible to modify the currently loaded root partition, e.g.
|
||||||
@ -420,58 +648,7 @@ creating directories. To do this, the parition needs to be mounted.
|
|||||||
systemctl status example
|
systemctl status example
|
||||||
```
|
```
|
||||||
|
|
||||||
More detailed information about the used q7s commands can be found in the Q7S user manual.
|
## PCDU
|
||||||
|
|
||||||
## 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
|
|
||||||
<username> hard rtprio 99
|
|
||||||
<username> 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 = <newMsgMaxLen>
|
|
||||||
```
|
|
||||||
|
|
||||||
Apply changes with:
|
|
||||||
```sh
|
|
||||||
sudo sysctl -p
|
|
||||||
```
|
|
||||||
|
|
||||||
A possible solution which only persists for the current session is
|
|
||||||
```sh
|
|
||||||
echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
|
|
||||||
```
|
|
||||||
|
|
||||||
# PCDU
|
|
||||||
|
|
||||||
Connect to serial console of P60 Dock
|
Connect to serial console of P60 Dock
|
||||||
````
|
````
|
||||||
@ -496,102 +673,6 @@ p60-dock # param get out_en[0]
|
|||||||
GET out_en[0] = 1
|
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
|
## Core commands
|
||||||
|
|
||||||
Display currently running image:
|
Display currently running image:
|
||||||
@ -773,7 +854,10 @@ EIVE implementation
|
|||||||
- Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir`
|
- Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir`
|
||||||
- Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir`
|
- Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir`
|
||||||
- Folder `scripts` in `/home/root` folder.
|
- 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
|
### SD Cards
|
||||||
|
|
||||||
@ -783,7 +867,76 @@ EIVE implementation
|
|||||||
- Folder `tm` for telemetry
|
- Folder `tm` for telemetry
|
||||||
- Folder `xdi` for XDI components (e.g. for firmware or device tree updates)
|
- Folder `xdi` for XDI components (e.g. for firmware or device tree updates)
|
||||||
|
|
||||||
# Running the EIVE OBSW on a Raspberry Pi
|
# <a id="static-code-analysis"></a> 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=..
|
||||||
|
```
|
||||||
|
|
||||||
|
# <a id="eclipse"></a> 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.
|
||||||
|
|
||||||
|
# <a id="rpi"></a> Running the EIVE OBSW on a Raspberry Pi
|
||||||
|
|
||||||
Special section for running the EIVE OBSW on the 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.
|
The Raspberry Pi build uses the `bsp_rpi` BSP folder, and a very similar cross-compiler.
|
||||||
@ -799,7 +952,7 @@ sudo apt-get install gpiod libgpiod-dev
|
|||||||
|
|
||||||
to install the required GPIO libraries before cloning the system root folder.
|
to install the required GPIO libraries before cloning the system root folder.
|
||||||
|
|
||||||
# Flight Software Framework (FSFW)
|
# <a id="fsfw"></a> Flight Software Framework (FSFW)
|
||||||
|
|
||||||
An EIVE fork of the FSFW is submodules into this repository.
|
An EIVE fork of the FSFW is submodules into this repository.
|
||||||
To add the master upstream branch and merge changes and updates from it
|
To add the master upstream branch and merge changes and updates from it
|
||||||
@ -816,4 +969,5 @@ After that, an update can be merged by running
|
|||||||
git merge upstream/master
|
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.
|
||||||
|
@ -72,13 +72,13 @@ void initmission::initTasks() {
|
|||||||
/* UDP bridge */
|
/* UDP bridge */
|
||||||
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
||||||
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"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) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||||
}
|
}
|
||||||
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
||||||
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"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) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ void Factory::setStaticFrameworkObjectIds(){
|
|||||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
|
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||||
// No storage object for now.
|
// No storage object for now.
|
||||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ void ObjectFactory::produce(void* args){
|
|||||||
Factory::setStaticFrameworkObjectIds();
|
Factory::setStaticFrameworkObjectIds();
|
||||||
ObjectFactory::produceGenericObjects();
|
ObjectFactory::produceGenericObjects();
|
||||||
|
|
||||||
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,13 +66,13 @@ void initmission::initTasks() {
|
|||||||
/* UDP bridge */
|
/* UDP bridge */
|
||||||
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
||||||
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"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) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||||
}
|
}
|
||||||
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
||||||
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"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) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ void Factory::setStaticFrameworkObjectIds() {
|
|||||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
|
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||||
// No storage object for now.
|
// No storage object for now.
|
||||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
@ -59,8 +59,8 @@ void ObjectFactory::produce(void* args){
|
|||||||
Factory::setStaticFrameworkObjectIds();
|
Factory::setStaticFrameworkObjectIds();
|
||||||
ObjectFactory::produceGenericObjects();
|
ObjectFactory::produceGenericObjects();
|
||||||
|
|
||||||
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
|
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
||||||
|
|
||||||
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
|
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
|
||||||
GpioCookie* gpioCookie = nullptr;
|
GpioCookie* gpioCookie = nullptr;
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
#include "CoreController.h"
|
#include "CoreController.h"
|
||||||
#include "q7sConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "OBSWVersion.h"
|
#include "OBSWVersion.h"
|
||||||
|
|
||||||
#include "fsfw/FSFWVersion.h"
|
#include "fsfw/FSFWVersion.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.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/scratchApi.h"
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
@ -188,6 +193,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
|||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
|
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
initPrint();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +275,8 @@ ReturnValue_t CoreController::incrementAllocationFailureCount() {
|
|||||||
ReturnValue_t CoreController::versionFileInit() {
|
ReturnValue_t CoreController::versionFileInit() {
|
||||||
|
|
||||||
std::string unameFileName = "/tmp/uname_version.txt";
|
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());
|
int result = std::system(unameCmd.c_str());
|
||||||
if(result != 0) {
|
if(result != 0) {
|
||||||
utility::handleSystemError(result, "CoreController::versionFileInit");
|
utility::handleSystemError(result, "CoreController::versionFileInit");
|
||||||
@ -348,3 +355,15 @@ ReturnValue_t CoreController::versionFileInit() {
|
|||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
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
|
||||||
|
}
|
||||||
|
@ -41,6 +41,7 @@ private:
|
|||||||
SdCardManager::SdStatusPair& statusPair);
|
SdCardManager::SdStatusPair& statusPair);
|
||||||
|
|
||||||
ReturnValue_t versionFileInit();
|
ReturnValue_t versionFileInit();
|
||||||
|
void initPrint();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,19 +82,20 @@ void initmission::initTasks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* UDP bridge */
|
/* UDP bridge */
|
||||||
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
||||||
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"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) {
|
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);
|
"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) {
|
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
|
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
||||||
// because it is a non-essential background task
|
// because it is a non-essential background task
|
||||||
PeriodicTaskIF* fsTask = factory->createPeriodicTask(
|
PeriodicTaskIF* fsTask = factory->createPeriodicTask(
|
||||||
@ -133,8 +134,8 @@ void initmission::initTasks() {
|
|||||||
|
|
||||||
sif::info << "Starting tasks.." << std::endl;
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
tmTcDistributor->startTask();
|
tmTcDistributor->startTask();
|
||||||
udpBridgeTask->startTask();
|
tmtcBridgeTask->startTask();
|
||||||
udpPollingTask->startTask();
|
tmtcPollingTask->startTask();
|
||||||
coreController->startTask();
|
coreController->startTask();
|
||||||
|
|
||||||
taskStarter(pstTasks, "PST task vector");
|
taskStarter(pstTasks, "PST task vector");
|
||||||
|
@ -63,9 +63,16 @@
|
|||||||
#include "fsfw/tmtcservices/PusServiceBase.h"
|
#include "fsfw/tmtcservices/PusServiceBase.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tm.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/UdpTmTcBridge.h"
|
||||||
#include "fsfw/osal/common/UdpTcPollingTask.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"
|
#include "linux/boardtest/SpiTestClass.h"
|
||||||
|
|
||||||
#if TEST_LIBGPIOD == 1
|
#if TEST_LIBGPIOD == 1
|
||||||
@ -83,7 +90,7 @@ void Factory::setStaticFrameworkObjectIds() {
|
|||||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
TmFunnel::downlinkDestination = objects::UDP_BRIDGE;
|
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||||
// No storage object for now.
|
// No storage object for now.
|
||||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
@ -131,8 +138,13 @@ void ObjectFactory::produce(void* args){
|
|||||||
createReactionWheelComponents(gpioComIF);
|
createReactionWheelComponents(gpioComIF);
|
||||||
#endif /* TE7020 != 0 */
|
#endif /* TE7020 != 0 */
|
||||||
|
|
||||||
new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||||
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);
|
||||||
|
#else
|
||||||
|
new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
|
new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Test Task */
|
/* Test Task */
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
|
@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
#define OBSW_ADD_LWGPS_TEST 0
|
#define OBSW_ADD_LWGPS_TEST 0
|
||||||
|
|
||||||
|
|
||||||
#endif /* COMMON_CONFIG_COMMONCONFIG_H_ */
|
#endif /* COMMON_CONFIG_COMMONCONFIG_H_ */
|
||||||
|
@ -8,8 +8,8 @@ enum commonObjects: uint32_t {
|
|||||||
/* First Byte 0x50-0x52 reserved for PUS Services **/
|
/* First Byte 0x50-0x52 reserved for PUS Services **/
|
||||||
CCSDS_PACKET_DISTRIBUTOR = 0x50000100,
|
CCSDS_PACKET_DISTRIBUTOR = 0x50000100,
|
||||||
PUS_PACKET_DISTRIBUTOR = 0x50000200,
|
PUS_PACKET_DISTRIBUTOR = 0x50000200,
|
||||||
UDP_BRIDGE = 0x50000300,
|
TMTC_BRIDGE = 0x50000300,
|
||||||
UDP_POLLING_TASK = 0x50000400,
|
TMTC_POLLING_TASK = 0x50000400,
|
||||||
FILE_SYSTEM_HANDLER = 0x50000500,
|
FILE_SYSTEM_HANDLER = 0x50000500,
|
||||||
|
|
||||||
/* 0x43 ('C') for Controllers */
|
/* 0x43 ('C') for Controllers */
|
||||||
|
BIN
doc/img/eive-logo.png
Normal file
BIN
doc/img/eive-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
2
fsfw
2
fsfw
@ -1 +1 @@
|
|||||||
Subproject commit b83259592a1f0ae5af20b00d1aef813fa26cd350
|
Subproject commit 1f6a5e635fcd6bd812e262cc65a15a8a054f7ecf
|
@ -17,6 +17,11 @@
|
|||||||
/* These defines should be disabled for mission code but are useful for
|
/* These defines should be disabled for mission code but are useful for
|
||||||
debugging. */
|
debugging. */
|
||||||
#define OBSW_VERBOSE_LEVEL 1
|
#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 0
|
||||||
|
|
||||||
#define OBSW_PRINT_MISSED_DEADLINES 1
|
#define OBSW_PRINT_MISSED_DEADLINES 1
|
||||||
#define OBSW_ADD_TEST_CODE 1
|
#define OBSW_ADD_TEST_CODE 1
|
||||||
#define OBSW_ADD_TEST_PST 1
|
#define OBSW_ADD_TEST_PST 1
|
||||||
|
42
scripts/q7s-cp.py
Executable file
42
scripts/q7s-cp.py
Executable file
@ -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 <eive-flatsat-ip>" -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()
|
11
scripts/q7s-port-tcp.sh
Executable file
11
scripts/q7s-port-tcp.sh
Executable file
@ -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 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 1537:192.168.133.10:7303 \
|
||||||
|
eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \
|
||||||
|
-t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash'
|
11
scripts/q7s-port-udp.sh
Executable file
11
scripts/q7s-port-udp.sh
Executable file
@ -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 UDP"
|
||||||
|
|
||||||
|
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 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash'
|
2
thirdparty/arcsec_star_tracker
vendored
2
thirdparty/arcsec_star_tracker
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f596c53315f1f81facb28faec3150612a5ad2ca0
|
Subproject commit c468400aaf8470a31e393f53c858d2bf2c361273
|
Loading…
Reference in New Issue
Block a user