根据韦东山修改的mini2440 nand flash裸机程序

来源:互联网 发布:js获取a标记的href 编辑:程序博客网 时间:2024/06/11 23:18

article from:  http://blog.sina.com.cn/s/blog_b90c3cdf0101jn5j.html

==========================================================


说明

       开发板:mini2440

       Nand flashK9F2G08U0B256M

       本程序实现功能:我是参考韦东山的第8章的裸机程序,但是他的nand flash型号是64MBK9F12080M,所以我依照他的程序加以修改,下载到nand flash,从nand flash实现将main.c程序复制到sdram中执行。

       参考书:《嵌入式应用开发完全手册》

                ARM处理器裸机开发实战---机制而非策略》

 

知识点梳理

       页的绝对地址与相对地址

 

       nand.c中有一个函数void RdNF2SDRAM(),它的功能是将nand flah的内容复制到sdram,如下:

 

根据韦东山修改的mini2440 <wbr>nand <wbr>flash裸机程序

nand flash的页读取函数原型是void nf_readpage(unsigned int block,unsigned int page,unsigned char *dstaddr),它的功能是从nand flash的第block块的第page页读取1(对于K9F2G来说,1页等于2KB)的内容,存放到指针dstaddr所指的地址处。有的人可能就会说了,既然nf_readpage可以读取1页的数据到指定的地址处,而sdram的地址是0x30000000,那直接可以使用它将nand flash的代码复制到sdram去啊,答案当然是可以啊!但是有个前提,复制到sdram的内容必须在2KB以内,一旦超过了2KB,那就需要借用RdNF2SDRAM()函数了,相信这样解释就能明白这两个函数的区别于联系了。

再说说绝对地址与相对地址,首先知道k9f2g2048个块,每个块有64个页,每页有2K字节。我们平常所说的第几块第几页就是相对地址,比如第2块第3页是相对地址。而绝对地址=块号*64+页号,例如前边的第2块第3页换成绝对地址就是131131=2*64+3)。

下面解释一下RdNF2SDRAM()函数:

113行:从117行可以看出,这里的i指的是相对地址

114行:在nand flash内的起始地址,这里的4096表示的是字节,k9f2g内存大小是256Mbyte,这里之所以令start_addr=4096,是因为咱们在nand.lds文件中,将main.c文件的地址定义在了4096处。如下图:

根据韦东山修改的mini2440 <wbr>nand <wbr>flash裸机程序

如果AT(4096)改为AT(5120),那么这里start_addr就等于5120。还要注意这里4096byte也就是4KB,为什么把他定义在nand flash4KB之后呢,因为硬件电路会自动将nand flash里的前4KB的内容搬移到stepping stone中去执行,如果定义在3KB之后,main.c函数直接就执行了,哪里还用复制。

       115行:定义了读取的nand flash的内容存放的位置,这里0x30000000sdram的物理地址。

       116行:定义了一共读取nand flash多少字节,这里定义的是1M,当然小小的一个main.c代码也就是不到2KB

       117-123行:这才是该函数的关键。因为nf_readpage函数是以页为单位进行读取的,每次读取2KB数据,因此,数据指针的移动是页对齐的,即每次移动一页。

       117行:因为每page大小为2KB2048Byte,这里start_addr>>11位,相当于start_addr/2048,这样就得到了给定地址多对应的页。

       119行:这里的i是绝对地址,因为每块包含64页,i/64得到给定地址处于哪一块;id是该页在块内的第几页。

 

       NAND FLASH地址周期:

      

       下面咱们讲讲地址周期。对于mini2440的开发板,它的nand flash的接口电路如下图:

根据韦东山修改的mini2440 <wbr>nand <wbr>flash裸机程序

