JZ2440 第6章 存储控制器

来源:互联网 发布:log4j sql日志级别 编辑:程序博客网 时间:2024/06/14 11:00

本章目标:

    了解S3C2410/S3C2440地址空间的布局
    掌握如何通过总线形式访问扩展的外设,比如内存、NOR Flash、网卡等
····································································································
    总线的使用方法是嵌入式低层开发的基础,了解它之后,再根据外设的具体特性,就可以驱动外设了。

6.1 使用存储控制器访问外设的原理

6.1.1 S3C2410/S3C2440的地址空间

    S3C2410/S3C2440的“存储控制器”提供了访问外部设备所需要的信息,它有如下特性:
① 支持小字节序、大字节序(通过软件选择);
② 每个BANK的地址空间为128MB,总共1GB(8 BANKs);
③ 可编程控制的总线位宽(8/16/32-bit),不过BANK0只能选择两种位宽(16/32-bit);
④ 总共8个BANK,BANK0~BANK5可以支持外接ROM、SRAM等,BANK6~BANK7除了可以支持
    ROM、SRAM外,还支持SDRAM等;
⑤ BANK0~BANK6共7个BANK的起始地址是固定的;
⑥ BANK7的起始地址可编程选择;
⑦ BANK6、BANK7的地址空间大小是可编程控制的;
⑧ 每个的访问周期均可编程控制;
⑨ 可以通过外部的“wait”信号延长总线的访问周期;
⑩ 在外接SDRAM时,支持自刷新(self-refresh)和省电模式(power down mode)。
    S3C2410/S3C2440对外引出的27根地址线ADDR0~ADDR26的访问范围只有128MB,CPU对外
还引出了8根片选信号nGCS0~nGCS7,对应于BANK0~BANK7,当访问BANKx的地址空间时,
nGCSx引脚输出低电平用来选中外接的设备。这8个BANK的地址空间如下图6.1所示:
 
     S3C2410/S3C2440作为32位的CPU,可以使用的地址范围理论上达到4GB。除去上述用于连接外设
的1GB地址空间外,还有一部分是CPU内部寄存器的地址,剩下的地址空间没有使用。
    S3C2410/S3C2440的寄存器地址范围都处于0x480 0000~0x5ff ffff,各功能部件的寄存器大体相同,
如下表所示:


6.1.2 存储控制器与外设的关系

    本书所用开发板使用了存储控制器的BANK0~BANK6,分别外接了如下设备:
NOR Flash、IDE接口、10M网卡CS8900A、100M网卡DM9000、扩展串口芯片16C2550、
SDRAM,连线方式如下图6.2所示。
    外设的访问地址 = 地址线确定的地址 + BANK的起始地址
比如:扩展串口。
    (1)它使用nGCS5,起始地址为0x2800 0000。
    (2)nCSA=ADDR24||nGCS5,nCSB=!ADDR24||nGCS5。当ADDR24和nGCS5均为低电平
时选中扩展串口A;当ADDR24为高电平、nGCS5为低电平时,选中扩展串口B。
    (3)CPU的ADDR0~ADDR2连接到扩展串口的A0~A2,所以访问空间为8字节。
    综上所述,扩展串口A的访问空间为:0x2800 0000~0x2800 0007;扩展串口B的
访问空间为:0x2900 0000~0x2900 0007(bit24为1)。
图4.2:

    BANK0~BANK5的连接方式都是类似的,BANK6连接SDRAM时复杂一点,CPU提供了一
组用于SDRAM的信号。
① SDRAM时钟有效信号SCKE;
② SDRAM时钟信号SCLK0/SCLK1;
③ 数据掩码信号DQM0/DQM1/DQM2/DQM3;
④ SDRAM片选信号nSCS0(它与nGCS6是同一引脚的两个功能);
⑤ SDRAM行地址选通脉冲信号nSRAS;
⑥ SDRAM列地址选通脉冲信号nSCAS;
⑦ 写允许信号nWE(它不是专用于SDRAM的)。
    SDRAM的内部是一个存储阵列,如同表格一样,将数据填进去。
    SDRAM的寻址基本原理:先指定一个行,在指定一个列,就可以准确地找到所需要的单元格。
