加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

U-boot-2014.04移植到MINI2440(8) nand flash 读写支持移植

发布时间:2020-12-15 07:20:49 所属栏目:百科 来源:网络整理
导读:上一篇帖子分析了nand flash,这篇帖子开始移植u-boot对nand flash的读写支持,进入正题。 ?????? 一 . 修改 mini2440.h ?????? 之前再初步移植的时候注释掉了nand的相关部分,这里再打开,在mini2440.h的第96行: ?????? #define CONFIG_CMD_NAND ?????? 既

上一篇帖子分析了nand flash,这篇帖子开始移植u-boot对nand flash的读写支持,进入正题。

??????

.修改mini2440.h

?????? 之前再初步移植的时候注释掉了nand的相关部分,这里再打开,在mini2440.h的第96行:

?????? #define CONFIG_CMD_NAND

?????? 既然打开了nand的配置,就需要在nand configuration里面做配置,在mini2440.h里面只有s3c2410的,这里需要进行添加,在第187行,红色字体为添加进去的部分:

/*

?*NAND configuration

?*/

#ifdef CONFIG_CMD_NAND

#ifdef CONFIG_S3C2440

#define CONFIG_NAND_S3C2440

#defineCONFIG_SYS_S3C2440_NAND_HWECC

#else

#define CONFIG_NAND_S3C2410

#define CONFIG_SYS_S3C2410_NAND_HWECC

#endif

#define CONFIG_SYS_MAX_NAND_DEVICE?? 1

#define CONFIG_SYS_NAND_BASE??????????? 0x4E000000

#endif

??????

?????? .拷贝s3c2410_nand.cs3c2440_nand.c

?????? 由于支持了2410的nand的读写,所以只需要以其为蓝本,将其拷贝再做修改就可以了。这里进入目录:/drivers/mtd/nand/下,执行

cp s3c2410_nand.c s3c2440_nand.c.

然后使用vim打开s3c2440_nand.c,这里面配置都是2410的,我们执行命令:

:%s/2410/2440

这样会将该文件下的所有2410替换成2440,关于vim字符替换的命令格式可以自行网上查阅。

??????

?????? .修改/drivers/mtd/nand/Makefile

?????? 第55行:

obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o

?????? 是说如果定义了CONFIG_NAND_S3C2410那么久将s3c2410_nand编译进去,这里我们在下面一行添加2440的:

?????? obj-$(CONFIG_NAND_S3C2440) +=s3c2440_nand.o

?

?????? .修改drivers/mtd/nand/s3c2440_nand.c

?????? 因为我们只是把2410的蓝本拷贝过来,现在要根据2440和具体的nand型号做修改,这里首先修改的是时序,第19行:

#define S3C2440_NFCONF_TACLS(x)??? ((x)<<8)

#define S3C2440_NFCONF_TWRPH0(x)?? ((x)<<4)

#define S3C2440_NFCONF_TWRPH1(x)?? ((x)<<0)

?????? 这里的三个参数TACLS,TWRPH0,TWRPH1是在读写nand的时候需要配置的三个时序参数,这里可以对照s3c2440和nand的datasheet,对照网上别人的分析总结如下:

TACLS:CLE/ALE有效到nWE有效之间的持续时间。

TWRPH0:CLE/ALE的持续时间。

?????? TWRPH1:表示CLE/ALE的维持时间(hold?time)。

?????? 同时看到s3c2440的datasheet的NFCONF寄存器有关位如下:

?????? 上图中给出了三个值的取值范围,对应寄存器的位,12,8,4以及持续时间的计算方法,HCLK一般是100MHZ,所以我们需要进行修改:

?????? #define S3C2440_NFCONF_TACLS(x)??? ((x)<<12)

#define S3C2440_NFCONF_TWRPH0(x)?? ((x)<<8)

#define S3C2440_NFCONF_TWRPH1(x)?? ((x)<<4)

?????? 下面第123行:

