关于MLC的4bit ECC/EDC算法,能否进来指点下

zhangcf   2008-3-14 10:02 楼主
由于硬件不支持MLC的4bit ECC/EDC
所以需要软件来实现

兄弟们觉得这个可行性如何?
软件实现的话,性能要打多大的折扣?

关于MLC用到的4bit ECC/EDC 的算法,兄弟们能给个资料或者什么的吗?
贴个链接也行  

感谢

回复评论 (24)

其实这部分是每一个厂商比较核心的地方。
并且软体去check bit error是非常耗时的,也不现实的。
曾经试验过,速度极其慢。。。。。。
我之前开发的IC也没有支援4bit ecc检验。仅仅有256byte 1bit ecc。
后来使用的IC支援512byte 8bit ECC检验(叫做BCH),MLC的速度依然不是很快。。
点赞  2008-3-14 17:11
不容易,找到一个和我一样写Device驱动的。。交个朋友吧。。呵呵
开发Nand Flash也有2年多了,从底层到管理层。。
做nand driver确实很痛苦。。
点赞  2008-3-14 17:12
qq 112027289
点赞  2008-3-14 17:18
呵呵,谢谢nancyk2h兄指点

看来nancyk2h兄做的比我更底层啊,
我目前的水平也就是在厂家提供的BSP上做做修改而已,惭愧惭愧

我现在连那个SLC上的1bit ECC\EDC都还没咋看明白,这两天困惑呀
点赞  2008-3-14 17:27
SLC的ECC算法就是一个行列的累加计算。这个网络上都有现成的算法分析和代码。
厂家?IC厂家!呵呵我是做IC技术支持的。。
点赞  2008-3-14 17:32

SLC的那算法我是看明白了的
就是下面这段代码里面有部分没看明白

下面是代码,原帖地址在http://blog.2@1ic.com/user1/3633/33493.html#

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 < 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 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 < 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 reg2 怎么的就跟j来运算出来就是行累加啊 /* // 下面的注释里面的值是我根据nand_trans_result函数倒推出来的 BIT7 BIT7 BIT7 BIT7 BIT7 BIT7 BIT7 BIT7 reg2 !P64’ !P32’ !P16’ !P8’ !P1024’ !P512’ !P256’ !P128’ reg3 !P64 !P32 !P16 !P8 !P1024 !P512 !P256 !P128 */ ????????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 block ??int 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;
??}

 

点赞  2008-3-15 10:03
nancyk2h兄
你们做哪方面IC的呀
点赞  2008-3-15 10:04
我做的是消费类电子的IC,主要是手机,mp3,电子字典等.
点赞  2008-3-15 13:49
呵呵 那说不定我们也在用你们的产品呢
点赞  2008-3-17 09:47
哪家的IC?
点赞  2008-3-17 10:09
三星 掌微 凌阳 安凯
点赞  2008-3-18 09:58
晕。。。我是凌阳的工程师。。。
点赞  2008-3-18 11:25
呵呵 北京?深圳?
以前用凌阳的作过一款学习机 不过那时俺才刚毕业 还做应用的
点赞  2008-3-18 16:34
学习机? 哈哈!用的是16位的IC吧!162001 GPL162002 GPL162003??
很可能你是我的客户哦!我在北京。但是马上要去深圳出差。。
点赞  2008-3-18 17:11
记不得啦 都是一年前做的了 再说那会我还做应用 对硬件不关心呢

请教nancyk2h
nand 的管理驱动里面 实现磨损均衡怎么个实现原理?
点赞  2008-3-19 14:59
写平均是吗?可以实现.创建于一个动态的管理表(好块表),并且做一个空闲链表.
当你写一个blk,就从空闲链表中取出,写入该blk中,并且在c area标记擦写的次数.
并将动态管理表的物理地址和逻辑地址进行更新.标记你刚刚写入的blk和逻辑的对应,将之前对应的物理blk
回收到空闲表中....
点赞  2008-3-19 21:54
绝对的写平均是做不到的,只能是相对的,主要思想是减少擦除次数
点赞  2008-3-19 21:55
我目前用Sniper167贴的算法,但是发现有问题,如下:


  1. /* Found and will correct single bit error in the data */
  2. if ((a == 0x55) && (b == 0x55) && (c == 0x54))
  3. {
  4.      // ...
  5. ???return 1; // 返回1表示纠错成功,但实际上的写入和读取的数据差异相当大,
  6.                  // 纠正一位根本就没有任何效果
  7. }


