1、课程导论:为什么需要硬件在环测试?STM32CubeAI整体工作流概览

1.1 一个让我翻过车的真实案例

先讲个我自己的故事吧。

几年前,我接了一个电机控制的项目。算法在PC上跑得漂漂亮亮,MATLAB仿真曲线那叫一个丝滑。我信心满满地把模型转成C代码,烧进STM32F4里。

结果呢?电机一启动,直接抖成了筛子。

我当时就懵了。仿真明明没问题啊!后来排查了整整三天,才发现是ADC采样时序和算法计算周期没对齐。PC仿真里根本不会考虑这种硬件细节,但到了真芯片上,一个时钟周期的偏差就能让整个系统崩溃。

从那以后,我养成了一个习惯:模型验证必须上硬件,仿真跑得再好也只是“看起来很美”

1.2 为什么需要硬件在环测试?

说白了,硬件在环测试(HIL)就是把你的AI模型放到真实的STM32芯片上跑一遍。不是仿真,不是模拟,是真刀真枪地烧录、运行、看结果。

你可能会问:“我在PC上仿真得好好的,为什么非要折腾硬件?”

嗯,这里有几个你绕不开的理由:

  • 仿真环境太“干净”了:PC上的浮点运算精度是双精度的,但STM32F4系列只有单精度硬件FPU。我见过有人用double算出来的模型参数,转到float后直接精度丢失,推理结果完全不对。
  • 时序问题只有硬件能暴露:你的模型推理需要多少毫秒?中断会不会打断推理过程?DMA传输和CPU计算能不能并行?这些问题,仿真一个都回答不了。
  • 资源限制是硬伤:PC上有无限的内存和Flash,但STM32可能只有256KB Flash和64KB RAM。模型量化后能不能塞进去?运行时会不会栈溢出?只有烧进去才知道。

核心观点:硬件在环测试不是可选项,而是嵌入式AI落地的必经之路。跳过这一步,你就是在赌运气。

1.3 STM32CubeAI整体工作流概览

好,既然知道了HIL的重要性,那STM32CubeAI这套工具链到底怎么用?我把它拆成四个阶段,你跟着走一遍就明白了。

第一阶段:模型准备与训练

这一步其实和普通AI开发差不多。你用Keras、PyTorch或者TensorFlow训练好模型。但要注意,不是所有模型都能直接往STM32上搬

我个人习惯在训练时就考虑部署问题:

  • 尽量用轻量级网络,比如MobileNetV2、TinyML常用的一些结构
  • 激活函数避免用太复杂的,ReLU就挺好
  • 输入尺寸别太大,224x224对于STM32来说已经有点吃力了

第二阶段:模型转换与量化

这一步是STM32CubeAI的核心。你把训练好的模型(比如.h5文件)丢进CubeAI工具里,它会帮你做两件事:

  1. 模型转换:把Keras/PyTorch模型转成STM32能识别的中间格式
  2. 量化:把float32的权重转成int8。我刚开始做量化时总觉得会损失精度,后来发现对于大多数分类任务,int8量化后准确率下降不到1%。

我的经验:量化后的模型大小能缩小4倍,推理速度提升2-3倍。但要注意,如果你的模型对精度极其敏感(比如回归任务),建议先做混合量化试试。

第三阶段:代码生成与集成

CubeAI会生成一堆C代码,包括模型推理函数、内存分配、输入输出接口。你只需要把这些代码集成到你的STM32工程里。

这里有个坑,我曾经踩过:生成的代码默认使用静态内存分配。如果你的模型比较大,记得检查一下链接脚本里的堆栈设置,不然很容易硬故障。

/* CubeAI生成的典型代码结构 */
#include "ai_platform.h"
#include "network.h"

// 模型实例
ai_handle network = AI_HANDLE_NULL;
ai_network_report report;

// 初始化模型
void model_init(void) {
    ai_error err;
    err = ai_network_create(&network, AI_NETWORK_CONFIG);
    if (err.type != AI_ERROR_NONE) {
        // 处理错误,我一般在这里加个断言
        Error_Handler();
    }
}

// 推理函数
float model_predict(float* input_data) {
    ai_i32 batch_size = 1;
    ai_buffer input = ai_network_inputs_get(network, NULL);
    ai_buffer output = ai_network_outputs_get(network, NULL);
    
    // 填充输入数据
    input.data = AI_BUFFER_DATA_PTR(input, input_data);
    
    // 执行推理
    ai_network_run(network, &input, &output);
    
    // 获取输出
    float* result = (float*)output.data;
    return result[0];
}

第四阶段:硬件在环验证

代码集成完了,烧进去,然后呢?

你需要验证两件事:

  • 功能正确性:模型在硬件上的输出和PC仿真是否一致?我一般会准备一组测试数据,在PC上跑一遍,在STM32上再跑一遍,对比结果。
  • 性能指标:推理时间、内存占用、功耗。这些数据只有硬件能给你。

注意:不要只测一组数据。我建议至少准备100组测试样本,覆盖各种边界情况。我曾经只测了10组数据,结果都通过了,但上线后遇到一个极端输入,模型直接输出NaN。

1.4 一个典型的验证流程

给你看看我常用的验证流程,你可以直接拿来用:

步骤 操作 验证指标
1 PC端仿真,记录输出 准确率、推理结果
2 CubeAI转换+量化 模型大小、量化误差
3 生成代码,集成到工程 编译无警告、无错误
4 烧录到STM32,运行 推理结果与PC一致
5 测量推理时间 是否满足实时性要求
6 压力测试(连续运行) 无内存泄漏、无硬故障

1.5 写在前面的话

这门课一共30章,我会带你从零开始,一步步把AI模型部署到STM32上,并且完成完整的硬件在环测试。

你可能会遇到各种问题:模型转换失败、推理结果不对、内存不够用……别慌,这些都是正常的。我当年也是一路踩坑过来的。

记住一句话:仿真给的是可能性,硬件给的是确定性。只有让模型在真实的芯片上跑起来,你才能真正说“这个方案可行”。

下一章,我们开始搭建开发环境。准备好你的STM32开发板,咱们动手干起来。