这个单元格被称为存储单元。这个表格(存储阵列)就是逻辑Bank(简称L-Bank),SDRAM一般含有
4个L-BANK。
    SDRAM的逻辑结构如图6.3所示。

    可以想象,对SDRAM的访问可以分为如下4个步骤
    (1)CPU发出的片选信号nSCS0有效,它选中SDRAM芯片;
    (2)SDRAM中有4个L-Bank,需要两根地址信号来选中其中一个,从图6.2可知使用ADDR24、
ADDR25作为L-Bank的选择信号;
    (3)对被选中的芯片进行统一行、列(存储单元)寻址;
    根据SDRAM芯片的列地址线数目设置CPU的相关寄存器后,CPU就会从32位地址中自动分出
L-Bank选择信号、行地址信号、列地址信号,然后先后发出行地址信号、列地址信号。L-Bank选
择信号在发出行地址信号的同时发出,并维持到列地址信号结束。
    在图6.2中,行地址、列地址公用地址线ADDR2~ADDR14(BANK6位宽为32,ADDR0/1没有使
用),使用nSRAS、nSCAS两个信号来区分它们。比如本开发板中,使用两根地址线ADDR24、
ADDR25作为L-Bank的选择信号;SDRAM芯片K4S561632的行地址数为13,列地址数为9,所以
当nSRAS信号有效时,ADDR2~ADDR14上发出的是行地址信号,它对应32位地址空间的bit[23:11];
当nSCAS信号有效时,ADDR2~ADDR10上发出的是列地址信号,它对应32位地址空间的bit[10:2]。
由于图6.2中BANK6以32位的宽度连接SDRAM,ADDR0、ADDR1恒为0,不参与译码。
    (4)找到存储单元后,被选中的芯片就要进行统一的数据传输了。
    开发板中使用两片16位的SDRAM芯片并联组成32位的位宽,与CPU的32根数据线(DATA0~DATA31)相连。
    BANK6的起始地址为0x3000 0000,所以SDRAM的访问地址为0x3000 0000~0x33ff ffff,共64MB。
    对图6.2中连接的外设,它们的访问地址(物理地址)如表6.2所示。

 6.1.3 存储控制器的寄存器使用方法

    存储控制器共有13个寄存器,BANK0~BANK5只需要设置BWSCON和BANKCONx(x为0~5)两个
寄存器:BANK6和BANK7外接SDRAM时,除BWSCON和BANKCONx(x为6、7)外,还要设置REFRESH、
BANKSIZE、MRSRB6、MRSRB7等4个寄存器。下面分类说明:
    1.位宽和等待控制寄存器BWSCON
    每4位控制一个BANK,最高4位对应BANK7、接下来4位对应BANK6,以此类推。
    (1)STx:启动/禁止SDRAM的数据掩码引脚,对于SDRAM, 此位为0;对于SRAM,此位为1;
    (2)WSx:是否使用存储器的WAIT信号,通常设为0;
    (3)DWx:使用两位来设置相应BANK的位宽:
    0b00:8位,0b01:16位,0b10:32位,0b11:保留;
       BANK0比较特殊,只支持16和32位两种位宽,它没有ST0和WS0,DW0([2:1])只读——由硬件跳线决定:
    0b01:16位,0b10:32位;
        对于本开发板,没有使用BANK7,根据表6.1可以确定BWSCON的值为:0x2201 1110。
    2.BANK控制寄存器BANKCONx(x为0~5)
    这几个寄存器用来控制BANK0~BANK5外接设备的访问时序,使用默认的0x0700即可满足
本开发板所接各外设的要求。
    3.BANK控制寄存器BANKCONx(x为6~7)
    在8个BANK中,只有BANK6和BANK7可以外接SRAM或SDRAM,所以BANKCON6~
BANKCON7与BANKCON0~BANKCON5有点不同。
    (1)MT([16:15]):用于设置本BANK外接的是ROM/SRAM还是SDRAM。
    当MT = 0b00:时,接SRAM,此寄存器与BANKCON0~BANKOCN5类似;
    当MT = 0b11:时,接SDRAM,此寄存器其他值如下设置。
    (2)Trcd([3:2]):RAS to CAS delay,设为推荐值0b01。
    (3)SCAN([1:0]):SDRAM的列地址位数,对于本开发板使用的SDRAM K4S561632,
