Chinaunix首页 | 论坛 | 博客
  • 博客访问: 803617
  • 博文数量: 869
  • 博客积分: 201
  • 博客等级: 入伍新兵
  • 技术积分: 3376
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-21 19:42
文章分类

全部博文(869)

文章存档

2014年(4)

2013年(415)

2012年(453)

我的朋友

分类:

2012-10-13 11:09:12

原文地址:(五)、 存储器控制 作者:machoe

有了前几节的基础,相信大家对ARM程序的开发有了一定的了解和掌握,也会产生浓厚的兴趣。但细心的读者肯定会问:为什么我们每次都能将编译好的程序直接下载到SDRAM中呢?难道它不用我们对其进行操作就可以运行吗?

其实,SDRAM并不是想象的那么神奇,在我们使用它的时候,我们肯定要为他做一些初始化和配置,那为什么我们前几节的代码中没有涉及到SDRAM呢?那是因为我们利用的是天嵌科技的U-BOOT启动的开发板,又利用U-BOOT将程序下载到开发板中,SDRAM初始化和配置等工作都由U-BOOT为我们准备好了,因此,我们就可以直接拿来用了。

本章介绍了一些存储器、存储器控制器的相关概念和具体的TQ2440开发板上SDRAM的使用方法。并通过一个实例来告诉大家如何使用存储器。建议读本章的朋友配合《S3C2440手册》的第5章,进行学习。

 一、基础知识准备

1、单位

我的TQ2440开发板的硬件配置是256MBNandFlash64MB Sdram2MB NorFlash。这里请大家注意,单位我用的是MB,而有一些场合用的是Mb,这大写的B代表的是BYTE,也就是通常我们说的字节;而小写的b代表的是bit,也就是位。

下面请大家牢记:

括号内表明,我们需要多少个字节来表示这么大的空间,如:1KB,我们需要2^10Byte来表示。

以后,我推荐大家尽量统一使用一个单位,例如上面的三个单位,我都使用MB,这样免得一不小心看错。

2S3C2440地址空间

S3C2440 CPU共有27根地址线,ADDR0~ADDR26,因此它可以访问2^27大小的地址空间,这也正是2^7*2^20大小,128MB。在天嵌的论坛上曾有人提问过,手册上说可以访问1GB的大小,这是怎么做到的呢?

CPU除了这27根地址线外,还有8根“片选”,nGCS0~nGCS7,这8根“片选”也正好对应着CPUBANK0~BANK7。加上这8根上,正好可以构成一个1GB大小的地址空间。

TQ2440开发板使用存储器控制器来控制外设,说得通俗一点,就是把外设的一些端口,寄存器映射到CPU的内部地址空间中,这样,我们对外设的操作就可以转向对CPU内部地址空间的操作,简化我们的操作,这里我不细讲,免得给大家弄糊涂了,我们每讲一种外设时,我们再对应该外设来详细说明,等所有的外设都讲过了,我相信大家的肯定就会清楚“用存储器控制器来控制外设”这句话的意思了。

3SDARM

SDRAM:Synchronous Dynamic Random Access Memory,同步动态随机存储器,同步是指 Memory工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机是指数据不是线性依次存储,而是自由指定地址进行数据读写。

这里给大家做一个知识补充:在我们现在所用的PC机中,所指的内存,其实就是SDRAM,只不过是他的升级版,如DDR内存,DDR2内存,DDR3内存等等,而且很多喜欢玩3D游戏的玩家肯定对显卡也很有研究,其实大部分显卡上的显存也是SDRAM的,那么DDRSDRAM是什么关系呢?有什么区别呢?简单的说,DDR就是SDRAM的升级版。这里不多说,有兴趣的朋友可以阅读“推荐阅读”版块的内容。

另外,SDRAM在嵌入式开发中起什么作用呢?学过单片机的朋友肯定会知道,程序的运行需要有两个必备条件:一、要有能存储程序代码(BIN文件)的存储器;二、要有能够运行的RAM。单片机(以51单片机为例)内部集成了ROMRAM,因此外围可以不必再扩展存储器,而对于S3C2440CPU,内部没有集成存储器,因此,我们必须要有外部扩展存储器来存储代码和运行程序。等大家学完了NAND FLASHNor FLASHSDRAM后就会明白各个器件的作用了。

