免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 814 | 回复: 0
打印 上一主题 下一主题

NAND FLASH ECC校验原理与实现 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-25 09:42 |只看该作者 |倒序浏览

ECC简介
??由于NAND Flash的工艺不能保证NAND的Memory Array在其生命周期中保持性能的可靠,因此,在NAND的生产中及使用过程中会产生坏块。为了检测数据的可靠性,在应用NAND Flash的系统中一般都会采用一定的坏区管理策略,而管理坏区的前提是能比较可靠的进行坏区检测。
??如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出错。
??对数据的校验常用的有奇偶校验、CRC校验等,而在NAND Flash处理中,一般使用一种比较专用的校验——ECC。ECC能纠正单比特错误和检测双比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。
ECC原理
??ECC一般每256字节原始数据生成3字节ECC校验数据,这三字节共24比特分成两部分:6比特的列校验和16比特的行校验,多余的两个比特置1,如下图所示:

??
??ECC的列校验和生成规则如下图所示:


??用数学表达式表示为:
????P4=D7(+)D6(+)D5(+)D4??P4`=D3(+)D2(+)D1(+)D0
????P2=D7(+)D6(+)D3(+)D2??P2`=D5(+)D4(+)D1(+)D0
????P1=D7(+)D5(+)D3(+)D1??P1`=D6(+)D4(+)D2(+)D0
??这里(+)表示“位异或”操作
??
??ECC的行校验和生成规则如下图所示:

??用数学表达式表示为:
????P8 = bit7(+)bit6(+)bit5(+)bit4(+)bit3(+)bit2(+)bit1(+)bit0(+)P8
????……………………………………………………………………………………
??这里(+)同样表示“位异或”操作
?
??当往NAND Flash的page中写入数据的时候,每256字节我们生成一个ECC校验和,称之为原ECC校验和,保存到PAGE的OOB(out-of-band)数据区中。
??当从NAND Flash中读取数据的时候,每256字节我们生成一个ECC校验和,称之为新ECC校验和。
??校验的时候,根据上述ECC生成原理不难推断:将从OOB区中读出的原ECC校验和新ECC校验和按位异或,若结果为0,则表示不存在错(或是出现了ECC无法检测的错误);若3个字节异或结果中存在11个比特位为1,表示存在一个比特错误,且可纠正;若3个字节异或结果中只存在1个比特位为1,表示OOB区出错;其他情况均表示出现了无法纠正的错误。
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
??};
??//?Creates non-inverted ECC code from line parity
??static void nand_trans_result(u_char reg2, u_char reg3,u_char *ecc_code)
??{
????u_char a, b, i, tmp1, tmp2;
????/* Initialize variables */
????a = b = 0x80;
????tmp1 = tmp2 = 0;
????/* Calculate first ECC byte */
????for (i = 0; i  ecc_code[0] */
????????tmp1 |= b;
??????b >>= 1;
??????if (reg2 & a)??? /* LP14,12,10,8 --> ecc_code[0] */
????????tmp1 |= b;
??????b >>= 1;
??????a >>= 1;
????}
????/* Calculate second ECC byte */
????b = 0x80;
????for (i = 0; i  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;
??}
??//?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;
????/* Build up column parity */
????for(j = 0; j > 1)) & 0x55;
??????b = (d2 ^ (d2 >> 1)) & 0x55;
??????c = (d3 ^ (d3 >> 1)) & 0x54;
??????/* Found and will correct single bit error in the data */
??????if ((a == 0x55) && (b == 0x55) && (c == 0x54))
??????{
????????c = 0x80;
????????add = 0;
????????a = 0x80;
????????for (i=0; i>= 2;
??????????a >>= 1;
????????}
????????c = 0x80;
????????for (i=0; i>= 2;
??????????a >>= 1;
????????}
????????bit = 0;
????????b = 0x04;
????????c = 0x80;
????????for (i=0; i>= 2;
??????????b >>= 1;
????????}
????????b = 0x01;
????????a = dat[add];
????????a ^= (b >= 1;
????????}
????????while (d2)
????????{
??????????if (d2 & 0x01)
????????????++i;
??????????d2 >>= 1;
????????}
????????while (d3)
????????{
??????????if (d3 & 0x01)
????????????++i;
??????????d3 >>= 1;
????????}
????????if (i == 1)
????????{
??????????/* ECC Code Error Correction */
??????????read_ecc[0] = calc_ecc[0];
??????????read_ecc[1] = calc_ecc[1];
??????????read_ecc[2] = calc_ecc[2];
??????????return 2;
????????}
????????else
????????{
??????????/* Uncorrectable Error */
??????????return -1;
????????}
??????}
????}
????/* Should never happen */
????return -1;
??}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/6071/showart_237527.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP