ECC的代码实现
数据校验介绍:
通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值。接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是完整的。
如果是时序或者电路方面有什么问题的话,错误数据的发生是无法通过数据校验来进行弥补的,而对于受外界干扰而产生的位翻转错误,则可以一定程度上通过HW或者SW的数据校验来进行数据的检测和纠正。
常用的数据校验算法有CRC校验和ECC校验等,它们的基本原理很相似。
ECC介绍:
ECC(错误检查和纠正),这种技术也是在原来的数据位上外加校验位来实现的,具体的原理不再描述,大致的描述可以参照:http://blog.csdn.net/nhczp/archive/2007/07/20/1700031.aspx.
它有一个规律:数据位每增加一倍,ECC只增加一位检验位,也就是说当数据位为16位时ECC位为6位,32位时ECC位为7位,数据位为64位时ECC位为8位,依此类推,数据位每增加一倍,ECC位只增加一位。
附件说明:
附件1:256字节ECC校正1比特错误代码实现
附件2:512字节ECC校正1比特错误代码实现
/*************************************************************************************************************/
附件1:256字节ECC校正1比特错误代码实现
// 256ByteECC071123.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
//071126
unsigned char dat[]={
0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0xf ,0x5a ,0x5a ,0xf ,0xc ,0x59 ,0x3 ,0x56 ,0x55 ,0x0 ,
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 ,
0x3 ,0x56 ,0x55 ,0x0 ,0x5a ,0xf ,0xc ,0x59 ,0x59 ,0xc ,0xf ,0x5a ,0x0 ,0x55 ,0x56 ,0x3 ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0xc ,0x59 ,0x5a ,0xf ,0x55 ,0x0 ,0x3 ,0x56 ,0x56 ,0x3 ,0x0 ,0x55 ,0xf ,0x5a ,0x59 ,0xc ,
0xf ,0x5a ,0x59 ,0xc ,0x56 ,0x3 ,0x0 ,0x55 ,0x55 ,0x0 ,0x3 ,0x56 ,0xc ,0x59 ,0x5a ,0xf ,
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 ,
0xf ,0x5a ,0x59 ,0xc ,0x56 ,0x3 ,0x0 ,0x55 ,0x55 ,0x0 ,0x3 ,0x56 ,0xc ,0x59 ,0x5a ,0xf ,
0xc ,0x59 ,0x5a ,0xf ,0x55 ,0x0 ,0x3 ,0x56 ,0x56 ,0x3 ,0x0 ,0x55 ,0xf ,0x5a ,0x59 ,0xc ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0x3 ,0x56 ,0x55 ,0x0 ,0x5a ,0xf ,0xc ,0x59 ,0x59 ,0xc ,0xf ,0x5a ,0x0 ,0x55 ,0x56 ,0x3 ,
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 ,
0x0 ,0x55 ,0x56 ,0x3 ,0x59 ,0xc ,0xf ,0x5a ,0x5a ,0xf ,0xc ,0x59 ,0x3 ,0x56 ,0x55 ,0x0
};
//071123
unsigned char ECCTable[]={
0x0 ,0x55 ,0x56 ,0x3 ,0x59 ,0xc ,0xf ,0x5a ,0x5a ,0xf ,0xc ,0x59 ,0x3 ,0x56 ,0x55 ,0x0 ,
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 ,
0x3 ,0x56 ,0x55 ,0x0 ,0x5a ,0xf ,0xc ,0x59 ,0x59 ,0xc ,0xf ,0x5a ,0x0 ,0x55 ,0x56 ,0x3 ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0xc ,0x59 ,0x5a ,0xf ,0x55 ,0x0 ,0x3 ,0x56 ,0x56 ,0x3 ,0x0 ,0x55 ,0xf ,0x5a ,0x59 ,0xc ,
0xf ,0x5a ,0x59 ,0xc ,0x56 ,0x3 ,0x0 ,0x55 ,0x55 ,0x0 ,0x3 ,0x56 ,0xc ,0x59 ,0x5a ,0xf ,
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 ,
0xf ,0x5a ,0x59 ,0xc ,0x56 ,0x3 ,0x0 ,0x55 ,0x55 ,0x0 ,0x3 ,0x56 ,0xc ,0x59 ,0x5a ,0xf ,
0xc ,0x59 ,0x5a ,0xf ,0x55 ,0x0 ,0x3 ,0x56 ,0x56 ,0x3 ,0x0 ,0x55 ,0xf ,0x5a ,0x59 ,0xc ,
0x69 ,0x3c ,0x3f ,0x6a ,0x30 ,0x65 ,0x66 ,0x33 ,0x33 ,0x66 ,0x65 ,0x30 ,0x6a ,0x3f ,0x3c ,0x69 ,
0x3 ,0x56 ,0x55 ,0x0 ,0x5a ,0xf ,0xc ,0x59 ,0x59 ,0xc ,0xf ,0x5a ,0x0 ,0x55 ,0x56 ,0x3 ,
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 ,
0x0 ,0x55 ,0x56 ,0x3 ,0x59 ,0xc ,0xf ,0x5a ,0x5a ,0xf ,0xc ,0x59 ,0x3 ,0x56 ,0x55 ,0x0
};
//计算ECC代码
void NandTranResult(unsigned char reg2,unsigned char reg3,unsigned char *ECCCode)
{
unsigned char temp1,temp2,i,a,b;
temp1=temp2=0;
a=b=0x80;
for(i=0;i<4;i+&#