STM32F7 QSPI内存映射模式写入问题及分区可行性咨询
先直接给你明确结论:内存映射模式下,QUADSPI硬件层面只支持读操作,没法直接写外部Flash,这和AN4760里的描述完全一致。不过针对你「分区用QSPI,一部分跑代码一部分存数据,不想来回跳转内部Flash」的需求,有几个实用的优化方案:
一、QSPI分区的可行性:完全没问题
你完全可以把外部QSPI Flash拆成两个独立区域:
- 区域A:内存映射模式,用来放可执行代码(映射到
0x90000000起始的地址段) - 区域B:命令模式专用,用来存配置数据(支持读写擦除)
但要注意:QUADSPI同一时间只能工作在一种模式下——要么内存映射(只读跑代码),要么命令模式(可读写数据)。所以访问数据区时,需要临时切换模式,不过这个流程可以优化到不用跳转内部Flash。
二、优化模式切换:全程在外部Flash执行,不用跳内部
你担心跳转内部Flash的问题,其实完全可以把切换逻辑放在外部Flash的代码里完成,步骤大概是这样:
- 当需要写数据时,先把当前寄存器状态、程序上下文存到片内RAM里(毕竟RAM是独立于Flash的,不会受QSPI模式影响)
- 调用HAL库的
HAL_QSPI_MemoryMappedExit(&hqspi)退出内存映射模式 - 切换到命令模式,执行数据区的擦除、写入操作(注意要精准避开代码区的地址,别误擦了程序)
- 写完之后,再调用
HAL_QSPI_MemoryMapped(&hqspi)切回内存映射模式 - 从RAM恢复之前保存的上下文,继续在外部Flash里跑代码
这个过程全程都在外部Flash的代码里执行,不需要跳回内部Flash,只是短暂切换QSPI的工作模式,性能开销极低,几乎不会影响程序运行。
三、进阶玩法:用双Bank的QSPI Flash
如果你的QSPI Flash支持**双Bank(Dual Bank)**功能(比如Winbond的W25Q系列部分型号、MXIC的MX25L系列),那可以更省心:
- 把Bank 0设为内存映射模式,专门跑代码
- 把Bank 1设为命令模式,专门存数据
部分STM32F7的QUADSPI外设支持双Bank独立访问,这时候甚至不用切换模式,就能一边从Bank 0读代码运行,一边往Bank 1写数据。不过这个得先确认你的Flash型号和STM32F7的QUADSPI是否支持这个特性,查一下Flash的数据手册和STM32F7的参考手册就行。
四、其他替代思路
如果上面的方案都不符合你的要求,还有两个备选方向:
- 用片内RAM当缓存:把要保存的配置先存在RAM里,等系统空闲或者关机前,再一次性切换模式写入QSPI Flash,减少模式切换的次数
- 额外加个小SPI Flash:专门用来存数据,和跑代码的QSPI Flash分开,这样两个Flash互不干扰,不用切换模式
补充一句:AN4760里明确说了,内存映射模式下QUADSPI的FIFO只开放读通路,写通路是被硬件禁用的,所以确实没法在这个模式下直接写,必须切命令模式。
内容的提问来源于stack exchange,提问作者Fredrick Gauss