在这里,无论您的学习方向是硬件还是软件,我推荐的学习方法是都要先看一下硬件的连接,原理图,这样有助于理解。TQ2440是选用2HY57V561620FTP-H组成64MB32位的内存,每片32MB容量、16位数据总线。

看原理图之前,先来介绍一下CPU提供的一组用于SDRAM的信号:

1.       SDRAM的时钟有效信号SCKE

2.       SDRAM的时钟信号SCLK0SCLK1

3.       数据掩码信号DQM0DQM1DQM2DQM3

4.       SDRAM片选信号nSCS0(它与nGCS6是同一引脚的两个功能);

5.       SDRAM行地址选通脉冲信号nSRAS

6.       SDRAM列地址选通脉冲信号nSCAS

7.       写允许信号nWE(它不是专用于SDRAM的)。

SDRAM的内部是一个存储阵列,阵列就类似于表格一样,有行、列之分,这样我们要访问(读、写)一个单元,就要先指定一个行地址,一个列地址,这样就找到了该单元,这就是SDRAM的寻址的基本原理。这里的单元我们一般称为存储单元,而整个表格称为逻辑BANKLogical  Bank , L-BANK),一般每个SDRAM都会有4L-BANK。如下图:有4L-BANK,每个4Mx16位,并且分为XY也就是行和列。

二、SDRAM相关操作 1CPU操作SDRAM的一般步骤

1.         CPU发出片选信号nSCS0,选中SDRAM芯片。

2.         用两根地址线选中L-BANK,对应芯片的BA0BA1两引脚。

3.         对被选中芯片的L-BANK进行行、列寻址。

TQ2440开发板是由两块16位的SDRAM芯片并联组成32位的位宽,与CPU32根数据线DATA0~DATA1相连。SDRAM是连接在BANK6上的,起始地址为0x30000000,大小为64MB,根所上面的公式可以得出:

64  MB = Byte

因此,地址空间为:0x30000000----- 0x33FFFFFF

2、存储器控制寄存器使用介绍

BANK0~BANK5只需设置BWSCONBANKCONx两个寄存器;BANK6BANK7外接SDRAM时,除BWSCONBANKCONx外,还要设置REFRESHBANKSIZEMRSRB6MRSRB7四个寄存器。

1.       BWSCON位宽和等待控制寄存器

该寄存器每4位控制一个BANK,最高4位控制BANK7,最低4位控制BANK0

1)         STx:启动/禁止SDRAM的数据掩码引脚,对于SDRAM,此位为0

2)         WSx:是否使用WAIT信号,通常设为0.

3)         DWx:使用两位来选择位宽。00对应8位,01对应16位,10对应32位,11暂时保留。

比较特殊的是BANK0,它没有ST0WS0DW0为只读-------它是由硬件来决定的。BANK0只支持16位、32位两种模式,01代表16位,10代表32位。引脚OM[10]决定,如下图。

2.       BANKCONx BANK控制寄存器

l  x0~5,这些寄存器控制相应BANK的外接设备访问时序。

l  x67时,

MT :用来选择外接设备的类型,00代表SRAM11代表SDRAM

Trcd RAS To CAS delay 推荐使用01

SCANSDRAM的列地址数,要根据硬件的实际情况来选择。00代表8位,01代表9位,10代表10位。

SRAM:

      静态随机存储器,相比SDRAM,其优点是速度更快,不用动态刷新。

 

 

 

 


3.       REFRESH 刷新控制寄存器

REFEN :0代表禁止SDRAM的刷新功能;1代表开启刷新功能。

TREFMD:刷新模式的选择,0代表CBR/Auto Refresh1代表Self Refresh(自刷新,一般在系统休眠时使用)

Trp:时序设置,设为0

Tsrc:时序设置,设为11

Refresh Couner: 即,R_CNT此值需计算得出,公式为:

 

SDRAM的时钟频率为HCLK,在未使用PLL倍频前,就是晶振频率12MHz;刷新周期为见手册(HY57V561620F(L)T(P) Series)第5页,其中有一句8,192 Refresh cycles / 64ms。可以得出:刷新周期=64ms/8192=7.8125uS.最后可以得出:R_CNT=1955

4.  BANKSIZE 寄存器

BURST_EN0代表ARM核禁止突发传输。1代表ARM核支持突发传输。

SCKE_EN: 0表示不使用SCKE信号令SDRAM进入省电模式;1表示使用SCKE信号令SDRAM进入省电模式。

SCLK_EN: 0表示时时刻刻都发出SCLK信号;1表示只在当访问SDRAM期间才发出SCLK信号。

