设为首页 加入收藏

TOP

u-boot-2011.06在基于s3c2440开发板的移植之硬件ECC(一)
2014-11-24 12:42:39 来源: 作者: 【 】 浏览:0
Tags:u-boot-2011.06 基于 s3c2440 开发 移植 硬件 ECC

NandFlash的每一页分为main区和spare区,S3C2440的NandFlash控制器支持这两个区的硬件ECC,但为了兼容u-boot-2011.06,我们只实现main区的硬件ECC。


为了实现硬件ECC,首先需要在include/configs/zhaocj2440.h文件内定义宏CONFIG_S3C2440_NAND_HWECC,这样在drivers/mtd/nand/s3c2440_nand.c文件内就定义了硬件ECC所需要的三个函数:s3c2440_nand_enable_hwecc函数、s3c2440_nand_calculate_ecc函数和s3c2440_nand_correct_data函数,而且在board_nand_init函数内,又把这三个函数分别赋给了相对应的结构体的三个成员,这样在进行NandFlash读写时,就会调用这三个函数,从而实现了硬件ECC。s3c2440_nand_enable_hwecc函数负责使能硬件ECC,s3c2440_nand_calculate_ecc函数负责计算ECC(当然这种计算是由硬件来完成的),s3c2440_nand_correct_data函数负责进行ECC的校验(同样地,这种校验也是由硬件自动完成的)。


相关阅读:


为了理解u-boot是如何进行硬件ECC的,我们先来简要地分析一下相关的函数。NandFlash是以页为最小单位进行读写操作的,支持硬件ECC的读操作最终是由nand_read_page_hwecc函数(在drivers/mtd/nand目录下)来完成的,支持硬件ECC的写操作最终是由nand_write_page_hwecc函数(在drivers/mtd/nand目录下)来完成的。nand_read_page_hwecc函数的流程为先读取main区数据,同时通过调用s3c2440_nand_calculate_ecc函数来得到硬件ECC;再读取spare区数据;然后提取出储存在spare区内的main区ECC;最后通过调用s3c2440_nand_correct_data函数来对刚刚读取的main区数据进行校验。nand_write_page_hwecc函数的流程比较简单,它先写入main区数据,同时通过调用s3c2440_nand_calculate_ecc函数来得到硬件ECC;然后就是把硬件ECC写入到spare区内。



无论是nand_write_page_hwecc函数,还是nand_write_page_hwecc函数,内部都有一个这样的for循环体:


for(i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {


}


其中三个主要变量的定义为:


eccsize= chip->ecc.size;


eccbytes= chip->ecc.bytes;


eccsteps= chip->ecc.steps;


下面我们就来介绍一下这个循环的作用:不同的CPU的NandFlash控制器一次所能完成的硬件ECC的字节数是不一样的,例如有些CPU一次只能完成512字节的硬件ECC,但如果开发板上的NandFlash每页有2048个字节,那该怎么办呢?这时就要用到一个循环体,通过循环多次来得到一页的硬件ECC。例如上面这种情况,就要循环4次(2048÷512=4),才能得到这个页内数据完整的硬件ECC。另外每一次硬件ECC,不同的CPU所生成的ECC字节数也是不同的,有的是3个字节,有的是4个字节。


那么,上面那三个变量的含义就分别为:


ecc.size:每一次硬件ECC所检验的字节个数


ecc.bytes:每一次硬件ECC所生成的字节个数


ecc.steps:每一页需要进行硬件ECC的次数


对于S3C2440来说,一次硬件ECC可以检验2048个字节,并且生成4个字节的ECC,因此ecc.size应该为2048,ecc.bytes应该为4。而ecc.steps是通过计算得到的,即系统上电后能够获知NandFlash的每页的大小,用这个值除以ecc.size就等于ecc.steps。所以对于这三个参数,只需事先定义好前两个参数即可。而这两个参数是在drivers/mtd/nand/s3c2440_nand.c文件中的board_nand_init函数内被定义赋值的,即:


nand->ecc.size = 2048;


nand->ecc.bytes = 4;



u-boot-2011.06对S3C2440的NandFlash控制器的寄存器定义得不完整,而且有错误,因此我们还需要对此进行修改。删除arch/arm/include/asm/arch-s3c24x0/s3c24x0.h文件内的第167行至第178行内容,添加进下面的内容:


struct s3c2440_nand {


u32 nfconf;


u32 nfcont;


u32 nfcmd;


u32 nfaddr;


u32 nfdata;


u32 nfmeccd0;


u32 nfmeccd1;


u32 nfseccd;


u32 nfstat;


u32 nfestat0;


u32 nfestat1;


u32 nfmecc0;


u32 nfmecc1;


u32 nfsecc;


u32 nfsblk;


u32 nfeblk;


};



最后,我们对s3c2440_nand_enable_hwecc函数、s3c2440_nand_calculate_ecc函数和s3c2440_nand_correct_data函数进行修改。



void s3c2440_nand_enable_hwecc(structmtd_info *mtd, int mode)


{


struct s3c2440_nand *nand = s3c2440_get_base_nand();


debugX(1,"s3c2440_nand_enable_hwecc(%p,%d)\n", mtd, mode);


writel(readl(&nand->nfcont)| S3C2440_NFCONT_INITECC& ~S3C2440_NFCONT_MECCL,&nand->nfcont);


}


该函数的任务就是初始化ECC(即复位ECC),并解锁main区ECC。



static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, constu_char *dat,


u_char *ecc_code)


{


struct s3c2440_nand *nand = s3c2440_get_base_nand();


u32 mecc0;



writel(readl(&nand->nfcont)| S3C2440_NFCONT_MECCL,&nand->nfcont);



mecc0= readl(&nand->nfmecc0);


ecc

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇u-boot-2011.06在基于s3c2440开发.. 下一篇u-boot-2011.06在基于s3c2440开发..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·常用meta整理 | 菜鸟 (2025-12-25 01:21:52)
·SQL HAVING 子句:深 (2025-12-25 01:21:47)
·SQL CREATE INDEX 语 (2025-12-25 01:21:45)
·Shell 传递参数 (2025-12-25 00:50:45)
·Linux echo 命令 - (2025-12-25 00:50:43)