SPI NOR Flash:固件为什么上电就能跑
更新时间:2026-09-12。本文是「集成电路大类 · 芯片设计」**入门层(beginner)**数字逻辑基础第一百零一篇。几乎每块带 MCU/FPGA/SoC 的板子上都有一颗 8 脚串行芯片,断电后程序就躺在里面,上电第一时间被读走——它就是 SPI/QSPI NOR Flash。理解它,就把 SPI 时序、非易失存储和「芯片怎么启动」串了起来(FPGA 侧用同类 Flash 存比特流)。
本文要回答的问题
- NOR 和 NAND Flash、EEPROM、SRAM 的使用方式差在哪?为什么 NOR 能直接取指(XIP)?
- 标准读、快速读、QSPI 读的时序分别长什么样?
- 为什么写之前要「写使能」、为什么要先擦除才能写?
- 扇区、页、WIP 状态位是什么,烧录一个固件要走哪几步?
- CPU 怎么把 QSPI Flash 当成内存一样直接跑代码?
一、NOR Flash 的定位:可随机读的非易失存储
Flash 靠浮栅/电荷阱存 0/1,断电不丢。两大类用法很不同:
- NOR Flash:按字节/字随机寻址读,读出延迟低、可直接挂在内存总线上取指,这叫 XIP(eXecute-In-Place,就地执行);容量偏小(Mb~Gb)、擦写慢、成本高,用来存启动代码和固件;
- NAND Flash:按页读/写、按块擦,不能随意字节寻址,密度高、便宜,用来存大数据(见 NAND/eMMC);
- EEPROM 可字节擦写但容量小,存配置参数。
上电后 CPU 的取指总线(经一个 SPI/QSPI 控制器)直接从 NOR 读指令,不需要先把程序搬到 RAM——这正是「上电就能执行」的原因。
二、标准 SPI 读:命令 + 地址 + 数据
标准单线 SPI(模式 0/3)一次读:
- 拉低片选 /CS;
- 主机发命令 0x03(Read Data);
- 发 3 字节地址(24 位,A23..A0);
- 之后主机给时钟,Flash 从该地址连续输出数据,地址自动递增,直到 /CS 拉高。
/CS ‾‾\_________________________________________/‾‾
MOSI |03| A23..A16|A15..A8|A7..A0| ——————— (主机发 dummy) ——
MISO ——命令/地址阶段——| D0 | D1 | D2 | ...(Flash 连续输出,地址自增)高频时用 0x0B Fast Read:地址后加若干 dummy(等待)周期再出数据,换取更高时钟;QSPI 用 0x6B(四线快速读)/0xEB,命令地址后 4 根数据线一起吐数据,带宽近似 ×4。
三、写入:先使能、先擦除、按页编程
Flash 的物理特性是「只能把位从 1 写成 0,不能直接 0→1」,所以改数据必须先擦除(把整块恢复成全 1)。完整写流程:
- WREN(0x06,写使能):每次写/擦前先发,置状态寄存器 WEL 位(操作完自动清,防止误写);
- 擦除:按 **4KB 扇区(0x20)/32KB 块(0x52)/64KB 块(0xD8)/整片(0xC7)**为单位,发送命令+地址;
- 轮询 RDSR(0x05)读状态寄存器,等 **WIP(bit0,Write-In-Progress)**变 0(擦除要几十~几百 ms);
- 页编程 PP(0x02):发命令+地址+数据,一次最多写满一页(通常 256B,跨页会回卷覆盖页首);写完同样轮询 WIP;
- 重复到所需数据写完。掉电保护有状态/标志位(如 WEL、块锁 BP、状态寄存器 SRP)防止意外改写启动区。
四、内存映射读与 XIP
实际取指不会用软件逐字节发 0x03——QSPI 控制器提供内存映射(memory-mapped)模式:硬件把对某段地址的读总线事务自动翻译成 QSPI 读命令和连续地址突发,CPU 看到的就是一段只读内存,直接在上面取指执行(XIP),数据线多用 dummy 周期和连续读摊薄命令开销。写/烧录仍走命令模式由加载器或驱动完成。32 位地址的大容量 NOR 需进入 **4 字节地址模式(0xB7)**或用 Bank 寄存器。
| 命令 | 含义 |
|---|---|
| 0x03 / 0x0B | 普通读 / 快速读(带 dummy) |
| 0x6B / 0xEB | QSPI 四线快速读 |
| 0x06 / 0x05 | 写使能 WREN / 读状态 RDSR(WIP、WEL) |
| 0x20 / 0xD8 | 4KB 扇区擦除 / 64KB 块擦除 |
| 0x02 | 页编程(≤256B/页) |
| 0xB7 | 进入 4 字节地址模式 |
与现有篇目的衔接
总结
一句话总结:SPI/QSPI NOR Flash 是板上存放固件和启动代码的可电擦写非易失存储器,它按字节随机寻址读、读出延迟低,因而能被挂到取指总线上做 XIP 就地执行——这是上电后不先搬运程序就能直接跑代码的原因,区别于按页访问、密度高成本低的 NAND 和按字节改写的 EEPROM;标准 SPI 读时序是拉低片选后发 0x03 命令、3 字节地址,然后 Flash 随时钟连续输出数据且地址自动递增,高频用带 dummy 周期的 0x0B 快速读,QSPI 用 0x6B/0xEB 在四根数据线上把带宽提高数倍;写入受「只能把 1 写成 0」的物理限制,必须先发 0x06 写使能置位 WEL、再按 4KB 扇区或更大块擦除恢复全 1,轮询 0x05 状态寄存器的 WIP 位确认擦除完成后,才能用 0x02 页编程一次写至多 256 字节(跨页会回卷)并再次等待 WIP;大容量器件用 0xB7 进入 4 字节地址模式;真正运行时控制器用内存映射模式把 CPU 的读事务自动翻译成 QSPI 突发、伪装成一段只读内存实现透明取指,而烧录仍走命令模式,FPGA 也用同类 NOR/NAND 存放上电配置比特流。