ECC(Error Correction Code,错误纠正码)是一类给数据增加冗余校验信息的编码机制,使系统在读取时能检测并纠正一定数量的 bit error;在 NAND Flash、eMMC、UFS 和内存系统中都很常见。
这里的 ECC 是错误纠正码,不是密码学里的 Elliptic Curve Cryptography(椭圆曲线密码)。
核心问题
存储介质和传输链路都可能出现 bit 翻转。对 NAND Flash 来说,随着制程缩小、单元存储 bit 数增加、擦写次数上升和数据保持时间变长,原始 bit error 变得更常见。
如果只保存原始数据,读出 101100... 时系统无法知道其中某一位是否被翻转。ECC 的思路是写入时额外保存冗余信息,读取时用冗余信息判断并修复错误。
核心对象
| 对象 | 含义 | 工程关注点 |
|---|---|---|
| message | 原始数据 | 需要保护的 page、sector 或 cache line |
| parity / redundancy | 冗余校验信息 | 占用额外空间,常存于 OOB/spare 区 |
| codeword | 数据加冗余后的编码结果 | 可检测/纠正能力由编码方案决定 |
| syndrome | 校验计算结果 | 用于定位错误模式 |
| correction strength | 纠错能力 | 每个数据单位可纠正多少 bit error |
| uncorrectable error | 不可纠正错误 | 超过 ECC 能力,可能造成 I/O error |
核心机制
抽象流程如下:
write:
codeword = encode(data)
store(codeword)
read:
codeword' = read()
data, status = decode_and_correct(codeword')data是原始数据。encode(data)会生成包含冗余校验位的codeword。codeword'是读出的结果,可能和写入时不同。decode_and_correct根据冗余关系计算错误位置,并在能力范围内修复。status通常分为无错误、已纠正错误、不可纠正错误。
一个直观但很弱的例子是三重重复码:
bit 1 -> 111
bit 0 -> 000读出 101 时,多数投票得到 1,可以纠正一位错误。但这种方法冗余太大,真实 NAND 常使用 BCH 或 LDPC 等更高效的纠错码。
工程用途
- NAND/eMMC/UFS 控制器用 ECC 纠正读出 bit error。
- DRAM ECC 用于服务器和安全关键系统,检测或纠正内存错误。
- 通信和存储系统用 ECC 提高可靠性。
- 设备健康监控可以跟踪 corrected error 增长趋势,提前发现介质退化。
在 eMMC 这类托管式存储中,ECC 细节通常由控制器隐藏;主机可能只能看到读写错误、寿命估计或厂商扩展健康字段。
边界与常见坑
- ECC 不能纠正无限错误:超过纠错能力后仍会出现不可纠正错误。
- 已纠正错误不是零风险:纠错次数升高说明介质 margin 变差,可能需要数据搬迁或更换设备。
- ECC 不是校验和:校验和通常只能检测错误,ECC 还要定位并纠正错误。
- ECC 不是加密:它不提供保密性或认证,只处理误码。
- ECC 强度和性能有代价:更强纠错需要更多冗余、计算和延迟。