天嵌 ARM开发社区

 找回密码
 注册
查看: 2344|回复: 5

裸奔程序5-内存控制器及SCATT文件

[复制链接]
吕氏春秋8266 发表于 2010-12-5 13:08:26 | 显示全部楼层 |阅读模式
本帖最后由 吕氏春秋8266 于 2010-12-5 13:26 编辑

第四章 存储控制器

S3c2440存储控制器提供了访问外部设备所需的信号,有如下特征:
每个BANK空间为128M,总共1G
编程控制总线宽度(8/16/32),不过BANK0只能选择16/32
BANK0~BANK5外接ROM\SRAM,BANK6~BANK7还可外接SDRAM
BANK0~BANK6起始地址固定,BANK7起始地址可编程选择
每个BANK访问周期可编程控制
通过外部的“wait”信号延长总线的访问周期
S3c2440对外引出27根地址线ADDR0~ADDR26,其访问范围为128M,此外,CPU还对外引出8根片选信号nGCS0~nGCS7

在访问SDRAM时,CPU提供了一组用于SDRAM的信号
SDRAM时钟有效信号SCKE;
SDRAM时钟信号 SCLK0/SCLK1
数据掩码信号DQM0~DQM3
片选信号nGCS6~nGCS7
SDRAM行地址选通信号nSRAS
SDRAM列地址选通信号nSCAS

SDRAM结构:



我们先看看对SDRAM读写的时序图:


从上图我们可以看出,根据SDRAM芯片的列地址设置相关寄存器后,CPU就会从32位地址中自动分出L-BANK选择信号、行、列地址信号,然后先后发出行地址及信号,列地址及信号及L-BANK信号。也就是说,CPU分两次将行及列地址分别送入SDRAM进行锁存,然后再进行数据读写。

内存控制器
内在控制器为访问外部存储空间提供存储器控制信号,提供了13个特殊功能寄存器。
1、        BSWCON总线宽度控制寄存器用来控制各组存储器的总线宽度和访问周期。每4位控制一个BANK,最高位对应BANK7
BWx[0:1]:设置相应BANK的位宽。00:8 ,01:16,10:32
WSx[2]  :是否使用存储器等待信号,通常为0
STx[3]   :启动\禁止SDRAM掩码引脚,其中SDRAM:0,SRAM:1
2、        BANKCONx控制外接设备的访问时序。

其中BANK6~BANK7位[16:15]来表示存储器的类型:
00:ROM或SRAM
11:SDRAM
Tacs[14:13]:在nGCSn有效前地址信号建立时间
Tcos[12:11]:在nOE   有效前芯片选择信号建立时间
Tacc[10:8]: 访问周期,如启用nWAIT信号,则Tacc大于或等于4个周期
Tcoh[7:6]:  nOE信号无效后芯片选择信号保持时间
Tcah[5:4]:  nGCSn无效后地址保持时间
Tacp[3:2]:页模式访问周期
PMC[1:0]:页模式配置
如果BANK6~BANK7外接SDRAM时,即[16:15]=11,则[3:0]位定义如下:
Trcd[3:2]:从RAS到CAS延时
SDRAM使用的频率是HCLK。
FCLK for CPU,
HCLK for the AHB bus peripherals,
PCLK for the APB bus peripherals.
在TQ2440开发板的uboot中,FCLK = 400MHz
FCLK:HCLK:PCLK = 1:4:8  
TQ2440使用的是SDRAM是HY67V561620F,查看Spec.

RAS to CAS Delay的最小值为15~20 ns
HCLK为100MHz,所以一个clock为10ns,所以至少需要2个clock.

SCAN[1:0]:列地址位数。00:8,01:9,10:10
查阅Spec,列地地址位数为9

BANK0~BANK5在系统复位后,其值为0x700表示Tacs=Tcos=Tcon=Tcah=Tacp=1,
Tacc=14个周期,PMC=0表示页配置正常模式。
BANK6~BANK7在系统复位后,其值为0x180008表示BANK6~BANK7外接SDRAM,同时设定RAS到CAS延时4个周期,8位列地址数目。


TQ2440中BANKCON6和BANKCON7的其它位数均为0。
综合以上各值,BANKCON6~BANKCON7设为0x00018005

3、        REFRESH用于设置SDRAM的自动刷新。
REFEN[23]:  0:无效1:使能有效
TREFMD[22] 0:自动刷新;1:选择自刷新方式
Trp[21:20] SDRAM预充电时间
Tsrc[19:18]控制SDRAM半行周期时间
Refcnt[10:0]SDRAM刷新计数器,

得到刷新周期为64ms/8192=7.8125us,
TQ2440的HCKL为100MHz
结合公式,R_CNT=2^11 + 1 – 12 * 7.8125 = 1955。

Refresh count = 2^11 +1 -100X7.8125 = 1268 = 0x4F4
Trp([21:20]):设置为0即可。(Precharge time)