(测试所用的数据以及计算得到的ECC校验)

写入的数据(256字节):
79 83 BB 48 24 00 00 00 00 00 00 00 00 A8 C3 C2
D4 AA BE 15 43 DC 74 82 B6 6D 5B BD 8D B9 96 6B
DB 96 6D E3 D8 71 25 37 6F DB 36 6A 9D A7 E5 62
A7 DD DB B6 7D B8 36 7E DA 27 6E 5B A0 05 8F 00
20 00 00 00 00 00 00 50 6D 34 AE 58 BD 5D A8 70
BF B7 58 8B D0 27 0D 3B 24 EF 48 F4 44 70 2D D7
3E 5C FB 70 6D FB B4 AD D3 B6 71 DC B6 DC D3 B6
31 67 E2 37 38 B4 74 8B AA 11 84 10 01 80 00 00
08 E1 35 02 6B A0 EA 96 2E A4 52 85 3F A9 EE A9
C0 CF D5 D8 C5 56 58 C3 EB FE 94 5C DA 6D 4F B6
F6 03 7A A7 73 F7 69 39 87 0B DA F8 A7 1F EE 28
FD D6 5D 43 08 21 02 00 01 00 10 C2 DF A4 3E 34
F5 ED FD E4 3E 91 BF 66 6B DF C9 47 47 22 BF F2
93 30 FB 76 CB 1D 5C EB 70 41 C3 2F 9D 82 B5 12
17 C7 8F D3 C6 6D 83 3F CC 66 B6 2D CC 88 10 63
08 00 44 00 21 84 46 25 AB A5 EB DB F7 62 FB 6D

写入计算得到的3字节ECC校验:65 66 AB

读出的数据(256字节):
69 03 22 08 24 00 00 00 00 00 00 00 00 28 01 00
00 00 2C 14 03 58 74 02 20 6D 5A A8 80 A9 80 63
D3 86 49 82 90 10 01 32 6D 9A 06 00 00 02 40 60
20 1D 58 12 64 10 16 3A 10 02 0A 1A 00 01 03 00
00 00 00 00 00 00 00 10 28 34 22 00 04 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00
00 41 25 02 61 20 62 12 2A 20 52 05 3F 28 6C 29
40 43 54 50 41 14 08 80 C0 EC 80 5C DA 6D 45 A4
E2 02 7A A7 73 F7 69 38 87 0B DA F0 A7 1F EE 28
FD C2 4C 00 08 21 02 00 01 00 10 80 90 A4 20 34
C1 CD E8 C4 3C 91 AB 42 40 C2 C1 44 43 22 BA A0
12 10 82 16 89 04 10 60 60 41 41 21 1C 00 31 00
00 80 06 50 46 61 82 03 80 60 96 20 8C 80 10 02
00 00 40 00 21 84 04 21 21 20 48 4A 72 60 8B 09

读入的256字节计算得到的3字节ECC校验:3C F3 0F
点赞  2008-3-24 11:32
更正上面贴的读出的数据为:
读出的数据(256字节):
69 03 22 08 24 00 00 00 00 00 00 00 00 28 01 00  
00 00 2C 14 03 58 74 02 20 6D 5A A8 80 A9 80 63  
D3 86 49 82 90 10 01 32 2D 9A 06 00 00 02 40 60  
20 1D 58 12 64 10 16 3A 10 02 0A 1A 00 01 03 00  
00 00 00 00 00 00 00 10 28 34 22 00 04 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00  
00 41 25 02 61 20 62 12 2A 20 52 05 3F 28 6C 29  
40 43 54 50 41 14 08 80 C0 EC 80 5C DA 6D 45 A4  
E2 02 7A A7 73 F7 69 38 87 0B DA F0 A7 1F EE 28  
FD C2 4C 00 08 21 02 00 01 00 10 80 90 A4 20 34  
C1 CD E8 C4 3C 91 AB 42 40 C2 C1 44 43 22 BA A0  
12 10 82 16 89 04 10 60 60 41 41 21 1C 00 31 00  
00 80 06 50 46 61 82 03 80 60 96 20 8C 80 10 02  
00 00 40 00 21 84 04 21 21 20 48 4A 72 60 8B 09  
点赞  2008-3-24 14:43
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复