BK76MAP:用来设置BANK6BANK7的大小。

    010=128MB001=64MB000=32MB111=16MB110=8MB101=4MB100=2MB

5.  MRSRBx模式寄存器

这里只能修必CL[64]位,这需要根据硬件的实际情况,查手册来修改,此为SDRAM的时序设置。

000 = 1 clock          010 = 2 clock          011 = 3 clock

三、复习

经过几面几章的复习,我想大家能成功的完成各章节实验。前几节的实验我的建议是利用TFTP手动下载到SDRAM中运行,而SDRAM的初始化工作一直由U-BOOT来完成。现在大家可以使用天嵌科技提供的U-BOOT来将代码直接下载到NAND FLASH中运行,但这里一定要注意,要确保SP的位置,如果直接下载到SDRAM中,确保SP一定要在SDRAM中;如果下载到NAND FLASH中,一定要在NAND FLASH的前4KB中,因此,如果下载到NAND FLASH中,要将SP设置为1024*4,即:“ldr sp,=1024*4”。

下载的方法是利用NOR FLASH启动,然后选择“n”,进入TFTP下载菜单,然后选择“a”键,就可以下载程序到NAND FLASH中了。请大家再次学习天嵌的手册教程,熟悉U-BOOT的使用。大家不要怕弄坏板子或里面烧写好的程序,学习就需要一个失败再尝试的过程,只有在不断的失败中总结经验,才能学到真东西,如果大家遇到麻烦,请天嵌论坛或我个人博客上发帖。

四、代码详解

本章例程我将提供两个程序,一个是leds,一个是sdram。其中leds程序是流水灯程序,内容比较简单,只是单纯的实现了流水灯;而sdram程序是包涵了sdram的操作的流水灯程序。二者的区别是:leds下载到nand flash后,只能在nand flash中(4KB大小的SRAM)执行,而sdram程序下载到nand flash后,由于里面包涵了代码搬运和sdram初始化工作后,自动跳转到sdram中运行。

Leds程序相对比较简单,有了前几章的基础后,大家自行学习,我就不再讲了,这里,我主要讲一下sdram程序。下面我先列出代码。

@*************************************************************************

@ Filehead.S

@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

@*************************************************************************    

.equ        MEM_CTL_BASE,       0x48000000   @SDRAM寄存器地址基址

.equ        SDRAM_BASE,         0x30000000   @SDRAM连接在BANK6上,此为SDRAM内存空间地址

.text

.global _start

_start:

    bl  disable_watch_dog                   @ 关闭WATCHDOG,否则CPU会不断重启

    bl  memsetup                              @ 设置存储控制器

    bl  copy_steppingstone_to_sdram              @ 复制代码到SDRAM

    ldr pc, =on_sdram                            @ 跳到SDRAM中继续执行

on_sdram:

    ldr sp, =0x34000000                          @ 设置堆栈

    bl  main

halt_loop:

    b   halt_loop

disable_watch_dog:

    @ WATCHDOG寄存器写0即可

    mov r1,     #0x53000000

    mov r2,     #0x0

    str r2,     [r1]

    mov pc,     lr                               @ 返回

copy_steppingstone_to_sdram:

    @ Steppingstone4K数据全部复制到SDRAM中去

    @ Steppingstone起始地址为0x00000000SDRAM中起始地址为0x30000000   

    mov r1, #0

    ldr r2, =SDRAM_BASE

    mov r3, #4*1024

1: 

    ldr r4, [r1],#4                         @ Steppingstone读取4字节的数据,并让源地址加4

    str r4, [r2],#4                         @ 将此4字节的数据复制到SDRAM中,并让目地地址加4

    cmp r1, r3                           @ 判断是否完成:源地址等于Steppingstone的未地址?

    bne 1b                              @ 若没有复制完,继续

    mov pc,     lr                       @ 返回

memsetup:

    @ 设置存储控制器以便使用SDRAM等外设

    mov r1,     #MEM_CTL_BASE          @ 存储控制器的13个寄存器的开始地址

    adrl    r2, mem_cfg_val               @ 13个值的起始存储地址

    add r3,     r1, #52                   @ 13*4 = 54

1: 

    ldr r4,     [r2], #4                    @ 读取设置值,并让r24

    str r4,     [r1], #4                    @ 将此值写入寄存器,并让r14

    cmp r1,     r3                       @ 判断是否设置完所有13个寄存器

    bne 1b                              @ 若没有写成,继续

    mov pc,     lr                       @ 返回

