⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecc.txt

📁 256B ecc(writed by c++)
💻 TXT
字号:
 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++)
	{
		if(reg3&a)
			temp1|=b;
		b>>=1;
		if(reg2&a)
			temp1|=b;
		b>>=1;
		a>>=1;
	}

	b=0x80;

	for(i=0;i<4;i++)
	{
		if(reg3&a)
			temp2|=b;
		b>>=1;
		if(reg2&a)
			temp2|=b;
		b>>=1;
		a>>=1;
	}
	
	//将最终的ECC存入数组ECCCode
	ECCCode[0]=temp1;//存放高8bit
	ECCCode[1]=temp2;//存放中间的8bit
}

void NandCalECC(const unsigned char *dat,unsigned char *ECCCode)
{
	unsigned char reg1,reg2,reg3,temp;
	int j;

	reg1=reg2=reg3=0;

	for(j=0;j<256;j++)
	{
		temp=ECCTable[dat[j]];
		reg1^=(temp&0x3f);

		if(temp&0x40)
		{
			reg3^=(unsigned char)j;
			reg2^=(~((unsigned char)j));
		}
	}

	NandTranResult(reg2,reg3,ECCCode);

	//计算最终的ECC码
	//此处为什么要做一个求非的操作呢??????
	ECCCode[0]=~ECCCode[0];
	ECCCode[1]=~ECCCode[1];
	
	ECCCode[2]=(((~reg1)<<2)|0x03);
}

/*
* 参数解释
* dat[]:实际读取的数据
* ReadECC[]:保存数据时根据原始数据产生的ECC码
* CalECC[]:读取数据的同时产生的ECC码
*/

int NandCorrectData(unsigned char *dat,unsigned char *ReadECC,unsigned char *CalECC)
{
	unsigned char a,b,c,bit,add,i,d1,d2,d3;

	//计算
	d1=ReadECC[0]^CalECC[0];
	d2=ReadECC[1]^CalECC[1];
	d3=ReadECC[2]^CalECC[2];

	//printf("d1=0x%0x,d2=0x%0x,d3=0x%0x\n",d1,d2,d3);

	if((d1|d2|d3) == 0)
	{
		//无错误发生
		printf("无错误发生\n");
		return 0;
	}
	else
	{
		a=((d1>>1)^d1)&0x55;
		b=((d2>>1)^d2)&0x55;
		c=((d3>>1)^d3)&0x54;

		//此处的理论依据是:如果发生了1bit的ECC错误,那么ECC异或地结果是--每个配对的bit数据相反,即为0&1或者1&0
		if((a == 0x55)&(b == 0x55)&(c == 0x54))
		{
			//可校正的1bit ECC错误
			
			//首先计算错误的Byte
			
			a=b=c=0x80;
			add=0;

			for(i=0;i<4;i++)
			{
				if(d1&a)
					add|=b;
				a>>=2;
				b>>=1;
			}
			
			for(i=0;i<4;i++)
			{
				if(d2&c)
					add|=b;
				c>>=2;
				b>>=1;
			}
			
			//计算发生错误的Bit
			bit=0;
			a=0x80;
			b=0x04;
			
		//	printf("d3 = 0x%0x\n",d3);

			for(i=0;i<3;i++)
			{
				if(d3&a)
				{
					bit|=b;
		//			printf("Detected!\n");
				}
				else
				{
					//printf("d3=0x%0x,a=0x%0x,d3&a=0x%0x\n",d3,a,d3&a);
		//			printf("Not Detected!\n");
				}
				a>>=2;
				b>>=1;
			}

			//进行数据纠正
		//	printf("开始进行数据纠正\n");
		//	printf("Error byte: %2d,Error bit: %2d\n",add,bit);
			b=0x01;
			b<<=bit;
			a=dat[add];
			a^=b;
			dat[add]=a;
			return 1;
		}
		else
		{
			i=0;
		//	printf("计算异或结果d1,d2,d3中1的个数\n");
			//计算异或结果d1,d2,d3中1的个数
			while(d1)
			{
				if(d1&0x01)
					i++;
				d1>>=1;
			}
			while(d2)
			{
				if(d2&0x01)
					i++;
				d3>>=1;
			}
			while(d3)
			{
				if(d3&0x01)
					i++;
				d3>>=1;
			}

			if(i == 1)
			{
				//发生了ECC错误,即存放ECC数据的区域发生了错误,正常的情况下,无论多少
				//bit发生了反转,都不会出现i=1的情况,出现了这种情况的原因只可能是ECC代码本身有问题
			//	printf("存放ECC数据的区域发生了错误\n");
				return 2;
			}
			else
			{
				//不可校正的ECC错误,即Uncorrectable Error
			//	printf("Uncorrectable Error\n");
				return -1;
			}

		}
	}
	return -1;
}

int main(int argc, char* argv[])
{
	int temp,i,j,k,l,m=0;
	unsigned char ReadECC[3]={0,0,0},CalECC[3]={0,0,0};

	NandCalECC(dat,CalECC);

	for(i=0;i<256;i++)
	{
		j=0x80;
		l=dat[i];
		for(k=0;k<8;k++)
		{
			m++;
	dat[i]^=j;
	j>>=1;
	NandCalECC(dat,ReadECC);
	
	temp=NandCorrectData(dat,ReadECC,CalECC);
	if(temp == 1)
	{
		if(dat[i]==l)
			printf("Success\n");			
		else
			printf("Failed\n");
	//	printf("可以校正的错误\n");
	//	printf("dat[0]=0x%0x\n",dat[0]);
	}
	else if(temp == -1)
	{
		//printf("不可以校正的错误");
	}
	else if(temp == 0)
	{
		//printf("无错误");
	}
	else
	{
	//	printf("数据区发生了错误");
	}
		//////////////////
			/*
	dat[5]=0x02;
	NandCalECC(dat,ReadECC);
	
	temp=NandCorrectData(dat,ReadECC,CalECC);
	if(temp == 1)
	{
		printf("可以校正的错误\n");
		printf("dat[0]=0x%0x\n",dat[0]);
	}
	else if(temp == -1)
	{
		printf("不可以校正的错误");
	}
	else if(temp == 0)
	{
		printf("无错误");
	}
	else
	{
		printf("数据区发生了错误");
	}
*/
	//////////////////////////
		}
	}
	printf("rotate times:%5d\n",m);
	return 0;
}

/**********************************************
* 如有疑问,欢迎联系guopeixin@126.com
***********************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -