这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » nand,flash,ecc nand flash ecc校验

共2条 1/1 1 跳转至

nand,flash,ecc nand flash ecc校验

院士
2006-09-17 18:14:16     打赏
nand,flash,ecc nand flash ecc校验



关键词: flash     校验    

院士
2006-12-22 22:43:00     打赏
2楼

     周工或者各路大侠,哪位有nand flash ecc校验的算法? 先谢谢!! 1: yaffs就有 2: Ecc校验的修复有问题我对于ecc的理解是:
在写nand时,需要计算ecc校验码,并存入空闲区,这样页编程之后不必读出数据校验,
但是执行读操作后,需要再次计算ecc码,如果1位有错误,则可进行修复,不必替换了。但是在修复过程中必须更改1位。如将1 改为0,可以编程一次,如将0 改为1,nandflash怎么修改?一般是通过擦除操作。可能还是需要执行块的替换。
这地方小弟还不明白,大家怎么校验的? 3: 看一下yaffs关于ecc的源码就清楚了还是给你贴出来吧

CONST BYTE EccTable[] = {
0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
};

LONG EccCountBits(BYTE x)
{
    LONG r = 0;
    while(x)
    {
        if(x & 1) r++;
        x >>= 1;
    }
    return r;
}

/*********************************************************************************************************
** 函数名称: ECCCal
** 功能描述: 产生ecc效验
**
** 输 入: Data : 要效验的数据首地址
**         CurEcc : 存放ecc效验的首地址
**
** 输 出: 无
**         
** 全局变量: 无
** 调用模块: 无
**
** 日 期: 2006.1.20
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ECCCal(BYTE *Data,BYTE *CurEcc)
{
    LONG i;    
    BYTE col_parity = 0;
    BYTE line_parity = 0;
    BYTE line_parity_prime = 0;
    BYTE t;
    BYTE b;
    
    for(i = 0; i < 256; i++)
    {
        b = EccTable[*Data++];
        col_parity ^= b;

        if(b & 0x01)
        {
            line_parity ^= i;
            line_parity_prime ^= ~i;
        }
        
    }
    
    CurEcc[2] = (~col_parity) | 0x03;
    
    t = 0;
    if(line_parity       & 0x80) t |= 0x80;
    if(line_parity_prime & 0x80) t |= 0x40;
    if(line_parity       & 0x40) t |= 0x20;
    if(line_parity_prime & 0x40) t |= 0x10;
    if(line_parity       & 0x20) t |= 0x08;
    if(line_parity_prime & 0x20) t |= 0x04;
    if(line_parity       & 0x10) t |= 0x02;
    if(line_parity_prime & 0x10) t |= 0x01;
    CurEcc[1] = ~t;
    
    t = 0;
    if(line_parity       & 0x08) t |= 0x80;
    if(line_parity_prime & 0x08) t |= 0x40;
    if(line_parity       & 0x04) t |= 0x20;
    if(line_parity_prime & 0x04) t |= 0x10;
    if(line_parity       & 0x02) t |= 0x08;
    if(line_parity_prime & 0x02) t |= 0x04;
    if(line_parity       & 0x01) t |= 0x02;
    if(line_parity_prime & 0x01) t |= 0x01;
    CurEcc[0] = ~t;

    t = CurEcc[0];
    CurEcc[0] = CurEcc[1];
    CurEcc[1] = t;
}

/*********************************************************************************************************
** 函数名称: ECCChk
** 功能描述: ecc检测
**
** 输 入: Data : 检测的数据
**         OldEcc : 之前效验的ecc
**
** 输 出: ECC_OK : 正确
**         ECC_DATA_FIXED : 数据被修正
**         ECC_ECC_ERR :  之前效验的ecc是错误的
**         ECC_DATA_UNFIXED : 数据无法恢复
**         
** 全局变量: 无
** 调用模块: ECCCal, EccCountBits
**
** 日 期: 2006.1.20
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
BYTE ECCChk(BYTE *Data, BYTE *OldEcc)
{
    BYTE d0, d1, d2;
    BYTE NewEcc[3];

    ECCCal(Data,NewEcc);

    d0 = OldEcc[0] ^ NewEcc[0];
    d1 = OldEcc[1] ^ NewEcc[1];
    d2 = OldEcc[2] ^ NewEcc[2];
    
    if((d0 | d1 | d2) == 0)
    {
        return ECC_OK;
    }
    
    if( ((d0 ^ (d0 >> 1)) & 0x55) == 0x55 )
    if( ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 )
    if( ((d2 ^ (d2 >> 1)) & 0x54) == 0x54 )
    {        
        unsigned byte;
        unsigned bit;
        BYTE t;
        
        t = d0;
        d0 = d1;
        d1 = t;    
        bit = byte = 0;
                
        if(d1 & 0x80) byte |= 0x80;
        if(d1 & 0x20) byte |= 0x40;
        if(d1 & 0x08) byte |= 0x20;
        if(d1 & 0x02) byte |= 0x10;
        if(d0 & 0x80) byte |= 0x08;
        if(d0 & 0x20) byte |= 0x04;
        if(d0 & 0x08) byte |= 0x02;
        if(d0 & 0x02) byte |= 0x01;

        if(d2 & 0x80) bit |= 0x04;
        if(d2 & 0x20) bit |= 0x02;
        if(d2 & 0x08) bit |= 0x01;

        Data[byte] ^= (1 << bit);
        
        return ECC_DATA_FIXED;
    }
    
    if((EccCountBits(d0)+EccCountBits(d1)+EccCountBits(d2)) == 1)
    {        
        return ECC_ECC_ERR;    
    }
    else
    {    
        return ECC_DATA_UNFIXED;        
    }
}
4: thanks原来是在ram中修改,或是给出报错。谢谢 eleven11。 5: 三星的网站上有ecc校验的源码与方法 6: eleven11,谢谢你!我正在找ECC的资料! 7: 我以前都是用写-读-比较的方式了事。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]