前面几篇文章分别讲述了存储系统的地址线连接方法、存储芯片的写屏蔽、存储系统的扩展,以及SDRAM/DDR的结构和寻址,本文将以ARM芯片s3c2440为例,从整体上描述一个包含有同时SDRAM、Nor Flash、Nand Flash的存储系统的设计、工作原理和注意事项。

    下面这幅原理图就是这样一个完整的存储系统,主控芯片是三星公司的ARM芯片s3c2440(未画出,但相关引脚都在图中的导线上的标号标出),该存储系统包含了一个SDRAM(HY57V561620),一个Nor Flash(Am29LV160DB)一个Nand Flash(K9F1208)。

    由该存储系统原理图,我们提出以下几个问题,并一一解答:

   (1)SDRAM芯片和 Nor Flash芯片都连接了ARM芯片的地址线,他们各自在存储系统中的地址范围是多少?由什么决定当前访问的是哪一个存储器 ?

   (2)如果希望再扩展一个ROM存储器,如何连线,地址范围如何确定?

   (3)Nand Flash芯片并没有连接到ARM芯片的地址线,如何寻址?怎样选中它?

   (4)ARM芯片如何知道外接存储器的位宽,即8位、16位还是32位?

   (5)程序代码可能存储在Nor Flash中,或者 Nand Flash中,系统启动时如何知道从哪个存储器中读代码? 


 

1. 首先回答第一个问题,存储芯片地址范围的确定。

    参考s3c2440的datasheet,我们可以找到该芯片的内存映射表(Memory Map),如下图:

    根据OM[1]和OM[0]引脚的不同,内存映射的方式有细微差别(具体原理在本文后面讲述)。但基本可以看出,决定外接存储器的存储地址范围的因素主要是一组引脚 nGCS0[0]~nGCS[7] 。

    s3c2440芯片把存储系统分为了8个Bank,由nGCS0[0]~nGCS[7] 这8根引脚决定当前访问的是哪一个Bank对应的存储器。其中,前6个Bank用于连接ROM或者SRAM(或者类似SRAM接口的存储器,如Nor Flash)(图中由SROM标识),而第7和第8个Bank用于连接SDRAM,并且规定由第7个Bank地址作为SDRAM的起始地址(即0x30000000)。

    原理图中,我已经将决定存储芯片起始地址的nGCS0x引脚用特殊的亮红色标记出来了。我们可以看到,SDRAM芯片被连接到第7个Bank中,起始地址为0x30000000,而Nor Flash被连接到了第0个Bank,起始地址为0x0000000

2. 再回答第二个问题,如何添加新的存储芯片?

    其实,由第一个问题的解释,我们基本上就知道该怎么回答这个问题了。如果添加的是SRAM或者ROM芯片,则自然是将ARM的地址线对应着芯片的地址线进行连接(连接方法在本系列第一篇文章中讲过),然后由 nGCS0[0]~nGCS[5] 这6根引脚中,任选一个尚未使用到的Bank,连接到新添加的芯片上,以决定其地址起始。例如下图,外接一个8位的ROM芯片,片选信号使用 nGCS1,查上面给出的内存映射得知,其起始地址为 0x08000000:

3.  然后解决第三个问题,Nand Flash芯片是如何选中和访问的?

    首先要了解Nand Flash的芯片原理,它不是直接通过地址线来寻址和访问的,而是有一套自己的读写擦除机制。该原理的介绍网上文章很多,这里不再赘述。这里需要说明的是,Nand Flash芯片虽然不需要连接ARM的地址线来寻址,但是额外需要其他的一些引脚来控制对其的访问,例如图中的Nand Flash相关的控制引脚说明如下:

    对应的,ARM端(s3c2440)也为Nand Flash的访问单独提供这些引脚,正好对应连接,例如Nand Flash片选信号nCE连接到了ARM端的Nand Flash片选引脚nFCE上。当ARM需要访问Nand Flash时,就会使能这些相关的引脚,比如使能片选(nFCE),这样就选中了对应的Nand Flash芯片,然后进行读写擦除等操作。

4.  下面回答第四个问题,如何配置外接存储器的位宽?

    从s3c2440的datasheet可以找到,有一个寄存器是专门用于配置各个Bank外接存储器的位宽的,并且配置了该外接存储器是否使用写屏蔽(即写时序中是否分高字节和低字节)(在本系列第2篇文章中有描述),该寄存器说明如下:

    那么,加问一句,为什么需要配置这个位宽呢?

    举个例子来说明这个问题吧。

    假设 ARM 扩展了两片16MB的SRAM芯片,每片SRAM芯片为16位,扩展后,存储系统为32位,两片SRAM片选引脚均连接的是ARM芯片的 nGCS1。

    由于每一片芯片都是16MB,两片的地址增量应该是32MB。因为2^20=1MB,即0x0100000,那么32MB的话,应该是0x2000000,又起始地址连接到nGCS1,故地址范围为 0x8000000~0x10000000,即这个范围内的寻址都应该让nGCS1有效。

    由于 nGCS1决定起始地址0x8000000,而nGCS2决定起始地址0x10000000,那么,如果ARM不知道当前Bank外接的存储芯片的位宽,就无法计算出当前外接的这个存储系统的地址范围,当ARM需要访问0x10000000地址时,就可能会让nGCS2有效,从而无法访问到正确的SRAM芯片了。

5.  下面回答最后一个问题,系统的启动方式

    从s3c2440的datasheet可以知道,系统的启动方式由 OM[0]和OM[1]引脚的电平决定,即硬件决定。如下图:

    

    如果 OM[1:0]=00时,系统会选择从 Nand Flash 中读取代码启动(通过片内的BootSRAM中的启动程序从Nand Flash中拷贝前4KB的代码运行,从而启动整个系统,具体过程网上也有许多文章论述,在此也不再赘述);如果 OM[1:0]=01或者10,则从0x00000000位置启动,一般该位置连接的存储器为Nor Flash,从而直接从Nor Flash中读取代码启动。

    注意回答第一个问题时给出的内存映射图,不同的启动方式,内存的映射是不同的,当从Nand Flash启动时,片上的BootSRAM被映射到了高位地址(0x40000000),而非Nand Flash方式启动时,则映射到了0x00000000.

    到此,整个s3c2440的存储系统原理就基本说完了。因为s3c2440非常常用,市面上也有许多基于s3c2440的开发板,故以该芯片作为核心芯片来展开关于ARM存储系统原理的讨论,其他ARM芯片应该会有着类似的结构和原理,参考本文就应该不难理解了。文中有讲得不清楚或者错误的地方,欢迎批评指正,留言或者来信lujun.hust@gmail.com交流。