本記事は STM32Cube.AI (X-CUBE-AI) v10 系を念頭に、STM32H7 / U5 を主軸として解説します。STM32N6(最新 NPU 搭載品)にも触れます。リンカスクリプト書き換えは GCC ベース(STM32CubeIDE / Arm GNU Toolchain)の .ld 書式で示しますが、IAR / Keil でも考え方は同じです。
はじめに:学習はできた、で実装は?
「Keras で MobileNet を学習させて 98% の精度が出た。さあ STM32 に載せよう」――ここで多くのエンジニアが詰まります。モデルサイズが 内蔵 Flash 容量を超える、または載せても 推論速度がリアルタイム要件に届かない。さらにバッテリ駆動製品なら 消費電流もシビア。
これらをワンセットで解決するのが STM32Cube.AI(旧 X-CUBE-AI)です。Keras / TFLite / ONNX で学習済みのモデルを 量子化 + 最適化 + STM32 専用 C コード化し、さらに重み(weights)を 外部 Quad-SPI Flash に置いて Memory-Mapped Mode で読みに行くといった配置最適化まで可能です。
本記事は「Cube.AI で C コード化できた、でも内蔵 Flash に収まらない / 動かない」段階のエンジニアが、リンカスクリプト(.ld ファイル)書き換えレベルで外部メモリ配置に踏み込めるよう、ST 公式の UM2526 / AN5050 / AN4839 を一次資料に体系化します。基礎となる DMA は STM32 DMA 完全ガイド、FreeRTOS との連携は STM32 + FreeRTOS 入門 を併せてご覧ください。
弊社は 画像認識・組込み AI 案件を多数 手がけており、STM32 系のエッジ推論実装でリンカスクリプト書き換えやキャッシュ最適化を伴う案件のノウハウを蓄積しています。本記事はその実案件で踏んだ落とし穴と公式ドキュメントの読み解きを整理したものです。
STM32Cube.AI とは(X-CUBE-AI / AI Studio / Edge AI Suite)
2026年現在、ST のエッジ AI ツールは 「ST Edge AI Suite」というブランド傘下に統合されつつあります。整理すると:
| ツール | 位置付け | 使う場面 |
|---|---|---|
| X-CUBE-AI (STM32Cube.AI) | CubeMX 内蔵ミドルウェアパック。MCU 向けコード生成の中核 | 既存の CubeMX フローを継続する案件 |
| STM32Cube AI Studio | 2025-2026 リリースの新スタンドアロンデスクトップツール | 新規案件で、量子化~ベンチマーク~デプロイを統合 UI で進めたい |
| NanoEdge AI Studio | AutoML(異常検知中心)、オンデバイス学習可 | 異常検知 / 1-class classification |
| ST Edge AI Developer Cloud | オンライン版、board farm で実機ベンチ可 | 実機を持たずにベンチマーク取得したい |
| X-LINUX-AI | STM32 MPU (Linux) 向け | STM32MP1 / MP2 系 |
X-CUBE-AI の基本機能
- 対応モデル形式:Keras (.h5) / TFLite (.tflite) / ONNX (.onnx) / scikit-learn 等
- 最適化:量子化(int8)、Pruning、メモリ最適化(共有バッファ活用)
- 対応 STM32 系列:F3 / F4 / F7 / G4 / H7 / L4 / L4+ / L5 / WB / WL(H5 / U5 は最新版で要確認)。N6 は NPU 経由でサポート
- AI Validation:PC 上での精度比較(validate on desktop)+ 実機での推論時間・精度検証(validate on target)
- 統合形態:CubeMX のソフトウェアパック / CubeIDE プラグイン / CLI(
stm32ai/stedgeai)
(出典: UM2526「Getting started with X-CUBE-AI Expansion Package」)
生成コードのファイル構成とメモリ 3 区分
X-CUBE-AI が CubeMX 経由で生成するファイルは典型的に以下の構成です。
X-CUBE-AI/App/
├── app_x-cube-ai.c / .h // MX_X_CUBE_AI_Init / Process(ユーザが触る層)
├── network.c / .h // 推論関数(ai_network_create / init / run)
├── network_data.c / .h // 重みデータ(const 配列)と参照関数
├── network_config.h // モデルメタデータ(テンソル形状等)
└── network_generate_report.txt // メモリ・MAC 使用量レポート
覚えるべきは「Weights / Activations / I/O buffers」の 3 区分
X-CUBE-AI の世界では、モデルが消費するメモリは次の 3 つに分けられます。
| 区分 | 内容 | デフォルト配置 | 典型サイズ |
|---|---|---|---|
| Weights | 推論パラメータ(モデル重み) | 内蔵 Flash(const 配列) | 数十 KB ~ 数 MB |
| Activations | レイヤ間中間バッファ(推論中のみ使用) | 内蔵 RAM | 数 KB ~ 数百 KB |
| I/O buffers | 入力テンソル / 出力テンソル | 内蔵 RAM | 数百 B ~ 数十 KB |
CubeMX の X-CUBE-AI 設定で "Use activation buffer for input/output" をオンにすると、I/O バッファを activations と兼用してくれます。これだけで RAM 使用量が数〜数十 KB 削減されることが多く、まず最初に試すべきオプションです。
メモリ階層と速度の関係(STM32H7 を例に)
STM32H7 系は、AI 用途で最もよく使われる MCU の一つです。多階層のメモリ構造を持ち、各層でアクセス速度が大きく異なります。(出典: AN4891「STM32H72x/H73x system architecture and performance」/ RM0433)
| メモリ | アドレス | 典型サイズ | レイテンシ | 備考 |
|---|---|---|---|---|
| ITCM | 0x00000000 | 64 KB | 0 wait state | コア最近接、命令専用 |
| DTCM | 0x20000000 | 128 KB | 0 wait state | コア最近接、データ専用 |
| AXI SRAM (RAM_D1) | 0x24000000 | 512 KB | 数サイクル | D-Cache 有効可 |
| SRAM (RAM_D2) | 0x30000000 | 288 KB | 数サイクル | - |
| SRAM (RAM_D3) | 0x38000000 | 64 KB | 数サイクル | - |
| 内蔵 Flash | 0x08000000 | 最大 2 MB | キャッシュ要 | 64-128 bit バス幅 |
| 外部 OCTOSPI/QSPI(Memory-Mapped) | 0x90000000 | 8 MB ~ | 大幅レイテンシ | 4-bit / 8-bit シリアル |
内蔵 Flash は 64-128 bit バスで接続されているのに対し、Quad-SPI Flash は 4 bit シリアルです。OCTOSPI でも 8 bit。理論帯域差は約 8-16 倍あります。さらに Quad-SPI は SPI ベースなのでオーバーヘッドが大きく、実測では 10 MB/s 程度に収まる報告もあります(STM32H735 ユーザ実測)。これを Cache 有効化で何倍にも改善するのが本記事の主役テクニックです。
重み配置の 5 パターンとトレードオフ
X-CUBE-AI 公式が STM32H747I-DISCO の FoodReco サンプル等で示している、重み・活性化の配置パターンは大きく 5 つです。(出典: AI:How to run larger models on STM32H747I-DISCO wiki / UM2611)
| パターン | Weights | Activations | 特徴 |
|---|---|---|---|
| ① 標準 | 内蔵 Flash | 内蔵 RAM | 最高速。サイズ限界が早い |
| ② Ext_Qspi | 外部 QSPI | 内蔵 RAM | 大モデル可。推論は遅い |
| ③ Split_Qspi | 内蔵 Flash + QSPI 分割 | 内蔵 RAM | ホット層を内蔵、大層を外部 |
| ④ Ext_Sdram | QSPI | 外部 SDRAM | 大活性化対応 |
| ⑤ Split_Sdram | 起動時 QSPI→SDRAM コピー | SDRAM | WEIGHT_EXEC_EXTRAM=1。SDRAM から実行 |
選択ガイド
- モデル < 内蔵 Flash 容量 - アプリ用領域:迷わず①
- モデル数 MB、推論レイテンシ寛容:②
- モデル数 MB、最初の数層は高速処理したい:③(最重要)
- 大画像 ResNet 等で活性化バッファが内蔵 RAM を超える:④
- QSPI 読出しでも遅い、SDRAM を持っている:⑤
リンカスクリプト書き換え実践
パターン② Ext_Qspi(重みを QSPI に配置)を例に、リンカスクリプトの書き換え手順を示します。STM32H750 を題材にした典型例です。(出典: AN5050「Getting started with OCTOSPI, HEXADECASPI and XSPI interface」/ ControllersTech 公開例)
Step 1:MEMORY ブロックに QSPI を追加
CubeIDE 生成の STM32H750xx_FLASH.ld(または同等ファイル)の MEMORY セクションに QSPI 領域を追加します。
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
QSPI (rx) : ORIGIN = 0x90000000, LENGTH = 8M /* ← 追加 */
}
Step 2:SECTIONS に重み専用セクションを追加
SECTIONS
{
/* (既存の .isr_vector / .text / .rodata / .data / .bss 等は省略) */
.nn_weights :
{
. = ALIGN(4);
*(.nn_weights*) /* このパターンに合致する入力セクションを集める */
. = ALIGN(4);
} > QSPI /* QSPI 領域に配置 */
}
Step 3:重み配列に section 属性を付ける(生成コードを編集しない方法)
X-CUBE-AI 公式は 「生成された network_data.c は編集しない」を推奨します。代わりに、CubeMX の X-CUBE-AI 設定で "Split weights using linker script" オプションを有効化すると、重みが .nn_weights* 系のセクション名を持って生成されるので、Step 2 のリンカ側で配置を指定するだけで済みます。(出典: X-CUBE-AI documentation)
手動で配置を指定する必要がある場合(例:別のラッパーから重みを参照する場合)は、ソース側で __attribute__((section(...))) を付ける方法もあります。
__attribute__((section(".nn_weights")))
const ai_u8 ai_network_data_weights[] = { /* 重みバイナリ */ };
Step 4:起動コードで XSPI Memory-Mapped Mode を main 冒頭に有効化
これが最も重要かつ落とし穴の多いステップです。XSPI Memory-Mapped Mode は main() の冒頭で有効化する必要があります。これより前に重みアクセスする初期化コード(C++ コンストラクタ、__libc_init_array() 内の初期化等)が走るとハードフォルトします。
int main(void)
{
HAL_Init();
SystemClock_Config();
/* ★ ここで XSPI を Memory-Mapped Mode に。重みアクセスの前に必須 */
MX_OCTOSPI1_Init();
BSP_QSPI_Init();
BSP_QSPI_EnableMemoryMappedMode();
/* 必要なら MPU + Cache 設定(次セクション) */
MPU_Config();
SCB_EnableICache();
SCB_EnableDCache();
/* ここから先で QSPI 上の重みを参照できる */
MX_X_CUBE_AI_Init();
while (1) {
MX_X_CUBE_AI_Process();
}
}
MPU + D-Cache 最適化
QSPI Memory-Mapped Mode はそのままでは遅いですが、MPU で Cacheable 領域として設定 + D-Cache 有効化することで、初回読込み後はキャッシュヒットで内蔵 SRAM 並の速度を実現できます。(出典: AN4839「Level 1 cache on STM32F7 / STM32H7」/ AN4838「Managing the MPU」)
MPU 設定の鉄則(QSPI / OCTOSPI 領域)
- Cacheable + Bufferable + Not Shareable + XN=0 が定石
- Cortex-M7 では、何も設定しないと QSPI 領域は Strongly Ordered として扱われ、投機読み (speculative read) でバスエラーが起きる事例あり → 必ず MPU で明示設定
- Shareable に設定すると D-Cache が無効化される(F7/H7 系)。共有しない領域は Shareable = 0
- 重みは Read-Only なので Write-Through / Write-Back の選択は影響しない。Read-allocate のみ重要
MPU 設定コード例(QSPI 領域 8MB を Cacheable に)
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
HAL_MPU_Disable();
/* QSPI 領域: 0x90000000, 8MB, Cacheable Normal Memory */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO_URO; /* Read-Only */
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
その後 SCB_EnableICache() / SCB_EnableDCache() を呼ぶ順序を守れば、Cache 効果で QSPI 重み読み出しが初回後は数倍速くなります。
STM32U5 は DCACHE が 2 系統あり、DCACHE1 は外部 RAM(OCTOSPI / HSPI / FMC)専用、DCACHE2 は内部 RAM 用に分業しています。重みを外部メモリに置く設計では DCACHE1 の設定が重要です。(出典: AN5212「How to use STM32 cache to optimize performance」/ STM32U5 system cache training)
CubeMX / CubeIDE での実装ワークフロー
0 から実装を始める場合の標準ステップです。
- STM32CubeMX で対象 MCU を選択(H743 / H747 / U585 / N657 など)
- Software Packs → STMicroelectronics.X-CUBE-AI を Enable
- 左ペインの X-CUBE-AI セクションで "Add network" → モデルファイル(.h5 / .tflite / .onnx)を投入
- 設定:
- Compression(1x / 4x / 8x)
- Optimization(Time / Balanced / RAM)
- Use activation buffer for input/output(RAM 節約)
- Split weights using linker script(外部メモリ配置するなら必須)
- "Analyze" でメモリフットプリント・MAC 数を確認
- "Validate on Desktop / Target" で精度・推論時間を実測
- Project Manager → Code Generator → "Generate Code"
- main.c に自動追加された
MX_X_CUBE_AI_Init()(初期化)とMX_X_CUBE_AI_Process()(推論ループ)を確認 - (外部メモリ配置する場合)リンカスクリプト編集 + main 冒頭で BSP_QSPI_Init / MemoryMappedMode 呼出し追加
- ビルド → 書き込み → 動作確認
最新動向:STM32N6 + Neural-ART NPU
2024年12月にリリースされた STM32N6 は、ST 史上初の 内蔵 NPU 搭載マイコンです。X-CUBE-AI / ST Edge AI Suite の今後の主軸となる品種です。
主な仕様
- CPU:Arm Cortex-M55 @ 800 MHz(Helium SIMD 拡張搭載)
- NPU:ST 自社開発 Neural-ART Accelerator @ 1 GHz、最大 600 GOPS(電力効率は ST 公称で 3 TOPS/W 級。具体値は最新の製品資料を参照)
- 内蔵 RAM:4.2 MB の連続 embedded RAM(STM32 史上最大)
- 内蔵 Flash なし:外部 OCTOSPI / HSPI / FMC からブート前提
- NeoChrom GPU、H.264 エンコーダ、JPEG、MIPI CSI-2 + ISP も内蔵
(出典: ST blog stm32n6 / STM32N6 Series page)
X-CUBE-AI v10 連携時の特殊事情
NPU 利用時、X-CUBE-AI は [modelname]_atonbuf.AXISRAM5.raw という extra raw ファイルを生成します。これは NPU からアクセス可能なメモリに実行時にロードする必要があり、リンカスクリプトでの配置だけでなく起動時ローダコードの記述も必要です。(出典: ST Community td-p/813915)
2026 年現在、CubeMX が N6 を完全にサポートできていない事例も報告されており(生成時エラー、メモリ未活性化など)、量産案件で採用するなら ST のサポートエンジニアと密に連携することを強く推奨します。
公式リソース・参考文献
最重要 Application Note / User Manual
- UM2526 – Getting started with X-CUBE-AI Expansion Package for AI(日本語版あり)
st.com → UM2526 PDF - UM2611 – AI and Computer Vision function pack for STM32H7 (FP-AI-VISION1)
st.com → UM2611 PDF - AN5050 – Getting started with OCTOSPI, HEXADECASPI and XSPI interface on STM32 MCUs
st.com → AN5050 PDF - AN5188 – External memory code execution on STM32H750 / H7B0 / H730 / F7x0 value line
st.com → AN5188 PDF - AN4839 – Level 1 cache on STM32F7 / STM32H7 Series
st.com → AN4839 PDF - AN4838 – Managing memory protection unit in STM32 MCUs
st.com → AN4838 PDF - AN5212 – How to use STM32 cache to optimize performance and power
st.com → AN5212 PDF
Reference Manual / Datasheet
- RM0433 – STM32H743 Reference Manual
- AN4891 – STM32H72x/H73x/H74x/H75x system architecture and performance
- AN5872 – Introduction to the system architecture and performance in STM32H5 MCUs
ベンチマーク / モデル Zoo
- ST Wiki – STM32Cube.AI Model Performances(公式ベンチマーク表)
- GitHub – ST AI Model Zoo(140+ モデル)
- GitHub – ST AI Model Zoo Services
- MLPerf Tiny v1.2(2024年4月)/ v1.3 ベンチマーク
関連製品ページ
- X-CUBE-AI 製品ページ
- ST Edge AI Developer Cloud
- STM32N6 Series Page
まとめ
この記事のまとめ
- STM32Cube.AI (X-CUBE-AI) は Keras / TFLite / ONNX を STM32 用 C コードに変換する公式ツール。2026 年は STM32Cube AI Studio 移行期
- メモリ消費は Weights / Activations / I/O buffers の 3 区分で把握。"Use activation buffer for input/output" でまず RAM 節約
- 内蔵 Flash と外部 QSPI Flash の帯域差は約 1 桁。MPU + D-Cache 最適化で実用速度に
- 重み配置の主要 5 パターン:標準 / Ext_Qspi / Split_Qspi / Ext_Sdram / Split_Sdram。Split_Qspi が大モデル × レイテンシ要件の現実解
- リンカスクリプトに QSPI MEMORY 追加 →
.nn_weightsセクションを QSPI に配置 + main 冒頭で BSP_QSPI Memory-Mapped Mode 有効化 が定石 - MPU 設定は Cacheable + Bufferable + Not Shareable + XN=0。Cortex-M7 で Strongly Ordered のまま放置すると投機読みでクラッシュ
- STM32N6 + Neural-ART NPU は次世代の本命。CubeMX のサポート成熟度はまだ過渡期
STM32 を使った組込み AI 推論や TinyML 量産設計でお困りのことがあれば、弊社にお気軽にご相談ください。画像認識・AI 案件の実績をもとに、モデル選定から MCU 選定・メモリ配置最適化・量産品質まで一貫してサポートします。
STM32 + TinyML / エッジ AI 推論の PoC、モデル軽量化、量産品質の確保まで 組込み制御・マイコン開発 として対応しています。
STM32 + TinyML / エッジ AI の受託開発・PoC
STM32Cube.AI / X-CUBE-AI を活用した予知保全・異常検知・キーワード認識・画像認識など、組込みエッジ AI の試作 PoC からモデル軽量化・量産品質確認まで一貫して対応します。