STM32 ファームウェア (CubeMX/HAL + PlatformIO, ST-Link)
コーディング規約、アーキテクチャ、単体テスト、一般的なデバッグについては embedded-c-cpp も読み込んでください。このスキルには STM32 固有の部分が含まれています。
最初に、プロジェクトを特定する
コードを書く前にリポジトリを読んでください。以下の事実によって回答が変わります。
| 項目 | 確認場所 |
|---|---|
| 正確な品番 (例: STM32G431KBT6) とファミリ (F0/F1/F4/G0/G4/L4/H7/U5...) | .ioc (Mcu.UserName)、platformio.ini の board =、スタートアップファイル名 |
| プロジェクトタイプ | .ioc + .project/.cproject → CubeIDE; .ioc + CMakeLists.txt/CMakePresets.json → CubeMX CMake; platformio.ini → PlatformIO |
| HAL vs LL vs レジスタ | Drivers/STM32xx_HAL_Driver、#include "stm32xx_ll_*.h"、CubeMX ペリフェラルごとの "Advanced settings" |
| RTOS | Middlewares/Third_Party/FreeRTOS、cmsis_os.h |
| クロック | main.c 内の SystemClock_Config()、.ioc の RCC セクション; Nucleo ボードは通常 ST-Link から HSE 8 MHz を供給 (HSE バイパス) |
| プローブ | ST-Link (Nucleo/Discovery ボード上内蔵、または ST-Link V2/V3 スタンドアロン) |
ファミリは重要です: コア (M0+/M3/M4F/M7/M33)、FPU の有無、フラッシュ書き込み粒度 (F1 はハーフワード、G4/L4 はダブルワード、H7 はフラッシュワード)、DMA (G0/G4/L4+/H7 は DMAMUX)、キャッシュ (F7/H7)。レジスタやペリフェラルの詳細が不明な場合は、推測せずにリファレンスマニュアル (RM) で確認すべきことを伝えてください。
作業を無駄にしないための CubeMX ルール
CubeMX は main.c、stm32xx_it.c、stm32xx_hal_msp.c、および初期化ファイルを毎回再生成します。/* USER CODE BEGIN x */ と /* USER CODE END x */ の間のテキストだけが保持されます。
- アプリケーションロジックは独自のファイル (
App/app.c、App/app.h、C++ の場合はapp.cpp) に配置し、USER CODE BEGIN 2とwhile (1)の USER CODE ブロックからapp_init()/app_loop()を呼び出してください。 - ピン、クロック、DMA、割り込み、ペリフェラルパラメータは
.iocファイルで変更し、その後再生成してください。MX_xxx_Init()を直接編集しないでください (上書きされ、.iocとコードの一致が失われます)。 .iocファイルをコミットしてください。これがハードウェア設定の信頼できる唯一の情報源です。- Project Manager → Code Generator で "Generate peripheral initialization as a pair of .c/.h files per peripheral" を有効にすると、
main.cが小さくなり、差分が明確になります。 - 詳細と C++ 統合については
references/cubemx-hal.mdを参照してください。
ビルド、フラッシュ、デバッグ
プロジェクトに合ったパスを選択してください。完全なコマンドは references/build-flash-debug.md にあります。
| プロジェクト | ビルド | フラッシュ (ST-Link) | デバッグ |
|---|---|---|---|
| CubeIDE | IDE、またはヘッドレス stm32cubeide ... -build | IDE、または STM32_Programmer_CLI -c port=SWD -w app.elf -v -rst | CubeIDE デバッガー (ST-LINK GDB サーバー) |
| CubeMX CMake (VS Code) | cmake --preset Debug && cmake --build --preset Debug | STM32_Programmer_CLI または OpenOCD | VS Code STM32 拡張 / OpenOCD + GDB |
| PlatformIO | pio run -e <env> | pio run -e <env> -t upload (upload_protocol = stlink) | pio debug / VS Code (debug_tool = stlink) |
フラッシュするとボードの状態が変わります。アップロードを実行する前に、どのボード/プローブが接続されているかをユーザーに確認し、明示的な確認なしにマスターイレース、オプションバイト、読み出し保護コマンドを実行しないでください (RDP レベル 2 は永続的です)。
HAL の使い方 — 最も時間を浪費するミス
- I2C アドレス は左シフトして渡します:
HAL_I2C_Master_Transmit(&hi2c1, 0x76 << 1, ...)。 - HAL コールバックは割り込みコンテキストで実行 されます (
HAL_UART_RxCpltCallback、HAL_GPIO_EXTI_Callback、HAL_TIM_PeriodElapsedCallback)。これらは短く保ち、HAL_Delayやブロッキング送信を入れないでください。 HAL_Delay/HAL_GetTickは SysTick を必要とします: これらをより高い優先度の ISR や割り込み禁止状態から呼び出すとハングします。FreeRTOS を使用する場合、CubeMX で SYS → Timebase Source を基本タイマー (TIM6/TIM7) に設定してください。- UART 受信:
HAL_UARTEx_ReceiveToIdle_DMA(可変長フレーム) または割り込みモードでリングバッファを使用します。コールバック内およびHAL_UART_ErrorCallback内で受信を再開してください (オーバーランは受信を静かに停止させます)。 - F7/H7 の DMA バッファ (データキャッシュ): TX の前にクリーニング、RX の後に無効化。32 バイトアラインでサイズも 32 の倍数に。H7 では DMA1/2 は DTCM RAM にアクセスできません。バッファは D2/AXI SRAM に配置してください。
- すべての HAL 関数の戻り値 (
HAL_OK、HAL_ERROR、HAL_BUSY、HAL_TIMEOUT) を確認してください。HAL_BUSYは通常、以前の転送が完了していないことを意味します。 - タイムアウト: 製品コードのパスで
HAL_MAX_DELAYを使用しないでください。 - その他のパターン (UART DMA、ADC DMA、タイマー/PWM、EXTI、低消費電力、フラッシュ書き込み、ウォッチドッグ、リセット原因):
references/cubemx-hal.mdを参照してください。
クラッシュした場合、または起動しない場合
- HardFault / MemManage / BusFault / UsageFault →
references/faults-and-recovery.md(CFSR/HFSR を読み、スタック上の PC を取得し、addr2lineでデコード) を参照。 - ST-Link が接続できない ("No target found"、"DEV_TARGET_HELD_UNDER_RESET") → リセット状態で接続してみる。SWD ピンが
.iocで GPIO に変更されていないか確認。BOOT0 を確認。RDP レベル →references/faults-and-recovery.mdを参照。 SystemClock_Configでハング → HSE が存在しない / バイパス設定の不一致、PLL 設定ミス、フラッシュレイテンシが低すぎる。- ペリフェラルが動作しない → クロックが有効か?ピンの AF 設定は正しいか?
MX_xxx_Initが実際に呼び出され、正しい順序で実行されているか (DMA はそれを使用するペリフェラルの前に初期化する)?
参考ファイル
| ファイル | 読むタイミング |
|---|---|
references/cubemx-hal.md | CubeMX プロジェクトのコードを書く/レビューするとき、C++ 統合、ペリフェラルパターン、低消費電力、フラッシュ/EEPROM エミュレーション、ウォッチドッグ、リセット原因 |
references/build-flash-debug.md | ツールチェーンインストール、CLI からのビルド、STM32 向け PlatformIO 設定、フラッシュ、GDB/OpenOCD、printf/SWV ロギング、サイズ分析 |
references/faults-and-recovery.md | HardFault およびその他のフォールト、ボードが接続できない場合、オプションバイトと読み出し保護、文鎮化したように見えるボードの復旧 |