2  Rechner vorbereiten

Dieser Text beschreibt die Installation der ES2 Arbeitsumgebung unter Linux. Wir werden beim Kurs hauptsächlich unter Linux im Terminal auf der Kommandozeile arbeiten, sollte ihnen das noch nicht so geläufig sein, dann nehmen sie den Kurs gerne als Anlass hier etwas aufzuholen. Wir werden auch nur freie Software (im Sinne von Open-Source) zur Programmentwicklung verwenden, im wesentlichen sind das die “GNU” Tools.

Der erste Abschnitt richtet sich an Leute die Windows 10 oder 11 auf ihrem Rechner installiert haben. Mit dem Windows Subsystem für Linux in der Version 2 kann man Linux innerhalb von Windows betreiben. Alle weiteren Abschnitte sind unabhängig davon, ob man auf einem “realen” Linux, in WSL2 oder in VirtualBox arbeitet.

2.1 WSL2 installieren (nur bei Windows 10/11)

Bei dieser Anleitung habe ich mich an https://goneuland.de/windows-10-subsystem-fuer-linux-wsl-2-installieren gehalten.

Wichtig ist auch, dass zunächst im BIOS des Rechners die Virtualisierung aktiviert wird. Der folgende Artikel behandelt diese BIOS Einstellungen ausführlich: https://s1gr1d.medium.com/how-to-set-up-linux-on-windows-with-wsl-2-debe2a64d20d

WSL aktivieren

In Powershell (Administrator) eingeben

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

Update auf WSL2

  • Windows muss mindestens Version 1903 sein (Windows Taste + R”, winver eingeben)

  • Powershell Eingabe:

    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
  • PC neu starten

  • WSL update herunterladen von https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi und installieren

  • WSL2 als Standard festlegen

    wsl --set-default-version 2
  • Welche Linux Distributionen gibt es?

    wsl.exe --list --online
  • Debian installieren

    wsl.exe --install -d Debian
  • Distro entfernen - auch alle Daten sind dann gelöscht!

    wsl --unregister Debian

Kommandos

Version und Status ausgeben

wsl.exe -l -v

Welche Distributionen gibt es?

wsl.exe --list --online

Distribution installieren

wsl.exe --install -d Debian

Distribution für Benutzer ausführen

wsl.exe --distribution <Distribution Name> --user <User Name>

WSL Version ausgeben

wsl.exe --version

Shutdown

wsl.exe --shutdown Debian

Beenden und neu starten (das WSL wird neu gestartet, auf der Kommandozeile in WSL sieht man das aber nicht)

wsl.exe --terminate debian

Mountpunkte

  • /mnt/c
  • /mnt/wsl
  • /mnt/wslg

USBIPD installieren unter Windows

Dieser Schritt ist nötig, da sich Windows alle angeschlossenen USB Geräte schnappt. Mit USBIPD gibt man bestimmte USB Geräte an die Linux Distribution weiter.

Auf der Homepage des Projekts unter

https://github.com/dorssel/usbipd-win

findet man einen msi Installer:

https://github.com/dorssel/usbipd-win/releases/

Mit

usbipd list

bekommt man eine Liste der angeschlossenen USB Geräte (das STM32L476 Nucleo ist über USB angeschlossen):

BUSID  VID:PID    DEVICE
STATE
3-1    046d:c534  USB-Eingabegerät                                              Not attached
3-6    04f2:b221  Integrated Camera                                             Not attached
4-2    0483:374b  ST-Link Debug, USB-Massenspeichergerät, Serielles USB-Ger...  Not attached

Danach “attached” man das gewünschte Gerät, in unserem Fall ist das der ST-Link Debugger auf dem Nucleo Board:

usbipd attach --wsl --busid 4-2

Mit usbipd list sieht man, dass das Gerät nun im Zustand “attached” ist.

Im Debian (in WSL2) installiert man die Pakete “usbip” und “usbutils” (darin ist lsusb).

