有天午休同事捏着一颗黑色LGA-8封装的小芯片凑过来问“BOM表里写着SD NAND里面装的既然是Flash为什么偏偏是NAND不是NOR我以前学的都是NOR随机读快、字节寻址简单NAND又要管坏块、又要做ECC怎么到了这个芯片上反而全用NAND了” 这个问题问得很有水平。它没法用一句“因为NAND容量大”草草糊弄过去。SD NAND这套方案链路上是“SD控制器 存储介质”的组合控制器负责把主机的SD协议翻译成对存储晶圆的读写请求存储介质则决定了这套翻译层的复杂程度。如果介质换成NORSD协议社区沉淀多年的“管理NAND的经验”几乎全废而介质用NANDSD协议几乎不用改就能跑得顺顺当当。这篇文章就围绕这个核心把原理拆开讲讲两者的工艺差异、协议匹配度、成本账和应用分工。刚入行的朋友花十分钟看完再有人问起这件事就能不慌不忙地把逻辑讲明白。1. 先认清两兄弟NAND和NOR的组织方式完全不同1.1 存储单元的“接线方式”决定了命运NAND和NOR在电路底层都算浮栅晶体管家族但阵列结构完全不一样。NOR里每个存储单元的源极、漏极、字线、位线基本都是各自引出的像一个真正的“仓库格子”任何一格只要给出对应的行地址和列地址就能单独把里面存的数读出来。这种近似SRAM/ROM的寻址模型让NOR天生支持随机字节读取控制逻辑非常简单MCU甚至可以把NOR直接映射到地址空间里当成一颗慢速内存来取指令。代价是每个单元都要预留独立的接触孔和连接线单元面积被接线大量占用。工艺微缩到一定程度后连线占的面积比重越来越大密度很难继续往上走。NAND则换了思路把一串存储单元像手拉手一样串联起来共用少数的位线接触点。读取某个页的时候先把整页数据搬进片上缓存page register再通过I/O引脚按顺序搬出去。因为横向只占一个接触孔、纵向压缩到一个器件间距阵列集成密度能比NOR高出几个量级——同样一片晶圆NAND能产出的容量是NOR没法比的。这就像仓库改成传送带单件取货确实不如仓格方便但整批整批过传送带的效率完全不同。理解这个组织方式差异是理解后面所有问题的起点。1.2 读写粒度页 vs 字节这是所有答案的起点NAND的操作粒度是页page常见一页4KB到16KB一次编程必须对一个页整体写入擦除则按块block进行一个块通常包含几十页甚至上百页整体擦除要耗时毫秒到几十毫秒。NOR的操作粒度则灵活得多读可以按字节、按字编程把1写为0也能按字节/字进行只有擦除才需要按扇区或块来操作常见扇区4KB到64KB。这个“粒度差”不是小差异而是两种Flash服务不同上层应用的根本原因。读速度的区别必须分开说。NOR的随机读延迟极低通常在几十纳秒到微秒级别对“随时从任意地址取代码”非常友好NAND读一个页时要发命令、发地址等存储阵列把整页数据加载到缓存这个过程通常要20~80微秒之后的数据传输速度才由I/O时钟决定。所以只要访问方式落在“单点、随机”上NOR完胜一旦访问方式是“大批量、连续”NAND就能用吞吐率找补回来。写和擦除则是另一个故事NOR往单元里写数据用的是沟道热电子注入需要较高的编程电压功耗大NAND用Fowler-Nordheim隧穿做编程和擦除整个页可以并行编程典型页写时间几百微秒块擦除一两毫秒。同样是连续大批量写入NAND比NOR快出几个数量级。维度NANDNOR阵列结构存储单元串联共用位线单元独立引线随机寻址读操作粒度页读取到缓存后I/O输出字节/字随机读写操作粒度页编程字节/字编程擦除粒度块擦除扇区/块擦除随机读首字节延迟页加载20~80µs级别极低ns~µs级别顺序读吞吐高可到几十MB/s以上受限于IO时钟中等写/擦性能页级并行批量写入快写入功耗大批量擦写明显慢容量密度高3D堆叠可达数百层低工艺微缩难度大单bit成本极低高容量越大越明显是否需要FTL必须坏块ECC磨损均衡不需要也能用典型应用SD/eMMC/UFS/SSDXIP启动、代码存储、小数据1.3 NAND的脏活累活提前认识一下NAND因为密度高、串行结构天然伴随几个“特性”出厂就可能带坏块读写过程中可能产生比特翻转反复擦写会磨损块。所以NAND存储系统绕不开三件事——坏块管理BBM、ECC纠错、磨损均衡wear leveling。NOR则因为阵列结构规整、可字节随机访问坏块少得多ECC可以做得很轻磨损均衡压力也小很多。这些差异决定了上层设计的走向。把NAND比作一个“高速但有点毛躁”的仓库管理员吞吐量大但偶尔把货号记错、个别货架容易坏必须有调度员跟着擦屁股。NOR则是“精准但手脚慢”的老员工每次拿单件货又快又准但一次只能搬一小箱整个仓库的规模也扩展不上去。理解了这两类角色的性格再去看SD协议为什么非要选NAND就顺理成章了。2. SD家族的底层基因就是NAND2.1 SD协议从诞生起就是围绕NAND写的SD卡在当年设计时存储介质就定位为NAND Flash整个命令体系和寄存器定义都建立在NAND的块页模型上。主机的读操作是CMD17/CMD18读单块/多块写操作是CMD24/CMD25写单块/多块最小访问单位是512B扇区。主机看到的512B扇区其实已经是SD卡控制器处理过的“逻辑块”视图——底层物理NAND的页可能4KB、8KB控制器会把若干个逻辑扇区映射到一个物理页里再负责搬数据。这种“逻辑块到物理页”的转换本质上和SSD里的FTLFlash Translation Layer是一回事。SD卡出厂时也内置了这样一层地址映射只是它把复杂度全部封在了卡片内部对外只暴露统一命令。所以当你把SD NAND焊上板子时你用的SD协议从寄存器到命令全部是照着NAND的脾气写的。协议栈、文件系统、主机驱动一整条生态都是为“NAND介质”服务的。2.2 坏块、ECC、磨损均衡这些能力被协议默认具备NAND不像NOR那样出厂就“干干净净”它允许存在坏块运行中还会老化出新坏块。因此SD卡/SD NAND控制器必须内置几个关键模块第一是坏块管理出厂时记录工厂坏块使用中发现的坏块被标记并替换到保留块区第二是ECC纠错常见BCH、RS或更高级的LDPC保证Flash出现随机位错时依然能返回正确数据第三是磨损均衡把写入操作尽量均匀分摊到所有块上避免个别块先被写穿。主机拿到手的是什么是一个“无论底层怎么坏、都不需要你操心”的块设备。这套能力从SD协议诞生之初就被默认了。反过来想如果SD协议面向的是NOR这些设计就变成了一种浪费NOR坏块极少ECC需求很轻磨损均衡几乎不用做。协议没有为NOR做这么多准备因为它压根不是为NOR设计的。这就是为什么“SD里面装NAND”不是偶然而是基因层面的匹配。2.3 如果介质换成NORSD架构会塌在哪假设有一天真有芯片厂推出“SD NOR”——外面是SD协议的LGA封装里面换成NOR晶圆会怎样第一个问题是指令语义错配SD协议最小读写单位是512B扇区主机和文件系统根本不会对SD设备发起“随机单字节写”NOR最引以为傲的字节随机写在这里毫无用武之地而协议要求的连续扇区写入、频繁擦写又正好是NOR最不擅长的场景。第二个问题是写放大的惨剧NOR擦除要按块擦写慢、功耗大一旦FATFS频繁更新文件NOR会被拖得很痛苦。第三SD卡协议还要求卡片提供CID/CSD寄存器、支持电压切换、流式写等机制这些对NOR来说既不是特长也不是刚需硬塞进去只会让系统更复杂。所以“SD NAND里装NAND”是协议栈和介质特性高度匹配的必然结果而不是顺手选了个流行方案。3. 为什么装在SD卡里的必须是NAND容量、成本和性能的账3.1 容量密度这道坎NOR真的过不去贴一个典型物联网项目的真实场景BootLoader加固件可能只有1~4MB但GUI图片资源、字库、语音素材、日志缓存、OTA升级包动辄几十MB到几百MB。NOR的工艺决定了它在16MB以上容量就会遭遇成本良率的剪刀差。市面上常见NOR容量大多在1Mbit128KB到128Mbit16MB之间再往上单片NOR的价格会非常难看。NAND这边完全是另一个世界主流SD卡从4GB起步SD NAND作为嵌入式封装常见容量从128MB到8GB甚至更高单位bit成本随工艺演进不断下降。所以容量需求一摆出来选NAND几乎不需要犹豫。更关键的是NAND工艺已经进入3D堆叠时代垂直堆到几十层、上百层容量和良率还能继续优化。NOR因为结构限制很难做3D化工艺微缩也遇到瓶颈。这是物理规律决定的不是哪家厂商偏心。3.2 写入性能的真实差距别被“NOR读得快”带偏NOR给人的印象常常是“快”但这个快必须严格限定在随机读和低延迟代码执行上。一旦进入批量写场景情况就反转了。比如往存储里写一个1MB的固件更新包NAND按页编程一个4KB页写几百微秒整个过程毫秒级完成NOR要先擦除若干扇区一次4KB/64KB擦除可能几十毫秒甚至更久再逐字节写入整体可能拖到秒级。更麻烦的是NOR按字节编程需要较高的编程电压和更大的瞬态电流对电池类设备不友好NAND的页级并行编程单位bit能耗更低。所以“NOR快”在数据存储任务里其实是个以偏概全的说法。一线量产选型时只要看到日志缓存、FATFS频繁更新、OTA升级这类需求工程师会毫不犹豫倾向NAND。把数据写入类比成搬家NOR是一辆随叫随到的小车单趟灵活但运量小NAND是整节火车皮调度门槛高一靠站就几十节一起装卸。只搬一个箱子小车好搬一整个仓库火车无可替代。3.3 算一笔成本与人力账拿一个实际选型场景举例。某项目原本用16MB SPI NOR存代码和资源单颗BOM成本在预算表里看着还行后来资源膨胀到64MBNOR方案要么用多颗并联要么找特殊的大容量NOR要么接受极高的单价。这时候接入一颗128MB甚至256MB的SD NAND价格区间反而更友好而且LGA-8封装只有8个引脚PCB占用比多颗SOIC-8 NOR还小。人力成本也是大头。SD NAND走标准SD协议MCU的HAL库、SDIO驱动、SPI模式驱动基本现成上层还能直接套FatFS而裸NAND方案需要自己写NAND时序、坏块扫描、ECC算法和磨损均衡这部分开发和维护成本非常高。把硬件成本、开发成本、维护成本放在一起算NAND方向几乎全面胜出。4. 那NOR什么时候登场它没有死只是角色不同4.1 XIPNOR不可替代的舞台XIPExecute in Place就地执行是NOR最不可替代的看家本领。MCU上电后代码可以直接从NOR映射地址取指执行BootLoader和关键启动参数必须能在不加任何RAM拷贝的情况下跑起来。NAND不具备这个能力它的读操作需要命令、地址、等待页装载、ECC校验执行粒度和CPU取指完全不匹配一旦读出的页里有不可纠正的错误程序甚至可能直接跑飞。所以在绝大多数嵌入式板子上你会看到一套固定组合一颗SPI NOR保存不能出错、必须上电即执行的BootLoader和关键启动参数一颗SD NAND或eMMC保存大容量用户数据、固件镜像、日志、资源包。它俩不是竞争关系而是上下游配合关系。4.2 从启动链看NOR和SD NAND为什么总是一起出现画一条典型启动链上电 → CPU从片内ROM读固化启动代码 → 从SPI NOR引导BootLoader → BootLoader初始化DDR和外部控制器 → 从SD NAND/eMMC加载内核或App镜像 → 运行期文件系统读写SD NAND。每一步的存储选型都有明确理由。第一步要求绝对可靠、时序实时NOR当仁不让后面的镜像和文件系统要求大容量和高吞吐NAND的优势完全释放。看懂这条启动链初级工程师就不会再纠结“既然SD NAND这么好为什么还要NOR”而是能主动判断某个存储元件该放到哪一环。4.3 工程选型决策什么时候坚持NOR什么时候果断上SD NAND需求特征推荐介质主要理由代码量小、需要上电即执行SPI NORXIP、随机读延迟低、无需驱动初始化需要频繁字节级随机修改、保存小参数NOR或小容量EEPROM字节寻址简单没有磨损管理负担需要存几十MB~GB级资源/日志/固件包SD NAND / eMMC容量、吞吐、单bit成本最均衡MCU只有SDIO/SPI接口、没有NAND控制器SD NAND协议成熟驱动现成省去FTL容量小于16MB、追求BOM最低视情况NOR更便宜此时NOR单价仍可接受频繁连续擦写、日志型负载SD NAND工业级优先控制器承担磨损均衡与掉电管理实战里还有一个常见过渡项目原来的代码只有几MB跑在SPI NOR里后来资源膨胀代码搬到SD NAND启动变慢于是把最核心的启动片段留在NOR业务代码和资源包放到SD NAND。这种“既有NOR又有NAND”的混合架构是嵌入式系统里最典型的存储布局。5. SD NAND内部的黑匣子到底干了什么5.1 NAND裸颗粒在外面是“刺头”在SD NAND里被控制器管住了很多初级工程师觉得NAND“难用”因为裸NAND直接暴露在MCU面前时所有脏活都要自己扛发命令前要检查状态寄存器、写之前要整块擦除、要维护坏块表、每次读要自己做ECC、还要处理读干扰和数据保持。真接了裸NAND驱动代码上千行很正常边界条件还特别多。SD NAND的做法就是把整套“NAND管家”固件和NAND晶圆封进同一个芯片。外面只露出8个引脚对MCU来说它就是一颗“只要喂命令就有数据返回”的SD卡内部固件负责消化NAND的所有脾气。这也是SD NAND在量产里特别受欢迎的原因不需要养NAND领域的资深驱动工程师就能稳定使用大容量Flash。5.2 控制器里的日常坏块标记、磨损均衡、掉电管理SD NAND控制器内部常年跑着几件事值得心里有数。第一是逻辑地址映射主机写LBA 100控制器此刻把它映射到物理页A下次再写LBA 100可能就映射到另一个空闲页B旧页A等垃圾回收。换页意味着不会反复写同一个物理块这叫动态映射磨损均衡。第二是坏块替换当某个物理块出现不可纠正的ECC错误或编程失败控制器把该块标记为坏把逻辑地址挪到保留区好块上。第三是掉电保护突然断电可能让一个页只写了一半控制器需要靠日志或备份区保证重启后要么返回旧数据、要么返回完整新数据而不是半截脏数据。这些工作裸NOR几乎不需要做得这么重因为NOR可以字节级改写、坏块极少。但NAND必须做。从外部用户的视角看你的程序只需要调用f_write复杂度全被芯片吃掉了。5.3 给初学者的落地实操从焊接到第一条CMD0SD NAND的实用之处在于它不像裸NAND需要从头写驱动。如果你用RTOS或HAL库SDIO/SPI驱动基本可以直接套用。实际落地时注意几个点焊接上LGA-8无引脚封装与普通IC无异注意焊盘散热和清洗别让助焊剂残留在引脚之间。硬件上DAT线和CMD线都要接上拉电阻CLK不需要上拉供电要加去耦电容电源纹波对NAND初始化成功率的影响比很多人想象的大。软件上初始化序列按顺序来上电后先等至少74个时钟周期然后CMD0进IDLE、CMD8核对接口电压参数0x000001AA、ACMD41反复查询直到Ready、CMD2/CMD3取CID和RCA、CMD7选中卡、读CSD确认容量之后就能用CMD17/18读、CMD24/25写。代码层面的最小序列示意伪代码// 伪代码SD NAND初始化最小序列 sd_power_on(); // 上电等待至少74个时钟 send_cmd(CMD0, 0x00000000); // 进入Idle send_cmd(CMD8, 0x000001AA); // 检查SD 2.0电压窗口 do { send_cmd(CMD55, 0); // ACMD41的前缀命令 send_cmd(ACMD41, 0x40000000); // HCS置位等待初始化完成 } while (!(response OCR_READY)); send_cmd(CMD2, 0); // 读CID send_cmd(CMD3, 0); // 获取RCA send_cmd(CMD7, rca); // 选中卡 send_cmd(CMD9, rca); // 读CSD解析容量 // 之后即可用CMD17/CMD18、CMD24/CMD25读写数据块注意ACMD41必须先发CMD55SPI模式下初始化流程略有差异但总体思想一致。这些细节在现场调试时能省下不少时间我建议第一次接触SD NAND的朋友把这套序列在逻辑分析仪上抓一遍亲眼看看响应波形理解会深很多。6. 常见误区与经验速查6.1 五个高频误区逐个拆误区一“NOR比NAND快。”准确说法是NOR的随机读延迟低、代码执行体验好顺序读、大规模写、擦除性能上NAND优势明显。不同负载下结论完全不同别拿一个“快”字一刀切。误区二“NOR更可靠所以重要数据都要放NOR。”NAND在正确FTL管理下能提供很强的数据完整性控制器有ECC和刷新机制裸NAND的易错点反而被SD NAND的控制器吸收掉了。数据可靠性不是介质单独扛而是“介质控制器应用冗余”的组合。误区三“SD NAND就是把SD卡去壳焊接。”封装不同、电气引脚不同SD NAND的LGA-8与SD卡金手指完全两回事它取消了卡座插拔链路专为板级集成设计但协议层面和SD卡一致驱动可以直接复用。误区四“NAND写入以块为单位所以只能整块操作。”准确说法是编程按页、擦除按块。单页内不能重复编多个不同数据控制器会做映射把文件系统的扇区访问转换成页操作用户并不直接感知。误区五“MCU有QSPI接口就能直接驱动SD NAND。”QSPI是给SPI NOR/Flash准备的SD NAND需要SDIO接口或者用SPI模式速度受限。SPI模式虽然也能跑但吞吐远远不如SDIO别指望测出几十MB/s。6.2 给初级工程师的几条工程建议第一先分清数据类型掉电必须保留的启动代码放NOR经常改写的业务数据放SD NAND。第二别在SD NAND上做高频率的单扇区小写即使有控制器磨损均衡过于极端的写放大依然会缩短寿命日志先缓存到内存、按块落盘是应用层最常见的优化手段。第三量产前一定做掉电老化测试SD NAND控制器的掉电策略直接决定数据安全这个测试环节省不得。第四对启动时间敏感的硬实时场景要预留SD NAND的上电初始化时间——ACMD41轮询可能比NOR的“上电即用”慢不少。第五学会看数据手册里的TBW/寿命参数和温标等级工业级和消费级在严苛环境下的表现有明显差距。最后聊一点个人体会。我帮朋友做存储选型时见过不少初级工程师把NOR和NAND当成两个相似的通用选项纠结半天。其实它们更像两种性格的工具NOR适合做“打开即执行”的代码仓库NAND适合做“大吞吐、多数据”的粮仓。SD NAND的出现是为了让你在不接触裸NAND驱动的前提下依然能获得SD生态的成熟便利。把这个思路理顺以后再遇到“为什么这颗芯片里装的不是NOR”这类问题你已经站在存储选型的正确起跑线上了。接下来打开数据手册把初始化序列亲手跑一遍比任何结论都更管用。