您的位置:首页 > 其它

02 ARM存储控制器   SDRAM操作 实验

2016-04-14 23:44 537 查看

什么是存储控制器?

S3C2440中文概述如下:

存储器控制器
概述
S3C2440A存储器控制器为访问外部存储的需要器提供了存储器控制信号。
S3C2440A包含以下特性:
–大/小端(通过软件选择)
–地址空间:每个Bank有128M字节(总共1G/8个Bank)
–大/小端(通过软件选择)
–除了BANK0(16/32位)之外,其它全部BANK都可编程访问宽度(8/16/32位)
–总共8个存储器Bank
6个存储器Bank为ROM,SRAM等
其余2个存储器Bank为ROM,SRAM,SDRAM等
–7个固定的存储器Bank起始地址
–1个可变的存储器Bank起始地址并Bank大小可编程
–所有存储器Bank的访问周期可编程
–外部等待扩展总线周期
–支持SDRAM自刷新和掉电模式
S3c2440向外引出27根地址线,可实现128M的寻找空间;那他怎么实现1G的空间范围访问呢?这就涉及到了nGCSx片选信号,由控制这几根信号线实现bank的切换,如下图所示:


左边为norflash下;右边为nandflash;说到此又想起一概念,就是有关于norflash与nandflash启动方式;一、norflash启动简而言之,既是norflash启动模式下cpu启动就会从地址0x00000000开始执行norflash下是就是norflash的首地址;其中原因为norflash支持一种名为XIP的执行机制;二、nandflash启动nandflash下不支持XIP因此在执行nandflash的程序是,系统将会把nandflash的头4K(最大)启动代码拷贝至系统SRAM中既s3c2440中的steppingstone;S3c2440向外引出27根地址线,可实现128M的寻找空间;那他怎么实现1G的空间范围访问呢?答案:S3C2440有27根地址线ADDR[26:0],8根片选信号ngcs0-ngcs7,对应bank0-bank7,当访问bankx的地址空间,ngcsx引脚为低电平,选中外设。2^27=2^7*2^10*2^10=128Mbyte8*128Mbyte=1Gbyte所以S3C2440总的寻址空间是1Gbyte选择的SDARM是HY57V561620F,4Mbit*4bank*16,共32Mbyte。在嵌入式中,存储控制器只是提供一种总线访问的形式,所接的外设不一定是内存。本节讲解使用S3C2440的存储控制器,操控外部SDRAM首先了解下SDRAM的寻址原理。SDRAM内部是一个存储阵列。可以把它想象成一个表格。和表格的检索原理一样,先指定行,再指定列,就可以准确找到所需要的存储单元。这个表格称为逻辑BANK。目前的SDRAM基本都是4个BANK。寻址的流程就是先指定BANK地址,再指定行地址,最后指定列地址。这就是SDRAM的寻址原理。查看HY57V561620F的资料,这个SDRAM有13根行地址线RA0-RA129根列地址线CA0-CA8/与行地址复用,选低9位2根L-BANK选择线BA0-BA1/S3C2440要求用ADDRESS24,ADDRESS25控制SDRAM的L-BANKSDRAM的地址引脚是分时复用的,在读写SDRAM存储单元时,操作过程是将地址分两次输入到芯片中,两次送到芯片上去的地址分别称为行地址列地址。它们被锁存到芯片内部的行地址锁存器和列地址锁存器。/RAS是行地址锁存信号,该信号将行地址锁存在芯片内部的行地址锁存器中;/CAS是列地址锁存信号,该信号将列地址锁存在芯片内部的列地址锁存器中DRAM的逻辑BANK概念是针对内存颗粒内部的。大家都知道DRAM内部的存储单元是以阵列形式排列的。如下图所示。行列地址总线分别经过行列地址译码器译码后分别指向一行和一列,行列重叠的单元就是我们所寻找的存储单元,这就是内存芯片寻址的基本原理。对于内存颗粒来说,这个阵列就是逻辑Bank(LogicalBank,简称L-Bank)。


但是,在实际应用中,由于技术、成本等原因,不可能只做一个全容量的L-BANK,而且最重要的是,由于DRAM的工作原理限制,单一的L-Bank将会造成严重的寻址冲突,大幅降低内存效率。所以人们在DRAM内部分割成多个L-Bank,每个L-Bank形状相同,彼此独立,可以独立工作。早期的DRAM芯片内部分为2个L-Bank,后来是4个,DDR3内存芯片为8个。在进行寻址时需要先确定是哪个L-Bank,然后再在这个选定的L-Bank中选择相应的行与列进行寻址。对内存的访问,一次只能是一个L-Bank,而每次与CPU交换的数据就是L-Bank存储阵列中一个“存储单元”的容量。SDRAM内存芯片一次传输的数据量就是芯片的位宽,那么这个存储单元的容量就是芯片的位宽(也是L-Bank的位宽)。上图为4BANK内存颗粒内部结构示意图。内存芯片容量的计算方法为:存储单元数量=行数×列数(得到一个L-Bank的存储单元数量)×L-Bank的数量。在很多内存产品介绍文档中,都会用M×W的方式来表示芯片的容量。M是该芯片中存储单元的总数,单位是兆,W代表每个存储单元的容量,也就是SDRAM芯片的位宽(Width),单位是bit。计算出来的芯片容量也是以bit为单位,但用户可以采用除以8的方法换算为字节(Byte)。


SDRAM的行地址有13根 (RAS#="L",CAS#="H",WE#="H",BAs=Bank,A0-A12=RowAddress)SDRAM的列地址有9根 (RAS#="H",CAS#="L",WE#="L",BAs=Bank,A10="L",A0-A8=ColumnAddress)S3C2440存储控制器的地址线A24,A25接到SDRAM的BA0,BA1,用来控制4个L-bank的选择

举个例子:SDRAM芯片就像小学生练字本,比如这个练字本有4页(可以理解为SDRAM有4个L-bank),每页有2^13行,每页有2^9列,每一行与列对应的单元格都是一个存储单元(EM63A165是16bit此处的存储单元是16bit)容量计算:(2^13*2^9*16*4)/8=32M解释:13位行地址译码器,对应有2^13行单元09位列地址译码器,对应有2^9行单元2^13*2^9=4194304个存储单元/L-bank每个存储单元是16bit,单片16bitSDRAM一次读取就是16bit,每片SDRAM有4个L-bank,4194304*4=16777216个存储单元/每个sdram每8个bit是一个字节16777216*16=268435456bit有了L-bank,行地址,列地址后,就可以访问sdram的任意一个单元了,
就像小学生,先翻开第几张纸,选哪一行,再选那一列,然后写下一个汉字(刚好16bitGBK编码)SDRAM芯片内部分为4个bank,BA0,BA1用来选择第几个bank(相当于小学生准备读/写的这个汉字,你要存到那一页)



实验:在SDRAM上,跑一个程序,LED闪烁思路:硬件平台准备JZ2440配置相关寄存器【行地址,列地址,l-bank,刷新率等等】程序从nandcopy4K到sram程序在sram中执行,把第二段程序copy到sdram跳到sdram中执行!实验完成1,硬件平台准备:JZ2440





chunli@ubuntu:~/my03$ll

total12

-rw-rw-r--1chunlichunli2703Apr1303:49head.S

-rw-rw-r--1chunlichunli532Apr1303:50leds.c

-rw-rw-r--1chunlichunli312Apr1303:50Makefile



chunli@ubuntu:~/my03$vimhead.S @************************************************************************* @File:head.S @功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行 @************************************************************************* .equMEM_CTL_BASE,0x48000000 .equSDRAM_BASE,0x30000000 .text .global_start _start: bldisable_watch_dog@关闭WATCHDOG,否则CPU会不断重启 blmemsetup@设置存储控制器 blcopy_steppingstone_to_sdram@复制代码到SDRAM中 ldrpc,=on_sdram@跳到SDRAM中继续执行 on_sdram: ldrsp,=0x34000000@设置堆栈 blmain halt_loop: bhalt_loop disable_watch_dog: @往WATCHDOG寄存器写0即可 movr1,#0x53000000 movr2,#0x0 strr2,[r1] movpc,lr@返回 copy_steppingstone_to_sdram: @将Steppingstone的4K数据全部复制到SDRAM中去 @Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000 movr1,#0 ldrr2,=SDRAM_BASE movr3,#4*1024 1: ldrr4,[r1],#4@从Steppingstone读取4字节的数据,并让源地址加4 strr4,[r2],#4@将此4字节的数据复制到SDRAM中,并让目地地址加4 cmpr1,r3@判断是否完成:源地址等于Steppingstone的未地址? bne1b@若没有复制完,继续 movpc,lr@返回 memsetup: @设置存储控制器以便使用SDRAM等外设 movr1,#MEM_CTL_BASE@存储控制器的13个寄存器的开始地址 adrlr2,mem_cfg_val@这13个值的起始存储地址 addr3,r1,#52@13*4=54 1: ldrr4,[r2],#4@读取设置值,并让r2加4 strr4,[r1],#4@将此值写入寄存器,并让r1加4 cmpr1,r3@判断是否设置完所有13个寄存器 bne1b@若没有写成,继续 movpc,lr@返回 .align4 mem_cfg_val: @存储控制器13个寄存器的设置值 .long0x22011110@BWSCON .long0x00000700@BANKCON0 .long0x00000700@BANKCON1 .long0x00000700@BANKCON2 .long0x00000700@BANKCON3 .long0x00000700@BANKCON4 .long0x00000700@BANKCON5 .long0x00018005@BANKCON6 .long0x00018005@BANKCON7 .long0x008C07A3@REFRESH .long0x000000B1@BANKSIZE .long0x00000030@MRSRB6 .long0x00000030@MRSRB7

chunli@ubuntu:~/my03$vimleds.c

#defineGPFCON(*(volatileunsignedlong*)0x56000050)
#defineGPFDAT(*(volatileunsignedlong*)0x56000054)

#defineGPF4_out(1<<(4*2))
#defineGPF5_out(1<<(5*2))
#defineGPF6_out(1<<(6*2))

voidwait(volatileunsignedlongdly)
{
for(;dly>0;dly--);
}

intmain(void)
{
unsignedlongi=0;

GPFCON=GPF4_out|GPF5_out|GPF6_out;//将LED1,2,4对应的GPF4/5/6三个引脚设为输出

while(1){
wait(30000);
GPFDAT=(~(i<<4));//根据i的值,点亮LED1,2,4
if(++i==8)
i=0;
}

return0;
}



chunli@ubuntu:~/my03$vimMakefile
sdram.bin:head.Sleds.c
arm-linux-gcc-c-ohead.ohead.S
arm-linux-gcc-c-oleds.oleds.c
arm-linux-ld-Ttext0x30000000head.oleds.o-osdram_elf
arm-linux-objcopy-Obinary-Ssdram_elfsdram.bin
arm-linux-objdump-D-marmsdram_elf>sdram.dis
clean:
rm-fsdram.dissdram.binsdram_elf*.o

chunli@ubuntu:~/my0










内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  02 ARM存储控制器