历史上的今天
返回首页

历史上的今天

今天是:2024年12月25日(星期三)

正在发生

2020年12月25日 | S3C6410使用---21yaffs2的ECC

2020-12-25 来源:eefocus

一. ECC校验


ECC: error Checking and correct,既能检查错误也能纠正错误.

优点是: 速度奇快

缺点是: 只能检查2bit的错误,只能纠正1bit的错误


如果想验证这儿需要打开 param . no_tags_ecc=0,默认 param . no_tags_ecc=1不进行tags校验.

同时,mkyaffs2image中也要把ECC校验信息加进去,这样才能从nand_flash中读出ECC进行比较.

nandmtd2_read_chunk_tags

        -->  yaffs_unpack_tags2

void yaffs_unpack_tags2(struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt, int tags_ecc)

{

    enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR;

    if (pt->t.seq_number != 0xffffffff && tags_ecc) {

        struct yaffs_ecc_other ecc;

        int result;

        yaffs_ecc_calc_other((unsigned char *)&pt->t, sizeof(struct yaffs_packed_tags2_tags_only), &ecc);

        result = yaffs_ecc_correct_other((unsigned char *)&pt->t,

                sizeof(struct yaffs_packed_tags2_tags_only), &pt->ecc, &ecc);

        switch (result) {

        case 0:

            ecc_result = YAFFS_ECC_RESULT_NO_ERROR;

            break;

        case 1:

            ecc_result = YAFFS_ECC_RESULT_FIXED;

            break;

        case -1:

            ecc_result = YAFFS_ECC_RESULT_UNFIXED;

            break;

        default:

            ecc_result = YAFFS_ECC_RESULT_UNKNOWN;

        }

    }

    yaffs_unpack_tags2_tags_only(t, &pt->t);


    t->ecc_result = ecc_result;            //保存校验后的结果, 调用它的函数是要检查的


    yaffs_dump_packed_tags2(pt);        //打印而己,不关心

    yaffs_dump_tags2(t);                //打印而己,不关心

}

这部分主要是校验yaffs_packed_tags2* pt中的结果, sizeof(yaffs_packed_tags2)=4*7=28

struct yaffs_packed_tags2_tags_only {

    unsigned seq_number;

    unsigned obj_id;

    unsigned chunk_id;

    unsigned n_bytes;

};

struct yaffs_ecc_other {

    unsigned char col_parity;

    unsigned line_parity;

    unsigned line_parity_prime;

};

struct yaffs_packed_tags2 {

    struct yaffs_packed_tags2_tags_only t;

    struct yaffs_ecc_other ecc;

};


注意: 这个校验只被 nandmtd2_read_chunk_tags所调用,因为 pt中的数据是存在nand flash的OOB区的,data区的数据在读取时己经被检验过了.

yaffs把OOB区前28个字节也拿来当数据使用了,所以这部分也需要校验.但是nand_flash只会对data区的数据进行校验,所以需要自己写代码来校验这OOB的28个字节


二.校验算法

2. 生成column_parity_table表

#include

#include

unsigned char entry(unsigned char x) 

    unsigned char b0, b1, b2, b3, b4, b5, b6, b7; 

    unsigned char p4, p2, p1, p4p, p2p, p1p; 

    unsigned char linep; 

    unsigned char result; 

      

    b0 = (x & 0x01) ? 1 : 0; 

    b1 = (x & 0x02) ? 1 : 0; 

    b2 = (x & 0x04) ? 1 : 0; 

    b3 = (x & 0x08) ? 1 : 0; 

    b4 = (x & 0x10) ? 1 : 0; 

    b5 = (x & 0x20) ? 1 : 0; 

    b6 = (x & 0x40) ? 1 : 0; 

    b7 = (x & 0x80) ? 1 : 0; 

      

    p4 = b7 ^ b6 ^ b5 ^ b4; p4p = b3 ^ b2 ^ b1 ^ b0; 

    p2 = b7 ^ b6 ^ b3 ^ b2; p2p = b5 ^ b4 ^ b1 ^ b0; 

    p1 = b7 ^ b5 ^ b3 ^ b1; p1p = b6 ^ b4 ^ b2 ^ b0; 

      

    linep = p1 ^ p1p; 

      

    result = 0; 

    if(p4) result |= 0x80; 

    if(p4p) result |= 0x40; 

    if(p2) result |= 0x20; 

    if(p2p) result |= 0x10; 

    if(p1) result |= 0x08; 

    if(p1p) result |= 0x04; 

    if(linep) result |= 0x01; 

      

    //result >>= 2; 

    //if(linep) result |= 0x40;       

    return result;       

}   

  

