QRV mit dem ESP32

Vorstellung

Seit einigen Jahren sind die SoC der chinesischen Firma Espressif eine feste Größe in der Bastlerszene. Vor allem durch den geringen Preis von <4€ gab es kaum einen Weg am ESP8266 vorbei. Bei diesem Preis-/Leistungsverhältnis muss im Bastlerhirn einfach der "Auch-Haben-Wollen-Impuls" zünden. Unzählige Blogs und YouTube-Videos zeigen blinkende LEDs auf Steckbrettern.

Nun schickt sich der ESP32 an, die Nachfolge anzutreten. Er ist ein wenig teurer, dafür aber wesentlich besser ausgestattet. Mit Doppelkern-Prozessor, einem Ultra-Low-Power-Prozessor und umfangreicher Peripherie steht vieles zur Verfügung, worauf beim Vorgänger verzichtet werden musste.
Als Handwerkzeug stellt Espressif das Framework (ESP-IDF) und eine gute Dokumentation bereit. Die mitgelieferten Anwendungsbeispiele runden das Ganze ab.

Für erste Experimente bietet der Handel preiswerte Entwicklungsboards ESP32-NodeMCU an. Dazu einen PC und ein passendes USB-Kabel, mehr benötigt man erst mal nicht. Für weiterführende Experimente und tatsächliche Projekte sind Standardmodule ESP32-WROOM für 4-6€ erhältlich.

Im folgenden Abschnitt werden die Schritte zur Installation des ESP-IDF auf Basis von Linux Mint 19.1 zusammengefasst. Im Ergebnis lässt sich C-Source-Code im Terminalfenster übersetzen und auf den Chip flashen.

Damit der Komfort nicht auf der Strecke bleibt, wird in einem weiteren Schritt Eclipse installiert und an das Framework "angeflanscht". Der Begriff Integration soll in den Zusammenhang vermieden werden.

Grundinstallation

Die Installation von Toolchain und Framework beschreibt Espressif in der Dokumentation Get Started recht ausführlich. Allerdings fehlt dort ein wenig Struktur sowie der eine oder andere Hinweis.
Hier mein Weg unter Linux Mint19 (64 Bit). Die Installation unter Ubuntu oder Debian sollte sich nicht großartig unterscheiden.
Es wird kein Anspruch auf Exclusivität oder Genialität erhoben. Es ist lediglich ein Weg zum Ziel.

Die komplette Installation kann in einem Unterverzeichnis des Users erfolgen. Das Löschen des Ordners beseitigt das Ganze rückstandsfrei.




Vorbereitung

Installation von Abhängigkeiten

sudo apt install -y gcc git wget make libncurses-dev flex bison gperf 
sudo apt install -y python python-serial python-pip

Python-Aktualisierungen

sudo pip install --upgrade pip
sudo pip install --upgrade setuptools

Zum späteren Flashen muss der User der Gruppe dialout angehören.

sudo usermod -a -G dialout $USER

Die Installation erfolgt in einem beliebigen Verzeichnis des Users. Beispielsweise:

mkdir -p $HOME/Development/esp32
cd $HOME/Development/esp32




Installation der Toolchain

Download und entpacken der xtensa-Toolchain. Aktualität des Links Links prüfen !

wget -O esp32-toolchain.tar.gz https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp32-2019r1-linux-amd64.tar.gz
tar -xzf esp32-toolchain.tar.gz
rm esp32-toolchain.tar.gz

Download und entpacken der ULP-Toolchain. Aktualität des Links prüfen !)

wget -O esp32ulp-toolchain.tar.gz https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp32ulp-20180809/binutils-esp32ulp-linux64-2.28.51-esp32ulp-20180809.tar.gz 
tar -xzf esp32ulp-toolchain.tar.gz 
rm esp32ulp-toolchain.tar.gz




Installation des Framework

Framework und Requirements installieren

git clone --recursive https://github.com/espressif/esp-idf.git
python -m pip install --user -r ${PWD}/esp-idf/requirements.txt




Das Ergebnis

Im aktuellen Verzeichnis sind nun drei Subfolder zu finden.

esp32ulp-elf-binutils
esp-idf
xtensa-esp32-elf




Nacharbeiten

Umgebungsvariablen setzen. Folgende Zeilen an das Ende von $HOME/.profile kopieren

# ESP32 - Environment
export PATH=$HOME/Development/esp32/xtensa-esp32-elf/bin:$PATH
export PATH=$HOME/Development/esp32/esp32ulp-elf-binutils/bin:$PATH
export IDF_PATH=$HOME/Development/esp32/esp-idf
# Eclipse Environment
export TOOLCHAIN_PATH=$HOME/Development/esp32/xtensa-esp32-elf
Zur Aktualisierung der Variablen nun ab- und wieder anmelden oder rebooten.




Ausprobieren

