0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文诠释NandFlash ECC校验原理与实现

strongerHuang 来源:nhczp 作者:nhczp 2021-07-27 16:15 次阅读

大家应该都在用U盘,而U盘中的存储芯片就是NandFlash,你买的64G的U盘,实际并没有64G,其中一个原因就是存在坏块。

因为工艺和其他方面的原因,不能保证NandFlash不存在坏块,因此就需要“挑选出坏块”。

本文就为大家讲述一下用于NandFlash的ECC校验原理与实现。

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,如下图所示:

a3ff8f4a-eb95-11eb-a97a-12bb97331649.png

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

a41627c8-eb95-11eb-a97a-12bb97331649.png

用数学表达式表示为:

P4=D7(+)D6(+)D5(+)D4P4`=D3(+)D2(+)D1(+)D0P2=D7(+)D6(+)D3(+)D2P2`=D5(+)D4(+)D1(+)D0P1=D7(+)D5(+)D3(+)D1P1`=D6(+)D4(+)D2(+)D0

备注:这里(+)表示“位异或”操作

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

a423029a-eb95-11eb-a97a-12bb97331649.png

用数学表达式表示为:

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 paritystatic 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 《 4; i++){if (reg3 & a) /* LP15,13,11,9 --》 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 《 4; i++){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;}

//Calculate 3 byte ECC code for 256 byte blockvoid 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 《 256; j++){/* Get CP0 - CP5 from table */idx = nand_ecc_precalc_table[dat[j]];reg1 ^= (idx & 0x3f);

/* All bit XOR = 1 ? */if (idx & 0x40) {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;}

//Detect and correct a 1 bit error for 256 byte blockint nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc){u_char a, b, c, d1, d2, d3, add, bit, i;

/* Do error detection */d1 = calc_ecc[0] ^ read_ecc[0];d2 = calc_ecc[1] ^ read_ecc[1];d3 = calc_ecc[2] ^ read_ecc[2];

if ((d1 | d2 | d3) == 0){/* No errors */return 0;}else{a = (d1 ^ (d1 》》 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《4; i++){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)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)++i;d1 》》= 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;}

参考文档:

http://blogimg.chinaunix.net/blog/upfile2/080702112233.pdf

免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ECC
    ECC
    +关注

    关注

    0

    文章

    90

    浏览量

    20408

原文标题:NandFlash ECC校验原理与实现

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Traveo T2G SRAM不是32位的吗?如何得到个64位的?

    11010100_01000010_00100101_10000100_01001011_10100110_01011100_10110111; 如图所示,CODEWORD_SW[127:0] 与各自 ECC 常量的 AND 结果的 Reduction XOR 将给出
    发表于 06-03 08:49

    PSoC5LP:ECC总是返回失败的原因?

    我正在做个项目,需要在启动时检查闪存的完整性。 PSoC 是 CY8C5667AXI-LP040,我使用的是 Creator 4.3(ARM GCC 5.4-2016-q2-update) 启用
    发表于 05-30 08:15

    CYT4BF的监管区 (SFlash) 是否支持 ECC

    CYT4BF 的监管区 (SFlash) 是否支持 ECC? 如果支持 ECC, 控制 ECC 的寄存器是否与 FLASHC/FLASHC1_FLASH_CTL.MAIN_ECC_EN
    发表于 05-23 07:26

    stm32f767第次读取nandflash导致屏幕闪烁的原因?

    fmsc总线上同时挂在sdram做ltdc显存,nandflash存储文件图片,比如我把张图片存入nandflash,当我第次从nandflas
    发表于 04-09 06:02

    STM32G系列ECC校验错误,进入NMI中断后如何处理?

    ,断电重启无法恢复。经过系列的排查,应该是由于在上下电的过程中,Flash数据更新的过程中,造成ECC未写入,造成最终读Flash时,ECC错误,造成了NMI中断。。由于G系列比较新,我们只是搜到了
    发表于 03-29 07:43

    Pflash和Dflash都有闪存ECC保护,ECC内存在哪里?

    在用户手册中,Pflash 和 Dflash 都有闪存 ECC 保护,我想知道 ECC 内存在哪里? 它会占用 pflash 空间还是存储在用户无法访问的地方? 在此先谢谢!
    发表于 01-26 08:12

    CRC校验原理及其软件实现

    电子发烧友网站提供《CRC校验原理及其软件实现.pdf》资料免费下载
    发表于 11-16 10:11 0次下载
    CRC<b class='flag-5'>校验</b>原理及其软件<b class='flag-5'>实现</b>

    modbus协议怎么实现个数据帧的校验

    modbus是怎么实现校验
    发表于 10-31 08:09

    奇偶校验和crc校验的区别 CRC校验和奇偶校验之间有什么关系?

    方法都可以检测出特定类型的错误。 奇偶校验种简单的校验方法,适用于串行传输数据,主要用于检测传输中的单比特错误。其原理是通过添加校验
    的头像 发表于 10-17 16:28 2775次阅读

    什么是奇校验和偶校验?常见的奇偶校验方式有哪些?

    什么是奇校验和偶校验?常见的奇偶校验方式有哪些? 1. 奇偶校验是指在数字通信中采用种技术对传输的数据进行
    的头像 发表于 10-17 16:28 9188次阅读

    什么是奇偶校验电路?奇偶校验器是时序逻辑电路吗?

    什么是奇偶校验电路?奇偶校验器是时序逻辑电路吗? 奇偶校验电路是种数字电路,在数据传输过程中用于检测数据是否发生错误。在每个数据字节(通常是8位)的最高位添加
    的头像 发表于 10-17 16:16 3031次阅读

    什么是奇偶校验 奇偶校验的基本原理 奇偶校验电路什么意思

    什么是奇偶校验 奇偶校验的基本原理 奇偶校验电路什么意思  奇偶校验种用于检测二进制数据中错误的方法。它的基本原理是在二进制数据的末尾添
    的头像 发表于 10-17 16:16 3090次阅读

    SAP ECC到停止运营时间如何实现向S/4HANA的平稳升级

    , HR,Basis,PP, PS, PM, TR, IM等多个模块及子模块。   从2004年发布的ERP系统开始使用ECC说法。基于netweaver 2004,称为ECC 5.0。 之后SAP
    的头像 发表于 09-13 21:54 584次阅读
    SAP <b class='flag-5'>ECC</b>到停止运营时间如何<b class='flag-5'>实现</b>向S/4HANA的平稳升级

    STM32H7系列内部存储器保护的纠错码(ECC)管理

    保护,但本文档不涉及其实现方法。本文档介绍了 ECC 保护的般信息、详细的硬件 ECC 故障管理,以及在 STM32H7 系列微控制器中实现
    发表于 09-08 07:31

    ECC IP用户手册

    ECC(Error Correcting Code),纠错编码,是种能实现错误检测和纠正的技术。
    发表于 08-09 07:36