stm32-baremetal について
STM32 HALを使わず、CMSISデバイスヘッダーとスタートアップコードで最小構成のSTM32ファームウェアを作るためのエージェント向けスキルです。クロック設定、レジスタ操作、リンカースクリプト、再現可能なビルドを扱います。
主な機能
- 01CMSISのみのプロジェクト構成
- 02RCCクロック設定
- 03ペリフェラルレジスター操作
- 04リンカーとフラッシュ配置
- 05arm-none-eabi-gccのビルド設定
活用シーン
- 01Cube HALなしでSTM32開発を開始
- 02サンプルをレジスターレベルのドライバーへ移植
- 03クロックやフラッシュ配置の問題を調査
- 04RTOS導入前にSTM32レジスターを学習
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill stm32-baremetalインストール後、Claude Code で/stm32-baremetalを入力して読み込まれたか確認します。
詳細
STM32 ベアメタル(CMSIS、HAL なし)
目的
CMSIS デバイスヘッダーとスタートアップコードのみを使用する最小限の STM32 ベアメタルプロジェクトについて、エージェントをガイドします。STM32 HAL は使用せず、STM32F/G/H/L ファミリー向けのクロック設定、リンカースクリプトの統合、ペリフェラルレジスターへのアクセス、再現可能なビルドレイアウトを扱います。
使用する場面
- Cube HAL に依存せずに STM32 ファームウェアを開始する場合
- ベンダーのサンプルをレジスターレベルのドライバーに移植する場合
skills/baremetal/baremetal-startupとskills/embedded/linker-scriptsを統合する場合- STM32 のクロックやフラッシュ配置の問題をデバッグする場合
- RTOS や Zephyr の前に、STM32 のレジスターレベルの操作を学ぶ場合
ワークフロー
1. 最小限のプロジェクトレイアウト
stm32-bare/
├── startup_stm32f407xx.s # vector table + Reset_Handler
├── system_stm32f4xx.c # SystemInit(), SystemCoreClockUpdate()
├── stm32f407xx.h # CMSIS (from ST pack or copy)
├── linker.ld # FLASH/RAM regions
├── main.c
└── Makefile
CMSIS-Core(core_cm4.h)と、ST CMSIS パックまたはオープンソースのパック(例:stm32-cmsis-device-f4)に含まれるデバイスヘッダーを使用します。
2. クロック設定(RCC)
STM32 では、高速ペリフェラルを使用する前に、HSE/HSI と PLL を明示的に設定する必要があります。
/* system_stm32f4xx.c — simplified PLL from 8 MHz HSE */
void SystemInit(void)
{
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY)) {}
RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC_HSE | (8 << 0) | (336 << 6) | (0 << 16) | (7 << 24);
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_HPRE_DIV1;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY)) {}
FLASH->ACR = FLASH_ACR_LATENCY_5WS;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {}
SystemCoreClockUpdate();
}
FLASH_ACR のウェイトステートは、リファレンスマニュアルの表に従い、電圧スケールと SYSCLK に必ず合わせてください。
3. MMIO の前にペリフェラルクロックを有効化する
#define RCC_AHB1ENR_GPIOAEN (1U << 0)
static inline void gpioa_clock_enable(void)
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
(void)RCC->AHB1ENR; /* AHB read-after-write — required on STM32 */
}
4. ビルドフラグ(arm-none-eabi-gcc)
MCU = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS = $(MCU) -Wall -Wextra -ffunction-sections -fdata-sections -g3
LDFLAGS = $(MCU) -T linker.ld -Wl,--gc-sections -specs=nano.specs -lc -lm -lnosys
5. フラッシュマップ(一般的な F4)
| 領域 | アドレス | 備考 |
|---|---|---|
| フラッシュ | 0x08000000 | 起動時のベクターテーブル |
| SRAM1 | 0x20000000 | スタック、ヒープ、.data/.bss |
| CCM | 0x10000000 | F4 のみ — すべてのマスターから DMA アクセスできるわけではありません |
ブートローダーアプリは 0x08010000 にリンクすることが多く、エントリー時に SCB->VTOR = 0x08010000 を設定します。
6. QEMU に関する注意
QEMU の STM32 マシン(stm32vldiscovery、netduinoplus2 など)は、F407 とは異なる MCU を使用し、GPIO/DMA/I2C を省略しています(QEMU STM32 のドキュメントを参照)。シミュレーションには skills/qemu/qemu-embedded-simulation を使用し、F4 ファームウェアは実機で検証してください。
7. エージェントでの使用
/stm32-baremetal Scaffold CMSIS-only STM32F407 project with USART2 printf
よくある問題
| 症状 | 原因 | 対処方法 |
|---|---|---|
SystemInit で停止する | HSE が未実装/PLL の設定が誤っている | 初期立ち上げには HSI を使用し、水晶発振子を確認する |
| ペリフェラルが動作しない | RCC クロックゲートがオフ | AHB/APB ビットを有効にし、RCC を読み戻す |
| 起動時に HardFault が発生する | スタックが誤った領域にある/VTOR の設定が誤っている | linker.ld の _estack を確認する |
| ボーレートが誤っている | SystemCoreClock が古い | PLL の設定後に SystemCoreClockUpdate() を呼び出す |
| CCM から DMA が失敗する | CCM が AHB マトリックスの経路上にない | DMA バッファーを SRAM1 に配置する |
関連スキル
skills/baremetal/baremetal-startup— ベクターテーブルと.data/.bssskills/baremetal/mmio-and-bit-manipulation— レジスターアクセスのパターンskills/baremetal/bootloaders-embedded— アプリのオフセットと VTOR の再配置skills/embedded/linker-scripts— FLASH/RAM の MEMORY ブロックskills/embedded/openocd-jtag— ST-Link 経由のフラッシュ書き込みと GDB