SD NAND Flash 软件设计规范
V1.3:空闲预留、AU 对齐、关键读回、CID 绑定、FatFS 少碎写、温漂降额
1. 目的与范围
本规范规定 SD NAND 软件层的设计约束与推荐实现,目标是:
- 正确实现 SPI 模式 与 SD / SDIO 模式 的初始化、总线切换与读写
- 保证上电时序、≤400 kHz 初始化、CRC、超时与错误恢复
- 正确处理 CCS 块/字节寻址、单块/多块传输与停止条件
- 落实吞吐建议:多用 CMD18 / CMD25,少用 CMD17 / CMD24 循环
- 落实 空闲预留、AU 对齐、关键读回、CID 绑定、少碎写、温漂降额
- 厘清 片内 FTL/BBM/ECC 与主机职责边界(勿当裸 SPI NAND)
- 规范与 FatFS 等文件系统的分区、掉电与寿命策略
与 SPI NOR / SPI NAND 的本质差异
| 维度 | SPI NOR | SPI NAND | SD NAND |
|---|---|---|---|
| 主机视角 | 字节/页命令 | 页 Cache + 主机 BBM/ECC | 标准 SD 块设备 |
| 坏块 / FTL | 通常无 | 主机必须管 | 片内控制器完成 |
| 接口 | SPI/QSPI | SPI/QSPI | SD 4 线 / SDIO 或 SPI 模式 |
| 文件系统 | 可选 | 禁裸挂 FatFS | 可直接挂 FatFS |
2. 术语与缩写
| 术语 | 说明 |
|---|---|
| SD NAND | 带 SD 协议控制器的 NAND;对外呈 SD 卡行为 |
| SPI 模式 | CS / CLK / DI / DO;上电后靠 CS↓CMD0 切入 |
| SD / Native | CLK / CMD / DAT0~3 |
| OCR / CCS / HCS | 工作条件;卡容量状态;主机高容量支持 |
| CID / CSD / SCR / RCA | 识别、几何能力、配置、相对地址 |
| 初始化时钟 | ≤ 400 kHz;完成后切工作频率 |
禁止把 SD NAND 当 SPI NAND 去扫 OOB / 发 Page Read。
3. 软件分层架构
┌──────────────────────────────────────────────┐
│ 应用 / 文件系统 (FatFS / exFAT / ...) │
├──────────────────────────────────────────────┤
│ 块设备层(扇区缓存、分区、写保护) │
├──────────────────────────────────────────────┤
│ SD NAND 协议驱动(SPI 或 SD 二选一) │
├──────────────────────────────────────────────┤
│ SPI HAL 或 SDMMC/SDIO 主机 HAL │
└──────────────────────────────────────────────┘
强制:应用禁止直接拼 CMD;同一上电周期模式锁定;初始化须完成 tVSL → ≥74 时钟 → 识别 → 能力表 → 升频。
3.1 上电时序与总线预热 强制
| 项 | 要求 |
|---|---|
| tVSL | ≥ Datasheet;无标称至少 1 ms |
| 时钟 | 初始化 100~400 kHz |
| ≥74 时钟 | 实践常发 80~100 拍后再 CMD0 |
| 热插拔 | 插拔后必须完整重新初始化 |
3.2 SPI vs SD 选型 强制
| 项 | SPI 模式 | SD / Native |
|---|---|---|
| 硬件 | 普通 SPI + CS | SDMMC/SDIO 主机 |
| 默认 | 须 CS↓CMD0 切入 | 上电即 SD 模式 |
| 总线 | 单线 DO | 1-bit / 4-bit |
| 性能 | 较低 | 高(量产优先) |
有 SDMMC → 优先 SD 4-bit;仅有 SPI → SPI 模式并严格按 §4.1。
3.3 Boot 架构 强制
SD NAND 通常不可 XIP。由 ROM/NOR 启动 Loader,再初始化 SD NAND 挂载 FS / 加载 App。
4. 接口模式与初始化流程 强制
上电默认为 SD 模式。SPI 模式必须在首次复位时用 CS 采样锁定;同一供电周期不可随意改模式。
4.1 SPI 模式初始化
上电默认为 SD 模式;须 CS↓ + CMD0 锁定 SPI。初始化阶段合法 CRC 不可省。
1. tVSL;Mode0/3;≤400 kHz;CS↑ DI↑ ≥74clk
2. CS↓ CMD0 (CRC=0x95) → R1=0x01 Idle(可重试)
3. CMD8 (0x1AA, CRC=0x87) → 校验 R7;失败走 v1 分支
4. 循环 CMD55+ACMD41(HCS) 至离开 Idle(墙钟约 1s)
5. CMD58 → CCS;SC 则 CMD16=512
6. (推荐)CMD59 开 CRC;升频=min(CSD,稳定值,温区降额)
7. 能力表落盘;READY
CMD12 后注意 SPI stuff byte;多块写必须
0xFD 停止后再 busy 双确认。4.2 SD / SDIO(Native)初始化
1. tVSL;≤400 kHz;1-bit;≥74clk;CMD0
2. CMD8 → 决定 HCS
3. CMD55+ACMD41 至 OCR Busy=1(注意与 SPI R1 Idle 语义不同)
4. CMD2 CID → CMD3 RCA → CMD9 CSD → CMD7 Select
5. (强烈推荐)ACMD13 取 AU;ACMD51 读 SCR
6. (推荐)CMD6 HS、ACMD6 4-bit;失败必须回退
7. 升频;READY
4-bit/HS 每次上电重新协商,禁止假定上次已切换成功。
4.3 初始化状态机
POWER_ON_WAIT → CLOCK_TRAINING → IDLE
→ IF_COND → OCR_NEGOTIATE → IDENTIFY
→ TRANSFER → READY
失败 → ERROR → 复位重试 → FATAL
4.4 模式锁定与防混用 强制
- 禁止未掉电时 SPI 驱动与 SDMMC 驱动轮流操作同一颗卡
- Loader 与 App 必须约定同一模式
- 引脚复用时须有互斥与模式配置表
5. 读写擦与 Timeout 强制
主机视角是块设备,不是页 Cache。
| 操作 | SPI 要点 | SD 要点 |
|---|---|---|
| 单块读 | CMD17 → 令牌 0xFE + 512B + CRC | CMD17 → DAT 数据块 |
| 多块读 | CMD18 … CMD12 | CMD18 … CMD12 |
| 单块写 | CMD24 → 0xFE + 数据 → busy | CMD24 → DAT0 busy |
| 多块写 | CMD25 → 0xFC… 停 0xFD | CMD25 → CMD12 |
| 擦除 | CMD32 → CMD33 → CMD38 → 等 busy | |
5.3 Timeout 策略
优先级:Datasheet Max → CSD 估算 → 料号表 → 温区放大。禁止万能单一超时。
| 操作 | 建议起点 |
|---|---|
| ACMD41 初始化 | 1 s |
| 单块读令牌 | ≥ 100 ms |
| 单块写 busy | 250~500 ms |
| 多块写整段 | 按块数线性 + 上限 |
| 擦除 | 按范围;须有上限 |
禁止仅靠固定 delay 盲等写完成。
5.4 Busy 双重确认 强制
仅一次空闲不得判定完成(对齐 SPI NOR 的 WIP 双确认思想)。默认连续 2 次独立采样为空闲;中间若再次变忙则计数清零。SD 建议再 CMD13 查错误比特。
clear_streak = 0
do {
idle = read_busy_idle() // SPI: byte!=0;SD: DAT0 高
if (!idle) clear_streak = 0
else if (++clear_streak >= 2) {
// SD: CMD13 查 ERROR → 才 OK
return OK
}
if (timeout) return ERR_TIMEOUT
} while (1)
5.6 多块优先与吞吐建议 强烈推荐
一句话:能合并就合并——多
CMD18 / CMD25,少 CMD17 / CMD24 循环。| 场景 | 推荐 | 避免 |
|---|---|---|
| 连续读 ≥2 扇区 | CMD18 | 循环 CMD17 |
| 连续写 ≥2 扇区 | CMD25 | 循环 CMD24 |
| 已知写 N 块(SD) | 先 ACMD23(N) 再 CMD25 | 无预擦碎写 |
| 大范围废弃数据 | CMD32/33/38 或 Discard | CMD24 逐扇区填 |
| 仅 1 扇区 | CMD17 / CMD24 | 不必强行多块 |
read/write_blocks:count==1单块;count≥2必须多块,禁止 for 拆单块- 超长传输分段(如 32~128 扇区),每段正确 STOP /
0xFD - FS/缓存:脏扇区按连续 LBA 合并一次 CMD25;应用少 sync、整簇缓冲
- 测速须区分单块 IOPS 与多块顺序 MB/s,避免只用 CMD24 误判“卡慢”
5.7 AU 对齐写入 强烈推荐
为何:跨 AU 碎写抬高片内写放大,表现为带宽掉、busy 抖、寿命短。AU 对齐需与 CMD25、空闲预留叠加。
- SD:Transfer 后 ACMD13 解析
AU_SIZE,写入能力表;失败则 au=未知,至少整簇对齐 - 大文件/日志:起始 LBA 与长度尽量 AU 对齐;缓冲攒满 max(簇, AU)
- ACMD23 块数尽量 AU 整数倍;格式化簇选 AU 约数
- 分区起始建议 AU 对齐,避免首文件长期跨边界