当前位置:文档之家› NandFlash+ECC原理和实现

NandFlash+ECC原理和实现

if (d1 & c) add |= a;
c >>= 2; a >>= 1; } c = 0x80; for (i=0; i<4; i++) { if (d2 & c)
add |= a; c >>= 2; a >>= 1; } bit = 0; b = 0x04; c = 0x80; for (i=0; i<3; i++) { if (d3 & c)
/* Initialize variables */ a = b = 0x80; tmp1 = tmp2 = 0;
/* Calculate first ECC byte */
for (i = 0; i < 4; i++) {
if (reg3 & a) tmp1 |= b;
b >>= 1; if (reg2 & a)
bit |= b; c >>= 2; b >>= 1; } b = 0x01; a = dat[add]; a ^= (b << bit); dat[add] = a; return 1; } else { i = 0; while (d1) { if (d1 & 0x01)
NAND FLASH ECC 校验原理与实现
ECC 简介 由于 NAND Flash 的工艺不能保证 NAND 的 Memory Array 在其生命周期中保持性能的
可靠,因此,在 NAND 的生产中及使用过程中会产生坏块。为了检测数据的可靠性,在应 用 NAND Flash 的系统中一般都会采用一定的坏区管理策略,而管理坏区的前提是能比较可 靠的进行坏区检测。
校验的时候,根据上述 ECC 生成原理不难推断:将从 OOB 区中读出的原 ECC 校验和 新 ECC 校验和按位异或,若结果为 0,则表示不存在错(或是出现了 ECC 无法检测的错误); 若 3 个字节异或结果中存在 11 个比特位为 1,表示存在一个比特错误,且可纠正;若 3 个 字节异或结果中只存在 1 个比特位为 1,表示 OOB 区出错;其他情况均表示出现了无法纠 正的错误。
reg3 ^= (u_char) j; reg2 ^= ~((u_char) j); } }
/* Create non-inverted ECC code from line parity */ nand_trans_result(reg2, reg3, ecc_code);
/* Calculate final ECC code */ ecc_code[0] = ~ecc_code[0]; ecc_code[1] = ~ecc_code[1]; ecc_code[2] = ((~reg1) << 2) | 0x03; }
如果操作时序和电路稳定性不存在问题的话,NAND Flash 出错的时候一般不会造成整 个 Block 或是 Page 不能读取或是全部出错,而是整个 Page(例如 512Bytes)中只有一个或 几个 bit 出错。
对数据的校验常用的有奇偶校验、CRC 校验等,而在 NAND Flash 处理中,一般使用 一种比较专用的校验——ECC。ECC 能纠正单比特错误和检测双比特错误,而且计算速度 很快,但对 1 比特以上的错误无法纠正,对 2 比特以上的错误不保证能检测。
这里(+)同样表示“位异或”操作
当往 NAND Flash 的 page 中写入数据的时候,每 256 字节我们生成一个 ECC 校验和, 称之为原 ECC 校验和,保存到 PAGE 的 OOB(out-of-band)数据区中。
当从 NAND Flash 中读取数据的时候,每 256 字节我们生成一个 ECC 校验和,称之为 新 ECC 校验和。
tmp1 |= b; b >>= 1; a >>= 1; }
/* LP15,13,11,9 --> ecc_code[0] */ /* LP14,12,10,8 --> ecc_code[0] */
/* Calculate second ECC byte */
b = 0x80;
for (i = 0; i < 4; i++)
// Calculate 3 byte ECC code for 256 byte block void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) {
u_char idx, reg1, reg2, reg3; int j;
/* Initialize variables */ reg1 = reg2 = reg3 = 0; ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
ECC 原理 ECC 一般每 256 字节原始数据生成 3 字节 ECC 校验数据,这三字节共 24 比特分成两
部分:6 比特的列校验和 16 比特的行校验,多余的两个比特置 1,如下图所示:
ECC 的列校验和生成规则如下图所示:
用数学表达式表示为: P4=D7(+)D6(+)D5(+)D4 P2=D7(+)D6(+)D3(+)D2 P1=D7(+)D5(+)D3(+)D1
{
if (reg3 & a)
/* LP7,5,3,1 --> ecc_code[1] */
tmp2 |= b;
b >>= 1;
if (reg2 & a)
/* LP6,4,2,0 --> ecc_code[1] */
tmp2 |= b;
b >>= 1;
a >>= 1;
}
/* Store two of the ECC bytes */ ecc_code[0] = tmp1; ecc_code[1] = tmp2; }

/* Build up column parity */ for(j = 0; j < 256; j++) {
/* Get CP0 - CP5 from table */
idx = nand_ecc_precalc_table[dat[j]]; reg1 ^= (idx & 0x3f);
/* All bit XOR = 1 ? */ if (idx & 0x40) {
ECC 算法的实现 static const u_char nand_ecc_precalc_table[] = { 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
相关主题