Hinweise zur STM32 Cube IDE

Als Ergänzung zu meiner STM32 Anleitung gebe ich hier Tipps zum Umgang mit der STM32 Cube IDE. Sie basiert auf Eclipse mit dem C/C++ Development Toolkit (CDT).

So sieht ein neues 'leeres' Projekt aus

ST kaufte das Atollic TrueStudio auf, reduzierte es auf STM32 Controller und machte daraus dann die Cube IDE, indem Funktionen von CubeMX integriert wurden. Ab Version 2.0 muss man Cube MX aber doch wieder separat installieren und starten. Die Cube IDE kann Projekte vom Atollic TrueStudio und von der AC6 System Workbench importieren, umgekehrt geht es nicht.

Download: STM32 Cube IDE

Unter Linux wird das Paket libncurses5 benötigt. Wenn man ein neues Projekt startet und der Dialog "Target Selection" komplett leer bleibt, muss man die IDE mit folgendem Befehl starten: /usr/bin/env GDK_BACKEND=x11 ./stm32cubeide

Projekt erzeugen

Ich empfehle für den Anfang ohne Cube HAL (nur mit den CMSIS Headern) zu arbeiten. Das geht so:

  1. Gehe im Menü auf File/STM32 Project Create/Import. Erzeuge dort ein STM32CubeIDE Empty Project. Die IDE fragt nach dem Mikrocontroller Modell, um dazu passend Linker-Script und Startup-Code (in Assembler, das muss so sein) zu erzeugen.
  2. Von dem CMSIS Paket brauchst du das "core" Verzeichnis und ein "device" Verzeichnis passend für dein STM32 Modell. Füge sie zur Projektkonfiguration hinzu: Klicke dazu mit der rechten Maustaste auf den Projektnamen und dann auf Properties. Gehe dann zu dem Bereich C/C++ Build / Settings
  3. Wähle ganz oben All configurations aus und gehe dann darunter nach MCU GCC Compiler / Include paths. Dort fügst du die beiden Verzeichnisse hinzu.

    Einstellungen für Libraries

  4. Die Include Datei für die STM32F3 Serie heißt stm32f3xx.h. Bei den anderen Serien ist es ähnlich. In dieser Datei sind Definitionen für die Modelle der Serie aufgelistet:
      /* #define STM32F301x8 */   /*!< STM32F301K6, STM32F301K8, STM32F301C6, STM32F301C8, STM32F301R6 and STM32F301R8 Devices */
      /* #define STM32F302x8 */   /*!< STM32F302K6, STM32F302K8, STM32F302C6, STM32F302C8, STM32F302R6 and STM32F302R8 Devices */
      /* #define STM32F302xC */   /*!< STM32F302CB, STM32F302CC, STM32F302RB, STM32F302RC, STM32F302VB and STM32F302VC Devices */
      /* #define STM32F302xE */   /*!< STM32F302RE, STM32F302VE, STM32F302ZE, STM32F302RD, STM32F302VD and STM32F302ZD Devices */
      /* #define STM32F303x8 */   /*!< STM32F303K6, STM32F303K8, STM32F303C6, STM32F303C8, STM32F303R6 and STM32F303R8 Devices */
      /* #define STM32F303xC */   /*!< STM32F303CB, STM32F303CC, STM32F303RB, STM32F303RC, STM32F303VB and STM32F303VC Devices */
      /* #define STM32F303xE */   /*!< STM32F303RE, STM32F303VE, STM32F303ZE, STM32F303RD, STM32F303VD and STM32F303ZD Devices */
      /* #define STM32F373xC */   /*!< STM32F373C8, STM32F373CB, STM32F373CC, STM32F373R8, STM32F373RB, STM32F373RC, STM32F373V8, STM32F373VB and STM32F373VC Devices */
      ...
    
  5. Wähle dort die richtige Definition aus und füge sie unter MCU GCC Compiler / Preprocessor hinzu. Zum Beispiel musst du für den STM32F303CC die Definition STM32F303xC hinzufügen.

    Einstellungen für Definitionen

Programm übertragen

Klicke auf den grünen Start-Knopf oder mit der rechten Maustaste auf den Projektnamen, dann auf Run as... und dann auf STM32 Cortex-M C/C++ Application. Änderungen am Programm werden ggf. automatisch auf den Mikrocontroller übertragen. Dabei verwendet die IDE die gleichen Verbindungsoptionen, wie beim Debuggen.

Debuggen

Klicke auf den grünen Käfer, oder mit der rechten Maustaste auf den Projektnamen, dann auf Debug as... und dann auf STM32 Cortex-M C/C++ Application. Auch hier werden Änderungen am Programm ggf. automatisch auf den Mikrocontroller übertragen. Der Debugger hält das Programm am Anfang der main() Funktion an. Danach kannst du es über Schaltflächen und Funktionstasten fortsetzen. Am linken Rand des Texteditors (vor den Zeilennummern) kannst du Unterbrechungspunkte setzen.

Verbindungsoptionen

Die Cube IDE unterstützt folgende Optionen zum Verbindungsaufbau:

Modus Beschreibung Einschränkung
Connect Under Reset Der Programmieradapter löst einen Hardware-Reset aus und verbindet sich während dessen. Wenn die NRST Leitung nicht verbunden ist, muss man den Reset Knopf manuell drücken.
Software System Reset Über die SWJ Schnittstelle wird ein Reset-Kommando abgesetzt, danach verbindet er sich. Funktioniert nicht, wenn das Programm die SWJ Schnittstelle deaktiviert hat oder wenn die CPU schläft. Im Bootloader ist SWJ immer aktiv.
Hardware Reset Der Programmieradapter löst einen Hardware-Reset aus, danach verbindet er sich. Benötigt eine Reset-Leitung zwischen Programmieradapter und dem NRST Pin des Mikrocontrollers. Funktioniert nicht, wenn das Programm direkt nach dem Start in einen Schlafmodus geht oder die SWJ Schnittstelle deaktiviert.
Core Reset Über die SWJ Schnittstelle wird ein Reset-Kommando nur an den ARM Kern (nicht an die Peripherie) abgesetzt. Danach verbindet er sich. Funktioniert nicht, wenn das Programm die SWJ Schnittstelle deaktiviert hat oder in einen Schlafmodus gegangen ist.
None Der Debugger verbindet sich ohne Reset mit dem laufenden Programm. Setzt voraus, dass auf dem Mikrocontroller bereits genau das Programm läuft, das gerade im Editor geöffnet ist. Funktioniert nicht, wenn das Programm die SWJ Schnittstelle deaktiviert hat oder in einen Schlafmodus gegangen ist.

⭐ Wenn dein Programm die SWJ Schnittstelle deaktiviert oder die CPU schlafen legt, empfiehlt sich ein 5s Delay ganz am Anfang der main() Funktion. Der Debugger bekommt dadurch genug Zeit, sich vorher zu verbinden.

Zum Ändern, klicke auf den kleinen Pfeil neben dem grünen Käfer oder Start-Knopf, dann auf Debug Configurations.... Gehe in dem folgenden Dialog in den Debugger Tab, wo du die Einstellung ändern kannst:

Wenn du statt desen den alternativen "OpenOCD" verwendest, kannst du die Einstellung im Abschnitt "Configuration Script" vornehmen. Klicke dort auf die Schaltlfäche "Show generator options".

Trace Meldungen ausgeben

Alle ARM Controller ab Cortex M3 aufwärts können Trace Meldungen (ITM, Instrumentation Trace Messages) auf der SWO Leitung ausgeben.

mit GDB

Die Cube IDE kann diese Meldungen bei Verwendung des ST-Link GDB Server oder Segger J-Link folgendermaßen anzeigen:

Neben dem grünen Käfer ist ein kleiner Pfeil, der nach unten Zeigt. Klicke darauf und dann auf Debug Configurations.... Aktiviere im Debugger Tab die rot markierte Option und stelle die Taktfrequenz des Mikrocontrollers ein:

Nun starte den Debugger durch Klick auf den grünen Käfer. Jetzt gehe in das Menü Window/Show View/Other... und wähle SWV ITM Data Console. Dieses Fenster ist zunächst leer. Klicke in der rechten oberen Ecke des Fensters auf das Werkzeug-Knopf.

Schalte im nächsten Dialog den "ITM Stimulus Port" Nummer 0 ein.

Direkt neben dem Werkzeug-Knopf ist ein roter Punkt mit der Beschriftung "Start Trace". Klicke darauf. Danach klicke am oberen Rand der IDE auf den Resume-Knopf.

Nun sollten in dem "SWV ITM Data Console" Fenster alle Trace Meldungen erscheinen, die das Programm auf dem Mikrocontroller erzeugt.

mit OpenOCD

Klicke auf den kleinen Pfeil neben dem grünen Käfer, dann auf Debug Configurations.... Wähle im Debugger Tab den ST-Link OpenOCD aus, und darunter die Option User defined configuration script.

Nun öffne dieses "Configuration Script" im Texteditor und hänge ganz unten zwei Zeilen an:

tpiu config internal /tmp/debug.txt uart off 8000000
itm port 0 on

Die Zahl 8000000 muss der CPU Taktfrequenz entsprechen.

Bei der nächsten debug Sitzung werden die Trace Meldungen dann in die Datei /tmp/debug.txt geschrieben. Zur fortlaufenden Anzeige benutze ich unter Windows den Befehl tail -f debug.txt in einem CygWin Fenster:

Die Datei enthält zwischen den Buchstaben nicht darstellbare Steuerzeichen. Falls tail diese unerwünscht anzeigt, kann man sie so heraus filtern: tail -f debug.txt | tr -dc '[:print:]\n'

Man kann die Schnittstelle auch so konfigurieren, dass sie die Meldungen im gleichen Format ausgibt, wie ein normaler serieller Port:

monitor tpiu config external uart off 8000000 2000000
itm port 0 on

Die Zahl 8000000 muss der CPU Taktfrequenz entsprechen, die Zahl 2000000 ist die serielle Baudrate - maximal 1/4 des CPU Taktes. Nun kann man die Ausgabe mit einem gewöhnlichen USB-UART Adapter empfangen.

mit ST-Link Utility

Außerhalb einer Debugger-Sitzung kann man das ST-Link Utility zur Anzeige benutzen, und zwar über dem Menüpunkt ST-LINK/Printf via SWO Viewer. Stelle die richtige Taktfrequenz ein und klicke dann auf Start.

STM32 Anleitungen