4、        BANKSIZE寄存器用于调整BANK大小
BURST_EN[7]:0/1 禁止/允许ARM核突发传输.。
SCKE_EN[5]:0/1 不使用/使用SCKE信号令SDRAM进入省电模式
SCKE_EN[4]:0/1 时刻/SDRAM访问期间发出SCKE信号,
BK67MAP[02]:设置大小。000-32 001-64 010-128
本开发板仅使用BANK6的64M空间,其中BK76MAP(bit[2:0])配置BANK6/7映射的大小,可设置为010 = 128MB/128MB或001 = 64MB/64MB,只要比实际RAM大都行,多出来的空间程序会检测出来,不会发生使用不存在的内存的情况(Bootloader和Linux内核都会作内存检测)。。
5、        MRSRBx
能修改的只有位CL[6:4](CAS latency,000 = 1 clock, 010 = 2 clocks, 011=3 clocks),其他的全部是固定的(fixed),故值为0x00000030。SDRAM 不支持CL=1的情况,所以位[6:4]取值为010(CL=2)或011(CL=3),开发板保守的值为0b11。

TQ2440存储器控制器
BWSCON: 0x22121110;GCS4=GCS6=GCS7=32bit,
   由于TQ2440外接NOR flash,开发板采用了最保守的值,即正常模式,每次读写一个数据,其它所有时钟周期均最大
BANK0  :0x7ff4
BANK1~BANK5:0x2e50
表示外接SDRAM,其列地址为9位,RAS到CAS延时为2周期。
BANK6~BANK7:0x18005
设置寄存器刷新HCLK=100M u=7.812us   2048+1-100*7.81=1268=0x4f4
REFRESH:0x9404f4
BANKSIZE:0x32
MRSRBx  :0x30

程序说明:
因为存储寄存器为连续地址空间,有初始化程序中,我们用如下代码进行设置:
;初始化存储控制器寄存器,使SDRAM可用

        adr r0,MEMDAT
        ldr r1,=BWSCON
        add r2,r0,#52
0
        ldr r3,[r0],#4
        str r3,[r1],#4
        cmp r2,r0
        bne %b0        
        
MEMDAT DATA
        DCD 0x22121110
        DCD 0x7ff4
        DCD 0x2e50
        DCD 0x2e50
        DCD 0x2e50
        DCD 0x2e50
        DCD 0x2e50
        DCD 0x18005
        DCD 0x18005
        DCD 0x9404f4
        DCD 0x32
        DCD 0x30
        DCD 0x30
adr r0,MEMDAT是伪指令,其汇编为如下个一条指令:
[0xe28f0018]   add      r0,pc,#0x18 ; #0xa4显然它被汇编成基于PC+8+偏移地址模式,能正确读取。

在本例中,我们程序是从NAND中启动,在初始化存储寄存器的基础后,我们打算将点亮LED灯代码从CPU内部RAM中搬移到SDRAM中运行,自然我们产生第一个问题,我们知道,从NAND和SDRAM中运行,其地址不一致,如何保证各模块间地址正确编译呢,在这里,我们将scatter文件来控制。
LOAD_IMAGE 0x0
{
   LOAD_FLASH 0x0 0x1000            ;4K flash
   {
    s3c2440.o(Init,+First)
    TestMain.o(+ro)
   }
   LOAD_SDRAM 0x30000000 0x4000000  ;64M  sdram
   {
    led.o(+ro)
   }
}
第二个问题,我们只想搬运LED代码并将它放在0x30000000,如何得到它在RAM中的起始地址及大小呢,这就将用到如下三个定义
     IMPORT |Load$$LOAD_SDRAM$$Base|     
       IMPORT |Image$$LOAD_SDRAM$$Base|
       IMPORT |Image$$LOAD_SDRAM$$Length|
其拷贝代码如下:
     ldr r0,=|Load$$LOAD_SDRAM$$Base|
        ldr r1,=|Image$$LOAD_SDRAM$$Base|
        ldr r2,=|Image$$LOAD_SDRAM$$Length|
        
        add r2,r0,r2
        
0
        ldr r3,[r0],#4
        str r3,[r1],#4
        cmp r0,r2
        bne %b0
因为,程序从CPU内部RAM跳转至SDRAM中运行,因此,其范围大于32M空间,必须使用ldr pc,=_LEDDISPLAY  指令进行跳转。_LEDDISPLAY由LOAD_SDRAM 0x30000000 0x4000000 模块决定,其值为0x30000000
说明:经过反复测试和反汇编我们得知,如果我们将LOAD_FLASH 初始值改为非0,比如0x1000,|Load$$LOAD_SDRAM$$Base|的值由编译器根据LOAD_FLASH模块的初始值进行决定,在进行软件甚至JLINK仿真时都能通过,但下载到NAND中将不会正常运行。这是因为软件或JLINK仿真都是将程序下载到指定的位置运行,地址正确。但下载到NAND中时,其地址永远从0x0处运行,将导致地址错误。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 吕氏春秋8266 发表于 2010-12-5 13:13:17 | 显示全部楼层
附上源代码,呵呵!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
nuckzjt 发表于 2010-12-5 15:05:15 | 显示全部楼层
先顶一个,收藏一下,以后学习到这里了好做参考!
天嵌_support1 发表于 2010-12-6 11:16:17 | 显示全部楼层
2# 吕氏春秋8266


不错哈,给网友加精一下。供其他网友学习讨论
nuckzjt 发表于 2010-12-23 21:10:27 | 显示全部楼层
很不错的 学习机会,希望继续努力,
xinanjiaoda 发表于 2011-4-24 21:31:41 | 显示全部楼层
相当的牛逼
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-21 02:55 , Processed in 1.062500 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表