3. STM32CubeMX集成TFLite
任务目标
在STM32CubeMX中完成一个面向TFLite部署的基础工程配置:使能所需外设(UART、GPIO、时钟),生成CMake或Makefile工程,并将TFLite运行时头文件与静态库正确接入构建系统,最终得到一个可编译通过的裸机工程骨架。
环境与依赖
- STM32CubeMX 6.x(含STM32CubeFW包,如F4/F7/L4系列)
- 交叉编译器:arm-none-eabi-gcc(或Keil/IAR,本案例以CMake+GCC为例)
- TFLite Micro运行时源码(从tflite-micro获取,版本建议与CubeMX生成的CMSIS版本兼容)
- 本案例以STM32F407VET6 + 外部HSE 8MHz为例,其他型号操作相同
CubeMX工程配置步骤
- 新建工程:选择MCU型号,配置时钟树(HSE→PLL→168MHz主频)。
- 使能外设:UART1(用于日志输出,115200-8-N-1)、PA5(LED,用于状态指示)、SWD调试口。
- 生成方式:Project Manager → Project → Toolchain选择
CMake,生成初始工程。 - 调整链接脚本:TFLite运行时需要较大RAM/Flash,确认
_Min_Heap_Size与_Min_Stack_Size至少为0x800(2KB),建议在CubeMX中直接修改链接脚本或生成后手动调整。
集成TFLite运行时
将tflite-micro源码中的tensorflow目录整体复制到工程根目录下third_party/tflite中。需要保留的头文件路径为:
third_party/tflite/tensorflow/lite/micro
third_party/tflite/tensorflow/lite/micro/compiler
third_party/tflite/tensorflow/lite/c
third_party/tflite/tensorflow/lite/core/api
third_party/tflite/tensorflow/lite/schema
third_party/tflite/third_party/flatbuffers/include
third_party/tflite/third_party/gemmlowp
third_party/tflite/third_party/ruy
在CubeMX生成的CMakeLists.txt中追加以下内容(位置在add_executable之前):
# TFLite Micro 运行时源文件(按需裁剪,此处为最小推理所需)
set(TFLITE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/tflite)
set(TFLITE_SRCS
${TFLITE_DIR}/tensorflow/lite/micro/all_ops_resolver.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_interpreter.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_mutable_op_resolver.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_profiler.cc
${TFLITE_DIR}/tensorflow/lite/micro/recording_micro_allocator.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_allocator.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_error_reporter.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_time.cc
${TFLITE_DIR}/tensorflow/lite/micro/micro_utils.cc
${TFLITE_DIR}/tensorflow/lite/micro/system_setup.cc
${TFLITE_DIR}/tensorflow/lite/micro/debug_log.cc
${TFLITE_DIR}/tensorflow/lite/micro/memory_helpers.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/conv.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/fully_connected.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/softmax.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/reshape.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/pad.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/add.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/mul.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/quantize.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/dequantize.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/logistic.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/activations.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/circular_buffer.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/ethosu.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/transpose_conv.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/unidirectional_sequence_lstm.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/svdf.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/cmsis_nn/conv.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/cmsis_nn/fully_connected.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/cmsis_nn/pooling.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/cmsis_nn/softmax.cc
${TFLITE_DIR}/tensorflow/lite/micro/kernels/cmsis_nn/svdf.cc
)
# 头文件搜索路径
target_include_directories(${PROJECT_NAME} PRIVATE
${TFLITE_DIR}
${TFLITE_DIR}/tensorflow/lite/micro
${TFLITE_DIR}/tensorflow/lite/micro/compiler
${TFLITE_DIR}/tensorflow/lite/c
${TFLITE_DIR}/tensorflow/lite/core/api
${TFLITE_DIR}/tensorflow/lite/schema
${TFLITE_DIR}/third_party/flatbuffers/include
${TFLITE_DIR}/third_party/gemmlowp
${TFLITE_DIR}/third_party/ruy
)
# 将TFLite源文件加入编译
target_sources(${PROJECT_NAME} PRIVATE ${TFLITE_SRCS})
# 若使用CMSIS-NN优化内核,需额外链接CMSIS库(CubeMX已生成)
# target_link_libraries(${PROJECT_NAME} PRIVATE cmsis_nn)
若实际模型只用少量算子,可大幅裁剪上述源文件列表,仅保留对应算子内核,以减小Flash占用。
最小验证代码
在main.c的main()函数中,MX_Init()之后加入以下代码,验证TFLite头文件可正常包含、链接无误:
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "tensorflow/lite/micro/system_setup.h"
#include "tensorflow/lite/schema/schema_generated.h"
// 在main()中,外设初始化之后:
tflite::InitializeTarget();
printf("TFLite runtime headers OK\r\n");
// 验证MicroInterpreter类型可用(不实例化,仅编译期验证)
tflite::MicroInterpreter* interpreter_ptr = nullptr;
(void)interpreter_ptr;
printf("MicroInterpreter type OK\r\n");
while (1) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(500);
}
编译与运行
- 在CubeMX生成目录下执行:
cmake -B build -DCMAKE_TOOLCHAIN_FILE=arm-none-eabi-gcc.cmake
cmake --build build
- 将生成的
.elf或.bin通过ST-Link烧录至开发板。 - 打开串口助手(115200),复位开发板。
验证判定标准
- 编译无错误、无未定义引用,链接通过。
- 串口输出两行日志:
TFLite runtime headers OK与MicroInterpreter type OK。 - LED以500ms间隔闪烁,表明系统未因TFLite集成而进入HardFault。
满足以上三点即判定CubeMX集成TFLite运行时成功。后续案例将在此工程骨架上添加具体模型与推理逻辑。