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

NandFlash操作详解(三)

发布时间:2020-12-15 20:08:28 所属栏目:百科 来源:网络整理
导读:代码正确性验证: ???????? 验证代码的正确性可以使用先写入特定字符,然后在读出来的方法验证。 实验板:MINI2440 256M 首先下载一个可用的u-boot到NorFlash中,用于查看NandFlash中的数据。 然后以NorFlash启动进入u-boot,使用tftp工具或者其他工具把测试

代码正确性验证:

???????? 验证代码的正确性可以使用先写入特定字符,然后在读出来的方法验证。

实验板:MINI2440 256M

首先下载一个可用的u-boot到NorFlash中,用于查看NandFlash中的数据。

然后以NorFlash启动进入u-boot,使用tftp工具或者其他工具把测试程序下载到NandFlash的0地址。以NandFlash启动查看测试结果。

?

测试文件main.c: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

int xboot_main()

{

???????? int num = 0;

???????? int a = 1;

???????? int b = 2;

???????? char buf[2048] = {"hello NandFlash"};

???????? char buf2[2048] = {};

???????? uart_init();

?

???????? printf("start nandflash read/writenr");

?

???????? NF_Erase(0x32345);

???????? NF_WritePage(0x32345,buf);

???????? NF_PageRead(0x32345,buf2);????????

???????? printf("nn%snr",buf2);

?

???????? while(1)

???????? {

?????????????????? printf("n***************************************nr");

?????????????????? printf("n****************XBOOT*****************nr");

?????????????????? printf("1:Download Linux Kernel from TFTP Server!nr");

?????????????????? printf("2:Boot Linux from RAM!nr");

?????????????????? printf("3:Boot Linux from Nand Flash!nr");

?????????????????? printf("n Plese Select:");

??? ????????

?????????????????? scanf("%d",&num);

???

?????????????????? switch (num)

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

??????????????????????????? case 1:

??????????????????????????? //tftp_load();

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

???????????

??????????????????????????? case 2:

??????????????????????????? //boot_linux_ram();

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

???????????

??????????????????????????? case 3:

??????????????????????????? //boot_linux_nand();

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

???????????

??????????????????????????? default:

??????????????????????????? printf("Error: wrong selection!nr");

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

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

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

???????? return 0;

}

?

完整的nand.c文件:

#define NFCONF (*(volatile unsigned long*)0x4E000000) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

#define NFCONT (*(volatile unsigned long*)0x4E000004)

#define NFCMD? (*(volatile unsigned char*)0x4E000008)

#define NFADDR (*(volatile unsigned char*)0x4E00000C)

#define NFDATA (*(volatile unsigned char*)0x4E000010)

#define NFSTAT (*(volatile unsigned char*)0x4E000020)

?

#define TACLS 1

#define TWRPH0 2

#define TWRPH1 1

?

?

void select_chip()

{

??? NFCONT &= ~(1<<1);??????

}

?

void deselect_chip()

{

??? NFCONT |= (1<<1);?

}

?

void clear_RnB()

{

?? NFSTAT |= (1<<2);

}

?

void send_cmd(unsigned cmd)

{

???? NFCMD = cmd;

}

?

void send_addr(unsigned addr)

{

???? NFADDR = addr;

}

?

void wait_RnB()

{

?? while (!(NFSTAT&(1<<2)))?

?? {

?????? ;

?? }

}

?

void nand_reset()

{

??? //选中flash

??? select_chip();

???

??? //清除RnB

??? clear_RnB();

???

???

??? //发送0xff命令

??? send_cmd(0xff);

???

???

??? //等待RnB

??? wait_RnB();

???

????????

??? //取消选中flash

??? deselect_chip();

}

?

void nand_init()

{

??? //初始化NFCONF

??? NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);

???

??? //初始化NFCONT

??? NFCONT = (1<<0) | (1<<1);

???

??? //复位

??? nand_reset();?

}

?

void NF_PageRead(unsigned long addr,unsigned char* buff)

{

???????? int i;

????????

???????? //int col = addr % 2048;

???????? //int page = addr / 2048;

???????? int col = 0x0;

???????? int page = addr;

?

???????? //选中nandflash芯片

???????? select_chip();

????????

???????? //清除RnB

???????? clear_RnB();

????????

???????? //发送命令0x00

???????? send_cmd(0x00);

????????

???????? send_addr(col & 0xff);

???????? send_addr((col >> 8) & 0xff);

?

???????? send_addr(page & 0xff);

???????? send_addr((page >> 8) & 0xff);

???????? send_addr((page >> 16) & 0xff);

????????

???????? //发送命令0x30

???????? send_cmd(0x30);

????????

???????? //等待RnB

???????? wait_RnB();

????????

???????? //读取数据

???????? for(i=0;i<2048;i++)

???????? {

???????? ?? buff[i] = NFDATA;? ??

???????? }

????????

???????? //取消选中nandflash芯片

???????? deselect_chip();

}

