4. STM32N6开发环境搭建
STM32N6 是 ST 首款集成自研 NPU(Neural-ART 加速器)的 MCU,主频 800 MHz 的 Cortex-M55 加 1 GHz 的 NPU,片上还有 4.2 MB 连续 SRAM 和 MIPI CSI-2 摄像头接口。这意味着它的开发环境不是"装一个 IDE 就能跑"那么简单:一条完整的工具链要同时覆盖 Cortex-M55 固件开发、NPU 模型编译、摄像头/显示外设调试和实时性能观测。本节把这条链拆开讲清楚,并给出可直接照做的搭建步骤。
一、工具链全景:四个角色,各管一段
先建立整体认知,避免把工具混用。STM32N6 的开发环境由四类工具构成,它们的分工是明确的:
- STM32CubeIDE:基于 Eclipse + GCC 的集成开发环境,负责工程创建、代码编辑、编译、下载和 GDB 调试。它是"写固件"的主战场。
- STM32CubeMX:图形化配置工具,负责时钟树、引脚复用、外设初始化(如 MIPI CSI、DCMI、LTDC、XSPI)和中间件(FreeRTOS、FatFS)的代码生成。它已集成在 CubeIDE 内,也可独立运行。
- STM32Cube.AI(X-CUBE-AI 扩展包):把训练好的神经网络模型(.tflite / .onnx / .h5)转换成 STM32N6 可执行的 C 代码,并调用 NPU 或 Cortex-M55 的算子库。它是"模型落地"的关键环节。
- 调试与观测工具:ST-LINK/V3 负责下载与 SWD 调试;STM32CubeMonitor 或 SWV/ITM 负责运行时变量与性能观测;STM32CubeProgrammer 负责外部 Flash(XSPI)烧录。
下面这张图给出四类工具在一条典型开发流中的位置与数据流向,注意 Cube.AI 的输出是"代码",而不是"模型文件"——这是初学者最容易误解的一点。
二、安装与版本匹配
STM32N6 属于较新的产品线,工具版本必须匹配,否则会出现"器件列表里找不到 STM32N6"或"NPU 算子不支持"的问题。建议按以下顺序安装:
- 安装 STM32CubeIDE 1.16 或更高版本(内置 CubeMX 与 GCC 13)。
- 在 CubeIDE 中通过 Help → Manage Embedded Software Packages 安装 STM32Cube MCU Package for STM32N6(如 STM32CubeN6 1.0.0 及以上),它包含 HAL、BSP、中间件和示例工程。
- 安装 X-CUBE-AI 扩展包(9.1.0 及以上),可在 CubeMX 的 Additional Software 中勾选,也可从 ST 官网下载后离线安装。
- 安装 STM32CubeProgrammer(用于 XSPI 外部 Flash 烧录)和 STM32CubeMonitor(用于运行时变量观测)。
- 安装 ST-LINK/V3 驱动,确认设备管理器中识别为 "STMicroelectronics STLINK-V3"。
三、从零创建一个可运行的 NPU 工程
下面以 STM32N6570-DK 开发板为例,走一遍最小可运行流程。目标:让一个简单的图像分类模型在 NPU 上跑起来,并通过串口打印推理耗时。
第 1 步:创建工程。在 CubeIDE 中 File → New → STM32 Project,选择 MCU 选择器,输入 STM32N657X0H3,命名工程为 n6_npu_demo,工具链选 STM32CubeIDE。生成后先编译一次,确认空工程能通过。
第 2 步:配置时钟与调试接口。在 CubeMX 视图中,将系统时钟配置为 800 MHz(Cortex-M55),使能 SWD 调试(SYS → Debug → Serial Wire),使能一个 UART(如 USART1,115200-8-N-1)用于打印。注意 STM32N6 的时钟树有独立的 CPU 与 NPU 域,NPU 时钟需在 RCC 中单独使能。
第 3 步:接入 Cube.AI。在 CubeMX 的 Middleware and Software Packs 中选择 X-CUBE-AI,模式选 Application。在 AI 面板中点击 Add network,导入一个已量化好的 .tflite 模型(例如 MobileNetV1 0.25 输入 96×96×3)。关键配置项:
- Runtime:选择 NPU(若模型算子全部被 NPU 支持)或 M55(回退到 CPU)。
- Quantization:确认模型为 int8 量化,NPU 只接受 int8 权重与激活。
- Memory pool:激活缓冲区大小由工具自动估算,通常几十到几百 KB,需确认不超过片上 SRAM 预算。
点击 Analyze,工具会给出每层算子的映射结果。若某层显示 "unsupported",说明该算子无法在 NPU 上执行,会被自动放到 M55 上,此时整体延迟会明显上升——这是判断模型是否"NPU 友好"的直接依据。
第 4 步:生成代码并调用推理。点击 Generate Code,Cube.AI 会在工程中生成 X-CUBE-AI/App/ 目录,包含 network.c、network_data.c 和 app_x-cube-ai.c。核心调用接口如下:
#include "app_x-cube-ai.h"
ai_handle network;
ai_buffer *ai_input;
ai_buffer *ai_output;
/* 初始化:创建网络实例并获取输入输出缓冲区 */
ai_error err = ai_network_create_and_init(&network, ai_input, ai_output);
if (err.type != AI_ERROR_NONE) {
printf("AI init failed: %d\r\n", err.code);
}
/* 填充输入:int8 量化数据,尺寸 96*96*3 */
memcpy(ai_input[0].data, input_buf, 96*96*3);
/* 执行推理 */
ai_network_run(network, ai_input, ai_output);
/* 读取输出:分类得分,取最大值即为预测类别 */
int8_t *out = (int8_t *)ai_output[0].data;
第 5 步:编译、下载、运行。编译后通过 ST-LINK 下载到内部 Flash 或 XSPI 外部 Flash。若代码段较大(模型权重通常几百 KB 到数 MB),需要配置 XSPI 启动模式,并用 STM32CubeProgrammer 将 .bin 烧录到外部 Flash 的 0x70000000 起始地址。运行后串口应打印类似:
AI init OK, input size=27648 bytes
Inference time: 3.2 ms (NPU)
Output class=7, score=112
四、调试与性能观测
NPU 推理是"黑盒"执行,传统单步调试无法进入 NPU 内部。因此观测手段要换思路:
- SWV/ITM 时间戳:在推理前后各写一次
ITM_SendChar()或翻转一个 GPIO,用示波器或 CubeMonitor 测量时间差,得到真实推理延迟。 - DWT 周期计数器:使能
DWT->CYCCNT,在推理前后读取计数值,除以 800 MHz 即得毫秒数。这是最轻量的方法,不占用串口。 - STM32CubeMonitor:通过 SWD 实时读取变量(如推理计数、分类结果),适合长时间运行观察。
- Cube.AI 验证模式:在 PC 端用
stm32ai validate命令对比 PC 推理与目标板推理的输出差异,确认量化没有引入过大误差。
一个实用的判断标准:对于 96×96 输入的轻量分类模型,NPU 推理应在 1~5 ms 量级;若超过 10 ms,优先怀疑算子回退或时钟未使能。把每次修改后的延迟记录成表,就能快速定位是模型问题还是配置问题。
五、常见坑与排查顺序
搭建过程中最容易卡住的几个点,按排查优先级排列:
- 器件找不到:CubeN6 包未装或版本低,重装对应版本。
- NPU 选项灰色:X-CUBE-AI 版本不支持 NPU,升级到 9.1.0+。
- 编译报错 "region RAM overflowed":模型权重或激活缓冲区超出片上 SRAM,需将权重放到 XSPI Flash,或减小模型。
- 下载后不运行:检查启动模式引脚(BOOT0/BOOT1)是否配置为 XSPI 启动,以及外部 Flash 是否已正确烧录。
- 推理结果全为同一类:输入数据未做与训练一致的归一化/量化,检查
ai_input的 scale 与 zero_point 是否与模型匹配。
把上述流程走通一次后,后续换模型、换输入尺寸都只是重复"导入—分析—生成—编译—测延迟"这个循环。真正需要花时间的是模型本身的 NPU 友好度优化,而这正是下一阶段要展开的内容。