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

    文章

    100

    浏览量

    21559

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    芯片失效分析篇 —— 浅谈MICRON Memory ECC 功能

    摘要:本文介绍了ECC(错误纠正码)在存储器中的关键作用,重点分析了其在NandFlash应用中的重要性。文章指出,ECC功能未开启可能导致系统误报"坏块"、启动
    的头像 发表于 11-25 16:12 252次阅读
    芯片失效分析篇 —— 浅谈MICRON Memory <b class='flag-5'>ECC</b> 功能

    CS校验原理与应用

    接收方重新计算校验和,与接收到的校验值比较。 特点: 简单快速:计算量小,硬件/软件实现容易。 检测能力有限: 能检测奇数个比特错误。 能检测部分突发错误(但不如CRC)。 无法检测某些常见错误(如
    发表于 11-19 07:51

    CRC校验的原理和应用

    原理: CRC校验将数据视为个二进制多项式,用个预先定义好的生成多项式(Generator Polynomial) 进行模2除法,得到的余数作为CRC校验码。 例如:数据多项式 ÷
    发表于 11-14 06:48

    电能质量在线监测装置自诊断功能的软件校验具体是如何实现的?

    )和通信异常,具体实现可分为三大核心模块,每个模块都有明确的校验逻辑和落地方法: 、数据合理性校验:基于物理规律的 “数据质检” 软件通过预设电网运行的 “合理边界”,
    的头像 发表于 11-06 10:44 505次阅读

    进行数据校验时如何保证场景覆盖的全面性?

    的方法论和实施步骤,结合典型场景示例说明: 、先明确场景覆盖的核心维度:避免 “碎片化思考” 数据校验场景的全面性,需围绕 “数据从产生到应用的全生命周期” 展开,覆盖以下 5 个核心维度,每个维度对应不同的校验目标: 核心维
    的头像 发表于 09-25 17:42 515次阅读

    怎样选择适合的数据校验系统时间同步硬件?

    在电能质量在线监测装置的数据校验系统中, 时间同步硬件的选择需紧密匹配 “数据校验准确性” 核心需求 (如多监测点数据时间戳致性、校验结果时间溯源性),同时兼顾工业现场(如变电站、电
    的头像 发表于 09-19 11:46 348次阅读
    怎样选择适合的数据<b class='flag-5'>校验</b>系统时间同步硬件?

    高精度电测校验装置实战复盘():从调研到落地的全流程解析

    案例:江苏省电力公司苏州供电分公司计量中心多功能校验升级项目 项目背景与挑战 江苏省电力公司苏州供电分公司计量中心承担着苏州地区12个县市区约45万户用电客户的电测仪表校验任务。2023年初,该
    的头像 发表于 08-22 16:43 528次阅读
    高精度电测<b class='flag-5'>校验</b>装置实战复盘(<b class='flag-5'>一</b>):从调研到落地的全流程解析

    搞定英伟达 H100 ECC 报错:从原理到维修,步到位解烦忧

    最近,捷智算GPU维修室收到了不少H100服务器需要维修,故障问题集中为ECC报错。为了帮大家更好地认识和了解情况,下面就详细分享ECC报错系统化排查方法和维修流程。
    的头像 发表于 08-14 18:05 1399次阅读
    搞定英伟达 H100 <b class='flag-5'>ECC</b> 报错:从原理到维修,<b class='flag-5'>一</b>步到位解烦忧

    S32K311如何在Flash上测试ECC

    我有些与目标 S32K311 上的 Flash ECC 相关的问题 - ERM 是否负责 Code Flash 和 Data Flash ECC 中断通知? - 我们如何在 Flash 上测试
    发表于 04-14 08:47

    基于Verilog语言实现CRC校验

    CRC即循环冗余校验码:是数据通信领域中最常用的种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是种数
    的头像 发表于 03-24 10:36 2190次阅读
    基于Verilog语言<b class='flag-5'>实现</b>CRC<b class='flag-5'>校验</b>

    求助,关于STM32H7系列芯片下的ECC功能的疑问求解

    无法关闭ECC就无法测对于单bit错误。特别是位错误下,原始数据,读出数据,以及ECC码无法同时看到。 1.想问下STM32官网工程师,是否存在关闭ECC,严格实现单bit和双bit错
    发表于 03-11 07:43

    请问ECC功能开启后如何验证这个功能是否正常开启呢?

    各位大佬,现在我这边个项目,代码层面开启ECC监控和中断后,如何验证当真实应用环境下,Ram区或者Flash区某个位被打翻后,会正常触发中断,实现读和回写的功能呢?
    发表于 03-11 06:19

    ECC204 mikroBUS™评估板用户指南

    电子发烧友网站提供《ECC204 mikroBUS™评估板用户指南.pdf》资料免费下载
    发表于 01-22 16:55 0次下载
    <b class='flag-5'>ECC</b>204 mikroBUS™评估板用户指南

    ECC608-TMNGTLS CryptoAuthentication™数据手册

    电子发烧友网站提供《ECC608-TMNGTLS CryptoAuthentication™数据手册.pdf》资料免费下载
    发表于 01-22 15:46 0次下载
    <b class='flag-5'>ECC</b>608-TMNGTLS CryptoAuthentication™数据手册

    ECC206概要数据手册

    电子发烧友网站提供《ECC206概要数据手册.pdf》资料免费下载
    发表于 01-21 14:05 0次下载
    <b class='flag-5'>ECC</b>206概要数据手册