ECC校验原理
ECC的全称是Error Checking and Correction,是一种用于Nand的差错检测和修正算法。如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出错。ECC能纠正1个bit错误和检测2个bit错误,而且计算速度很快,但对1bit以上的错误无法纠正,对2比特以上的错误不保证能检测。
ECC校验码生成算法:ECC校验每次对256字节的数据进行操作,包含列校验和行校验。对每个待校验的Bit位求异或,若结果为0,则表明含有偶数个1;若结果为1,则表明含有奇数个1。列校验规则如表所示。256字节数据形成256行、8列的矩阵,矩阵每个元素表示一个Bit位。
列校验如上图所示:
CP0 == 所有的 Bit0 ^ Bit2 ^ Bit4 ^ Bit6
CP1 == 所有的 Bit1 ^ Bit3 ^ Bit5 ^ Bit7
CP2 == 所有的 Bit0 ^ Bit1 ^ Bit4 ^ Bit5
CP3 == 所有的 Bit2 ^ Bit3 ^ Bit6 ^ Bit7
CP4 == 所有的 Bit0 ^ Bit1 ^ Bit2 ^ Bit3
CP5 == 所有的 Bit4 ^ Bit5 ^ Bit6 ^ Bit7
--> 每个列校验都是 1024 位异或的结果
--> 如果结果为1,说明有奇数个1位,结果如果为0,说明为偶数个1.
--> 列校验结果一共有上面6位
行校验如上图所示:
RP0 第0行以及每隔 1 行所有位的异或结果。
RP1 第1行以及每隔 1 行所有位的异或结果。
RP2,RP3 是间隔 2 行所有位的异或结果。
RP4,RP5 是间隔 4 行所有位的异或结果。
RP6,RP7 是间隔 8 行所有位的异或结果。
RP8,RP9 是间隔 16 行所有位的异或结果。
RP10,RP11 是间隔 32 行所有位的异或结果。
RP12,RP13 是间隔 64 行所有位的异或结果。
RP14,RP15 是间隔 128 行所有位的异或结果。
--> 这些结果都是8 * 128 = 1024 位的异或结果。
--> 如果结果为1,说明有奇数个1位,结果如果为0,说明为偶数个1.
--> 行校验一共有16位。
综上所示,8位宽的256字节数据生成6个bit的列校验数据,16个bit的行校验数据,总共22个bit,可得512字节的数据生成6个bit的列校验数据,18个行校验数据,总共24bit。同理,16位宽的256字节数据生成8个bit的列校验数据,14个bit的行校验数据,可得512字节的数据生成8个bit的列校验数据,16个bit的行校验数据。
ECC校验纠错
当往NAND Flash的page中写入数据的时候,每256字节我们生成一个ECC校验和,称之为原ECC校验和,保存起来。当从NAND Flash中读取数据的时候,每256字节我们生成一个ECC校验和,称之为新ECC校验和。将原ECC校验和与新ECC校验和按位异或,若结果为0,则表示不存在错误(或是出现了ECC无法检测的错误);若22个bit校验和结果中存在11个bit为1,表示存在一个bit数据错误,且可以纠正;若结果中只存在1个bit为1,表示出现了无法纠正的错误。因为每个字节中的每个bit至少会参加列校验总数(CP0…CPn)n/2次列校验计算和行校验总是(RP0…RPm)m/2次行校验校验。因此当256字节的数据校验和结果22个bit校验和结果中存在11个bit为1时,才会表示一个bit数据发送错误。
定位出错的bit位的方式为:先确定行地址(即哪个字节出错),再确定列地址(即该字节的哪一个bit位出错)。将原ECC校验和与新ECC校验和按位异或之后,得到新的“RP15,RP14…RP1,RP0,CP5,CP4…CP1,CP0”校验和结果。抽取RP15,RP13,RP11,RP9,RP7,RP5,RP3,RP1组成新的8bit数据,表示的值就是出错的字节的行地址(范围0~ 255)。抽取CP5,CP3,CP1组成新的3bit数据,表示的值就是出错的字节的列地址(范围0~ 7)。
如上图列地址为例:若CP5发生变化(异或后的CP5=1),则出错处肯定在 Bit 4 ~ Bit 7中;若CP5无变化(异或后的CP5=0),则出错处在 Bit 0 ~ Bit 3 中,这样就筛选掉了一半的Bit位。剩下的4个Bit位中,再看CP3是否发生变化,又选出2个Bit位。剩下的2Bit位中再看CP1是否发生变化,则最终可定位1个出错的Bit位。从异或结果中抽取CP5,CP3,CP1位,便可定位出错bit位的列地址。同理行校验抽取异或结果的RP15,RP13,RP11,RP9,RP7,RP5,RP3,RP1位便可定位出哪个Byte出错,再用CP