STM32 firmware (CubeMX/HAL + PlatformIO, ST-Link)

Développement de firmware STM32 avec STM32CubeMX / STM32CubeIDE + HAL/LL et PlatformIO — structure de projet et règles USER CODE, périphériques (UART/I2C/SPI/ADC/timers/DMA), horloges, basse consommation, flash/option bytes, construction en ligne de commande, flashage et débogage avec ST-Link (STM32CubeProgrammer CLI, OpenOCD, GDB, SWV), et analyse des HardFault.

Qu'est-ce que HAL + PlatformIO, ST-Link) ?

Cette compétence spécialisée couvre le développement de firmware pour microcontrôleurs STM32 en utilisant les outils officiels (STM32CubeMX, STM32CubeIDE) et alternatifs (PlatformIO). Elle guide l'utilisateur à travers l'identification du projet (partie exacte, famille, type de projet, RTOS, horloges, sonde), l'application des règles de régénération CubeMX pour ne pas perdre de code, et les bonnes pratiques pour les appels HAL (adresses I2C, callbacks en contexte d'interruption, gestion des timeouts, utilisation du DMA avec cache). La compétence propose également des procédures de construction, flashage et débogage pour les trois types de projets (CubeIDE, CubeMX CMake, PlatformIO) avec ST-Link, et fournit des références détaillées pour l'analyse des HardFault, la récupération de carte, et les patterns avancés (basse consommation, flash/EEPROM, watchdog). Utilisez cette compétence dès que l'utilisateur travaille sur une carte STM32, Nucleo, Discovery ou Blue Pill, un fichier `.ioc`, CubeMX/CubeIDE, des fonctions `HAL_`, ST-Link, ou rencontre un HardFault.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/budenga/firmware-skills/tree/HEAD/skills/stm32-firmware

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait HAL + PlatformIO, ST-Link) ?

Chargez également embedded-c-cpp pour les normes de codage, l'architecture, les tests unitaires et le débogage général. Cette compétence contient les parties spécifiques à STM32.

Premièrement, identifier le projet

Lisez le dépôt avant d'écrire du code. Ces faits modifient la réponse :

TrouverOù
Partie exacte (ex. STM32G431KBT6) et famille (F0/F1/F4/G0/G4/L4/H7/U5...).ioc (Mcu.UserName), platformio.ini board =, nom du fichier startup
Type de projet.ioc + .project/.cproject → CubeIDE ; .ioc + CMakeLists.txt/CMakePresets.json → CubeMX CMake ; platformio.ini → PlatformIO
HAL vs LL vs registresDrivers/STM32xx_HAL_Driver, #include "stm32xx_ll_*.h", "Advanced settings" de CubeMX par périphérique
RTOSMiddlewares/Third_Party/FreeRTOS, cmsis_os.h
HorlogesSystemClock_Config() dans main.c, section RCC du .ioc ; les cartes Nucleo fournissent généralement HSE 8 MHz depuis le ST-Link (HSE bypass)
SondeST-Link (intégré sur Nucleo/Discovery, ou ST-Link V2/V3 autonome)

La famille a beaucoup d'importance : cœurs (M0+/M3/M4F/M7/M33), FPU ou non, granularité d'écriture flash (demi-mot sur F1, double-mot sur G4/L4, mot flash sur H7), DMA (DMAMUX sur G0/G4/L4+/H7), caches (F7/H7). En cas de doute sur un registre ou un détail de périphérique, dites ce qu'il faut vérifier dans le manuel de référence (RM) au lieu de deviner.

Les règles CubeMX qui évitent de perdre du travail

CubeMX régénère main.c, stm32xx_it.c, stm32xx_hal_msp.c et les fichiers d'initialisation à chaque fois. Seul le texte entre /* USER CODE BEGIN x */ et /* USER CODE END x */ est conservé.

  • Placez la logique applicative dans vos propres fichiers (App/app.c, App/app.h, ou app.cpp pour le C++) et appelez app_init() / app_loop() depuis USER CODE BEGIN 2 et le bloc USER CODE du while (1).
  • Modifiez les broches, horloges, DMA, interruptions et paramètres des périphériques dans le fichier .ioc, puis régénérez — ne modifiez pas MX_xxx_Init() directement (elle sera écrasée, et le .ioc ne correspondra plus au code).
  • Commitez le fichier .ioc. C'est la source de vérité pour la configuration matérielle.
  • Activez "Generate peripheral initialization as a pair of .c/.h files per peripheral" dans Project Manager → Code Generator : main.c plus petit, diffs plus propres.
  • Détails et intégration C++ : references/cubemx-hal.md.

Construction, flashage, débogage

Choisissez le chemin correspondant au projet ; commandes complètes dans references/build-flash-debug.md.

ProjetConstructionFlashage (ST-Link)Débogage
CubeIDEIDE, ou stm32cubeide ... -build en mode headlessIDE, ou STM32_Programmer_CLI -c port=SWD -w app.elf -v -rstDébogueur CubeIDE (serveur GDB ST-LINK)
CubeMX CMake (VS Code)cmake --preset Debug && cmake --build --preset DebugSTM32_Programmer_CLI ou OpenOCDExtension STM32 VS Code / OpenOCD + GDB
PlatformIOpio run -e <env>pio run -e <env> -t upload (upload_protocol = stlink)pio debug / VS Code (debug_tool = stlink)

Le flashage modifie la carte : confirmez avec l'utilisateur quelle carte/sonde est connectée avant d'exécuter un téléversement, et n'exécutez jamais d'effacement de masse, de commande d'option byte ou de protection en lecture sans confirmation explicite (le niveau RDP 2 est permanent).