根据韦东山修改的mini2440 <wbr>nand <wbr>flash裸机程序

       从接口电路可以看到,地址线和数据线是复用的,接口线宽是8位,因此每次只能发送一个字节,又因为nand flash的地址是28位的,需要5个地址周期才能将地址发送完毕,如图1所示。发送完地址后,NAND FLASH内部的地址译码电路会自动将收到的地址进行组合,不需要我们关心,但是需要注意发送的顺序,按照先发送低地址,再发送高地址的顺序发送。

       那么为什么是29根地址线,而不是28根或者30根呢?这里肯定有它的原因的。通常来说,nand flash的地址的表示形式为:

地址线

[A28A18]

[A17A12]

[A11A0]

地址表示

块地址

页地址

页内偏移地址

       对于k9f2g来说,它有2048个块,故用11根地址线寻址(2^11=2048);每个块有64页,故用6根地址线寻址(2^6=64);每页有2048字节的数据和64字节的信息,也就是说它有2112字节,故用12根地址线寻址。理解了这里的话就很容易明白下面的发送地址了。

不论是在nand flash页读取函数还是也写入函数内,都需要向地址寄存器送地址,如下图:

根据韦东山修改的mini2440 <wbr>nand <wbr>flash裸机程序

为什么是这样呢?由于页读取和写入函数均是以页为单位进行的,所以每次都要在页的第0个字节开始,也就是说页内偏移地址为0,所以对地址线的低12位设为0即可,如第93行,94行。

95行,此时处于第3个地址周期因此需要发送blockpage(此时blockpage是页的绝对地址)的A12-A19位,因此,将blockpage0xff相与即可。一定要注意页的绝对地址是A28-A12共同表示的,与A11-A0无关。

96行,此时处于第3个地址周期因此需要发送blockpage(此时blockpage是页的绝对地址)的A20-A27位,因此,将blockpage右移8位,与0xff相与即可。

97行,此时处于第3个地址周期因此需要发送blockpage(此时blockpage是页的绝对地址)的A28位,从图1可以看到,此时虽然是发送8位,但是只有第0位是有效的,其他位无效。因此,将blockpage右移16位,然后再与0x1相与,只保留第0位。

 

       nand.lds代码解释:

      

       如果代码小于4096字节,那么开发板启动后它们被自动复制进“Steppingstone”中;本实例的目的就是把一部分代码存放在NAND Flash地址4096之后,当程序启动通过NAND Flash控制器将它们读出来、执行。nand.lds就是实现这个目的的,即连接脚本nand.lds把代码分为两部分,nand.lds代码如下:

根据韦东山修改的mini2440 <wbr>nand <wbr>flash裸机程序

       2行表示head.oinit.onand.o3个文件的运行地址为0,它们在生成的映像文件中的偏移地址也为0(0开始存放)

       3行表示main.o的运行地址为0x30000000,它在生成的映像文件中的偏移地址为4096

       此时生成的bin文件大小为4.10KB

       如果将第3行的AT(4096)去掉,其他的文件程序不变的话,make生成的bin文件大小为1.7KB。这样子对比就可以看出来AT真的起作用了。

 

 

 

mini2440开发板的时钟

 

    Fin=12MHz    FCLK=400MHz    HCLK=100MHz     PCLK=50MHz

       所以FCLKHCLKPCLK=1:4:8CLKDIV_VAL=5

       MDIV=127   PDIV=2   SDIV=1

编译生成bin文件,下载运行

 

       本实验一共包含6个文件,分别为Makefilehead.Sinit.cmain.cnand.cnand.lds,最后会把文件源代码全部贴出来。

       6个文件复制到虚拟机的linux系统中,然后make编译生成nand.bin文件,通过superviviv命令,结合DNW将它下载到板子中,然后板子从nand flash启动,可以看到4led灯全亮。

 

 

代码源文件


百度文库pdf地址:http://wenku.baidu.com/view/85e30572168884868662d603.html?st=1

pdf文件下载地址:http://download.csdn.net/detail/mybelief321/5234586

源代码下载地址:http://download.csdn.net/detail/mybelief321/5234602


0 0
原创粉丝点击