sudo apt install usbip usbutils

Danach erkennt das lsusb Kommando in Debian das USB Gerät (sudo ist dazu nötig). Die Ausgabe sollte so ähnlich sein:

$ sudo lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 0483:374b STMicroelectronics ST-LINK/V2.1
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Quelle: https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl/

Damit man ohne sudo auf die USB Geräte zugreifen kann müssen udev Regeln angelegt werden. Prinzipiell funktioniert das unter dem virtuellen Debian genauso wie im richtigen Debian - ist also weiter unten im Text beschrieben. Allerdings muss man bei WSL2 zunächst noch den udev Service aktivieren. Den aktuellen Status findet man mit sudo service udev status heraus.

Falls /etc/wsl.conf noch nicht existiert, legt man sie an mit den folgenden drei Zeilen:

[boot]
command="service udev start"
systemd=true

Die dritte Zeile ist optional, wenn sie vorhanden ist wird der systemd aktiviert.

Um das Zusammenspiel mit Windows zu verbessern kann man auch die folgenden zwei Zeilen einfügen (Danke für den Tipp):

[interop]
appendWindowsPath=true

Nun beendet man Debian und startet es sofort neu mit dem Kommando

wsl.exe --terminate debian

Dieser Vorgang dauert einige Sekunden, danach sollte der Zugriff auf die USB Geräte auch ohne sudo möglich sein, sofern die USB Regeln installiert sind.

Falls systemd aktiviert wurde, kann man die laufenden Dienste wie folgt ausgeben:

systemctl list-units --type=service

WSL Konfiguration

Es gibt zwei Konfigurationsdateien, die am Anfang noch nicht existieren:

  • C:\Users\<UserName>\.wslconfig (in Windows)

    In diese Datei stehen globale WSL2 Einstellungen, z.B. wie viel Speicher
    und Prozessoren die Linux VMs bekommen sollen.

  • /etc/wsl.conf (in Linux)

    Hier sind die Einstellungen der jeweiligen Linux VM zu finden. Zum Beispiel kann man Dienste beim Booten starten oder systemd aktivieren.

Quelle: https://learn.microsoft.com/en-us/windows/wsl/wsl-config

