Flash存储器深度解析:NAND vs NOR Flash,内部架构、读写机制与磨损均衡策略
说到嵌入式系统的非易失存储,Flash 是绕不开的主角。很多刚入行的朋友问我:「NAND 和 NOR 到底怎么选?」我的回答通常是:先搞清楚你的代码是在上面跑,还是你的数据要往里面塞。这两种 Flash 的差异,说白了就是架构基因不同导致的。
我最早接触 NOR Flash 是在做一款工业控制器的时候。当时需要在芯片上直接执行代码,NOR 的 XIP(片上执行)特性帮了大忙。后来做消费类产品,容量需求上来了,才真正开始跟 NAND 打交道。嗯,这两者的区别,咱们得从最底层的存储单元说起。
存储单元与基本架构差异
NOR Flash 的每个存储单元都并联在位线上,像个「或非门」阵列。这种结构让它能随机访问——你给个地址,它就能直接读出那个字节。NAND 呢?单元是串联的,像一串链条,读写必须按页进行。
| 对比维度 | NOR Flash | NAND Flash |
|---|---|---|
| 存储单元连接方式 | 并联(每位独立连接位线) | 串联(32/64 个单元串成一串) |
| 读取方式 | 随机访问,按字节/字读取 | 按页读取(通常 2KB~16KB) |
| 写入方式 | 按字节/字编程 | 按页编程 |
| 擦除方式 | 按扇区擦除(64KB~256KB) | 按块擦除(128KB~几MB) |
| 典型容量 | 1MB~512MB | 1GB~1TB |
| 读速度(随机) | ~100ns(接近SRAM) | ~25μs(页加载时间) |
你看这个表格,NOR 的随机读速度是纳秒级的,NAND 是微秒级的。差了两个数量级。但 NAND 的容量密度高,成本低,大容量场景下几乎没有对手。
关键认知:NOR 适合存代码(XIP),NAND 适合存数据(文件系统、音视频)。如果你需要在 Flash 上直接运行程序,选 NOR;如果只是存数据,选 NAND。
读写机制深度对比
咱们来拆解一下读写过程。NOR 的读操作很简单:给地址,数据就出来了。写操作呢?需要先擦除再编程。擦除是把所有位从 0 变成 1,编程是把需要的位从 1 变成 0。这个「先擦后写」的机制,是所有 Flash 的共性。
NAND 的读操作分两步:先发读命令和地址,等芯片把整页数据搬进内部缓存,再从缓存读出来。写操作也是先擦除块,然后按页编程。我遇到过一个问题:有次在 NAND 上做日志存储,没注意页编程的「写后读校验」机制,结果写进去的数据读出来是错的。后来才加上 ECC 校验。
实战技巧:NAND 的页编程时间通常 200~700μs,块擦除时间 1~4ms。设计时序时,别把这两个时间算得太紧。我习惯留 20% 的余量。
坏块管理与 ECC
NAND 出厂时就可能有坏块,这是它的「出厂缺陷」。NOR 基本没有这个问题。NAND 的坏块管理是必须做的,不做的话,数据随时可能丢。
我曾经在一个项目里用了某品牌的 NAND,出厂坏块率大概 2%。当时没做坏块跳过,结果量产到第 1000 台的时候,有 20 台在格式化阶段就挂了。从那以后,我所有的 NAND 驱动都强制包含坏块表(BBT)。
ECC 方面,SLC NAND 通常需要 1-bit ECC 每 512 字节,MLC 需要 4-bit 甚至 8-bit。现在主流的做法是用 BCH 或 LDPC 纠错码。我建议你直接用硬件 ECC 引擎,软件算太慢,而且容易出错。
注意:不要相信 NAND 芯片手册上写的「不需要 ECC」——那是针对特定测试条件。实际项目中,ECC 是标配。没有 ECC 的 NAND 系统,就像没系安全带的司机。
磨损均衡策略
Flash 的擦写次数是有限的。SLC 约 10 万次,MLC 约 3000~10000 次,TLC 只有 1000~3000 次。磨损均衡就是让所有块被擦写的次数尽量平均,避免某些块提前「退休」。
磨损均衡分两种:动态均衡和静态均衡。动态均衡只在写入时选择擦写次数少的块;静态均衡还会把长期不动的冷数据搬走,腾出「年轻」的块给热数据用。
| 均衡策略 | 原理 | 适用场景 | 额外开销 |
|---|---|---|---|
| 动态磨损均衡 | 写入时选擦写次数最少的空闲块 | 日志、缓存等频繁写入场景 | 低(仅需维护块擦写计数表) |
| 静态磨损均衡 | 定期将冷数据迁移到高擦写块 | 文件系统、数据库等混合读写场景 | 中(需要扫描和搬移数据) |
| 全局磨损均衡 | 所有块统一管理,冷热数据动态交换 | 高可靠性工业/车载存储 | 高(需要 GC 和映射表) |
我做过一个对比测试:同样的 NAND,不做磨损均衡,写入 500GB 数据后就有块失效;做了动态均衡,撑到 2TB 才开始出现坏块。静态均衡能再延长 30%~50% 的寿命。
我的建议:如果你的系统写入量不大(比如每天写几 MB),动态均衡就够了。如果写入频繁(比如视频监控、数据采集),必须上静态均衡。别省这点代码量,省下来的代价是数据丢失。
NAND vs NOR 架构对比图
下面这张图展示了两种 Flash 的内部架构差异。你可以看到 NOR 的位线是独立的,NAND 的单元是串起来的。这个结构差异决定了它们的读写方式完全不同。
实际项目中的选型建议
我总结了几条经验,供你参考:
- 代码直接在 Flash 上跑:选 NOR。它的随机读延迟低,CPU 可以直接取指执行。我做过一个 Bootloader,放在 NOR 上,上电 50ms 就能开始执行。
- 大容量数据存储:选 NAND。1GB 以上的场景,NOR 的价格会让你心疼。NAND 的每 MB 成本只有 NOR 的 1/10 左右。
- 混合场景:代码放 NOR,数据放 NAND。很多 SoC 都支持这种双 Flash 方案。我最近一个项目就是这么做的,效果很好。
- 极端环境:工业级 NOR 的温度范围更宽(-40°C~125°C),NAND 通常只有 -40°C~85°C。如果环境温度高,优先考虑 NOR。
避坑指南:我曾经在一个项目里把 NAND 当 NOR 用——直接映射到地址空间,结果读一个字节要等 25μs,CPU 直接卡死。后来才加上 Cache 和预取机制。记住:NAND 不能 XIP,必须用 DMA 或缓存。