Zurück zur Startseite

CMake für STM32F407: Erstellung mit GCC unter Windows

Der Artikel beschreibt das Einrichten von CMake für den plattformübergreifenden Firmware-Build von STM32F407VE mit ARM GCC unter Windows. Detaillierte Migration von GNU Make, Konfiguration der HAL-Module und strenge Compiler-Flags. Geeignet für Middle-/Senior-Embedded-Entwickler.

STM32-Firmware-Build: CMake + GCC unter Win10
Advertisement 728x90

CMake für STM32F407-Firmware unter Windows mit GCC einrichten

CMake ermöglicht plattformübergreifendes Erstellen von Firmware für STM32-Mikrocontroller. Mit einem einzigen Satz von Skripten können Sie Projekte sowohl unter Windows als auch Linux bauen. Dies löst das Problem von betriebssystemspezifischen Pfaden und Utilities in GNU Make. Für die Entwicklung auf einer einzigen Plattform ist ein Wechsel nicht nötig, aber bei der Unterstützung mehrerer Betriebssysteme wird CMake zum Standard unter den Meta-Build-Systemen.

Das System generiert native Build-Dateien: GNU Make für Linux/Windows, Ninja oder IDE-Projekte. Der Fokus liegt auf ARM GCC für STM32F407VE mit STs HAL und CMSIS.

Vorteile skriptbasierter Builds

Das Bauen über die Kommandozeile skaliert auf Hunderte von Firmware-Projekten. GUI-IDEs schränken die Automatisierung ein, wenn Projekte wachsen. Skripte ermöglichen Ihnen:

Google AdInline article slot
  • CI/CD-Pipelines automatisieren
  • Alle Varianten über Nacht bauen
  • Integration in Repositories mit einem einzigen Befehl

Für 150+ Firmware-Projekte reicht eine Batch-Datei: ausführen, und innerhalb weniger Minuten sind .hex-Dateien fertig.

Aufgabendefinition: Ein C-Projekt für STM32F407VE. ARM GCC Cross-Compiler. CMake generiert GNU Make. STM32 HAL + CMSIS. Ziel: Windows 10.

Strikte Flags an den Compiler übergeben:

Google AdInline article slot
-MMD -MP -O0 -std=c11 -Wall -Werror -mcpu=cortex-m4 -march=armv7e-m -Werror=address -Werror=address-of-packed-member -Werror=array-bounds=1 -Werror=bool-compare -Werror=bool-operation -Werror=char-subscripts -Werror=clobbered -Werror=div-by-zero -Werror=duplicate-decl-specifier -Werror=empty-body -Werror=enum-compare -Werror=float-equal -Werror=ignored-qualifiers -Werror=implicit -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=init-self -Werror=int-in-bool-context -Werror=int-to-pointer-cast -Werror=logical-not-parentheses -Werror=logical-op -Werror=maybe-uninitialized -Werror=memset-elt-size -Werror=misleading-indentation -Werror=missing-braces -Werror=multistatement-macros -Werror=old-style-declaration -Werror=overflow -Werror=pointer-arith -Werror=pointer-sign -Werror=return-local-addr -Werror=return-type -Werror=shadow -Werror=shift-count-overflow -Werror=sign-compare -Werror=sizeof-pointer-div -Werror=strict-aliasing -Werror=switch -Werror=tautological-compare -Werror=type-limits -Werror=uninitialized -Werror=unused-variable -g3 -Wextra -Wno-conversion -Wno-cpp -Wno-discarded-qualifiers -Wno-implicit -Wno-int-conversion -Wno-nonnull-compare -Wno-redundant-decls -Wno-restrict -Wno-sign-compare -Wno-stringop-truncation -Wno-switch-bool -Wno-unused-parameter -fallthrough -fdata-sections -ffreestanding -ffunction-sections -finline-small -fmax-errors=70 -fno-common -fno-move-loop-invariants -fno-printf-return-value -fomit-frame-pointer -fshort-enums -fsigned-char -fstack-usage -fzero-initialized-in-bss -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb

An den Linker:

-specs=nosys.specs -Xlinker --gc-sections -Xlinker --nmagic -Wl,--gc-sections -Xlinker --print-memory-usage -t -Wl,--cref -Wl,--gc-sections --verbose -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -lm

STM32CubeMX generiert CMake nicht direkt – nur GNU Make. Die Lösung: manuelle Migration.

Theorie: Von Make zu CMake

Umgebungsvariablen speichern Pfade, Compiler-Flags und Einstellungen. Für alle Utilities sichtbar.

Google AdInline article slot

Build-System automatisiert Kompilierung, Linking und Abhängigkeiten. Beispiele: GNU Make, Ninja, IAR.

Build-System-Generator (CMake, Meson) erstellt Dateien für native Build-Systeme.

CMake + GNU Make Schema:

  • CMake liest CMakeLists.txt
  • Generiert Makefile
  • GNU Make baut Artefakte

CMake prüfen: where cmake unter Windows.

Migration Make → CMake

Mechanische Syntax-Ersetzung. CMake ist ausführlicher, aber leistungsfähiger.

| GNU Make | CMake | Erklärung |

|----------|--------|-----------|

| VAR += value | string(APPEND VAR " value") | An Variable anhängen |

| CRC=Y | set(CRC Y) | Definition |

| $(VAR) | ${VAR} | Einfügung |

| ifeq($(IAR),Y) | if(IAR STREQUAL Y) | Bedingung |

| SOURCES_C += src/main.c | target_sources(app PRIVATE src/main.c) | Quelldateien |

| OPT += -Ipath | target_include_directories(app PUBLIC path) | Pfade |

Transformationsbeispiele:

  • LINKER_FLAGS += -u _printf_floattarget_link_options(app PRIVATE -u _printf_float)
  • include file.mkinclude(${file}.cmake)
  • SOURCES += file.cstring(APPEND SOURCES " ${file}.c")
  • ifneq($(FLAG),Y)if(NOT (FLAG STREQUAL Y))

CMakeLists.txt (Root):

cmake_minimum_required(VERSION 3.16)
project(jz_f407vet6_mbr_gcc_cmake)
set(PROJECT_NAME jz_f407vet6_mbr_gcc_cmake)
enable_language(C ASM)

set(CURRENT_CMAKELISTS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(PROJECT_LOC ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${PROJECT_LOC})

set(BUILD_DIR ${PROJECT_LOC}/build)
set(TARGET ${PROJECT_NAME})
set(EXECUTABLE ${TARGET})

get_filename_component(WORKSPACE_LOC "${PROJECT_LOC}/../.." ABSOLUTE)
include_directories(${WORKSPACE_LOC})

include(${PROJECT_LOC}/config.cmake)
include(${WORKSPACE_LOC}/cmake_scripts/code_base.cmake)
include(${WORKSPACE_LOC}/cmake_scripts/rules.cmake)

Komponentenkonfiguration

In config.cmake Module aktivieren:

set(CONTROL Y)
set(DWT Y)
set(ARM_GCC Y)
set(CORTEX_M4 Y)
set(FLASH Y)
set(FPU Y)
set(GPIO Y)
set(INTERRUPT Y)
set(JZ_F407VET6 Y)
set(LED_MONO Y)
set(MBR Y)
set(MCAL_STM32 Y)
set(MICROCONTROLLER Y)
set(NVIC Y)
set(RCC Y)
set(SCHEDULER Y)
set(STM32F407VE Y)
set(STM32F4X_HAL_DRIVER Y)
set(SUPER_CYCLE Y)
set(SYSTEM Y)
set(SYSTICK Y)
set(SYS_INIT Y)
set(TIME Y)

In code_base.cmake Komponenten bedingt hinzufügen:

if(GPIO STREQUAL Y)
  target_sources(app PRIVATE gpio/src/gpio.c)
  target_include_directories(app PUBLIC gpio/inc)
  add_compile_definitions(GPIO_ENABLED)
endif()

Wichtige Erkenntnisse

  • CMake bietet plattformübergreifende Kompatibilität ohne Skripte neu schreiben
  • Make→CMake-Migration ist eine vorlagenbasierte Ersetzung, automatisierbar mit KI
  • Strikte -Werror-Flags fangen Fehler zur Kompilierzeit
  • config.cmake verwaltet HAL-Modulauswahl
  • Skriptbasierte Builds skalieren auf 100+ Firmware-Projekte

— Editorial Team

Advertisement 728x90

Weiterlesen