存储基础:NOR Flash与NAND Flash的区别、接口类型、存储单元原理
在嵌入式系统设计中,特别是涉及XIP(Execute in Place,就地执行)的场合,NOR Flash与NAND Flash的选择往往决定了系统架构的走向。两者虽然同属非易失性存储家族,但在存储单元结构、读取方式、接口协议、寿命特性以及应用场景上存在本质差异。理解这些差异不仅是硬件选型的基础,更是理解XIP机制为何依赖NOR Flash、以及如何设计高效存储子系统的关键前提。本章将从存储单元原理出发,系统对比两种Flash的架构区别,并深入解析常见的接口类型及其在工程中的实际影响。
2.1 存储单元原理:从浮栅晶体管到阵列架构
无论是NOR还是NAND Flash,其基本存储单元都是浮栅晶体管(Floating Gate Transistor)或电荷俘获型晶体管(Charge Trap Transistor)。两者的核心差异在于浮栅中电荷的注入与擦除方式,以及存储单元在阵列中的连接拓扑。理解这一层,才能解释为什么NOR Flash的读取延迟远低于NAND,而NAND的存储密度却远高于NOR。
核心原理:浮栅电荷与阈值电压
浮栅晶体管在控制栅和沟道之间嵌入了一层由多晶硅制成的浮栅,被氧化层绝缘包裹。当电子注入浮栅后,晶体管的阈值电压(Vth)会升高;反之,浮栅不带电时阈值电压较低。读取操作通过向控制栅施加一个介于两个阈值之间的电压,检测沟道是否导通,从而判断存储的是"0"还是"1"。写入(编程)利用沟道热电子注入(CHE)或Fowler-Nordheim隧穿效应将电子注入浮栅;擦除则通过隧穿效应将电子拉出。对于SLC(单层单元),每个单元存储1 bit;MLC/TLC通过控制注入电荷量实现多级阈值,但读取裕量变小,寿命也随之下降。
阵列拓扑:并联与串联的本质区别
NOR Flash的存储单元采用并联结构:每个单元的漏极连接到位线(Bit Line),源极接地,控制栅连接到字线(Word Line)。这种结构使得每个单元都可以被独立寻址,读取时只需对目标字线施加电压,即可通过位线直接读出该单元的状态,因此支持字节级随机读取。然而,并联结构需要为每个单元预留接触孔,导致单元面积较大,存储密度受限。
NAND Flash则采用串联结构:多个单元(通常32-64个)串成一个串(String),串的两端分别通过选择晶体管连接到位线和源线。读取时,必须对同一串中的其他单元施加导通电压(Pass Voltage),仅对目标单元施加读取电压,通过检测整个串的导通状态来判断目标单元的数据。这种结构大幅减少了接触孔数量,单元面积可缩小至NOR的1/4以下,但代价是无法进行字节级随机访问,只能以页(Page)为单位读取(典型页大小2KB-16KB)。
| 对比维度 | NOR Flash | NAND Flash |
|---|---|---|
| 单元连接方式 | 并联(每个单元独立连接位线) | 串联(多个单元串接成串) |
| 读取粒度 | 字节/字随机读取 | 页(2KB-16KB)读取 |
| 典型读取延迟 | 80-120ns(首次访问) | 25-50μs(页加载)+ 串行输出 |
| 写入/擦除粒度 | 写入按字节/字,擦除按扇区(4KB-64KB) | 写入按页,擦除按块(64页-256页) |
| 存储密度 | 低(最大512Mb-1Gb) | 高(可达1Tb以上) |
| 单位成本 | 高(约NAND的5-10倍) | 低 |
小型场景化说明:为什么代码必须放在NOR上
假设MCU主频为200MHz,总线周期为5ns。若从NOR Flash直接读取一条32位指令,NOR的随机读取时间约100ns,加上总线协议开销,CPU需要插入约20个等待周期。虽然慢,但CPU可以接受。若改用NAND Flash,CPU发出读取指令后,NAND需要先将整个页(假设4KB)加载到内部SRAM,再通过IO口串行输出,整个过程至少25μs,相当于5000个等待周期。更关键的是,NAND无法只输出目标地址的4字节,必须整页输出,这导致CPU无法按线性地址随机取指。因此,XIP系统必须使用NOR Flash,或者使用支持XIP的SPI NOR(通过内存映射控制器实现)。
2.2 接口类型:从并行总线到串行协议
Flash的接口类型直接决定了其在系统中的连接方式、访问时序和XIP实现复杂度。工程实践中,NOR Flash主要有并行接口和SPI串行接口两大类,而NAND Flash则几乎全部采用并行接口(或基于并行接口的衍生协议如ONFI、Toggle)。
并行NOR接口:传统XIP的首选
并行NOR Flash提供完整的地址总线(A0-Ax)和数据总线(D0-D15),以及控制信号(CE#、OE#、WE#、RESET#等)。CPU可以直接将NOR映射到其地址空间,通过片选信号选中Flash,然后像访问SRAM一样进行读写。这种接口的优点是:零软件开销,CPU取指无需任何初始化配置;随机访问性能最优,每个地址的读取延迟固定。缺点是引脚占用多(典型32引脚-56引脚),PCB布局压力大,且随着容量增大,封装成本急剧上升。
SPI NOR接口:现代嵌入式的主流选择
SPI NOR Flash通过4线(CLK、CS#、DI、DO)或增强型(Quad SPI:IO0-IO3)接口通信。虽然串行协议增加了协议解析开销,但现代SPI NOR控制器(如Xilinx QSPI、STM32 QUADSPI)内置了内存映射模式(Memory-Mapped Mode),硬件自动将SPI传输转换为CPU可寻址的线性地址空间。在内存映射模式下,CPU发起读取时,控制器自动产生SPI读命令(如0x03、0x0B、0xEB),并将返回数据送入CPU总线。对于单线SPI,时钟频率通常为50-100MHz,有效带宽约6-12MB/s;Quad SPI可达到50-100MB/s,已能满足大多数MCU的XIP需求。
NAND接口:高密度存储的代价
NAND Flash采用8位或16位并行接口,但地址、命令和数据复用在同一组IO上。访问时需分阶段发送命令(如00h-Read)、地址(5字节:列地址+行地址)和数据。这种接口设计使得NAND无法直接映射到CPU地址空间,必须通过NAND控制器或软件模拟(GPIO翻转)进行访问。更复杂的是,NAND存在坏块(出厂即有,且随擦写增加),需要FTL(Flash Translation Layer)进行坏块管理和地址映射。因此,NAND在嵌入式系统中通常作为大容量数据存储(文件系统、日志),而非代码执行介质。
| 接口类型 | 引脚数 | 最大带宽 | XIP支持 | 典型应用 |
|---|---|---|---|---|
| 并行NOR(8/16位) | 28-56 | 100-200MB/s | 原生支持 | 军工、航天、高端通信 |
| SPI NOR(单线) | 6-8 | 6-12MB/s | 需内存映射控制器 | 消费电子、IoT |
| Quad SPI NOR | 8-10 | 50-100MB/s | 需QSPI控制器 | MCU XIP、FPGA配置 |
| NAND(8/16位) | 20-48 | 50-200MB/s(页突发) | 不支持 | 文件系统、大容量存储 |
实战场景:SPI NOR XIP的初始化时序
以STM32H743外接Quad SPI NOR(W25Q256JV)为例,实现XIP需要以下步骤:
- GPIO配置:将PE2(CLK)、PE4(CS#)、PE5(IO0)、PE6(IO1)、PE7(IO2)、PE8(IO3)复用为QUADSPI功能。
- QUADSPI初始化:设置时钟分频(通常为AHB时钟的1/2),配置Flash大小(256Mb = 32MB),选择内存映射模式。
- Flash参数配置:发送命令0x01(Write Status Register)使能Quad Enable位(W25Q256JV的Status Register-2 bit1)。
- 内存映射使能:设置QUADSPI_CR的EN位,并将地址映射到0x90000000。
- 代码重映射:将中断向量表重定位到0x90000000,并将启动代码(Reset_Handler)复制到RAM或直接从Flash执行。
// QUADSPI 内存映射模式配置示例(STM32H743 + W25Q256JV)
QUADSPI->CR = 0; // 禁用QUADSPI
QUADSPI->DCR = (31 << 16) | (0x1F << 8) | 0x1F; // FSIZE=31 (32MB), CSHT=1, CSHIGH=31
QUADSPI->CCR = (0x01 << 24) | (0xEB << 16) | (0x01 << 14) | (0x01 << 12) | (0x01 << 10) | (0x01 << 8) | 0x03;
// 0xEB: Quad I/O Fast Read, 4-4-4模式, 8个dummy周期
QUADSPI->CR = (1 << 2) | (1 << 0); // DMA_EN=1, EN=1
// 映射地址:0x90000000 - 0x91FFFFFF
配置完成后,CPU可直接从0x90000000地址取指。实测在200MHz主频下,Quad SPI读取带宽约80MB/s,CPU访问延迟约120ns(含协议开销),相比并行NOR的100ns略慢,但足以满足大多数实时应用。
2.3 判断方法与选型决策框架
在实际项目中,选择NOR还是NAND、选择并行还是SPI,需要综合评估代码大小、启动时间、数据更新频率、引脚预算和成本。以下是一个实用的决策流程:
判断流程:五步选型法
- 评估代码体积:若固件小于32MB,优先考虑NOR;若超过64MB,NAND几乎是唯一选择(或考虑外部SDRAM+SD NAND)。
- 确认XIP需求:若系统要求上电后CPU直接从Flash取指(如无外部RAM、或RAM容量不足),必须选NOR(并行或SPI)。
- 计算带宽需求:根据CPU主频和总线宽度,估算所需最小读取带宽。例如,200MHz 32位总线需要至少100MB/s带宽,此时Quad SPI NOR(80MB/s)可能不足,需选并行NOR或双Quad SPI。
- 检查引脚预算:若可用引脚少于15个,SPI NOR是唯一选择;若引脚充裕(>40),并行NOR可提供最佳性能。
- 考虑数据更新策略:若固件需要频繁OTA升级,NOR的扇区擦除(4KB)比NAND的块擦除(128KB)更灵活,且无需坏块管理,升级软件更简单。
案例拆解:工业控制器的存储系统设计
背景与约束:某工业PLC控制器需要存储1MB固件代码和4MB运行日志。CPU为Cortex-A7(800MHz),外部总线支持16位并行NOR和Quad SPI。系统要求上电后500ms内完成启动,且支持现场固件升级。引脚预算:存储接口最多分配20个引脚。
初始方案:工程师最初选择16位并行NOR(S29GL512P,64MB),引脚占用48个,远超预算。且并行NOR封装大,PCB面积紧张。
分析过程:重新评估需求——固件仅1MB,但日志需要4MB且频繁擦写。并行NOR的扇区擦除(64KB)对于日志记录过于粗粒度,且擦写寿命(10万次)在频繁日志场景下可能不足。而Quad SPI NOR(W25Q128JV,16MB)引脚仅6个,支持4KB扇区擦除,且内存映射模式可满足XIP需求。日志可存储在同一芯片的高地址区域,利用4KB扇区进行循环写入。
实际操作:采用W25Q128JV(Quad SPI),映射到0x90000000。固件存储在低1MB区域,日志存储在高4MB区域。启动时,BootROM将中断向量表重定位到0x90000000,CPU直接从Flash执行。日志写入通过QUADSPI页编程(256字节)和扇区擦除(4KB)完成。
结果对比:启动时间实测420ms(满足500ms要求),引脚占用仅6个(CLK、CS#、IO0-IO3),PCB面积减少60%。日志擦写寿命:4MB区域按4KB扇区循环,每个扇区擦写10万次,总擦写次数可达10万×1024=1亿次,远超设备10年使用寿命需求。
风险与代价:Quad SPI的XIP性能在Cache Miss时延迟约150ns,比并行NOR慢50%。但通过将中断服务程序固定在连续地址区域(同一页内),实测中断响应时间仅增加3%。代价是固件链接脚本需要手动指定代码段布局,增加了构建复杂度。
复盘经验:存储选型不能只看峰值带宽,要综合引脚、封装、擦写粒度、寿命和软件复杂度。在本案例中,Quad SPI NOR以略低的性能换取了巨大的面积和成本优势,且4KB扇区擦除为日志管理提供了极大便利。
2.4 常见误区与总结复盘
在Flash选型与XIP设计中,以下误区反复出现,值得特别注意:
误区一:忽略NAND的坏块管理
NAND Flash出厂即包含坏块(通常<2%),且随着擦写次数增加,坏块会持续产生。若直接将NAND用于代码存储,一个坏块可能导致系统崩溃。即使使用SLC NAND,也必须实现完整的坏块管理、ECC校验和磨损均衡。这些软件开销(通常需要占用2-4KB RAM和1-2ms启动时间)在资源受限的MCU上难以承受。
误区二:SPI NOR的XIP性能评估不足
SPI NOR的标称带宽(如133MHz Quad = 66MB/s)是理论峰值,实际XIP性能受限于:命令开销(每个读命令需发送8位命令+24位地址+8位dummy)、页边界切换延迟(通常3-5个时钟周期)、以及Cache Miss时的总线等待。设计时应使用while(1)循环测试实际读取带宽,而非依赖数据手册。
误区三:忽视数据保持与温度特性
NOR Flash的数据保持时间在85℃环境下通常为20年,但在125℃环境下可能降至2年。对于汽车电子或工业高温应用,应选择支持高温等级的型号(如AEC-Q100 Grade 1),并考虑采用ECC或双Bank冗余。NAND的数据保持更差,MLC NAND在高温下数据保持可能不足1年,必须定期刷新(Read Disturb管理)。
总结:存储选型决策清单
| 决策项 | NOR Flash | NAND Flash |
|---|---|---|
| 代码直接执行(XIP) | ✅ 支持(并行/SPI内存映射) | ❌ 不支持(需加载到RAM) |
| 随机读取性能 | ✅ 优秀(80-120ns) | ❌ 差(页延迟25μs+) |
| 存储密度/成本 | ❌ 低密度高成本 | ✅ 高密度低成本 |
| 擦写寿命(SLC) | ✅ 10万-100万次 | ✅ 10万次(但需坏块管理) |
| 软件复杂度 | ✅ 低(无需FTL) | ❌ 高(FTL+ECC+磨损均衡) |
| 引脚占用 | SPI: 6-8个;并行: 28-56个 | 20-48个 |