#ifdefined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)

?????? tacls? = CONFIG_S3C24XX_TACLS;

?????? twrph0= CONFIG_S3C24XX_TWRPH0;

?????? twrph1=? CONFIG_S3C24XX_TWRPH1;

#else

?????? tacls= 4;

?????? twrph0= 8;

?????? twrph1= 8;

#endif

?????? 这里我们没有定义CONFIG_S3C24XX_CUSTOM_NAND_TIMING,所以会执行下面的参数,这三个参数等于多少,网上有很多,我没有一一去试过,这里暂且用一组0.1,1,修改如下:

?????? #ifdefined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)

?????? tacls?= CONFIG_S3C24XX_TACLS;

?????? twrph0 = CONFIG_S3C24XX_TWRPH0;

?????? twrph1 =?CONFIG_S3C24XX_TWRPH1;

#else

?????? tacls= 0;

?????? twrph0= 1;

?????? twrph1= 0;

#endif

?????? 在下面第133行:

?????? cfg = S3C2440_NFCONF_EN;

?????? cfg |= S3C2440_NFCONF_TACLS(tacls - 1);

?????? cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);

?????? cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);

?????? writel(cfg,&nand_reg->nfconf);

?????? 我们将这部分修改如下:

?????? //cfg =S3C2440_NFCONF_EN;

?????? cfg |= S3C2440_NFCONF_TACLS(tacls);

?????? cfg |= S3C2440_NFCONF_TWRPH0(twrph0);

?????? cfg |= S3C2440_NFCONF_TWRPH1(twrph1);

?????? writel(cfg,&nand_reg->nfconf);

?????? writel((1<<4)|(1<<1)|(1<<0),&nand_reg->nfcont);

?????? 这部分cfg这一段后面的第一个writel主要是将刚才设置的tacls,twrph0,twrph1赋给了NFCONF,这里&nand_reg指的是代表nand flash寄存器的结构体, writel使用方法复习下就是往内存映射的I/O空间上写数据:

?????? void?writel?(unsigned?char?data?,?unsigned?short?addr?)。

下面一个writel这里的(1<<4)|(1<<1)|(1<<0)意思是往nandflash的NFCONT寄存器的第0,1,4位分别置一,这里查看datasheet:

也就是初始化了ECC,禁止片选,以及使能了NandFlash控制器。

??????

接着,修改s3c2440_hwcontrol函数,第48行:

?????? if (ctrl & NAND_CTRL_CHANGE) {

????????????? ulong IO_ADDR_W = (ulong)nand;

?

????????????? if (!(ctrl & NAND_CLE))

???????????????????? IO_ADDR_W |=S3C2440_ADDR_NCLE;

????????????? if (!(ctrl & NAND_ALE))

???????????????????? IO_ADDR_W |=S3C2440_ADDR_NALE;

/*判断是命令还是地址,从而决定IO_ADDR_W的指向。*/

????????????? if(cmd==NAND_CMD_NONE)

???????????????????? {

??????????????????????????? IO_ADDR_W=&nand->nfdata;

??????????????????????????? }

?

????????????? chip->IO_ADDR_W = (void*)IO_ADDR_W;

?

????????????? if (ctrl & NAND_NCE)

???????????????????? writel(readl(&nand->nfcont)& ~(1<<1),

???????????????????? ?????? &nand->nfcont);

????????????? else

???????????????????? writel(readl(&nand->nfcont)| (1<<1),

???????????????????? ?????? &nand->nfcont);???????????????? //控制片选

?????? }

?????? 修改部分已经用红色字体标注出来了,以上修改还是因为2410和2440的寄存器不同,并且他们的偏移也不一样。

????????????? if(cmd==NAND_CMD_NONE)

???????????????????? {

??????????????????????????? IO_ADDR_W=&nand->nfdata;

???????????????????? }

