Memo

Rust 嵌入式:STM32G474 通过 XIP 扩容 Flash

Rust 嵌入式:STM32G474 通过 XIP 扩容 Flash * [ ] 等待 PCB 打样和焊接 * [ ] 验证 > 目前开发项目,写着写着固件体积超了,不得研究 XIP 技术来将程序放到外部扩展的存储器中使用。可惜 G4 系列只有少数高端系列支持 XIP,目前没时间折腾,直接换了大容量的版本 G474 先开发项目,等有时间了再用 G474 验证 XIP。 背景知识 eXecute...

Rust 嵌入式:STM32G474 通过 XIP 扩容 Flash

  • 等待 PCB 打样和焊接
  • 验证

目前开发项目,写着写着固件体积超了,不得研究 XIP 技术来将程序放到外部扩展的存储器中使用。可惜 G4 系列只有少数高端系列支持 XIP,目前没时间折腾,直接换了大容量的版本 G474 先开发项目,等有时间了再用 G474 验证 XIP。

背景知识

eXecute In Place (XIP): 一种直接在非易失性存储器(如 NOR Flash)中运行代码的技术,无需加载到 RAM,常用于嵌入式系统优化启动时间和内存占用。

Quad SPI (QSPI): 四通道高速串行外设接口,支持同时传输4位数据,用于连接闪存等设备,显著提升嵌入式系统的存储访问速度和带宽。

NOR Flash: 一种非易失性存储器,支持随机快速读取和就地执行(XIP)特性,常用于嵌入式系统固件存储,写入速度较慢但可靠性高于NAND Flash。

probe-rs: 开源跨平台嵌入式调试工具链,支持ARM Cortex-M/RISC-V芯片的Flash烧录、内存调试和实时控制,兼容J-Link/ST-Link/DAPlink等多种调试器,提供Rust生态集成与CLI工具链。

预研

STM32G474 支持 Quad SPI 和 XIP

AN4760 中有详细介绍 STM32 系列 Quad SPI 接口相关内容,其中,STMG474 是支持 Quad SPI 和 XIP 的。

同时,在 RM0440 的:

  • 2.2.2 Memory map and register boundary addresses
  • 2.6.1 Boot configuration
  • 10 System configuration controller (SYSCFG)
  • 20.3.7 QUADSPI memory-mapped mode

在 2.2.2 小节中, 有提到 QSPI bank1 在地址的 0x9000 0000 ~ 0xA000 0000 的范围内。 image_1740240297524.png 在 10 章中有提到可以通过修改寄存器位来选择 memory 映射。

image_1740240304006.png

Rust 开发环境下搞定 XIP 的可行性

STM32G474 启用 XIP 的流程概要

要让 STM32G474 通过 QSPI 接口从 W25Q128JVPIQ 实现 XIP,首先需要将外部 Flash 连接到 MCU 的 QSPI 引脚并供电 3.3V。一个运行在内部 Flash 的 bootloader 会负责初始化 QSPI,将 W25Q128JVPIQ 映射到 0x90000000,然后跳转过去执行主程序。主程序需要编译并链接到这个地址,而整个过程依靠 MCU 上电后从内部 Flash 启动 bootloader,最终实现从外部 Flash 的直接执行。

使用 Rust 编写 Bootloader 实现 XIP

用 Rust 打造 bootloader 时,重点在于配置 QSPI 以适配 W25Q128JVPIQ。开发者需要启用 QSPI 时钟,设置 Flash 大小为 16MB,调整时钟分频和模式,使用快速四线读取指令并启用内存映射模式,确保地址和数据通过四线传输,配合适当的时序要求。完成后,bootloader 将控制权交给 0x90000000 的主程序。这个过程需要硬件连接正确并与 W25Q128JVPIQ 的规格一致,最终通过工具刷到内部 Flash 执行。

probe-rs 刷写固件与 Quad SPI 的关系

probe-rs 刷写固件时,通过 SWD 或 JTAG 调试接口直接将数据送到指定地址,比如 0x90000000 或内部 Flash 的 0x08000000。它借助调试探针与 MCU 的硬件调试单元通信,利用 ARM Cortex-M 的调试功能(例如通过 DAP,Debug Access Port),完全绕过 MCU 的正常运行状态。这意味着刷写时 MCU 不需要执行任何代码,数据直接被写入目标地址,宛如通过“魔法”般精准操作。

然而,刷写外部 Flash(如 W25Q128JVPIQ)时,probe-rs 本身并不能直接控制 QSPI 接口,因为它只与 MCU 的调试系统交互,无法自行发送 QSPI 命令。要实现外部 Flash 的烧录,通常需要一种间接方式:先将一个临时程序刷到 MCU 的内部 RAM 或 Flash,这个程序会在 MCU 上电运行时,通过 QSPI 发送写命令(如 W25Q128JVPIQ 的 Quad Page Program 指令)将固件写入外部 Flash。probe-rs 的“魔法”在于它能通过调试接口加载并触发这个临时程序,暂停 MCU 执行,操作内存,甚至控制寄存器,让 QSPI 在调试模式下完成数据传输。另一种方法是借助外部工具直接编程,但若坚持用 probe-rs,这种借道 MCU 的技巧是关键。刷写阶段不依赖 bootloader,因为它只在正常启动时初始化 QSPI,而调试过程完全由探针主导。

总结

启用 XIP 的流程中,bootloader 配置 QSPI 并跳转到 W25Q128JVPIQ 的地址。probe-rs 通过调试接口刷写固件到指定位置,写入外部 Flash 则需借道 MCU 执行临时程序,整个过程将刷写与运行清晰分开,确保 XIP 的实现。

image_1740240297524.png