# DMM Demo Beispielprojekt zur Demonstration der wesentlichen Funktionen des DMM-Boards. Wird auch zur Installation des Bootloaders und Test nach der Inbetriebnahme eingesetzt. ## Anleitung ### Build-System und Entwicklungsumgebung Als plattformübergreifendes Build-System Dient das [PlatformIO](https://platformio.org/). Diese steht sowohl als Kommandozeilen-Tool, als auch als [Erweiterung](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide) zum [Visual Studio Code](https://code.visualstudio.com/). (auch unter Linux und MacOS verfügbar!) Nutzt man das VSCode, so können nach der Installation der Erweiterung die unten aufgeführten Befehle auch *ohne Installation der PIO im Betriebssystem* in den Terminals innerhalb der IDE genutzt werden. Für die Betriebssystemweite Installation siehe Anleitung unter [PlatformIO Core (CLI)](https://docs.platformio.org/en/latest/core/installation.html). *Nur Linux:* zur Programmierung des Bootloaders mit JTAGICE muss dieser für nicht-root Nutzer per udev-Regel freigegeben werden. Erstelle dazu Datei `/etc/udev/rules.d/99-jtagice3.rules` mit: ``` SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2140", MODE="0666" ``` ### Auschecken und bauen Es sollte sichergestellt sein, dass [Git](https://git-scm.com/) installiert und der [eigene SSH-Schlüssel im GitLab-Profil hinterlegt](https://docs.gitlab.com/ee/ssh/) ist. Für Git-Anfänger finden sich im Internet zahlreiche Anleitungen, zum Beispiel [diese](https://www.freecodecamp.org/news/learn-the-basics-of-git-in-under-10-minutes-da548267cc91/). *GUI:* VSCode unterstützt Git direkt und kann nach der Einrichtung als GUI genutzt werden. Auschecken: ``` $ git clone git@git.rz.tu-bs.de:emg/lehre/dmm/dmm-demo.git $ cd dmm-demo ``` Es sind dre PlatformIO-Environments definiert: * `release` wird standardmäßig genutzt und ist auf die Programmierung per Bootloader ausgelegt. * `debug` wird für das Debugging mittels avr-stub genutzt. * `jtag` wird zum Aufspielen des Bootloaders mittels externem JTAGICE3 Programmer genutzt. > **In `debug` darf daher kein UART genutzt werden, da es zur Kommunikation mit > GDB dient**. Entsprechende Programmteile müssen gegebenenfalls mit >`#ifndef GDBSTUB` deaktiviert werden! Bauen von `release`: ``` $ pio run -e release ``` Bauen von `debug`: ``` $ pio run -e debug ``` Wenn man `-e ` weglässt, wird immer `debug` gebaut, da dies die Standartkonfiguration ist, die von dem Debugger von VSCode genutzt werden soll. Die für die DMM-Projekte vorgesehenen [Bibliotheken](git@git.rz.tu-bs.de:emg/lehre/dmm/dmm-libs.git) sowie die Toolchain werden durch `pio run` automatisch heruntergeladen und müssen nicht extra installiert werden. Die Bibliotheken werden dabei im Ordner `dmm-demo/depends` hinterlegt. ### Programmierung & Nutzung *GUI*: die hier aufgeführten Befehle können auch aus dem PlatformIO-Toolbar des VSCode per Mausklick ausgeführt werden. #### Aufspielen des Bootloaders Auf einem neuen Board muss zunächst mittels JTAGICE3 ein Bootloader aufgespielt werden. Dazu wird es mit dem JTAG-Header verbunden (Polung beachten!). ``` $ pio run -t bootloader -e jtag ``` > Sollte es beim Aufruf zum Fehler `TypeError: expected str, bytes or > os.PathLike object, not NoneType ... > join(platform.get_package_dir("tool-avrdude"), "avrdude.conf")` > kommen, kann dieser durch einmaliges Aufrufen von > `$ pio run -t upload -e jtag` > vor der Installation des Bootloaders behoben werden. #### Aufspielen des Programms Das Board muss per USB verbunden und Bootloader gestarted werden. **Zum Start des Bootloaders den Joystick in Richtung unten halten, Reset-Taste drücken und den Joystick loslassen. Die Aktivierung des Bootloaders erkennt man an dreimaligem Blinken und anschließendem Dauerleuchten der LED4 auf dem Board**. ``` $ pio run -e release -t upload ``` Anschließend Reset-Taste drücken um das Programm zu starten. #### UART-Kommunikation Ein Teil des Demos beschäftigt sich mit Kommunikation über einen virtuellen SerialPort via USB. Der `COMx` (Windows) oder `/dev/ttyUSBx` (Linux) Port wird von PlattformIO automatisch erkannt. Dies geschieht anhand des `hwid` Parameters unter `boards/emgdmm_v3.json`, der den VID/PID des FTDI-Chips des DMM-Boards angibt. Ein Terminal kann somit einfach geöffnet werden: ``` $ pio device monitor ``` Beim Drücken des Joystick im entsprechenden Teil des Demos wird nun eine Meldung angezeigt. #### Unit-Test Die Demo enthält im Ordner `tests` einen Beispiel zur Ausführung von Unit-Tests auf dem Mikrocontroller. Dazu muss wie oben beschrieben der Bootloader aktiviert werden. ``` $ pio test ``` Nach dem Befehl wird eine Firmware auf das Board heruntergeladen, die bei der Ausführung per UART (wie auch bei `pio device monitor`) die Ergebnisse der Tests im Terminal ausgibt. #### Debugging mit avr-stub Normallerweise ist zum Debuggen (also Setzen von Breakpoints und Auslesen der Register) ein JTAG-Adapter notwendig. PlattformIO kann mittels einer [Bibliothek](https://github.com/jdolinay/avr_debug) die Funktion der Hardware-Debugger unter Inkaufnahme einiger Nachteile teilweise ersetzen. Die Kommunikation erfolgt dabei per UART, der nicht mehr im eigenen Programm genutzt werden kann. Die Konfiguration `debug` bindet die nötige Bibliothek ein, und schaltet Optimierung über das Setzen von `build_type` aus und definiert `GDBSTUB`. Am Anfang des programms muss `debug_init()` aus `avr8-stub.h` aufgerufen werden. Debugging wird in VScode mittels "Run & Debug" Tab gestartet. Vorher muss der Bootloader aktiv sein. Zu beachten ist: * Beakpoints funktionieren nur in Programmteilen, wo Interrupts aktiviert sind. **Das setzen eines Breakpoints innerhalb einer Interruptroutine führt immer zum Aufhängen des Programms**. * Breakpoints werden über das Neuschreiben vom Flash gesetzt. Dies hat einen Verschleiß zufolge, da der Flash nur für 10000 Schreibzyklen ausgelegt ist. Das "Steppen" einzelner Befehle ist daher sparsam zu verwenden. * Der Debugger nutzt den Watchdog-Interrupt, daher darf WDT nicht vom Programm genutzt werden. Außerdem können die gelegentlichen Interrupts die Timings beeinflussen. > **TODO:** aktuell muss der Port des Debuggers manuell in `platformio.ini` > unter `debug_port` gesetzt werden! > (z.B. `/dev/ttyUSBx` unter Linux oder `COMx` unter Windows). > Für automatisches Auflösen des Ports siehe > [Issue 253](https://github.com/platformio/platform-atmelavr/issues/253).