int main(int argc, char *argv[]) 

    unsigned i; 

      

    printf("const unsigned char column_parity_table[] = {"); 

    for(i = 0; i < 256; i++) 

    { 

        if((i & 0xf) == 0) printf("n"); 

        printf("0x%02x, ",entry((unsigned char) i)); 

    } 

    printf("n};n"); 

}




所以每一个result都是:

2.1校验步骤

     a. 通过yaffs_ecc_calc_other生成ECC, 称为new_ecc

     b. new_ecc与old_ecc进行异或,如果不一样,则说明出错

     c. 类似于二叉树,找到出错位,并进行校正

void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes, struct yaffs_ecc_other *ecc_other)  //生成新的ECC

{

    unsigned int i;

    unsigned char col_parity = 0;

    unsigned line_parity = 0;

    unsigned line_parity_prime = 0;

    unsigned char b;


    for (i = 0; i < n_bytes; i++) {

        b = column_parity_table[*data++];

        col_parity ^= b;

        if (b & 0x01) {

            /* odd number of bits in the byte */

            line_parity ^= i;

            line_parity_prime ^= ~i;

        }


    }


    ecc_other->col_parity = (col_parity >> 2) & 0x3f;

    ecc_other->line_parity = line_parity;

    ecc_other->line_parity_prime = line_parity_prime;

}


3. 

int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes,

             struct yaffs_ecc_other *read_ecc, const struct yaffs_ecc_other *test_ecc)     

{                                                                //与test_ecc比较如果不同则进行校正

    unsigned char delta_col; /* column parity delta */

    unsigned delta_line; /* line parity delta */

    unsigned delta_line_prime; /* line parity delta */

    unsigned bit;

    delta_col = read_ecc->col_parity ^ test_ecc->col_parity;

    delta_line = read_ecc->line_parity ^ test_ecc->line_parity;

    delta_line_prime = read_ecc->line_parity_prime ^ test_ecc->line_parity_prime;

    if ((delta_col | delta_line | delta_line_prime) == 0)

        return 0; /* no error */

    if (delta_line == ~delta_line_prime && (((delta_col ^ (delta_col >> 1)) & 0x15) == 0x15)) {

        bit = 0;                                                //bit <0-7>,代表哪一位出错

        if (delta_col & 0x20)                                   

            bit |= 0x04;

        if (delta_col & 0x08)

            bit |= 0x02;

        if (delta_col & 0x02)

            bit |= 0x01;

        if (delta_line >= n_bytes)

            return -1;

        data[delta_line] ^= (1 << bit);                            //找到出错的位了,把它反转                                

        return 1; /* corrected */

    }

    if ((hweight32(delta_line) + hweight32(delta_line_prime) + hweight8(delta_col)) == 1) {

        /* Reccoverable error in ecc */

        *read_ecc = *test_ecc;

        return 1; /* corrected */

    }

    /* Unrecoverable error */

    return -1;

}


推荐阅读

史海拾趣

Cables To Go公司的发展小趣事

在竞争激烈的电子行业中,优质的客户服务是赢得客户信任的关键。Cables To Go公司深知这一点,因此始终将客户服务放在首位。公司建立了一支专业的客服团队,随时为客户提供咨询、技术支持和售后服务。此外,公司还不断优化服务流程,提高服务效率,确保客户能够享受到及时、专业的服务。这种以客户为中心的服务理念赢得了客户的广泛赞誉。

Antiference公司的发展小趣事

近年来,随着物联网、5G等技术的快速发展,电子行业面临着巨大的变革。Antiference公司敏锐地捕捉到这一趋势,及时调整战略方向,将研发重点转向物联网设备的电磁兼容性研究。通过不断创新和优化产品,Antiference成功抓住了物联网发展的机遇,实现了业务的快速增长。

Analog Microelectronics GmbH公司的发展小趣事

随着技术的不断进步,Antiference公司开始将目光投向国际市场。公司积极参与国际电子展,展示其先进的电磁干扰抑制技术,并成功吸引了众多国外客户的关注。通过与国外知名企业的合作,Antiference的产品逐渐打入国际市场,品牌知名度也大幅提升。

CAROLCABLE公司的发展小趣事