Alle eigenen ESP32-Projekte sollten in einem gemeinsamen Ordner zusammengefasst werden, der später auch den Workspace von Eclipse bildet. Unterhalb davon erhält jedes Projekt seinen eigenen Subfolder. Vorschlag:

mkdir -p $HOME/Projects/espressif/esp32
cd $HOME/Projects/espressif/esp32

Das ESP-IDF liefert zahlreiche Beispielprojekte in xxxxx/esp-idf/examples mit.

Für den ersten Versuch kopiert man sich ein einfaches Projekt in den Workspace (in dem man sich aktuell befindet).

cp $HOME/Development/esp32/esp-idf/examples/get-started/blink ./

Den Build- und Flash-Prozess beschreibt die Doku recht übersichtlich. Einfach im Projektordner ein Terminalfenster öffnen und mit make all den Build-Process starten. Der erste Aufruf von make öffnet das Konfigurations-Menu. Das ist die Schaltzentrale für alle Einstellung rund um das Projekt. Exit übernimmt die Defaulteinstellungen und speichert sie in sdkconfig, auf die make im Folgenden projektbezogen zugreift.

Im ersten Buildprocess werden sämtliche Bibliotheken übersetzt. Das Ganze dauert ein paar Sekunden und sollte ohne Fehlermeldung ablaufen. Am Ende erscheint ein Hinweistext, wie man den Code in den Chip bekommt, was aber auch wesentlich einfacher funktioniert (s.u.).
Die Übersetzung von Sourcecode-Änderungen geht danach deutlich schneller von statten. Wer es eilig hat, kann das Ganze auch mit make -j4 all beschleunigen. Jetzt werden 4 Rechnerkerne gleichzeitig beschäftigt.
Hierbei legt man sich allerdings Fußangeln aus. Die Reihenfolge der Abläufe ist nicht mehr definiert, was bei Code-Abhängigkeiten zur Fehlern führen kann. Falls bspw. ULP-Assembler-Code übersetzt werden soll, muss auf die Mehr-Kern-Option verzichtet werden.




Der Flash-Prozess

Ist das NodeMCU-Board per USB-Kabel mit dem PC verbunden, muss ein Gerät /dev/ttyUSB0 zu finden sein.

ls -al /dev/ttyUSB*
Falls der PC mehrere ttyUSB - Schnittstellen zu verwalten hat, sollte man über eine feste Namen-Zuordnung für die USB-Adapter nachdenken.

Die Schnittstellenparameter können projektbezogen über make menuconfig geändert werden.
make flash übersetzt geänderte Quelltextpassagen neu und schiebt anschließend alle benötigten Binaries in den Flash-Speicher des ESP. Zum Abschluss wird der Chip automatisch resetet und das Programm gestartet. An GPIO 5 sollten jetzt Spannungswechsel im 2s-Takt messbar sein.

In vielen Fällen ist es sinnvoll, nach dem Flashen sofort die Debug-Ausgaben der seriellen Schnittstelle mitzulesen. Dies erfolgt mit make flash monitor, wobei die Schnittstellengeschwindigkeiten für beide Vorgänge in der sdkconfig getrennt festgelegt werden. Beendet wird monitor mit Ctrl+Alt+9.
Einen Überblick der möglichen Optionen zeigt make help.