.align 4

mem_cfg_val:

    @ 存储控制器13个寄存器的设置值

    .long   0x22011110      @ BWSCON

    .long   0x00000700      @ BANKCON0

    .long   0x00000700      @ BANKCON1

    .long   0x00000700      @ BANKCON2

    .long   0x00000700      @ BANKCON3 

    .long   0x00000700      @ BANKCON4

    .long   0x00000700      @ BANKCON5

    .long   0x00018005      @ BANKCON6

    .long   0x00018005      @ BANKCON7

    .long   0x008C07A3      @ REFRESH

    .long   0x000000B2      @ BANKSIZE

    .long   0x00000030      @ MRSRB6

    .long   0x00000030      @ MRSRB7

程序以_start为入口,先后调用关看门狗子程序、SDRAM寄存器设置子程序、代码搬动子程序,最后进入到SDRAM中调用MAIN函数。

SDRAM寄存器设置子程序采用的方法类似于我们初学单片机时使用的循环查表。R1中存放的是寄存器的基址0x48000000,关于寄存器的地址请大家查看手册,由于每个寄存器占4个字节,而且是挨着的,因此我们可以采用这种循环查表的方法,利用这个技巧,可以简化操作。R2存放的是表的首地址,表中的数据是用.long定义的立即数,具体的数值请大家根据上文的讲述和手册对照查看。R3存放的是第13个寄存器的地址,用来判断是否设置完毕。这里有一句代码“bne 1b”,新手可能会有所疑惑,简单的说,这句的意思就是跳转指令,跳转到哪呢?当然是“1b”了。那“1b”是什么意思呢,这里“1”代表标号,就是我们程序中的“1:”,其中“b”有“behind”的意思,就是说跳转到后面的“1:”处,但请注意,这里的“后面”可不是程序代码的“下面”,反而是“上面”,现在大家明白了吧。另外,除了“b”,还有“f”,代表“forward”,后面我们会用到。

程序中的leds.c文件比较简单,相信大家自己能理解。我就不多说了。这里请大家注意一下,head.s文件中,有一句“  ldr pc, =on_sdram”,这里为什么不用“b”呢?这个问题留给大家,希望大家广泛讨论。答案会在MMU一章公布。

别外重点是为什么经过了上面给pc赋值后就跳转到sdram中去了呢?在Makefile中有一句链接命令:arm-linux-ld –Ttext 0x30000000 head.o sdram.o –o sdram_elf。这里面确定了代码段的地址为0x30000000。这也对应着,链接时,入口(_start)地址为0x30000000,下面每条语句占4个字节,这样算来,“ldr pc,=on_sdram”就正好在0x30000010地址处了。

五、实验现象

1. 请大家将leds程序烧写到nand flash中后,直接利用nand flash启动,观察流水灯的变化速率,如果过快,可以自行调整leds.c文件中的延时函数,将延时增大。

2. 再实验leds程序后,大家再将同样延时大小的sdram的程序下载到nand flash中,再观察流水灯的变化速度,这里肯定会有样一个现象:延时函数一样,但流水灯的速度却不一样,这是为什么呢?

3. 再将leds程序修改SP指针,使其指向SDRAM中,“ldr sp,=0x31000000”,再将其通过nor flash启动,烧写到sdram中,观察实验现象。

分析1:对比12的实验现象

这是由于程序的运行地址不一样,leds程序运行在nand flash中自带的前4KBSRAM中,而sdram是将代码搬移到了sdram中运行。SRAMSDRAM的性能不一样,SRAM速度略优于SDRAM,因此实验效果不一样。

分析2:对比23的实验现象

  为什么leds下载到sdram中的速度是最快呢?这里我提示大家一下,板子是通过U-BOOT启动的,里面初始化了时钟,具体的原因,会在时钟一章节公布。

六、参考资料与推荐阅读

1.韦东山 《嵌入式LINUX应用开发完全手册》

2.三星 《S3C2440手册》

3.SDRAM介绍 http://baike.baidu.com/view/18583.htm

4.SDRAM介绍 http://zhidao.baidu.com/question/1857214.html?fr=ala0

5.SDRAM介绍 http://baike.baidu.com/view/194419.htm

6.SRAM介绍  http://baike.baidu.com/view/423438.htm

阅读(116) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~