CAROLCABLE公司的创立,标志着电子线缆行业迎来了一位新的竞争者。在电子科技飞速发展的时代背景下,创始人凭借对线缆技术的深刻理解和市场需求的敏锐洞察,决定创立CAROLCABLE公司。公司初期,面临着资金短缺、技术瓶颈和市场认知度低等多重挑战。然而,创始人凭借着坚定的信念和不懈的努力,带领团队克服了一个又一个困难。他们积极研发新产品,优化生产工艺,提高产品质量,逐渐在市场上站稳了脚跟。

随着公司业务的不断拓展,CAROLCABLE开始与一些知名的电子企业建立合作关系,为其提供高质量的线缆产品。这些合作不仅为公司带来了稳定的订单和收入,也进一步提升了CAROLCABLE在行业内的知名度和影响力。

Autotrol公司的发展小趣事

Autotrol公司成立于1964年,最初是一家领先的可定制小功率齿轮马达生产商。在初创时期,公司面临着激烈的市场竞争和技术挑战。然而,Autotrol凭借其卓越的技术实力和创新能力,成功开发出一系列具有竞争力的齿轮马达产品,逐渐在市场中脱颖而出。公司不断完善产品线,推出了永久磁铁同步电动机、滞后电动机和直流齿轮马达等,这些产品以其高效、稳定的性能赢得了客户的信赖。

Allied Electronic & Semiconductor Technology Inc公司的发展小趣事

近年来,电子行业正经历着深刻的变革,传统半导体市场逐渐饱和,新兴领域如物联网、人工智能等蓬勃发展。面对这一行业变革,AE&ST公司果断进行转型升级。公司调整战略方向,加大在新兴领域的研发投入,同时优化生产流程,降低成本。通过一系列的改革措施,AE&ST公司成功实现了从传统半导体制造商向新兴技术领域的转型。

问答坊 | AI 解惑

求助:冠林梯口机原程序

冠林梯口机原程序!!!!…

查看全部问答>

【FPGA设计实例】(7,4)线性分组码译码器

module decoder1(c,y,clk);output[6:0] c;input[6:0] y;input clk;reg[2:0] s;reg[6:0] e,c;always @(posedge clk) begins[0] = y[0] ^ y[3] ^ y[5] ^ y[6];s[1] = y[1] ^ y[3] ^ y[4] ^ y[5];s[2] = y[2] ^ y[4] ^ y[5] ^ y[6]; //s[0]~ s[2]为伴 ...…

查看全部问答>

步进电机到底是怎么转的?

一般控制步进电机的程序里都有一个“转动表格”之类的东西,比如{0xf1,0xe9,0xe5,0xe3}等等。本来我一直以为步进电机是一次接收一个数字所代表的信号,从第一个接收到第四个就是走一步,周而复始。 现在我编写了这样一个程序: void main() { & ...…

查看全部问答>

vxworks NAT的问题 .只要回复都给分...分不够再加...

版上的各位大侠,有人在vxworks5.4下做过NAT的东西没,能给小弟一点提示吗,现在这个东西已径把我折磨的半死了。 也可以把资料发到我的email中。zhouxiongjun@hotmail.com 谢谢啦。 …

查看全部问答>

wince 自动更新应用程序

请教大虾们如何实现如下功能: 平台:wince6.0 假如现在已经有一个应用程序myap.exe运行了。当我插入sd卡时(sk卡上有新版的myap.exe),点击更新程序按钮时,把sd卡新版本的myap.exe程序拷贝到旧版本的myap.exe处(把旧版的覆盖掉),然后自动运 ...…

查看全部问答>

各位大虾,请教一个内核移植的问题,

用的是linux的内核,ARM的CPU 我用make zImage编译好2.6.13的内核文件后,把/arch/arm/boot/zImage 文件烧进板子后,linux解压出错.错误信息如下:   VIVI version 0.1.4 (root@localhost.localdomain) (gcc version 2.95.2 20000516 (re ...…

查看全部问答>

debug调试中view----》terminalIO怎么用呢

                                  …

查看全部问答>

请教MSP430F149的谐波检测FFT的C语言程序

最近在用MSP430F149做一个谐波检测的功能,听说FFT能够实现,但是无从下手,希望高手们能够指教,或给出FFT程序,或给出学习的方法均可,谢谢大家能帮忙了~~~…

查看全部问答>

spi,的cs,我如果没用的话,是否可以当做一个io口使用

比如我只是用了SPI的三条线,clk,miso,mosi,那么我cs引脚是否可以单独作为一个io口来使用…

查看全部问答>

LPC1114是否可以做片内数据掉电存储?

看datasheet上好像没有片内eeprom,那是否可以做数据存储呢?还是要用其他方法实现呢?…

查看全部问答>