Eintrag

STM32 Entwicklung mit Visual Studio Code

Diese Anleitung ist veraltet. ST hat die Erweiterung aktualisiert und der Weg ist nun etwas anders und vielleicht auch etwas vereinfacht. Sofern ich zeit habe, werde ich die Anleitung aktualisieren.

STM32CubeIDE, basierend auf Eclipse und bereits über 20 Jahre alt, erschien mir immer etwas schwerfällig, aber dennoch besser als Keil. Mein aktueller Favorit für die Entwicklung von STM32-Mikrocontrollern ist Visual Studio Code (VS Code), den ich bereits in anderen Projekten einsetze, einschließlich der Erstellung dieses Blogs.

Zu Beginn dieses Jahres hat STMicroelectronics die STM32 VS Code Extension veröffentlicht, die die STM32-Entwicklung mit VS Code stark vereinfacht.

Die Schritte in diesem Tutorial sind auch auf GitHub verfügbar. STM32FirstSteps

Projekt in Visual Studio Code öffnen

Nach der Installation der STM32 VS Code Extension findest du ein STM32-Schmetterlings-Symbol in der linken Symbolleiste. Mit einem Klick darauf kannst du deine Projektdatei .cproject öffnen. Während der Einrichtung wird nach der Standardkonfiguration gefragt, und ich wähle Debug aus.

Build

Die Projektkonfiguration erfolgt mithilfe von CMake, das ich bereits installiert habe. Ebenso habe ich ninja als Alternative zu make sowie arm-none-eabi-gcc installiert. Alle diese Tools sind bereits in meinem Systempfad enthalten, daher sehen meine Konsolenausgaben wie folgt aus:

1
2
3
4
5
6
7
8
9
10
11
> cmake --version
cmake version 3.25.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).
> ninja --version
1.10.2
> arm-none-eabi-gcc --version
arm-none-eabi-gcc.exe (Arm GNU Toolchain 12.2.MPACBTI-Rel1 (Build arm-12-mpacbti.34)) 12.2.1 20230214
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Das Erstellen der Binärdateien erfolgt einfach per Mausklick auf F7.

Debugging

Mit F5 startest du den Debugger. Im Gegensatz zu STM32CubeIDE startet der Debugger nicht in der main-Funktion, sondern im Reset_Handler der Datei startup_stm32f446zetx.s. Daher habe ich manuell einen Breakpoint in der main-Funktion gesetzt, zu der der Debugger nach erneutem Drücken von F5 gelangt. Wenn du dieses Verhalten ändern möchtest, kannst du in der Datei .vscode\launch.json den Wert stopAtConnect`: true` aufstopAtConnect: false ändern.

Debugansicht in Visual Studio Code Debugansicht in VS Code: Auf der linken Seite werden lokale Variablen, CPU-Register sowie Peripherie-Register angezeigt und können bearbeitet werden. Darüber hinaus gibt es eine Beschreibung der Register.

Ein Blick hinter die Kulissen

Beim Konvertieren in ein VS Code-Projekt werden eine Vielzahl von Dateien erstellt. Im Verzeichnis .vscode findest du Konfigurationsdateien für VS Code. tasks.json enthält z.B. den Build-Task, und launch.json enthält die Konfiguration für den Bootloader.

Aber noch interessanter ist die Struktur der CMake-Dateien. Die Datei CMakeLists.txt enthält lediglich den Projektnamen, erstellt ein ausführbares Programm und fügt diesem die erforderlichen Eigenschaften hinzu:

1
2
3
4
5
6
7
8
cmake_minimum_required(VERSION 3.20)

project("STM32FirstSteps" C CXX ASM)

include(cmake/st-project.cmake)

add_executable(${PROJECT_NAME})
add_st_target_properties(${PROJECT_NAME})

Die Datei cmake\st-project.cmake enthält die Funktion add_st_target_properties, die Kompilierungs- und Link-Definitionen, Optionen, Include-Verzeichnisse und eine Liste aller verwendeten Quelldateien enthält. Es wird leider keine seperate statische Bibliothek für die STM HAL erstellt.

Die Verwendung von CMake Generator Expressions in den Optionen und Definitionen mag auf den ersten Blick verwirrend sein. Zum Beispiel wird DEBUG in jeder Debug-Konfiguration gesetzt, unabhängig von der Sprache. STM32F446xx und USE_HAL_DRIVER werden immer gesetzt, außer in Assemblerdateien. Diese Flags schaden jedoch auch in Assemblerdateien nicht.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
target_compile_definitions(
    ${TARGET_NAME} PRIVATE
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:ASM>>:DEBUG>"
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C>>:DEBUG>"
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C>>:USE_HAL_DRIVER>"
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C>>:STM32F446xx>"
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:CXX>>:DEBUG>"
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:CXX>>:USE_HAL_DRIVER>"
    "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:CXX>>:STM32F446xx>"
    "$<$<AND:$<NOT:$<CONFIG:Debug>>,$<COMPILE_LANGUAGE:C>>:USE_HAL_DRIVER>"
    "$<$<AND:$<NOT:$<CONFIG:Debug>>,$<COMPILE_LANGUAGE:C>>:STM32F446xx>"
    "$<$<AND:$<NOT:$<CONFIG:Debug>>,$<COMPILE_LANGUAGE:CXX>>:USE_HAL_DRIVER>"
    "$<$<AND:$<NOT:$<CONFIG:Debug>>,$<COMPILE_LANGUAGE:CXX>>:STM32F446xx>"
)

In einem nachfolgendem Artikel habe ich die CMake-Dateien optimieren.

Dieser Eintrag steht unter Urheberrecht .