Utilisation de la HAL — les erreurs qui coûtent le plus de temps

  • Les adresses I2C sont passées décalées à gauche : HAL_I2C_Master_Transmit(&hi2c1, 0x76 << 1, ...).
  • Les callbacks HAL s'exécutent en contexte d'interruption (HAL_UART_RxCpltCallback, HAL_GPIO_EXTI_Callback, HAL_TIM_PeriodElapsedCallback) : gardez-les courts, pas de HAL_Delay, pas de transmissions bloquantes.
  • HAL_Delay / HAL_GetTick nécessitent SysTick : les appeler depuis une ISR de priorité supérieure ou avec les interruptions désactivées bloque le système. Avec FreeRTOS, réglez SYS → Timebase Source sur un timer basique (TIM6/TIM7) dans CubeMX.
  • Réception UART : utilisez HAL_UARTEx_ReceiveToIdle_DMA (trames de longueur variable) ou le mode interruption avec un buffer circulaire ; relancez la réception dans le callback et dans HAL_UART_ErrorCallback (un dépassement de capacité arrête la réception silencieusement).
  • Buffers DMA sur F7/H7 (cache données) : nettoyez avant TX, invalidez après RX, alignés et de taille multiple de 32 octets ; sur H7, DMA1/2 ne peuvent pas atteindre la DTCM RAM — placez les buffers dans la D2/AXI SRAM.
  • Vérifiez la valeur de retour de chaque appel HAL (HAL_OK, HAL_ERROR, HAL_BUSY, HAL_TIMEOUT) ; un HAL_BUSY signifie généralement qu'un transfert précédent ne s'est jamais terminé.
  • Timeouts : jamais HAL_MAX_DELAY dans les chemins de production.
  • Plus de patterns (UART DMA, ADC DMA, timers/PWM, EXTI, basse consommation, écritures flash, watchdog, cause de reset) : references/cubemx-hal.md.

En cas de crash ou de démarrage impossible

  • HardFault / MemManage / BusFault / UsageFault → references/faults-and-recovery.md (lire CFSR/HFSR, PC empilé, décoder avec addr2line).
  • ST-Link ne peut pas se connecter ("No target found", "DEV_TARGET_HELD_UNDER_RESET") → connecter sous reset ; vérifier que les broches SWD n'ont pas été reconfigurées en GPIO dans le .ioc ; BOOT0 ; niveau RDP → references/faults-and-recovery.md.
  • Blocage dans SystemClock_Config → HSE absent / bypass erroné, mauvais PLL, latence flash trop faible.
  • Périphérique silencieux → horloge activée ? broche AF correcte ? MX_xxx_Init réellement appelée et dans le bon ordre (DMA init avant le périphérique qui l'utilise) ?

Fichiers de référence

FichierÀ lire quand
references/cubemx-hal.mdÉcrire/revoir du code dans un projet CubeMX, intégration C++, patterns périphériques, basse consommation, émulation flash/EEPROM, watchdog, cause de reset
references/build-flash-debug.mdInstallation de la chaîne d'outils, construction en CLI, configuration PlatformIO pour STM32, flashage, GDB/OpenOCD, journalisation printf/SWV, analyse de taille
references/faults-and-recovery.mdHardFault et autres fautes, carte ne se connecte pas, option bytes et protection en lecture, récupération d'une carte qui semble brickée

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

esp32-firmware

ESP32 firmware with PlatformIO — Arduino framework (primary) and ESP-IDF (also inside PlatformIO, or Arduino as an IDF component) — for ESP32, S2, S3, C3, C6. Covers platformio.ini setup, Arduino core 2.x vs 3.x API differences, safe pin selection (strapping/flash/PSRAM/ADC2 pins), FreeRTOS tasks and ISRs, memory/PSRAM, Wi-Fi/BLE, NVS/Preferences, OTA, deep sleep, partitions, flashing over USB/serial, decoding Guru Meditation panics and boot loops. Use this skill whenever the user works on any ESP32 / ESP32-S3 / C3 / C6 board, platformio.ini with espressif32, Arduino sketches for ESP32, idf.py/sdkconfig, or pastes ESP32 serial output (rst:, Guru Meditation, Brownout, watchdog) — even if they only say "a placa reinicia" or "o upload falha". Use together with embedded-c-cpp for general C/C++ quality, testing and architecture.

pic-firmware

Microchip PIC and dsPIC firmware with MPLAB X IDE, XC8 / XC16 / XC-DSC / XC32 compilers and MPLAB Code Configurator (MCC Melody/Classic) for PIC16, PIC18, PIC24, dsPIC33 (F/EP/EV/CK/CH dual-core/A) and PIC32 — configuration bits, oscillator/PLL, TRIS/LAT/PORT/ANSEL, PPS, interrupts per family, 8/16-bit atomicity and hardware-stack limits, dsPIC DSP engine and Q15 fixed-point, high-speed PWM/ADC control loops, motor control and digital power, XC8 memory and optimization, headless builds, programming and debugging with PICkit 4/5, MPLAB Snap and ICD (ipecmd), reset causes and traps. Use this skill whenever the user mentions any PIC or dsPIC part (PIC16F, PIC18F, PIC24F, dsPIC33EP/CK/CH, PIC32MX/MZ), MPLAB X, MCC, XC8/XC16/XC-DSC/XC32, PICkit, Snap, ICD, `#pragma config`, motorBench, or a .X project folder — even for a short question like "o pino não lê nada no PIC" or "o meu controlo PI no dsPIC oscila". Use together with embedded-c-cpp for general C quality, testing and arc...

Skills associés