列地址位数为9,所以SCAN = 0b01。如果使用其他型号的SDRAM,需要查看数据手册来
决定SCAN的取值。0b00:8位;0b01:9位;0b10:10位。
    综上所述,本开发板中BANKCON6、7均设为0x0001 8005。
    4.刷新控制寄存器REFRESH:设为0x008c 0000 + R_CNT
    (1)REFEN([23]):0 = 禁止SDRAM的刷新功能,1 = 开启SDRAM的刷新功能。
    (2)TREFMD([22]):SDRAM的刷新模式,0 = CBR/Auto Refresh,1 = Self Refresh(一般在系统休眠时使用)。
    (3)Trp([21:20]):设为0即可。
    (4)Tsrc([19:18]):设为默认值0b11即可。
    (5)Refresh Counter([10:0]):即上述的R_CNT,
            R_CNT = 2^11 + 1 - SDRAM时钟频率(MHz) * SDRAM刷新周期(us);
        其中SDRAM时钟频率就是HCLK,SDRAM的刷新周期在SDRAM数据手册上有标明,
在本开发板所使用的SDRAM 数据手册上,可以看见“ 64ms refresh period(8K Cycle)”。所以,
刷新周期 = 64ms/8192 = 7.8125us。
    在未使用PLl时,SDRAM时钟频率等于晶振频率12MHz。
    现在可以计算:R_CNT = 2^11 + 1 - 12*7.8125 = 1955。
    所以,在未使用PLL时,REFRESH = 0x008c 0000 + 195 = 0x008C 07A3。
    5.BANKSIZE寄存器BANKSIZE
    (1)BURST_EN([7])。
            0 = ARM核禁止突发传输,1 = ARM核支持突发传输。
    (2)SCKE_EN([5])。
            0 = 不使用SCKE信号令SDRAM进入省电模式,1 = 使用SCKEN信号令SDRAM进入省电模式。
    (3)SCLK_EN([4])。
            0 = 时刻发出SCLK信号,1 = 仅在访问SDRAM期间发出SCLK信号(推荐)。
    (4)BK76MAP([2:0]):设置BANK6/7的大小。
            BANK6/7对应的地址空间与BANK0~5不同:
            BANK0~5的地址空间大小都是固定的128MB,地址范围是(x * 128M)到(x+1)*128M -1,x表示0~5。
            BANK6/7的大小是可变的,以保持这两个空间的地址连续,即BANK7的起始地址会随着
它们的大小变化。
            BK76MAP的取值意义如下:
            0b010 = 128MB/128MB,0b001 = 64MB/64MB,0b000 = 32M/M,
            0b111 = 16M/16M,0b110 = 8M/8M,0b101 = 4M/4M,0b100 = 2M/2M
            本开发板BANK6外接64MB的SDRAM,令[2:0] = 0b001,表示BANK6/7的容量都是64MB,
虽然BANK7没使用。
    综上所述,开发板的BANKSIZE寄存器的值可算得0xB1。
    6.SDRAM模式设置寄存器MRSRBx(x为6~7)
    能修改的只有位CL([6:4]),这是SDRAM时序的一个时间参数:
    [work] 0b000 = 1 clock,0b010 = 2 clocks,0b011 = 3 clocks
    SDRAM K4S561632不支持CL = 1的情况,所以此位取值0b010(CL = 2)或0b011(CL = 3)。
本开发板取最保守值0b011,所以MRSRB6/7的值为0x30。

6.2 存储控制器操作实例:使用SDRAM

6.2.1 代码详解及程序的复制、跳转过程

    从NAND Flash启动CPU时,CPU会通过内部的硬件将NAND Flash开始的4KB数据复
到称为“Steppingstone”的4KB的内部RAM中(起始地址为0),然后跳到地址0开始执行。
    本实例先使用汇编语言设置好存储控制器,使外接的SDRAM可用;然后把程序从
Steppingstone复制到SDRAM处;最后跳到SDRAM中执行。
    源代码在/work/hardware/sdram目录中,包含两个文件head.S和leds.c。其中leds.c和第5
章中的leds的代码完全一样,也是让3个led从0~7轮流计数。
    重点在head.S,它的作用是设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM
继续执行。head.S的代码如下:
    程序是如何通过第15行的“ ldr pc, =on_sdram”指令来完成的
    程序标号“on_sdram”这个地址值在连接程序时被确定为0x3000 0010(这个是SDRAM的
地址),执行“ldr pc, =on_sdram”后,程序一下子就跳到SDRAM中去了。
    “on_sdram”这个地址值为什么等于0x3000 0010?
    Makefile中连接程序的命令为“arm-linux-ld -Ttext 0x30000000 head.o sdram.o -o
 sdram_elf”,意思就是代码段的起始地址为0x3000 0000,即程序的第一条指令(第12行)的
连接地址为0x3000 0000,第二条指令(第13行)的连接地址为0x3000 0004,...,第5条指
令(第17行)的连接地址为0x3000 0010,其程序标号“on_sdram”的值就是0x3000 0010。
    虽然第12~14行指令的连接地址都在SDRAM中,但是由于他们都是位置无关的相对
跳转指令,所以可以在Steppingstone里执行。
    Makefile如下(注意第4行,“-Ttext 0x30000000”指定了代码段的起始地址):
1
sdram.bin : head.S leds.c
2
    arm-linux-gcc -c -o head.o head.S
3
    arm-linux-gcc -c -o leds.o leds.c
4
    arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
5
    arm-linux-objcopy -O binary -S sdram_elf sdram.bin
6
    arm-linux-objdump -D -m arm sdram_elf > sdram.dis
7
clean:
8
    rm -f sdram.dis sdram.bin sdram_elf *.o
    为了更形象地了解本程序,下面用图6.4来演示程序的复制、跳转过程。



6.2.2 实例测试

    在sdram目录中执行make指令生成可执行文件sdram.bin后,下载到板子上运行。可以
发现与leds程序相比,LED闪烁得更慢,原因是外部SDRAM的性能比内部SRAM差一些。
    把程序从性能更好的内部SRAM移到外部SDRAM中去,是否多此一举呢?内部SRAM
只有4KB大小,如果程序大于4KB,那么就不能指望完全利用内部SRAM来运行了,得想
办法把存储在NAND Flash中的代码复制到SDRAM中去。对于NAND Flash中的前4KB,
芯片自动把它复制到内部SRAM中,可以很轻松地再把它复制到SDRAM中(实验代码中的
函数copy_steppingston_to_sdram就有此功能),要复制4KB后面的代码需要使用NAND Flash
控制器来读取NAND Flash,这就是第8章的内容。
附:代码:
链接: https://pan.baidu.com/s/1kV24a9L 密码: tfab
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 胶水瓶口被塞住怎么办 美林盖子打不开怎么办 美林瓶盖打不开怎么办 泰诺瓶盖打不开怎么办 玻璃罐头瓶盖打不开怎么办 塑料罐头瓶盖打不开怎么办 喷笔壶盖打不开怎么办 陶瓷壶盖卡住了怎么办 贝德玛瓶盖摔坏怎么办 塑料盖子错位拧不开怎么办 安全瓶盖坏了怎么办 刚买面霜打不开怎么办 可乐瓶盖鼓起来怎么办 暖壶塞子吸住了怎么办 茶兀瓶盖打不开怎么办 水杯盖太紧了拧不开怎么办 矿泉水瓶盖拧不开了怎么办 弩弦用手拉不上怎么办 茅台酒瓶口漏酒怎么办 化妆品盖子丢了怎么办 化妆品盖子碎了怎么办 自制水泵压力小怎么办 大学数学不会做怎么办 下雪了怎么办教案幼儿园小班 下水道被混凝土堵塞怎么办 日本足贴丢了胶布怎么办 牙齿被可乐腐蚀怎么办 三十岁满嘴无牙怎么办 水乳盖子打不开怎么办 蜂蜜罐子打不开了怎么办 蜂蜜盖子第二次拧不开怎么办 玻璃杯子拧不开盖子怎么办 玻璃杯水杯盖子拧不开怎么办 鞋子蝴蝶结掉了怎么办 蝴蝶翅膀受伤了怎么办 手被割了个口子怎么办 致炫方向盘重怎么办 黑檀7打不透怎么办 乒乓球底板太轻怎么办 狙击精英4卡怎么办 鼠标点一下变两下怎么办