Pakete in Linux installieren

  • Pakete, die sie unter Linux installieren sollten, falls sie noch nicht vorhanden sind (sudo apt install ...):
    • wget

    • openssh-client

    • git

    • tmux

      Die Konfigurationsdatei holt man wie folgt:

      $ cd ~
      $ wget https://hhoegl.informatik.hs-augsburg.de/es2/tools/_tmux.conf -O .tmux.conf
    • helix - Ein Editor der ähnlich wie Vim ist, aber leichter zu installieren, zu konfigurieren und zu verwenden (https://helix-editor.com).

      Wer C Code mit Helix (Kommando hx) editiert, sollte in ~/.config/helix/languages.toml den folgenden Abschnitt aufnehmen. Am Anfang ist es der einzige Eintrag, da die Datei nach der Installation noch nicht existiert. Damit wird der C/C++ language server clangd im Editor konfiguriert. Das Paket clang installiert man mit sudo apt install clangd.

      [[language]]
      name = "c"
      auto-format = false
      language-servers = [ "clangd" ]
      
      [language-server.clangd]
      command = "clangd"
      config = { clangd.fallbackFlags = [ "-std=gnu11" ] }
      args = []

      Damit clangd in einem Verzeichnis mit C/C++ Quelltext aktiv wird, muss es eine Datei compile_commands.json geben, sie wird auch “Compilation Database” genannt. Diese Datei muss zunächst erzeugt werden. Wenn die Übersetzung mit make gesteuert wird (wie meistens bei uns), dann führt das Kommando bear -- make zum Ziel. Bear (sudo apt install bear) lässt make laufen und wandelt die Ausgabe von make in die compile_commands.json um. Daneben gibt es auch das Python Programm compiledb, das Ähnliches macht. Die Installation erfolgt mit pip install compiledb. Ein alternativer Sprachserver für C/C++ ist ccls.

      hx --health gibt aus, welche Sprachen durch einen Sprachserver unterstützt werden.

  • vim

    Wer vim verwendet braucht zumindest eine rudimentäre Startup Datei ~/.vimrc. Ein Anfang wird mit der folgenden Datei gemacht:

    $ wget https://hhoegl.informatik.hs-augsburg.de/es2/tools/_vimrc -o .vimrc

    Zum Editieren von C Code verwende ich die “ALE” Erweiterung, siehe https://github.com/dense-analysis/ale. ALE spielt gut mit dem clangd Sprachserver zusammen.

  • Python Pakete, die sie installieren sollten (sudo pip install ...)

    • compiledb
    • pyserial

Windows Terminal

Komfortables Terminal, bei dem man Powershell und Linux in verschiedenen Tabs öffnen kann. Man kann das Terminal auch teilen wie bei einem Terminal Multiplexer.

https://learn.microsoft.com/en-us/windows/terminal/install

APT Repository

Wer häufig Pakete installiert sollte den Server in /etc/apt/sources.list auf einen Server in der Region ändern.

Literatur

2.2 ARM-GCC

Es gibt zwei Möglichkeiten, 1. Installation der Linux Pakete, oder 2. Download und Installation einer ARM Toolchain.

  1. Linux Pakete installieren

    $ sudo apt install binutils-arm-none-eabi gcc-arm-none-eabi
    $ sudo apt install gdb-multiarch

    Hinweis: Das ausführbare Programm des Debuggers heisst wie das Paket gdb-multiarch. Die Beispielprogramme haben in .estool/estool.ini den Namen arm-none-eabi-gdb oder gdb-multiarch konfiguriert. Eventuell den eingetragenen Namen ändern.

  2. Die aktuellen Toolchains von ARM findet man unter

    https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

    im Bereich “x86_64 Linux hosted cross toolchains” / AArch32 bare-metal target (arm-none-eabi).

    Zur Zeit (10/2023) ist das arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz. Eine Kopie ist unter https://hhoegl.informatik.hs-augsburg.de/es2/tools/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz.

    $ cd /opt
    $ sudo tar Jxvf ~/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz

    In ~/.bashrc die PATH Variable erweitern:

    export PATH=$PATH:/opt/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi/bin

    Das Installationsverzeichnis /opt/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi ist knapp 1 GByte gross.

2.3 OpenOCD

Auch hier gibt es wieder zwei Möglichkeiten: 1. Installation des Pakets, oder 2. Sourcen holen, kompilieren und installieren.

  1. Paket installieren

    $ sudo apt install openocd

    Die ausführbare Datei ist nachher in /usr/bin/openocd. Die Konfigurationsdateien liegen unter /usr/share/openocd.

  2. Selber kompilieren

    $ sudo apt install libusb-1.0-0-dev libtool pkg-config libusb-1.0-0-dev automake autoconf
    $ wget https://hhoegl.informatik.hs-augsburg.de/es2/tools/openocd-0.12.0.tar.bz2
    $ tar jtf openocd-0.12.0.tar.bz2
    $ cd openocd-0.12.0
    $ ./bootstrap
    $ ./configure --enable-stlink --prefix=/opt/openocd-0.12.0
    $ make
    $ sudo make install
    # PATH um /opt/openocd-0.12.0/bin erweitern

    Optional lässt sich noch die Dokumentation im PDF Format erzeugen. Es sollte vorher schon LaTeX installiert sein:

    sudo apt install texinfo
    make pdf

    Danach ist die Doku in doc/openocd.pdf zu finden.

    Siehe die PDF Datei

    Die aktuellen OpenOCD Sourcen findet man unter https://github.com/openocd-org/openocd.

2.4 Udev Regeln

Damit man als gewöhnlicher User auf die USB Schnittstelle des STLINK Adapters zugreifen kann, müssen sogenannte udev Regeln in das Verzeichnis /etc/udev/rules.d/ kopiert werden. Es genügt, eine einzelne Datei 60-openocd.rules zu kopieren:

$ sudo cp /lib/udev/rules.d/60-openocd.rules /etc/udev/rules.d/

Die Datei /lib/udev/rules.d/60-openocd.rules ist nur vorhanden, wenn man das Linux Paket openocd installiert hat. Wenn man OpenOCD manuell installiert, dann muss man den Pfad ändern, ähnlich wie in folgendem Beispiel: /opt/openocd-0.12.0/share/openocd/contrib/60-openocd.rules.

Damit die Regeln aktiviert werden, gibt man abschliessend die Kommandos ein:

$ sudo udevadm control --reload-rules
$ sudo udevadm trigger

2.5 Estool installieren

Das estool-rs Program ist ein Hilfsprogramm, um die Arbeit mit dem STM32 etwas zu erleichtern. Der Rust Quelltext und das aktuelle Executable liegt auf gitlab:

https://gitlab.com/hhoegl-tha/es/estool-rs

Legen Sie die ausführbare Datei in ein Verzeichnis in dem Programme gefunden werden (siehe PATH Umgebungsvariable!).

2.6 Beispiel “starter” für STM32F446 Nucleo holen, kompilieren und flashen

https://gitlab.com/hhoegl-tha/es/f446/starter

$ git clone https://gitlab.com/hhoegl-tha/es/f446/starter
$ cd starter
$ ls -a
.  ..  .estool  .git  .gitignore  img  Makefile  README.md  src STM32F446RETx_FLASH.ld

Im Beispielverzeichnis starter ist nun die Konfigurationsdatei vom OpenOCD Server im Verzeichnis .estool enthalten. Das Verzeichnis beginnt mit einem Punkt (“.”), deshalb sieht man es nicht in der Ausgabe des ls Programms. Damit man es sieht, muss man ls -a angeben. Wir starten den OpenOCD Server probeweise mit

$ openocd -f .estool/openocd.cfg
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
debug_level: 1
adapter speed: 500 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
<hier hängt das Programm; abbrechen mit Strg-c>

Man bricht den im Vordergrund laufenden OpenOCD mit Strg-c (Steuerung-C, auf englisch control-c) ab. Damit OpenOCD erfolgreich starten kann, muss er mit dem Debug-Adapter STLINK Verbindung aufnehmen können. Als gewöhnlicher User kann man das nur mit der installierten udev Datei (siehe oben).

Nun kompilieren und flashen:

$ cd starter
$ make
$ make flash

Bei make wird der Quelltext mit dem zuvor installierten ARM GCC Compiler kompiliert. Mit make flash wird der STM32 mit dem Programm geflasht. Das make flash Kommando startet in Hintergrund das estool, das wiederum den OpenOCD zum Flashen des STM32 startet und danach wieder beendet.

Danach sollte das über USB angesteckte Nucleo Board geflasht worden sein und die LED auf dem Board blinken. Über den UART, der auch über den STLINK Adapter verfügbar ist, werden die Schleifendurchläufe in ASCII mit 9600 Baud an den PC übertragen. Die Details stehen in der README.md Datei im starter Verzeichnis, und natürlich im Quelltext starter/src/.

Man kann ausserdem mit make gdb den GNU Debugger starten. Dieses Makefile Target ruft estool-rs gdb auf, womit zunächst der OpenOCD Server gestartet wird und danach der GNU Debugger. Nach Beenden des GDB wird auch der OpenOCD Server beendet.

2.7 Ohne ESTOOL

Man kann auch ohne das ESTOOL arbeiten. Allerdings muss man dann in einem zweiten Shell-Fenster den OpenOCD Server starten

  • OpenOCD Server starten

    Zunächst in ein Projekt-Verzeichnis gehen, z.B. mit cd starter.

    $ openocd -f .estool/openocd.cfg
    Open On-Chip Debugger 0.12.0
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    
    [stm32f4x.cpu] halted due to breakpoint, current mode: Thread
    xPSR: 0x61000000 pc: 0x080003fa msp: 0x20017fe8
    <blockiert - Abbrechen mit Ctrl-C>
  • Flashen mit telnet (dazu muss der OpenOCD im Hintergrund laufen). Das zu flashende Programm ist in main.bin:

    $ telnet localhost 4444
    > reset halt
    > flash probe 0
    > flash write_image erase main.bin 0x08000000
    > reset run
    > exit

    Man kann die Folge der Kommandos auch in eine Textdatei schreiben (z.B. oocd-flash.cmd) und diese mit netcat (nc) zum OpenOCD Server übertragen:

    cat oocd-flash.cmd | nc localhost 4444
  • Flashen mit OpenOCD, ohne dass Server im Hintergrund läuft. Der OpenOCD wird gestartet und die Anweisungen auf der Kommandozeile (-c ...) werden abgearbeitet.:

    openocd -f .estool/openocd.cfg -c "init" -c "reset halt" -c "flash probe 0" \
    -c "flash write_image erase main.bin 0x08000000" -c "reset run" \
    -c "shutdown"
  • GDB starten

    Die Kommandozeile zum Starten von GDB sieht wie folgt aus:

    gdb-multiarch --tui -silent -x .estool/gdbinit

    Erläuterung zu den Kommandozeilen-Argumenten:

    --tui - Text User Interface (sowas wie eine grafische Oberfläche in der Shell)

    -silent - GDB weniger gesprächig machen

    -x '.estool/gdbinit' - Die Datei gdbinit wird beim Start gelesen und ausgeführt. Darin wird in einem kurzen Abschnitt in Python die Variable gdbport gelesen und das Kommando target remote localhost:<port> abgesetzt. Das ist aktuell der einzige Grund warum der Python-Support in GDB nötig ist. Ein GDB mit eingebautem Python Interpreter ist nützlich, weil man alle Debug-Aufgaben damit auch per Python-Skript steuern kann.

    Die GDB Doku finden Sie online unter https://sourceware.org/gdb/current/onlinedocs/gdb.html.

2.8 Tipps

  • Beachten Sie, dass Sie nur kurzzeitig für die notwendigen Administrationsaufgaben root werden sollen. Vermeiden Sie es, die gewöhnlichen Anwendungsprogramme (gcc, gdb, make, openocd, estool, …) als root laufen zu lassen.

  • HSA Home mounten

    (Anleitung von Hr. Schäferling)

    $ sudo apt install sshfs
    $ mkdir /opt/bin
    $ cd /opt/bin
    $ sudo wget https://ti-srv.informatik.hs-augsburg.de/labs/common/bin/mount_HSA-Home.sh
    $ sudo wget https://ti-srv.informatik.hs-augsburg.de/labs/common/bin/umount_HSA-Home.sh
    $ sudo chmod +x mount_HSA-Home.sh umount_HSA-Home.sh
    $ echo "PATH=$PATH:/opt/bin" >> ~/.bashrc
    $ mount_HSA-Home.sh
    $ umount_HSA-Home.sh
    $ echo "PATH=$PATH:/opt/bin" >> ~/.bashrc
  • Serielle Schnittstelle als “normaler” User nutzen

    Dazu muss man den Usernamen in die Gruppe “dialout” aufnehmen. Das geht mit dem Kommando

    $ sudo usermod -a -G dialout $USER

    Damit das Kommando wirksam wird muss man sich aus- und wieder einloggen. Es kann auch sein, dass man den Rechner neu starten muss.