嵌入式 GUI 应用常需外部 Flash 存储图片、字体等资源,而 STM32CubeProgrammer 官方 Flash Loader(stldr 文件)无法覆盖所有 Flash 型号。ST 的 X-CUBE-DISPLAY 3.0 扩展包提供了 SPI/QSPI 接口 Flash Loader 的源码工程,支持用户基于 API 快速定制。本文基于 ST 官方 LAT1303 应用笔记,以 NUCLEO-STM32G474+GFX01M2 开发板(MX25L6433F SPI Flash)为例,详解 STM32CubeIDE、KEIL、IAR 三大编译器的工程配置与 Loader 生成全流程,适用于各类外部 Flash 的移植开发。
1. 核心背景与开发前提
1.1 核心定位与作用
- Flash Loader:作为 STM32CubeProgrammer 插件,实现外部 Flash 的擦除、写入、校验,支持资源下载至 SPI/QSPI/FMC 等接口存储器;
- 适配场景:GUI 素材存储、大容量数据备份等需扩展外部 Flash 的嵌入式项目;
- 关键文件:
Dev_Inf.c(存储 Flash 参数)、Loader_Src.c(核心操作接口),二者为 Loader 开发核心。
1.2 工具与硬件清单
- 硬件:NUCLEO-STM32G474 开发板、GFX01M2 扩展板(含 MX25L6433F Flash)、SPI 连接线;
- 软件:STM32CubeMX 6.8、X-CUBE-DISPLAY 3.0 扩展包、STM32CubeIDE 2.12、KEIL 5.36、IAR 9.30;
- 核心 API:X-CUBE-DISPLAY 提供的 BSP 总线驱动(BSP_BUS_DRIVER)、Flash 初始化 / 读写 / 擦除接口。
2. 通用开发流程(跨编译器适用)
无论使用哪种编译器,Flash Loader 的基础移植步骤一致,需先完成核心文件配置:
步骤 1:STM32CubeMX 工程搭建
- 新建工程,选择 MCU(STM32G474RET6),配置系统时钟;
- 配置 SPI 外设:MX25L6433F 连接 SPI2,引脚为 PB13(SCK)、PB14(MISO)、PB15(MOSI)、PA8(CS);
- SPI 参数:波特率 40MHz、CPOL=Low、CPHA=1Edge、8 位数据、MSB 优先、软件 NSS;
- 加载 X-CUBE-DISPLAY 扩展包:在 “Project Manager” 中勾选,绑定 CS 引脚(PA8)与 SPI2 总线;
- 关键设置:勾选 “Do not generate main ()”(Loader 无需 main 函数),点击生成代码。
步骤 2:添加核心文件与初始化函数
- 复制核心文件:将
Dev_Inf.c、Dev_Inf.h、Loader_Src.c、Loader_Src.h放入工程 Core/Src 和 Core/Inc 目录; - 复制
.extSettings文件:自动创建 “Loader” 文件组,关联核心文件,无需手动添加; - 新增初始化函数:在
main.c中添加MX_Init(),实现外设复位与 GPIO/SPI 初始化:
void MX_Init(void)
{
HAL_DeInit(); // 复位所有外设
HAL_RCC_DeInit();
HAL_PWR_DeInit();
HAL_Init(); // 初始化Flash与Systick
SystemClock_Config(); // 系统时钟配置
MX_GPIO_Init(); // GPIO初始化(含SPI引脚)
MX_SPI2_Init(); // SPI2初始化
}
步骤 3:修改核心文件参数
(1)Dev_Inf.c:配置 Flash 属性
更新
StorageInfo结构体,填写 MX25L6433F 的关键参数(需与 Flash datasheet 一致):const StorageInfo StorageInfoTable[] = {
{
"MX25L6433F", // Flash型号
0x90000000, // 外部Flash映射地址
0x800000, // 总容量(64Mbit=8MB)
0x1000, // 扇区大小(4KB)
0x0, // 扇区数量(自动计算)
1, // 支持扇区擦除
1, // 支持批量擦除
1, // 支持写入
1 // 支持读取
}
};
(2)Loader_Src.c:实现核心接口
Loader 需至少实现 3 个必需函数(Init/Write/SectorErase),可选函数按需实现:
- 必需函数:
Init(void):初始化 SPI 引脚与时钟,返回 1 = 成功、0 = 失败;Write(uint32_t Address, uint32_t Size, uint8_t* buffer):向指定地址写入数据;SectorErase(uint32_t StartAddress, uint32_t EndAddress):擦除指定扇区范围;
- 可选函数:
Read()(读取数据)、MassErase()(批量擦除)、Verify()(数据校验)。
3. 分编译器工程配置与 Loader 生成
基础移植完成后,需针对不同编译器修改工程属性,最终生成 stldr 文件(STM32CubeProgrammer 识别格式)。
3.1 STM32CubeIDE 配置(推荐首选)
(1)工程属性修改
- 移除启动文件:右键
startup_stm32g474retx.s,选择 “Exclude from build”; - 修改链接脚本:右键工程→Properties→C/C++ Build→Settings→MCU GCC Linker→Script file,选择
STM32_FLASH.ld; - 关闭标准库:编译器选项勾选 “-nostdlib”“-nosyslib”,避免默认启动文件冲突;
- 添加后处理命令:在 “Build Steps→Post-build steps” 输入命令,生成 stldr 文件:
cmd.exe /c copy /Y "$(BUILD_ARTIFACT_PATH)" "..MX25L6433F_STM32G4.stldr"
(2)生成与使用
点击 “Build Project”,编译成功后在工程上级目录生成
MX25L6433F_STM32G4.stldr,复制到 STM32CubeProgrammer 的bin/ExternalLoader目录,即可被工具识别。3.2 KEIL 工程配置
(1)工程属性修改
- 移除启动文件:右键
startup_stm32g474retx.s→Options,取消 “Include in Target Build”“Always Build”; - 编译器选择:Target 标签页→Arm Compiler→“Use default compiler version 6”;
- 修改链接脚本:Linker 标签页→取消 “Use Memory Layout from Target Dialog”,选择
stm32_loader.sct,Misc controls 添加参数:--paged --pagesize 0x10 --diag_suppress L6305 - 添加后处理命令:User 标签页→After Build/Rebuild→Run#1 输入命令:
cmd.exe /C copy /Y "!L" "..MDK-ARMMX25L6433F_STM32G4.stldr"
(2)生成与使用
编译工程后,在
MDK-ARM目录生成 stldr 文件,复制到 ExternalLoader 目录即可。3.3 IAR 工程配置
(1)工程属性修改
- 移除启动文件:右键
startup_stm32g474retx.s→Options→“Exclude from build”; - 修改链接脚本:General Options→Linker→Linker configuration file,选择
stm32_flash.icf; - 设置入口函数:General Options→Entry→“Override default program entry”,填写
_iar_program_start; - 添加后处理命令:Build Actions→Post-build command line 输入:
cmd.exe /C copy /Y "$TARGET_PATH" "$PROJ_DIR$MX25L6433F_STM32G4.stldr"
(2)生成与使用
编译工程后,在工程根目录生成 stldr 文件,复制到 ExternalLoader 目录即可。
4. 关键注意事项
- 启动文件必须移除:Loader 无需标准启动文件,残留会导致入口函数冲突,编译失败;
- 链接脚本适配:不同编译器链接脚本格式不同(.ld/.sct/.icf),需使用对应模板,不可混用;
- Flash 参数准确性:
Dev_Inf.c的容量、扇区大小需与实际 Flash 一致,否则擦除 / 写入地址错误; - 接口函数完整性:Init、Write、SectorErase 为必需函数,缺失会导致 Loader 无法被 STM32CubeProgrammer 识别;
- 路径无特殊字符:stldr 文件存放路径需无中文、空格,否则工具无法加载。
5. 扩展适配:其他 Flash 型号移植
若需适配非 MX25L6433F 的 Flash,仅需两步修改:
- 更新
Dev_Inf.c:填写目标 Flash 的型号、映射地址、容量、扇区大小; - 重写
Loader_Src.c:根据目标 Flash 的 datasheet,修改 Init(SPI 参数)、Write(写入命令)、SectorErase(擦除命令)的底层逻辑。
基于 X-CUBE-DISPLAY API 的 Flash Loader 开发,核心是 “基础移植 + 编译器专属配置”:先通过 STM32CubeMX 搭建 SPI 工程、移植核心文件,再按编译器特性修改链接脚本、入口函数与后处理命令,即可快速生成 stldr 文件。三大编译器的核心差异集中在工程属性配置,核心接口与 Flash 参数配置完全通用,无需重复开发。该方案大幅降低外部 Flash Loader 的开发成本,适用于所有 SPI/QSPI 接口 Flash,可直接复用框架,仅需适配底层驱动即可。
阅读全文
128