?????? 这部分代码主要是针对后面我们使用nand write写入数据失败的问题,具体是由于我们上一次是写的命令寄存器,但是下一次直接写数据,但是我们的IO_ADDR_W 还是指向的命令寄存器,所以这里如果判断我们写入的不是命令,就直接指向我们的数据寄存器NFDATA,这样我们就可以成功的使用nandwrite命令了。s3c2440_hwcontrol这个函数主要是命令控制函数,下面还是针对偏移不同做出的修改,在第23行:

?????? #define S3C2440_ADDR_NALE 4

#define S3C2440_ADDR_NCLE 8

?????? 修改成如下:

?????? #define S3C2440_ADDR_NALE 8

#define S3C2440_ADDR_NCLE 12

#define S3C2440_NFCONF_nFCE (1<<1)

?????? 同时注释掉第18行://#define S3C2440_NFCONF_nFCE??????? (1<<11)

到这里我们的s3c2440_nand.c文件修改结束。

?

?????? .修改drivers/mtd/nand/nand_base.c

?????? 在第207行,在nand_select_chip函数里面,修改第207行,如下:

?????? ?????? case0:

????????????? chip->cmd_ctrl(mtd,NAND_CMD_NONE,NAND_CTRL_CLE| NAND_CTRL_CHANGE);

????????????? break;

??????

?????? .编译测试

?????? make distclen

?????? makemini2440_config

?????? make

?????? 对生成的u-boot.bin,chmod 777 u-boot.bin

?????? 拷贝到tftp目录下cp u-boot.bin /tftpboot

?????? 从nor flash启动开发板,执行:

tftp 0x30008000 u-boot.bin

?????? go 0x30008000

?????? 出现以下信息:

U-Boot 2014.04 (Sep 02 2015 - 08:47:58)

?

CPUID: 32440001

FCLK:?????400 MHz

HCLK:?????100 MHz

PCLK:??????50 MHz

DRAM:?64 MiB

WARNING: Caches not enabled

Flash: 2 MiB

NAND:? 256 MiB

*** Warning - bad CRC,using defaultenvironment

?

In:???serial

Out:??serial

Err:??serial

Net:??dm9000

MINI2440 Deep_l_zh #

?????? 可以看到红色字体说明已经识别到了我们的nand,下面对读写进行测试:

?????? MINI2440 Deep_l_zh # nand write0x30008000 0 0xff

NAND write: device 0 offset 0x0,size 0xff

255 bytes written: OK

?????? 这暂时说明读是没有问题的,接下来往里面写:

?????? MINI2440 Deep_l_zh # nand read 0x320000000 0xff

NAND read: device 0 offset 0x0,size 0xff

NAND read from offset 0 failed -74

????? 0bytes read: ERROR

?????? 出现错误了。。。

?

?????? .nand read错误解决办法

?????? 网上查找资料说是根据校验码-74,是ecc校验的问题,具体修改方法比较复杂,这里我修改了一下时序参数。

tacls = 3;

?????? twrph0 = 3;

?????? twrph1 = 2;

?????? 然后在读写之前进行nand erase操作,这个很重要,可以读出如下信息:

?????? MINI2440 Deep_l_zh # nand read 0x300080000 0xff

?

NAND read: device 0 offset 0x0,size 0xff

????? 255bytes read: OK

?????? 可以看出来是读出来了,接着进行读写数据对比测试:

?????? MINI2440 Deep_l_zh # nand write 0x30008000 0 0xff

NAND write: device 0 offset 0x0,size 0xff

?255 bytes written: OK

MINI2440 Deep_l_zh # nand read 0x32000000 0 0xff

NAND read: device 0 offset 0x0,size 0xff

?255 bytes read: OK

MINI2440 Deep_l_zh # cmp.b 0x30008000 0x32000000 0xff

Total of 255 byte(s) were thesame

?????? 完全一样,说明我们读写都成功了。至此,nand flash读写移植结束,如有不正确的地方,还请指出,大家共同进步。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读