?

?

void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size)

{

???????? int page = start_addr / 2048;

???????? for(;size>0;)

???????? {

???????? ??? NF_PageRead(page,sdram_addr);

???????? ??? size -= 2048;

???????? ??? sdram_addr += 2048;

???????? ??? page++;

???????? }

}

?

int NF_Erase(unsigned long addr)

{

???????? int ret;

???????? unsigned int page = addr/2048;

????????

? //选中flash芯片

???????? select_chip();

????????

???????? //清除RnB

???????? clear_RnB();

????????

???????? //发送命令0x60

???????? send_cmd(0x60);

????????

???????? //发送行地址

???????? send_addr(page&0xff);

???????? send_addr((page>>8)&0xff);

???????? send_addr((page>>16)&0xff);

????????

???????? //发送命令D0

???????? send_cmd(0xD0);

????????

???????? //等待RnB

???????? wait_RnB();

????????

???????? //发送命令0x70

???????? send_cmd(0x70);

????????

???????? //读取擦除结果

???????? ret = NFDATA;

????????

???????? //取消选中flash芯片

???????? deselect_chip();

????????

???????? return ret;

????????

}

?

int NF_WritePage(unsigned long addr,unsigned char *buff)

{

???????? unsigned int i,ret = 0,page,col;

???????? col = addr % 2048;

???????? page = addr /2048;

???????? //选中nandflash

???????? select_chip();

????????

???????? //清除RnB

???????? clear_RnB();

????????

???????? //发送0x80命令

???????? send_cmd(0x80);

????????

???????? //发送2个列地址

???????? /* 这种写法ok

???????? send_addr(col & 0xff);

???????? send_addr((col >> 8) & 0xff);

???????? send_addr(page & 0xff);

???????? send_addr((page >> 8) & 0xff);

???????? send_addr((page >> 16) & 0xff);

???????? */

?

????????

???????? send_addr(addr & 0xff);???????? // a0~a7

???????? send_addr((addr >> 8) & 0x7);?? // 以程序角度看 a8~a10

?

???????? send_addr((addr >> 11) & 0xff); // 以程序角度看 a12~a19

???????? send_addr((addr >> 19) & 0xff); // 以程序角度看 a20~a27

???????? send_addr((addr >> 27) & 0xff); // 以程序角度看 a28???

????????

/*???? wrong 移位错误

???????? send_addr(addr & 0xff);???????? // a0~a7

???????? send_addr((addr >> 8) & 0x7);?? // 以程序角度看 a8~a10

?

???????? send_addr((addr >> 12) & 0xff); // 以程序角度看 a12~a19

???????? send_addr((addr >> 20) & 0xff); // 以程序角度看 a20~a27

???????? send_addr((addr >> 28) & 0xff); // 以程序角度看 a28???

*/

???????? //发送数据

???????? for(i=0;i<2048;i++)

???????? {

???????? ?? NFDATA = buff[i];? ??

???????? }

????????

???????? //发送0x10命令

???????? send_cmd(0x10);

????????

???????? //等待RnB

???????? wait_RnB();

????????

???????? //发送0x70命令

???????? send_cmd(0x70);

????????

???????? //读取写入结果

???????? ret = NFDATA;

????????

???????? //关闭nandflash

???????? deselect_chip();

???????? ?return ret;

}

?

?

使用到的命令:

tftp 30000000 xboot.bin; nand erase 0 10000; nand write 30000000 0 10000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

下载成功后把把拨码开关拨到Nand启动,使用命令:

reset

执行完reset后看到:

可以看到NandFlash已经能正常写入并读取了,安全起见,再来使用u-boot查看一下NandFlash中的情况:

以Nor启动进入u-boot:

nand read 33000000 0x32000 10000; md.b 33000000 100 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

回车

回车

回车

回车,可以看到:



这就完全可以清晰的看到NandFlash中的值了。

?

移植u-boot的过程中,为了实现NandFlash启动会使用一段实现u-boot.bin从NandFlash拷贝到SDRAM的代码,学习完上述NandFlash的操作再去看那段代码就没有任何难度了。

?

?

完整工程下载地址:http://download.csdn.net/detail/doccode/8914847

使用到的u-boot.bin下载地址:http://download.csdn.net/detail/doccode/8914859

(编辑:李大同)

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

    推荐文章
      热点阅读