Eigener Quellcode wird unterhalb von main abgelegt. Entweder wird der vorhandene C-Code angepasst oder eigene *.c/*.h-Dateien geschrieben.

Den Build- und Flash-Prozess beschreibt die Doku recht übersichtlich.




Was zu tun bleibt

Das ESP-IDF bietet nur den Komfort der nackten Konsole. Quelltext-Editor oder Projektverwaltung sind nicht vorhanden. Hier verweisen die Entwickler auf das Eclipse-Projekt als mögliche Alternative.

Komfort durch Eclipse

Grundsätzlich lässt sich Source-Code mit jedem beliebigen Texteditor verfassen. So richtig komfortabel wird es aber erst mit einer IDE wie Eclipse. Funktionen wie Quellcode-Prüfung im Editor oder Code-Vervollständigung erleichtern die Programmierung deutlich. Obendrein wir noch eine Projektverwaltung mitgeliefert. Ob das ein Segen ist, sei dahingestellt.
Espressif beschreibt das Zusammenführen der Toolchain/Framework mit Eclipse in der Doku.




Die Installation

Die Installation der Eclipse-IDE beschränkt sich auf herunterladen und entpacken des Paketes in ein beliebiges Verzeichnis. Hier bietet sich die Verzeichnisebene von Toolchain/Framework an.

cd $HOME/Development/esp32

Die aktuelle Version des C/C++ - Packages ist hier zu finden. Die Eclipse-Versionen sind sehr kurzlebig.

Gestartet wird die IDE mit ./eclipse/eclipse. Auf die Dauer hilft das Anlegen eines Menueintrages.
Im Ersten Schritt verlangt Eclipse nach Festlegung des Workspace, d.h. des Project-Verzeichnisses. Dies wäre aus dem vorigen Kapitel "$HOME/Projects/espressif/esp32".




Template anlegen

Die nachfolgenden Einstellungen sind recht aufwendig. Um dies nicht bei jedem Project wiederholen zu müssen, legt man sich ein Template an, das später im Project-Explorer mit copy and paste geforkt werden kann. Die dann noch nötigen Anpassungen sind minimal.

Aus dem vorigen Kapitel befindet sich bereits das Projekt "blink" im Workspace. Das soll als Ausgangsbasis dienen.

Project importieren:

Menu -> File -> Import... -> “C/C++” -> “Existing Code as Makefile Project" -> Next

  • Project Name => blink
  • Existing Code Location -> Browse (Ordner "blink" auswählen)
  • Toolchain for Indexer Settings => Cross GCC

  • Finish
New Project
RPi PinSceme

Damit erscheint das Projekt links im Project-Explorer.



Nun folgen diverse Projekt-Einstellungen in Menu -> Project -> Properties

“C/C++ Build” -> “Environment”

  • Add -> BATCH_BUILD = 1
  • Add -> IDF_PATH = ""
  • Add -> LANG = en_US.UTF-8
Environment
RPi PinSceme
Anmerkungen:
  - Die Variable Path sollte bereits vorhanden sein.
  - Der Wert von IDF_PATH sollte sich automatisch eintragen.
  - Die Sprache muss auf Englisch umgestellt werden, da es sonst zu Fehlinterpretationen im make-Process kommt.

Bei Problemen sollten die Umgebungsvariablen, aus der ESP-IDF-Installation ($HOME/.profile) untersucht werden.



“C/C++ General” -> “Preprocessor Include Paths” -> "Providers Tab"

  • "CDT Cross GCC Built-in Compiler Settings" => check
      "Command..." => xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"

  • “CDT GCC Build Output Parser” => check
      “Compiler command pattern” => xtensa-esp32-elf-(gcc|g\+\+|c\+\+|cc|cpp|clang)
Compiler
RPi PinSceme
Parser
SoC Functions

“C/C++ General” -> "Indexer"
  • “Enable project specific settings” => check
  • “Allow heuristic resolution of includes” => uncheck
Indexer
RPi PinSceme

Abschließen mit "Apply and Close" ==> Fertig.


icon Ein erster Build kann fehlschlagen, wenn zuvor kein make menuconfig im Projektverzeichnis ausgeführt wurde. Die Datei sdkconfig wird aber nun automatisch angelegt, sodass zumindest der zweite Build fehlerfrei durchlaufen sollte.

Falls die Fehlermeldungen im Editorfenster nicht verschwinden, hilft Clean mit anschließendem Build.





Zusammenspiel mit dem ESP32

Hier weicht mein Vorgehen von der Espressif-Doku ab. Eclipse ist in der Lage externe Programme zu starten. Über diese Funktion werden Terminalfenster geöffnet, denen beliebige Kommandos übergeben werden können.

Die Konfiguration erfolgt über:

Menu -> Run -> "External Tools" -> "External Tools Configuration ..."

flash and debug
RPi PinSceme
menuconfig
SoC Functions
erase flash
SoC Functions

Hier 3 Beispiele, wie make im externen Terminal bzw. im Fall von "erase flash" im Eclipse-Terminal aufgerufen werden kann. Die zusätzlichen Geometrie-Parameter platzieren das Terminalfenster an einer günstigen Stelle des Bildschirmes.

Die Einstellungen der external Tools wirken sich projektübergreifend im gesamten Workspace aus.

Der Start der Tools erfolgt über den Auswahlpfeil rechts neben dem "Tool"-Button. icon Der Button selbst wird immer mit dem zuletzt aufgerufenen Tool belegt.

Beim Aufruf eines Tools muss das Projekt im Project-Explorer selektiert sein oder ein Editorfenster des Projektes den Fokus besitzen. Eclipse beschwert sich sonst, dass die Variable "project_name" nicht definiert sei.

Es darf immer nur ein Terminal Zugriff auf die serielle Schnittstelle haben. Ein gleichzeitiger zweiter Zugriff führt zu Resourcenkonflikten.




Forken bestehender Projekte

Hat man sich durch die Einstellungen gequält und kann das Template fehlerfrei bauen, lässt dieses sich jetzt im Project-Explorer per copy + paste vervielfältigen. Beim Einfügen wird ein neuer Name vorgeschlagen.

Nach Abschluss des Kopiervorganges erscheint der Fork als separates Projekt im Explorer.

Nun muss unterhalb des neuen Projektes die Datei Makefile im Editor geöffnet und die Variable PROJECT_NAME := mit dem zuvor vergebenen Projektnamen gesetzt werden.

Das Ganze funktioniert natürlich auch mit jedem anderen Projekt.

nach oben