eive-obsw/README.md
Robin Mueller 146035de5a
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Merge remote-tracking branch 'origin/develop' into mueller/master
2021-09-02 09:14:28 +02:00

1094 lines
35 KiB
Markdown

<img align="center" src="./doc/img/eive-logo.png" width="20%">
<a id="top"></a> <a name="linux"></a> EIVE On-Board Software
======
# 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:
* OBC with Linux OS
* Xiphos Q7S
* Based on Zynq-7020 SoC (xc7z020clg484-2)
* Dual-core ARM Cortex-A9
* 766 MHz
* Artix-7 FPGA (85K pogrammable logic cells)
* Datasheet at https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/Q7S&fileid=340648
* Also a lot of information about the Q7S can be found on
the [Xiphos Traq Platform](https://trac2.xiphos.ca/eive-q7). Press on index to find all
relevant pages. The most recent datasheet can be found
[here](https://trac2.xiphos.ca/manual/wiki/Q7RevB/UserManual).
* Linux OS built with Yocto 2.5
* Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git . EIVE version can be found
[here](https://github.com/spacefisch/linux-xlnx) . Pre-compiled files can be
found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/q7s-linux-components&fileid=777299).
* Q7S base project can be found [here](https://egit.irs.uni-stuttgart.de/eive/q7s-base)
* Minimal base project files can be found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/xiphos-q7s-sdk&fileid=510908)
* Host System
* Generic software components which are not dependant on hardware can also
be run on a host system. All host code is contained in the `bsp_hosted` folder
* Tested for Linux (Ubuntu 20.04) and Windows 10
* Raspberry Pi
* EIVE OBC can be built for Raspberry Pi as well (either directly on Raspberry Pi or by installing a cross compiler)
The steps in the primary README are related to the main OBC target Q7S.
The CMake build system can be used to generate build systems as well (see helper scripts in `cmake/scripts`:
- Linux (Raspberry Pi): See special section below.
- Linux 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.
# <a id="prereq"></a> Prerequisites
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](https://wiki.eclipse.org/TCF) 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 &rarr; Import &rarr; C/C++ &rarr; Existing Code as Makefile Project
3. Set build command. Replace \<target\> with either debug or release.
* When on Linux right click project &rarr; Properties &rarr; C/C++ Build &rarr; 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 &rarr; Show View &rarr; Make Target)
* Right click eive_obsw &rarr; 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)
## Build generation
Replace `Debug` with `Release` for release build. Add `-G "MinGW Makefiles` or `-G "Ninja"`
on Windows or when `ninja` should be used. You can build with `cmake --build . -j` after
build generation. You can finds scripts in `cmake/scripts` to perform the build commands
automatically.
### Q7S OBSW
```sh
mkdir build-Debug-Q7S && cd build-Debug-Q7S
cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j
```
### Q7S Watchdog
```sh
mkdir build-Debug-Q7S && cd build-Debug-Q7S
cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DEIVE_BUILD_WATCHDOG=ON -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j
```
## 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
```
Other useful tmux commands:
- Enable scroll mode: You can press `ctrl + b` and then `[` (`AltGr + 8`) to enable scroll mode.
You can quit scroll mode with `q`.
- Kill a tmux session: run `ctrl + b` and then `k`.
- Detach from a tmux session: run `ctrl + b` and then `d`
- [Pipe last 3000 lines](https://unix.stackexchange.com/questions/26548/write-all-tmux-scrollback-to-a-file)
into file for copying or analysis:
1. `ctrl + b` and `:`
2. `capture-pane -S -3000` + `enter`
3. `save-buffer /tmp/tmux-output.txt` + `enter`
### 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
You can enable port forwarding for TMTC commanding with the following command:
```sh
ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash
```
This forwards TMTC packets on port `1536` of localhost to the TMTC reception port of the Q7S.
## Set up all port forwarding at once
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
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](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.
* Install settings. In the Devices selection, it is sufficient to pick SoC &rarr; Zynq-7000: <br>
<img src="https://egit.irs.uni-stuttgart.de/eive/eive-obsw/raw/branch/develop/doc/img/vivado-edition.png" width="50%"> <br>
<img src="https://egit.irs.uni-stuttgart.de/eive/eive-obsw/raw/branch/mueller/master/doc/img/vivado-hl-design.png" width="50%"> <br>
<img src="https://egit.irs.uni-stuttgart.de/eive/eive-obsw/raw/branch/mueller/master/doc/img/xilinx-install.PNG" width="50%"> <br>
* For supported OS refer to https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug973-vivado-release-notes-install-license.pdf .
Installation was tested on Windows and Ubuntu 21.04.
* Add path of linux cross-compiler to permanent environment variables (`.bashrc` file in Linux):
`<XilinxInstallation>\SDK\2018.2\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin`
or set up path each time before debugging.
### Installing on Linux - Device List Issue
When installing on Ubuntu, the installer might get stuck at the `Generating installed device list`
step. When this happens, you can kill the installation process (might be necessara to kill a process
twice) and generate this list manually with the following commands, according to
[this forum entry](https://forums.xilinx.com/t5/Installation-and-Licensing/Vivado-2018-3-Final-Processing-hangs-at-Generating-installed/m-p/972114#M25861).
1. Install the following library
```sh
sudo apt install libncurses5
```
2. ```sh
sudo <installRoot>/Vivado/2018.2/bin/vivado -nolog -nojournal -mode batch -source
<installRoot>/.xinstall/Vivado_2018.2/scripts/xlpartinfo.tcl -tclargs
<installRoot>/Vivado/2018.2/data/parts/installed_devices.txt
```
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)
### Compatibility issues with wayland on more recent Linux distributions
If Vivado crashes and you find following lines in the `hs_err_pid*` files:
```sh
#
# An unexpected error has occurred (11)
#
Stack:
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/server/libjvm.so(+0x923da9) [0x7f666cf5eda9]
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/server/libjvm.so(JVM_handle_linux_signal+0xb6) [0x7f666cf653f6]
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/server/libjvm.so(+0x9209d3) [0x7f666cf5b9d3]
/lib/x86_64-linux-gnu/libc.so.6(+0x35fc0) [0x7f66a993efc0]
/opt/Xilinx/Vivado/2017.4/tps/lnx64/jre/lib/amd64/libawt_xawt.so(+0x42028) [0x7f664e24d028]
...
```
You can [solve this](https://forums.xilinx.com/t5/Design-Entry/Bug-Vivado-2017-4-crashing-on-rightclick-in-console-log/td-p/881811)
by logging in with `xorg` like specified [here](https://www.maketecheasier.com/switch-xorg-wayland-ubuntu1710/).
### Using `docnav` on more recent Linux versions
If you want to use `docnav` for navigating Xilinx documentation, it is recommended to install
it as a standalone version from [here](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/documentation-nav.html).
This is because the `docnav` installed as part of version 2018.2 requires `libpng12`, which is not part of
more recent disitributions anymore.
## <a id="arm-toolchain"></a> 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).
If `wget` is available (e.g. MinGW64), you can use the following command to download the
toolchain for Windows
```sh
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/rfoaistRd67yBbH/download/gcc-arm-linux-gnueabi-win.zip
```
or the following command for Linux (could be useful for CI/CD)
```sh
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/MRaeA2XnMXpZ5Pp/download/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
```
## Installing CMake and MSYS2 on Windows
1. Install [MSYS2](https://www.msys2.org/) and [CMake](https://cmake.org/download/) first.
2. Open the MinGW64 console. It is recommended to set up aliases in `.bashrc` to navigate to the
software repository quickly
3. Run the following commands in MinGW64
```sh
pacman -Syu
```
It is recommended to install the full base development toolchain
```sh
pacman -S base-devel
```
It is also possible to only install required packages
```sh
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-make mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb python3
```
## Installing CMake on Linux
1. Run the following command
```sh
sudo apt-get install cmake
````
## <a id="q7s-sysroot"></a> Getting the Q7S system root
It is necessary to copy the Q7S system root to your local development machine for libraries
like `libgpio`. You can find the system root for the Q7S, the Raspberry Pi and the
Beagle Bone Black for download here
[here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/rootfs&fileid=831849).
Download it and unzip it somewhere in the Xilinx installation folder.
You can use the following command if `wget` can be used or for CI/CD:
```
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/agnJGYeRf6fw2ci/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
```
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
## 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
```
## <a id="tcf-agent"></a> 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
```sh
ifconfig eth0 192.168.133.10
ifconfig eth0 netmask 255.255.255.0
```
2. `tcfagent` application should run automatically but this can be checked with
```sh
systemctl status tcfagent
```
3. If the agent is not running, check whether `agent` is located inside `usr/bin`.
You can run it manually there. To perform auto-start on boot, have a look at the start-up
application section.
# <a id="remote-debugging"></a> Remote Debugging
Open SSH connection to flatsat PC:
```sh
ssh eive@flatsat.eive.absatvirt.lw
```
or
```sh
ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
```
or
```sh
ssh eive@192.168.199.227
```
If the static IP address of the Q7S has already been set,
you can access it with ssh
```sh
ssh root@192.168.133.10
```
If this has not been done yet, you can access the serial
console of the Q7S like this to set it
```sh
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`.
You can use `AltGr` + `X` to exit the picocom session.
To debug an application, first make sure a static IP address is assigned to the Q7S. Run ifconfig
on the Q7S serial console.
```sh
ifconfig
```
Set IP address and netmask with
```sh
ifconfig eth0 192.168.133.10
ifconfig eth0 netmask 255.255.255.0
```
To launch application from Xilinx SDK setup port fowarding on the development machine
(not on the flatsat!)
```sh
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 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.
# <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 &rarr; Debug As &rarr; Debug Configurations
6. Right click Xilinx C/C++ applicaton (System Debugger) &rarr; New &rarr;
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
```sh
ssh -L 1535:192.168.133.10:22 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5
```
An `example` file can be copied like this
```sh
scp -P 1535 example root@localhost:/tmp
```
Copying a file from Q7S to flatsat PC
````
scp -P 22 root@192.168.133.10:/tmp/kernel-config /tmp
````
From a windows machine files can be copied with putty tools (note: use IPv4 address)
````
pscp -scp -P 22 eive@192.168.199.227:</directory-to-example-file/>/example-file </windows-machine-path/>
````
More detailed information about the used q7s commands can be found in the Q7S user manual.
# <a id="q7s"></a> Q7S OBC
## Launching an application at start-up
You can also do the steps performed here on a host computer inside the `q7s-rootfs` directory
of the [Q7S base repository](https://egit.irs.uni-stuttgart.de/eive/q7s-base). This might
be more convenient while also allowing to update all images at once with the finished `rootfs.xdi`.
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.
creating directories. To do this, the parition needs to be mounted.
1. Disable write protection of the desired root partition
```sh
writeprotect 0 0 0 # unlocks nominal image on nor-flash 0
```
2. Mount the root partition
```sh
xsc_mount_copy 0 0 # Mounts the nominal image from nor-flash 0
```
The mounted partition will be located inside the `/tmp` folder
3. Copy the executable to `/usr/bin`
4. Make sure the permissions to execute the application are set
```sh
chmod +x application
```
5. Create systemd service in `/etc/systemd/system`. The following shows an example service.
```sh
cat > example.service
[Unit]
Description=Example Service
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/bin/application
[Install]
WantedBy=multi-user.target
```
6. Enable the service. This is normally done with `systemctl enable <service>` which would create
a symlink in the `multi-user.target.wants` directory. However, this is not possible
when the service is created for a mounted root partition. It is also not possible during run
time because symlinks can't be created in a read-only filesystem. Therefore, relative symlinks
are used like this:
```sh
cd etc/systemd/system/multi-user.target.wants/
ln -s ../example.service example.service
```
You can check the symlinnks with `ls -l`
7. The modified root partition is written back when the partion is locked again.
```sh
writeprotect 0 0 1
```
8. Now verify the application start by booting from the modified image
```sh
xsc_boot_copy 0 0
````
9. After booting verify if the service is running
```sh
systemctl status example
```
## Current user systemd services
The following custom `systemd` services are currently running on the Q7S and can be found in
the `/etc/systemd/system` folder.
You can query that status of a service by running `systemctl status <serviceName>`.
### `eive-watchdog`
The watchdog will create a pipe at `/tmp/watchdog-pipe` which can be used both by the watchdog and
the EIVE OBSW. The watchdog will only read from this pipe while the OBSW will only write
to this pipe. The watchdog checks for basic ASCII commands as a first basic feature set.
The most important functionality is that the watchdog cant detect if a timeout
has happened. This can happen beause the OBSW is hanging (or at least the CoreController thread) or
there is simply now OBSW running on the system. It does to by checking whether the FIFO is
regulary written to, which means the EIVE OBSW is alive.
If the EIVE OBSW is alive, a special file called `/tmp/obsw-running` will be created.
This file can be used by any other software component to query whether the EIVE OBSW is running.
The EIVE OBSW itself can be configured to check whether this file exists, which prevents two
EIVE OBSW instances running on the Q7S at once.
If a timeout occurs, this special file will be deleted as well.
The watchdog and its configuration will be directly integrated into this repostory, which
makes adaptions easy.
### `tcfagent`
This starts the `/usr/bin/agent` program to allows remote debugging. Might not be part of
the mission code
### `eive-early-config`
This is a configuration script which runs early after `local-fs.target` and `sysinit.target`
Currently only pipes the output of `xsc_boot_copy` into the file `/tmp/curr_copy.txt` which can be
used by other software components to read the current chip and copy.
### `eive-post-ntpd-config`
This is a configuration scripts which runs after the Network Time Protocol has run. This script
currently sets the static IP address `192.168.133.10` and starts the `can` interface.
## PCDU
Connect to serial console of P60 Dock
````
picocom -b 500000 /dev/ttyUSBx
````
General information
````
cmp ident
````
List parameter table:
x values: 1,2 or 4
````
param list x
````
Table 4 lists HK parameters
Changing parameters
First switch to table where parameter shall be changed (here table id is 1)
````
p60-dock # param mem 1
p60-dock # param set out_en[0] 1
p60-dock # param get out_en[0]
GET out_en[0] = 1
````
## Core commands
Display currently running image:
```sh
xsc_boot_copy
```
Rebooting currently running image:
```sh
xsc_boot_copy -r
```
### Setting time on Q7S
Setting date and time (only timezone UTC available)
````
timedatectl set-time 'YYYY-MM-DD HH:MM:SS'
````
Setting UNIX time
````
date +%s -s @1626337522
````
This only sets the system time and does not updating the time of the real time clock. To harmonize
the system time with the real time clock run
````
hwclock -w
````
Reading the real time clock
````
hwclock --show
````
## pa3tool Host Tool
The `pa3tool` is a host tool to interface with the ProASIC3 on the Q7S board. It was
installed on the clean room PC but it can also be found
[on the Traq platform](https://trac2.xiphos.ca/manual/attachment/wiki/WikiStart/libpa3-1.3.4.tar.gz).
For more information, see Q7S datasheet.
## Creating files with cat and echo
The only folder which can be written in the root filesystem is the `tmp` folder.
You can create a simple file with initial content with `echo`
```sh
echo "Hallo Welt" > /tmp/test.txt
cat /tmp/test.txt
```
For more useful combinations, see this [link](https://www.freecodecamp.org/news/the-cat-command-in-linux-how-to-create-a-text-file-with-cat-or-touch/).
## Using the scratch buffer of the ProASIC3
The ProASIC3 has a 1024 byte scratch buffer. The values in this scratch buffer will survive
a reboot, so this buffer can be used as an alternative to the SD cards to exchange information
between images or to store mission critical information.
You can use `xsc_scratch --help` for more information.
Write to scratch buffer:
```sh
xsc_scratch write TEST "1"
```
Read from scratch buffer:
```sh
xsc_scratch read TEST
```
Read all keys:
```sh
xsc_scratch read
```
Get fill count:
```sh
xsc_scratch read | wc -c
```
## Using `system` when debugging
Please note that when using a `system` call in C++/C code and debugging, a new thread will be
spawned which will appear on the left in Eclipse or Xilinx SDK as a `sh` program.
The debugger might attach to this child process automatically, depending on debugger configuration,
and the process needs to be selected and continued/started manually. You can enable or disable
this behaviour by selecting or deselecting the `Attach Process Children` option in the Remote
Application Configuration for the TCF plugin like shown in the following picture
<img src="https://egit.irs.uni-stuttgart.de/eive/eive-obsw/raw/branch/develop/doc/img/ProcessSettings.png" width="50%"> <br>
## Libgpiod
Detect all gpio device files:
````
gpiodetect
````
Get info about a specific gpio group:
````
gpioinfo <name of gpio group>
````
The following sets the gpio 18 from gpio group gpiochip7 to high level.
````
gpioset gpiochip7 18=1
````
Setting the gpio to low.
````
gpioset gpiochip7 18=0
````
Show options for setting gpios.
````
gpioset -h
````
To get the state of a gpio:
````
gpioget <gpiogroup> <offset>
````
Example to get state:
gpioget gpiochip7 14
Both the MIOs and EMIOs can be accessed via the zynq_gpio instance which
comprises 118 pins (54 MIOs and 64 EMIOs).
## Xilinx UARTLIE
Get info about ttyUL* devices
````
cat /proc/tty/driver
````
## I2C
Getting information about I2C device
````
ls /sys/class/i2c-dev/i2c-0/device/device/driver
````
This shows the memory mapping of /dev/i2c-0
## CAN
```sh
ip link set can0 down
ip link set can0 type can loopback off
ip link set can0 up type can bitrate 1000000
```
Following command sends 8 bytes to device with id 99 (for petalinux)
````
cansend can0 -i99 99 88 77 11 33 11 22 99
````
For Q7S use this:
````
cansend can0 5A1#11.22.33.44.55.66.77.88
````
Turn loopback mode on:
````
ip link set can0 type can bitrate 1000000 loopback on
````
Reading data from CAN:
````
candump can0
````
## Dump content of file in hex
````
cat file.bin | hexdump -C
````
All content will be printed with
````
cat file.bin | hexdump -v
````
To print only the first X bytes of a file
````
cat file.bin | hexdump -v -n X
````
## Preparation of a fresh rootfs and SD card
This section summarizes important changes between a fresh rootfs and the current
EIVE implementation
### rootfs
- 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 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
- Folder `bin` for binaries, for example the OBSW
- Folder `misc` for miscellaneous files. Contains `ls` for directory listings
- Folder `tc` for telecommands
- Folder `tm` for telemetry
- Folder `xdi` for XDI components (e.g. for firmware or device tree updates)
# <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
&rarr; C/C++ Build &rarr; 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 &rarr; 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 &rarr; Perspective &rarr; 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 &rarr; Debug Configurations &rarr; 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.
The Raspberry Pi build uses the `bsp_rpi` BSP folder, and a very similar cross-compiler.
For running the software on a Raspberry Pi, it is recommended to follow the steps specified in
[the fsfw example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example/src/branch/mueller/master/doc/README-rpi.md#top)
and using the TCF agent to have a similar set-up process also required for the Q7S.
You should run the following command first on your Raspberry Pi
```sh
sudo apt-get install gpiod libgpiod-dev
```
to install the required GPIO libraries before cloning the system root folder.
# <a id="fsfw"></a> 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
into the fork, run the following command in the fsfw folder first:
```sh
git remote add upstream https://egit.irs.uni-stuttgart.de/fsfw/fsfw.git
git remote update --prune
```
After that, an update can be merged by running
```sh
git merge upstream/master
```
Alternatively, changes from other upstreams (forks) and branches can be merged like that
in the same way.