裸奔程序7(二)-NAND芯片的读写及ECC检验软硬件实现
2011-01-15 09:23
344 查看
当我们要对NAND进行读写或复位擦除等操作时,其基本流程如下: 1. 允许片选信号NFCONT寄存器位[1]置0(低电平有效) 2. 传输命令 3. 传输地址 4. 等待操作结束,可以判断NFSTAT位[0]或位[2]为高电平表示操作结束,需注意的时,如果采用位[2]进行判断,我们在允许片选信号后,需向该位[2]写1清0,位[0]由硬件自动清除。 5. 发送命令70,读取操作状态是否成功。 6. 禁止片选信号 具体操作说明,每次操作都需要使能和禁止信号操作。 1. 复位,当我们初始化NAND寄存器后,一般需要复位一次 发送命令0xff 等待操作结束 2. 读取页数据 发送命令0x00 输入列地址(为0)及行地址(从位[11~27]) 发送命令0x30 等待操作结束 从寄存器NFDATA读取数据 3. 随机读取一页数据 发送命令0x00 输入列地址(为0)及行地址(从位[11~27]) 发送命令0x30 等待操作结束 发送命令0x05 传送列地址 发送命令0xe0 从寄存器NFDATA读取数据 个人认为,读取页数据时,是将一页数据都读取到其内部寄存器中,其内部指针为0,当发送随机读取命令和地址只是将其内部指针指向指定位置。读取NFDATA寄存时,其内部指针自动加1.经过程序调试发现,感觉其内部缓冲区大小为4K,也就是说,当我们从NFDATA寄存器读取数据时,读取4K数据后,其内部指针指向0,也就是可以从头再读取,同理,在随机读取数据时,0x05及0xe0命令只是将指针指向指定位置。因此我们可以修改页读取函数,将列地址指向我们需要指向的位置,就可以省两个命令。不过一直没搞明白,其缓冲区大小包括2K页数据和64个字节的SPACE区域,其它数据不知从哪来的。 4. 写页命令 发送命令0x80 传输列地址(为0)及行地址(位[11~27]) 传输数据 发送命令0x10 等待操作结束 5. 随机写命令 发送命令0x80 传输列地址(为0)及行地址(位[11~27]) 发送命令0x85 发送列地址 传输数据 发送命令0x10 等待操作结束 6. 块擦除命令 发送命令0x60 发送行地址(位[11~27]),不需传送列地址,同时,擦除是对整块(共64个页)进 行擦除,故位[11~16]表示块内某页,需清0 发送命令0xd0 由于NAND的物理特性,在写操作时,只能将位1反转为0,位0无法反转为位1,故在写操作前,必须保证该页已被擦除,即该页所有位均为1,如不为1,则写操作将不会得到正确的结果,如某页开始位存储如下 NAND 存储:30 04 二进制 0011 0000 0000 0100[位0无法反转写1] 该位 写值:df 4b 二进制 1101 1111 0100 1011 其值 结果:10 00 二进制 0001 0000 0000 0000[位0无法反转写1] 显然得到的10 00不是我们想要存储的字DF 4B。 体会:如果我们程序较大并用DWN下载到NAND中执行时,最好用命令9/2对NAND进行擦除操作,尽量不要有选用有坏块管理命令1,除非你读取程序中也有坏块管理,否则有可能得不到正确的结果,这是我反复测试后得到的体会。 第四节ECC检验 由于NAND的物理特性,不能完全保证数据的正确性,因此必须使用一定的算法对NAND读取的数据进行检验,ECC能纠正1个比特错误和检测2个比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。s3c2440内置了ECC错误检验算法,可硬件实现对数据的检验。 一、 Ecc算法概论 Flash在读写数据的时候是以页为单位进行的,一页有512/1024/2048个数据,所以可以以512/1024/2048 bit为单位生成校验码。每个数据有8位信息组成,可以把这512/1024/2 048个数据看成n×8的矩阵,这样就可以分别生成行校验码和列校验码来分别校验。 其生成校验码为:6位的列校验信息,2*n位行校验码,其中2^n=字节数,由于K9F2G08,一页数据为2048,故有22位行校验码,需校验数据增加一倍,行校验码只需增加2位 S3c2440ECC校验码组成 下载 (42.48 KB) 前天 21:02 其中P4,P41,P2,P21,P1,P11是列校验码,其余为行校验码。 当被校验的数据为512B时,只用到P1~P2048; 当被校验的数据为1024B时,用到了P1~P4096; 当被校验的数据为2048B时,则用到了P1~P8192; 在纠正时,根据P4_1,P2_1,P1_1组成一个字节,即为出错的位。将P8192_1,P4096_1,P2048_1,P1024_1,P512_1,P256_1...P8_1组成一个字,即为出错的字节. 知道哪个字节及哪一位出错后,就可以纠正了。 一、基本概念 在对2048个字节进行检验时,我们可以将其看成2048X8位的数组,如图: ECC检验码生成表 下载 (99.11 KB) 前天 21:02 列校验码生成规则: 对2048个字节的每一位都分别进行异或,得到D0~D7 举例如下: 对2048字节的第7位进行异或 D7=bit1(7)+bit2(7)+ bit3(7)+bit4(7)……bit2047(7)+bit2048(7) 对2048字节的第0位进行异或 D0=bit1(0)+bit2(0)+ bit3(0)+bit4(0)……bit2047(0)+bit2048(0) 得到D0~D7共8个校验码后,将这8个检验码进行分组 每一步,将其2平分进行异或 P4_1=d4+d5+d6+d7 p4_0=d0+d1+d2+d3 第二步,将其4平分后交差取值进行异或 P2_1=d2+d3+d6+d7 p2_0=d0+d1+d4+d5 第三步,将其8平分后交差取值进行异或 P1_1=d1+d3+d5+d7 p1_0=d0+d2+d4+d6 同理,对2048个字节的每一个字节的8位分别进行异或,得到E1~E2048 举例如下: 第一个字节的8位进行异或) E1=bit1(7)+bit1(6)+bit1(5) +bit1(4)+bit1(3) +bit1(2)+bit1(1)+bit1(0) 第2048个字节的8位进行异或 E2048=bit2048(7)+bit2048(6)+bit2048(5)+bit2048(4)+ Bit2048(3)+bit2048(2)+bit2048(1)+bit2048(0) 同理,对E1~E2048个校验码进行分组 将其进行2平分后交 P8912_1=E1024+E1025+……+E2047 P8912_0=E0 + E1…… +E1023 将其进行2048平分后交差取值进行异或 P8_1=E1+E3+E5+E7+E9 +E2047 P8_0=E0+E2+E6+E8+E10 +E2046 其它同理可得 二、算法实现 说明: 根据异或规则,对n个校验码进行异或时,改变其异或顺序,不影响其结果。 根据异或规则,当对0异或时,其值保持不变,对1异或时,其值改变,也就是说,当En=0时,不改变校验码Px_1或Px_0的值,在求行检验码时,我们就可以不用处理它。 由于校验码p8~p8192是对2048个校验码En进行分组交差异或所得,也就是说,当En=1是,将改变校验码Px_1或Px_0的值,2048字节将生成22个校验码,将改变11个行检验码的值,同理,将改变3个列校验码的值,也就是说,当2048个字节中有一位改变后,将导致14个校验码的值改变。 2.1.校验表的生成 由于我们对2048个字节进行校验,每个字节为8位,其值范围为0~255,由于异或顺序不影响异或结果,因此我们可以先生成这0~255每个值的列校验码,其格式如下:
Static Unsigned char Ecc_Table[256] void CreatEccTabe(unsigned char *Ecc_Table) { unsigned int i; unsigned char xData; for (i=0;i<256;i++) { xData=0; if(BIT1(i)^BIT3(i)^BIT5(i)^BIT7(i)){xData|=0x1;}//p1_1 if(BIT0(i)^BIT2(i)^BIT4(i)^BIT6(i)){xData|=0x2;}//p1_0 if(BIT2(i)^BIT3(i)^BIT6(i)^BIT7(i)){xData|=0x4;}//p2_1 if(BIT0(i)^BIT1(i)^BIT4(i)^BIT5(i)){xData|=0x8;}//p2_0 if(BIT4(i)^BIT5(i)^BIT6(i)^BIT7(i)){xData|=0x10;}//p4_1 if(BIT0(i)^BIT1(i)^BIT2(i)^BIT3(i)){xData|=0x20;}//p4_0 if(BIT0(i)^BIT1(i)^BIT2(i)^BIT3(i)^BIT4(i)^BIT5(i)^BIT6(i)^BIT7(i)) { xData|=0x40; } Ecc_Table=xData; } } 列校验码生成过程: 读取2048个字节,对每个字节查表Ecc_Table得到该字节的Ecc码,将其异或得所有列校验码 for(i=0;i<2048;i++) { j=pData; //得到要检验的数值 byte=Ecc_Table[j]; //查表得到ECC结果 list^=(byte&0x3f); //得到列检验码bit6位清零 } |
当我们要对NAND进行读写或复位擦除等操作时,其基本流程如下: 1. 允许片选信号NFCONT寄存器位[1]置0(低电平有效) 2. 传输命令 3. 传输地址 4. 等待操作结束,可以判断NFSTAT位[0]或位[2]为高电平表示操作结束,需注意的时,如果采用位[2]进行判断,我们在允许片选信号后,需向该位[2]写1清0,位[0]由硬件自动清除。 5. 发送命令70,读取操作状态是否成功。 6. 禁止片选信号 具体操作说明,每次操作都需要使能和禁止信号操作。 1. 复位,当我们初始化NAND寄存器后,一般需要复位一次 发送命令0xff 等待操作结束 2. 读取页数据 发送命令0x00 输入列地址(为0)及行地址(从位[11~27]) 发送命令0x30 等待操作结束 从寄存器NFDATA读取数据 3. 随机读取一页数据 发送命令0x00 输入列地址(为0)及行地址(从位[11~27]) 发送命令0x30 等待操作结束 发送命令0x05 传送列地址 发送命令0xe0 从寄存器NFDATA读取数据 个人认为,读取页数据时,是将一页数据都读取到其内部寄存器中,其内部指针为0,当发送随机读取命令和地址只是将其内部指针指向指定位置。读取NFDATA寄存时,其内部指针自动加1.经过程序调试发现,感觉其内部缓冲区大小为4K,也就是说,当我们从NFDATA寄存器读取数据时,读取4K数据后,其内部指针指向0,也就是可以从头再读取,同理,在随机读取数据时,0x05及0xe0命令只是将指针指向指定位置。因此我们可以修改页读取函数,将列地址指向我们需要指向的位置,就可以省两个命令。不过一直没搞明白,其缓冲区大小包括2K页数据和64个字节的SPACE区域,其它数据不知从哪来的。 4. 写页命令 发送命令0x80 传输列地址(为0)及行地址(位[11~27]) 传输数据 发送命令0x10 等待操作结束 5. 随机写命令 发送命令0x80 传输列地址(为0)及行地址(位[11~27]) 发送命令0x85 发送列地址 传输数据 发送命令0x10 等待操作结束 6. 块擦除命令 发送命令0x60 发送行地址(位[11~27]),不需传送列地址,同时,擦除是对整块(共64个页)进 行擦除,故位[11~16]表示块内某页,需清0 发送命令0xd0 由于NAND的物理特性,在写操作时,只能将位1反转为0,位0无法反转为位1,故在写操作前,必须保证该页已被擦除,即该页所有位均为1,如不为1,则写操作将不会得到正确的结果,如某页开始位存储如下 NAND 存储:30 04 二进制 0011 0000 0000 0100[位0无法反转写1] 该位 写值:df 4b 二进制 1101 1111 0100 1011 其值 结果:10 00 二进制 0001 0000 0000 0000[位0无法反转写1] 显然得到的10 00不是我们想要存储的字DF 4B。 体会:如果我们程序较大并用DWN下载到NAND中执行时,最好用命令9/2对NAND进行擦除操作,尽量不要有选用有坏块管理命令1,除非你读取程序中也有坏块管理,否则有可能得不到正确的结果,这是我反复测试后得到的体会。 第四节ECC检验 由于NAND的物理特性,不能完全保证数据的正确性,因此必须使用一定的算法对NAND读取的数据进行检验,ECC能纠正1个比特错误和检测2个比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。s3c2440内置了ECC错误检验算法,可硬件实现对数据的检验。 一、 Ecc算法概论 Flash在读写数据的时候是以页为单位进行的,一页有512/1024/2048个数据,所以可以以512/1024/2048 bit为单位生成校验码。每个数据有8位信息组成,可以把这512/1024/2 048个数据看成n×8的矩阵,这样就可以分别生成行校验码和列校验码来分别校验。 其生成校验码为:6位的列校验信息,2*n位行校验码,其中2^n=字节数,由于K9F2G08,一页数据为2048,故有22位行校验码,需校验数据增加一倍,行校验码只需增加2位 S3c2440ECC校验码组成 下载 (42.48 KB) 前天 21:02 其中P4,P41,P2,P21,P1,P11是列校验码,其余为行校验码。 当被校验的数据为512B时,只用到P1~P2048; 当被校验的数据为1024B时,用到了P1~P4096; 当被校验的数据为2048B时,则用到了P1~P8192; 在纠正时,根据P4_1,P2_1,P1_1组成一个字节,即为出错的位。将P8192_1,P4096_1,P2048_1,P1024_1,P512_1,P256_1...P8_1组成一个字,即为出错的字节. 知道哪个字节及哪一位出错后,就可以纠正了。 一、基本概念 在对2048个字节进行检验时,我们可以将其看成2048X8位的数组,如图: ECC检验码生成表 下载 (99.11 KB) 前天 21:02 列校验码生成规则: 对2048个字节的每一位都分别进行异或,得到D0~D7 举例如下: 对2048字节的第7位进行异或 D7=bit1(7)+bit2(7)+ bit3(7)+bit4(7)……bit2047(7)+bit2048(7) 对2048字节的第0位进行异或 D0=bit1(0)+bit2(0)+ bit3(0)+bit4(0)……bit2047(0)+bit2048(0) 得到D0~D7共8个校验码后,将这8个检验码进行分组 每一步,将其2平分进行异或 P4_1=d4+d5+d6+d7 p4_0=d0+d1+d2+d3 第二步,将其4平分后交差取值进行异或 P2_1=d2+d3+d6+d7 p2_0=d0+d1+d4+d5 第三步,将其8平分后交差取值进行异或 P1_1=d1+d3+d5+d7 p1_0=d0+d2+d4+d6 同理,对2048个字节的每一个字节的8位分别进行异或,得到E1~E2048 举例如下: 第一个字节的8位进行异或) E1=bit1(7)+bit1(6)+bit1(5) +bit1(4)+bit1(3) +bit1(2)+bit1(1)+bit1(0) 第2048个字节的8位进行异或 E2048=bit2048(7)+bit2048(6)+bit2048(5)+bit2048(4)+ Bit2048(3)+bit2048(2)+bit2048(1)+bit2048(0) 同理,对E1~E2048个校验码进行分组 将其进行2平分后交 P8912_1=E1024+E1025+……+E2047 P8912_0=E0 + E1…… +E1023 将其进行2048平分后交差取值进行异或 P8_1=E1+E3+E5+E7+E9 +E2047 P8_0=E0+E2+E6+E8+E10 +E2046 其它同理可得 二、算法实现 说明: 根据异或规则,对n个校验码进行异或时,改变其异或顺序,不影响其结果。 根据异或规则,当对0异或时,其值保持不变,对1异或时,其值改变,也就是说,当En=0时,不改变校验码Px_1或Px_0的值,在求行检验码时,我们就可以不用处理它。 由于校验码p8~p8192是对2048个校验码En进行分组交差异或所得,也就是说,当En=1是,将改变校验码Px_1或Px_0的值,2048字节将生成22个校验码,将改变11个行检验码的值,同理,将改变3个列校验码的值,也就是说,当2048个字节中有一位改变后,将导致14个校验码的值改变。 2.1.校验表的生成 由于我们对2048个字节进行校验,每个字节为8位,其值范围为0~255,由于异或顺序不影响异或结果,因此我们可以先生成这0~255每个值的列校验码,其格式如下:
Static Unsigned char Ecc_Table[256] void CreatEccTabe(unsigned char *Ecc_Table) { unsigned int i; unsigned char xData; for (i=0;i<256;i++) { xData=0; if(BIT1(i)^BIT3(i)^BIT5(i)^BIT7(i)){xData|=0x1;}//p1_1 if(BIT0(i)^BIT2(i)^BIT4(i)^BIT6(i)){xData|=0x2;}//p1_0 if(BIT2(i)^BIT3(i)^BIT6(i)^BIT7(i)){xData|=0x4;}//p2_1 if(BIT0(i)^BIT1(i)^BIT4(i)^BIT5(i)){xData|=0x8;}//p2_0 if(BIT4(i)^BIT5(i)^BIT6(i)^BIT7(i)){xData|=0x10;}//p4_1 if(BIT0(i)^BIT1(i)^BIT2(i)^BIT3(i)){xData|=0x20;}//p4_0 if(BIT0(i)^BIT1(i)^BIT2(i)^BIT3(i)^BIT4(i)^BIT5(i)^BIT6(i)^BIT7(i)) { xData|=0x40; } Ecc_Table=xData; } } 列校验码生成过程: 读取2048个字节,对每个字节查表Ecc_Table得到该字节的Ecc码,将其异或得所有列校验码 for(i=0;i<2048;i++) { j=pData; //得到要检验的数值 byte=Ecc_Table[j]; //查表得到ECC结果 list^=(byte&0x3f); //得到列检验码bit6位清零 } |
下载次数:0
前天 21:02
相关文章推荐
- 裸奔程序7(一)-NAND芯片的读写及ECC检验软硬件实现
- 裸奔程序7(三)-NAND芯片的读写及ECC检验软硬件实现
- 裸奔程序7(四)-NAND芯片的读写及ECC检验软硬件实现
- NAND芯片的读写及ECC检验软硬件实现
- 7.NAND芯片的读写及ECC检验软硬件实现_上
- VC读写注册表实现程序自启动的实现源代码
- 导入Excel和导出Excel:的简单方法与程序处理方法,使用Excel程序读写Excel ,实现Excel的多个 Sheets读写并导出
- C语言二进制文件读写程序实现(基础)
- 简单实现stm32f103芯片usb模拟U盘进行IAP更新用户程序
- matlab 实践程序3——实现读写.bin二进制文件(ciafr10图片的逆置)
- STM32通过读取芯片唯一ID号来实现程序的保护,防止被抄袭
- 使用java的java.nio.channels.FileLock,实现程序对文件的独占读写.
- C语言二进制文件读写程序实现(基础)
- 用VC++实现USB接口读写数据的程序
- VC读写注册表实现程序自启动的实现源代码
- 导入Excel和导出Excel的简单方法与程序处理方法,使用Excel程序读写Excel ,实现Excel的多个 Sheets读写并导出
- uboot下读写nand flash以及nand_read()函数的实现
- 实现Redis实例读写访问量采集统计程序知识点总结
- 用VC++实现USB接口读写数据的程序
- C#.net实现windows窗体程序对Excel文件的读写操作