共2条
1/1 1 跳转至页
nand,flash,ecc nand flash ecc校验
问
周工或者各路大侠,哪位有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: 我以前都是用写-读-比较的方式了事。
周工或者各路大侠,哪位有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 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【笔记】生成报错synthdesignERROR被打赏50分 | |
【STM32H7S78-DK评测】LTDC+DMA2D驱动RGBLCD屏幕被打赏50分 | |
【STM32H7S78-DK评测】Coremark基准测试被打赏50分 | |
【STM32H7S78-DK评测】浮点数计算性能测试被打赏50分 | |
【STM32H7S78-DK评测】Execute in place(XIP)模式学习笔记被打赏50分 | |
每周了解几个硬件知识+buckboost电路(五)被打赏10分 | |
【换取逻辑分析仪】RA8 PMU 模块功能寄存器功能说明被打赏20分 | |
野火启明6M5适配SPI被打赏20分 | |
NUCLEO-U083RC学习历程2-串口输出测试被打赏20分 | |
【笔记】STM32CUBEIDE的Noruletomaketarget编译问题被打赏50分 |