关于nor flash,nand flash, sram,sdram编址等困惑
SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也就是通常所说的内存。内存的工作原理、控制时序、及相关控制器的配置方法一直是嵌入式系统学习、开发过程中的一个难点。我们从其硬件的角度来分析其原理,然后再引出SDRAM的驱动编写过程。
内存是代码的执行空间,以PC机为例,程序是以文件的形式保存在硬盘里面的,程序在运行之前先由操作系统装载入内存中,由于内存是RAM(随机访问存储器),可以通过地址去定位一个字节的数据,CPU在执行程序时将PC的值设置为程序在内存中的开始地址, CPU会依次的从内存里取址,译码,执行,在内存没有被初始化之前,内存好比是未建好的房子,是不能读取和存储数据的,因此我们要想让MTOS运行在内存里必须进行内存的初始化。
其实S3C2440内部带有存储器硬件控制器,针对SDRAM来说,有硬件控制机制,驱动内存时只需要先配置与内存存储相关的寄存器,然后给定内存地址值就可以实现存储,而像其他的信号线,nWE,CLK,nSRAS,nSCAS等都是由硬件来完成操作的,使用起来方便了不少。
本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-04/101119.htm
相关阅读:
S3C2440上RTC时钟驱动开发实例分析 http://www.linuxidc.com/Linux/2013-06/86042.htm
S3C2440的UART功能测试 http://www.linuxidc.com/Linux/2013-05/85158.htm
S3C2440 地址分配硬件连接及其启动原理分析 http://www.linuxidc.com/Linux/2013-04/83218.htm
S3C2440时钟设置 http://www.linuxidc.com/Linux/2013-03/81245.htm
linux-2.6.14移植到S3C2440 http://www.linuxidc.com/Linux/2012-12/77125.htm
S3C2440开发板LED驱动——ioremap 映射 http://www.linuxidc.com/Linux/2012-12/76084.htm
---------------------------------分割线---------------------------------
例如:将一个地址处的数据或者代码搬运到SDRAM中去:
ldr r0,=ENTRY
ldr r3,=ROBASE
ldr r1,[r0]
str r1,[r3]
这几部就完成了将ENTRY(nor or nand flash)处的数据写到内存地址为ROBASE地方处。
通用存储设备:
在介绍内存工作原理之前有必要了解下存储设备的存储方式:ROM,RAM
l ROM(Read-Only Memory):只读存储器,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除。通常用在不需经常变更资料的电子或电脑系统中,资料并且不会因为电源关闭而消失。如:PC里面的BIOS。
l RAM(Random Access Memory) :随机访问存储器,存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器。可以理解为,当你给定一个随机有效的访问地址,RAM会返回其存储内容(随机寻址),它访问速度与地址的无关。这种存储器在断电时将丢失其存储内容,故主要用于存储短时间内随机访问使用的程序。计算机系统里内存地址是一个四字节对齐的地址(32位机),CPU的取指,执行,存储都是通过地址进行的,因此它可以用来做内存。
RAM按照硬件设计的不同,随机存储器又分为DRAM(Dynamic RAM)动态随机存储器和SRAM(Static RAM) 静态随机存储器。
l DRAM:它的基本原件是小电容,电容可以在两个极板上短时间内保留电荷,可以通过两极之间有无电压差代表计算机里的0和1,由于电容的物理特性,要定期的为其充电,否则数据会丢失。对电容的充电过程叫做刷新,但是制作工艺较简单,体积小,便于集成化,经常做为计算机里内存制作原件。比如:PC的内存,SDRAM, DDR, DDR2, DDR3等,缺点:由于要定期刷新存储介质,存取速度较慢。
l SRAM:它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据。因此其存取速度快,但是体积较大,功耗大,成本高,常用作存储容量不高,但存取速度快的场合,比如CPU的L1 cache,L2cache(一级,二级缓存) ,寄存器。
本文是以开发板MICRO2440为例子
MICRO2440在出厂时搭载了三种存储介质:
(1)NOR FLASH(2M):ROM存储器,通常用来保存BootLoader,引导系统启动
(2)NAND FLASH(256M,型号不一样,Nandflash大小不一样):保存操作系统映像文件和文件系统
(3)SDRAM(64M):内存,执行程序
l NORFLASH:它的特点是支持XIP芯片内执行(eXecute In Place),这样应用程序可以直接在Flash闪存内运行,不必再把代码读到系统RAM中,也就是说可以随机寻址。NOR FLASH的成本较高。
l NAND FLASH:它能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。其成本较低,不支持XIP。可做嵌入式里的数据存储介质。如:手机存储卡,SD卡等。
1.1.1 S3C2440存储器地址段(Bank)
S3C2440对外引出了27根地址线ADDR0~ADDR26,它最多能够寻址128MB,而S3C2440的寻址空间可以达到1GB,这是由于S3C2440将1GB的地址空间分成了8个BANKS(Bank0~Bank7),其中每一个BANK对应一根片选信号线nGCS0~nGCS7,当访问BANKx的时候,nGCSx管脚电平拉低,用来选中外接设备, S3C2440通过8根选信号线和27根地址线,就可以访问1GB。如图2-48所示。
图2-48 S3C2440存储器BANK
如图所示,左侧图对应不使用Nandflash启动时(通过跳线设置),存储器Bank分布图,通常在这种启动方式里选择Norflash启动,将Norflash焊接在Bank0, 系统上电后,CPU从Bank0的开始地址0x00000000开始取指运行。
上图右侧是选择从Nandflash引导启动(通过跳线设置),其中BANK[0]映射了2440内部的SRAM,通过nGCS0信号线来选通,系统上电后,CPU会自动将Nandflash里前4K的数据复制到S3C2440内部一个4K大小 SRAM类型存储器里(叫做Steppingstone),然后从Steppingstone取指启动。
其中Bank0~Bank5可以焊接ROM或SRAM类型存储器,Bank6~Bank7可以焊接ROM,SRAM,SDRAM类型存储器,也就是说,S3C2440的SDRAM内存应该焊接在Bank6~Bank7上,最大支持内存256M,Bank0~Bank5通常焊接一些用于引导系统启动小容量ROM,具体焊接什么样存储器,多大容量,根据每个开发板生产商不同而不同,比如MINI2440开发板将2M的Norflash焊接在了Bank0上,用于存放系统引导程序Bootloader,将两片32M,16Bit位宽SDRAM内存焊接在Bank6和Bank7上,并联形成64M,32位内存。
由于S3C2440是32位芯片,理论上讲可以达到4GB的寻址范围,除去上述8个BANK用于连接外部设备,还有一部分的地址空间是用于设备特殊功能寄存器,其余地址没有被使用。
表2-14 S3C2440设备寄存器地址空间
外接设备 |
起始地址 |
结束地址 |
存储控制器 |
0x48000000 |
0x48000030 |
USB Host控制器 |
0x49000000 |
0x49000058 |
中断控制器 |
0x4A000000 |
0x4A00001C |
DMA |
0x4B000000 |
0x4B0000E0 |
时钟和电源管理 |
0x4C000000 |
0x4C000014 |
LCD控制器 |
0x4D000000 |
0x4D000060 |
NAND FLASH控制器 |
0x4E000000 |
0x4E000014 |
摄像头接口 |
0x4F000000 |
0x4F0000A0 |
UART |
0x50000000 |
0x50008028 |
脉宽调制计时器 |
0x51000000 |
0x51000040 |
USB设备 |
0x52000140 |
0x5200026F |
WATCHDOG计时器 |
0x53000000 |
0x53000008 |
IIC控制器 |
0x54000000 |
0x5400000C |
IIS控制器 |
0x55000000 |
0x55000012 |
I/O端口 |
0x56000000 |
0x560000B0 |
实时时钟RTC |
0x57000040 |
0x5700008B |
A/D转换器 |
0x58000000 |
0x58000010 |
SPI |
0x59000000 |
0x59000034 |
SD接口 |
0x5A000000 |
0x5A000040 |
AC97音频编码接口 |
0x5B000000 |
0x5B00001C |
1.1.2 SDRAM内存工作原理
SDRAM的内部是一个存储阵列。阵列就如同表格一样,将数据“填”进去。在数据读写时和表格的检索原理一样,先指定一个行(Row),再指定一个列 (Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理,如图2-49所示。
图2-49内存行,列地址寻址示意图
这个单元格(存储阵列)就叫逻辑 Bank(Logical Bank,下文简称 L-Bank)。 由于技术、成本等原因,不可能只做一个全容量的 L-Bank,而且最重要的是,由于 SDRAM的工作原理限制,单一的 L-Ban k将会造成非常严重的寻址冲突,大幅降低内存效率。所以人们在 SDRAM内部分割成多个 L-Bank,目前基本都是 4个(这也是SDRAM规范中的最高L-Bank数量),由此可见,在进行寻址时就要先确定是哪个 L-Bank,然后在这个选定的 L-Bank中选择相应的行与列进行寻址。因此对内存的访问,一次只能是一个 L-Bank工作。如图2-50:
图2-50内存存储单元
当对内存进行操作时(见下图),先要确定操作L-Bank,因此要对L-Bank进行选择。在内存芯片的外部管脚上多出了两个管脚BA0, BA1,用来片选4个L-Bank。如前所述, 32位的地址长度由于其存储结构特点,分成了行地址和列地址。通过下面的内存结构图可知,内存外接管脚地址线只有13根地址线A0~A12,它最多只能寻址8M内存空间,到底使用什么机制来实现对64M内存空间进行寻址的呢?SDRAM的行地址线和列地址线是分时复用的,即地址要分两次送出,先送出行地址(nSRAS行有效操作),再送出列地址(nSCAS列有效操作)。这样,可以大幅度减少地址线的数目,提高器件的性能和制作工艺复杂度。但寻址过程也会因此而变得复杂。实际上,现在的SDRAM一般都以L-Bank为基本寻址对象的。由L-Bank地址线BAn控制L-Bank间的选择,行地址线和列地址线贯穿连接所有的L-Bank,每个L-Bank的数据的宽度和整个存储器的宽度相同,这样,可以加快数据的存储速度。同时,BAn还可以使未被选中的L-Bank工作于低功耗的模式下,从而降低器件的功耗。
图2-51 HY57561620内部结构图
开发板内存控制器管脚接线(以MINI2440开发板为例):
(1)确定BA0、BA1的接线
表2-15 BA0、BA1接线
Bank Size: 外接内存容量大小(HY57561620是4Mbit*16bit*4Bank*2Chips/8=64MB)(其中HY57561620和H57v256一样)
Bus Width: 总线宽度 (两片16位HY57561620,并联成32位)
Base Component:单个芯片容量(bit)(256Mb)
Memory Configration:内存配置 ((4M*16*4banks)*2Chips )
由硬件手册Bank Address管脚连接配置表可知,使用A[25:24]两根地址线作为Bank片选信号,正好两根接线可以片选每个存储单元的4个BANKS。
(2)确定其它接线
SDRAM内存是焊接在BANK6~BANK7上的,其焊接管脚,如图2-52:
图2-52 S3C2440 16位宽内存芯片
上图是S3C2440提供的两片16位芯片并联连接示意图,An是CPU地址总线,其中A2~A14为内存芯片寻址总线,之所以地址寻址总线从A2开始是因为内存地址都是按字节对齐的,,A24,A25为L-Bank片选信号,Dn为CPU数据总线,其它为对应控制信号线。
表2-16 内存芯片各管脚说明
外接管脚名 |
内接管脚名 |
全称 |
描述 |
A2~A14 |
A0~A12 |
Address |
地址线 |
D0 ~D31 |
DQ0~DQ31 |
Data Input/Output |
数据线 |
A24,A25 |
BA0,BA1 |
Bank Address |
L-BANK片选信号 |
DQM0~DQM3 |
LDQM, UDQM |
Data Input/Output Mask |
高,低字节数据掩码信号 |
SCKE |
SCKE |
Clock Enable |
输入时钟有效信号 |
SCLK |
SCLK |
Clock |
输入时钟 |
nSCS0 |
nSCS |
General Chip Select |
片选信号(它与nGCS6是同一管脚的两个功能) |
nSRAS |
nSRAS |
Row Address Strobe |
行地址选通信号 |
nSCAS |
nSCAS |
Column Address Strobe |
列地址选通信号 |
nWE |
newnWE |
Write Enable |
写入有效信号 |
通过S3C2440 16位宽内存芯片接线图可以看出,两片内存芯片只有两个地方不一样,LDQM, UDQM和数据总线DQn接线方式不一样。
{LDQM和UDQM}
由于存储芯片位宽为16位,一次可以进行两个字节的读取。但是,通常操作系统里最小寻址单位是1字节,因此内存控制器必须要保证可以访问内存里每一个字节。UDQM ,LDQM分别代表16位数据的高,低字节读取信号,当读取数据时,LDQM /UDQM分别用来控制16位数据中高低字节能否被读取,当LDQM /UDQM为低电平时,对应的高/低字节就可以被读取,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被读取。当向内存里写入数据时,LDQM /UDQM控制数据能否被写入,当LDQM /UDQM为低电平时,对应的高/低字节就可以被写入,如果LDQM /UDQM为高电平时,对应的高/低字节就不能被写入。通过对LDQM /UDQM信号的控制可以控制对两个存储芯片存储数据,由于两个存储单元的地址线是通用的,他们都能接收到CPU发出的地址信号,但是,发给两个存储单元的LDQM /UDQM信号是不同的,以此来区分一个字的高低字节。
S3C2440A为32位CPU,也就是说其数据总线和地址总线宽度都是32位(可以理解为32根线一端连接CPU内部,另外一端连接向内存控制器),那么内存数据的输入/输出端也要保证是32位总线,MINI2440上采用两片16位宽总线内存芯片并联构成32位总线。其中一个芯片连接到CPU数据总线的低16位,另外一个芯片连接到数据总线上的高16位,并联成32位总线,因此两个芯片的输入/输出总线连接到CPU总线上的不同管脚上。
1.1.3 SDRAM的读操作
SDRAM进行读操作时,先向地址线上送上要读取数据的地址,通过前面的知识了解到,地址被分成3部分,行地址,列地址,L-Bank片选信号。片选(L-Bank的定址)操作和行有效操作可以同时进行。
在CS、L-Bank定址的同时,RAS(nSRAS行地址选通信号)也处于有效状态。此时 An地址线则发送具体的行地址。A0~A12,共有13根地址线(可表示8192行),A0~A12的不同数值就确定了具体的行地址。由于行有效的同时也是相应 L-Bank有效,所以行有效也可称为L-Bank有效。
行地址确定之后,就要对列地址进行寻址了。但是,地址线仍然是行地址所用的 A0~A12。没错,在SDRAM中,行地址与列地址线是复用的。列地址复用了A0~A8,共9根(可表示512列)。那么,读/写的命令是怎么发出的呢?其实没有一个信号是发送读或写的明确命令的,而是通过芯片的可写状态的控制来达到读/写的目的。显然WE信号(nWE)就是一个关键。WE无效时,当然就是读取命令。有效时,就是写命令。
SDRAM基本操作命令, 通过各种控制/地址信号的组合来完成(H代表高电平,L代表低电平,X表示高,低电平均没有影响)。此表中,除了自刷新命令外,所有命令都是默认CKE(SCKEl输入时钟频率有效)有效。列寻址信号与读写命令是同时发出的。虽然地址线与行寻址共用,但CAS(nSCAS列地址选通信号)信号则可以区分开行与列寻址的不同,配合A0~A8,A9~A11来确定具体的列地址。
读取命令与列地址一块发出(当WE为低电平是即为写命令)然而,在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为 tRCD,即RAS to CAS Delay(RAS至 CAS延迟),这个很好理解,在地址线上送完行地址之后,要等到行地址稳定定位后再送出列地址,tRCD是SDRAM的一个重要时序参数,相关数值参看对应芯片硬件手册。通常tRCD以时钟周期(tCK,Clock Time)数为单位,比如笔者MINI2440所用内存芯片里面写到tRCD为20nst,如果内存工作在100MHz,那么RCD至少要为2个时钟周期, RCD=2。
图2-53 SDRAM读操作时序图
在选定列地址后,就已经确定了具体的存储单元,剩下就是等待数据通过数据 I/O通道(DQ)输出到内存数据总线上了。但是在列地址选通信号CAS 发出之后,仍要经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为 CL(CAS Latency,CAS潜伏期)。由于CL只在读取时出现,所以CL又被称为读取潜伏期(RL,Read Latency)。CL的单位与tRCD一样,也是时钟周期数,具体耗时由时钟频率决定(笔者官方手册CL=3)。不过,CAS并不是在经过CL周期之后才送达存储单元。实际上CAS与RAS一样是瞬间到达的。由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由S-AMP负责。但它要有一个准备时间才能保证信号的发送强度,这段时间我们称之为tAC(Access Time from CLK,时钟触发后的访问时间)。
1.1.4 SDRAM预充电操作
从存储体的结构图上可以看出,原本逻辑状态为1的电容在读取操作后,会因放电而变为逻辑0。由于SDRAM的寻址具有独占性,所以在进行完读写操作后,如果要对同一L-Bank的另一行进行寻址,就要将原先操作行关闭,重新发送行/列地址。在对原先操作行进行关闭时,DRAM为了在关闭当前行时保持数据,要对存储体中原有的信息进行重写,这个充电重写和关闭操作行过程叫做预充电,发送预充电信号时,意味着先执行存储体充电,然后关闭当前L-Bank操作行。预充电中重写的操作与刷新操作(后面详细介绍)一样,只不过预充电不是定期的,而只是在读操作以后执行的。
1.1.5 SDRAM突发操作
突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)数量就是突发长度(Burst Length,简称BL)。
在目前,由于内存控制器一次读/写P-Bank位宽的数据,也就是8个字节,但是在现实中小于8个字节的数据很少见,所以一般都要经过多个周期进行数据的传输,上文写到的读/写操作,都是一次对一个存储单元进行寻址,如果要连续读/写,还要对当前存储单元的下一单元进行寻址,也就是要不断的发送列地址与读/写命令(行地址不变,所以不用再对地寻址)。虽然由于读/写延迟相同可以让数据传输在I/O端是连续的,但是它占用了大量的内存控制资源,在数据进行连续传输时无法输入新的命令效率很低。为此,引入了突发传输机制,只要指定起始列地址与突发长度,内存就会依次自动对后面相应长度数据的数据存储单元进行读/写操作而不再需要控制器连续地提供列地址,这样,除了第一笔数据的传输需要若干个周期(主要是之间的延迟,一般的是tRCD + CL)外,其后每个数据只需一个周期即可。
总结下:
SDRAM的基本读操作需要控制线和地址线相配合地发出一系列命令来完成。先发出芯片有效命令(ACTIVE),并锁定相应的L-BANK地址(BA0、BA1给出)和行地址(A0~A12给出)。芯片激活命令后必须等待大于tRCD(SDRAM的RAS到CAS的延迟指标)时间后,发出读命令。CL(CAS延迟值)个时钟周期后,读出数据依次出现在数据总线上。在读操作的最后,要向SDRAM发出预充电(PRECHARGE)命令,以关闭已经激活的L-BANK。等待tRP时间(PRECHAREG命令后,相隔tRP时间,才可再次访问该行)后,可以开始下一次的读、写操作。SDRAM的读操作支持突发模式(Burst Mode),突发长度为1、2、4、8可选。
1.1.6 SDRAM写操作
SDRAM的基本写操作也需要控制线和地址线相配合地发出一系列命令来完成。先发出芯片有效命令,并锁定相应的L-BANK地址(BA0、BA1给出)和行地址(A0~A12给出)。芯片有效命令发出后必须等待大于tRCD的时间后,发出写命令数据,待写入数据依次送到DQ(数据线)上。在最后一个数据写入后,延迟tWR时间。发出预充电命令,关闭已经激活的页。等待tRP时间后,可以展开下一次操作。写操作可以有突发写和非突发写两种。突发长度同读操作。
图2-54 SDRAM写操作时序图
1.1.7 SDRAM的刷新
SDRAM之所以成为DRAM就是因为它要不断进行刷新(Refresh)才能保留住数据,因此它是SDRAM最重要的操作。
刷新操作与预充电中重写的操作一样,都是用S-AMP先读再写。但为什么有预充电操作还要进行刷新呢?因为预充电是对一个或所有 L-Bank中的工作行操作,并且是不定期的,而刷新则是有固定的周期,依次对所有行进行操作,以保留那些很长时间没经历重写的存储体中的数据。但与所有L-Bank预充电不同的是,这里的行是指所有L-Bank中地址相同的行,而预充电中各L-Bank中的工作行地址并不是一定是相同的。那么要隔多长时间重复一次刷新呢?目前公认的标准是,存储体中电容的数据有效保存期上限是64ms(毫秒,1/1000秒),也就是说每一行刷新的循环周期是64ms。这样刷新时间间隔就是: 64m/行数s。我们在看内存规格时,经常会看到4096 Refresh Cycles/64ms或8192 Refresh Cycles/64ms的标识,这里的4096与8192就代表这个芯片中每个L-Bank的行数。刷新命令一次对一行有效,刷新间隔也是随总行数而变化,4096行时为 15.625μs(微秒,1/1000毫秒),8192行时就为 7.8125μs。刷新操作分为两种:Auto Refresh,简称AR与Self Refresh,简称SR。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。对于 AR,SDRAM内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成行地址。由于刷新是针对一行中的所有存储体进行,所以无需列寻址,或者说CAS在 RAS之前有效。所以,AR又称CBR(CAS Before RAS,列提前于行定位)式刷新。由于刷新涉及到所有L-Bank,因此在刷新过程中,所有 L-Bank都停止工作,而每次刷新所占用的时间为9个时钟周期(PC133标准),之后就可进入正常的工作状态,也就是说在这9个时钟期间内,所有工作指令只能等待而无法执行。64ms之后则再次对同一行进行刷新,如此周而复始进行循环刷新。显然,刷新操作肯定会对SDRAM的性能造成影响,但这是没办法的事情,也是DRAM相对于 SRAM(静态内存,无需刷新仍能保留数据)取得成本优势的同时所付出的代价。SR则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是 STR(Suspend to RAM,休眠挂起于内存)。在发出AR命令时,将CKE置于无效状态,就进入了SR模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在SR期间除了CKE之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式并进入正常操作状态。