实验四、使用SDRAM

实验背景:系统在上电后,NandFlash的前4k代码会自动加载到CPU内部的SRAM中,这一过程参阅附录一《s3c2440启动过程详解》

知识点储备:

1、运行地址<--->链接地址:他们两个是等价的,只是两种不同的说法。

2、加载地址<--->存储地址:他们两个是等价的,也是两种不同的说法。

运行地址:程序在SRAM、SDRAM中执行时的地址。就是执行这条指令时,

PC应该等于这个地址,换句话说,PC等于这个地址时,这条指令应该保存在这个地址内。

加载地址:程序保存在Nand flash中的地址。

位置无关码:B、BL、MOV都是位置位置无关码。

位置有关码:LDR PC,=LABEL等类似的代码都是位置有关码。

实验目的:将SRAM中的代码进一步通过编程,搬移到SDRAM中运行。

实验思考:本实验顺利跳入主函数,但是无法进入中断,请问为什么?带着这个问题,请对比实验5中的代码,寻找差别,然后回答这个问题。

一、编写使用SDRAM程序

1、程序功能:设置SDRAM,将四个LED灯按0~15轮流计数方式点亮的控制程序led.c复制到SDRAM,然后跳到SDRAM继续执行。

2、写程序如下:head.S、leds.c、makefile

(1)head.S程序如下:

.equ MEM_CTL_BASE,0x48000000

.equ SDRAM_BASE,0x30000000

.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:

@将Steppingstone的4K数据全部复制到SDRAM中去

@ Steppingstone起始地址为0x00000000,SDRAM中起始地址为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 @读取设置值,并让r2加4

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

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 0x000000B1 @ BANKSIZE

.long 0x00000030 @ MRSRB6

.long 0x00000030 @ MRSRB7

(2)leds.c程序

#define GPBCON (*(volatile unsigned long *)0x56000010)

#define GPBDAT (*(volatile unsigned long *)0x56000014)

#define GPB5_out (1<<(5*2))

#define GPB6_out (1<<(6*2))

#define GPB7_out (1<<(7*2))

#define GPB8_out (1<<(8*2))

void wait(unsigned long dly)

{

for(; dly > 0; dly--);

}

int main(void)

{

unsigned long i = 0;

GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;

//将LED1-4对应的GPB5/6/7/8四个引脚设为输出

while(1){

wait(30000);

GPBDAT = (~(i<<5)); //根据i的值,点亮LED1-4

if(++i == 16)

i = 0;

}

return 0;

}

(3)makefile文件如下:

sdram.bin : head.S leds.c

arm-linux-gcc -nostdlib -c -o head.o head.S

arm-linux-gcc -nostdlib -c -o leds.o leds.c

arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf

arm-linux-objcopy -O binary -S sdram_elf sdram.bin

arm-linux-objdump -D -m arm sdram_elf > sdram.dis

clean:

rm -f sdram.dis sdram.bin sdram_elf *.o

Q&A

(1)请问中断向量入口地址是多少?查看反汇编代码,了解本实验中,处在该地址的指令是哪一条?

(2)在进行代码搬移之前,需要对13个寄存器做配置,请上网查阅这13个寄存器分别是什么,为什么要这样配置?

附录一 s3c2440启动过程详解

lS3C2440存储控制器和地址以及启动的理解

1.首先应该先了解Flash ROM的种类

ØNOR FLASH地址线和数据线分开,提供地址和控制信号,数据就可以读出。

ØNAND Flash地址线和数据线在一起,需要用程序来控制,才能出数据。通俗的说,只给地址不行,要先命令,再给地址,才能读到NAND的数据,在一个总线完成的。

结论:ARM无法从NAND直接启动。除非装载完程序,才能使用NAND Flash.

Nand Flash的命令、地址、数据都通过I/O口发送,管脚复用,这样做的好处是,可以明显减少NAND FLASH的管脚数目,将来如果设计者想将NAND FLASH更换为更高密度、更大容量的,也不必改动电路板。在S3C2440中NANDFLASH的控制依靠NAND FLASH控制器。不能够执行程序,总结其原因如下:

(1)NAND FLASH本身是连接到了控制器上而不是系统总线上。CPU启动后是要取指令执行的,如果是SROM、NOR FLASH等之类的,CPU发个地址就可以取得指令并执行,NAND FLASH不行,因为NAND FLASH是管脚复用,它有自己的一套时序,这样CPU无法取得可以执行的代码,也就不能初始化系统了。

(2)NAND FLASH是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。

2.在2440中为什么可以配置成从Nand Flash中启动程序?

  如果S3C2440被配置成从Nand Flash启动, S3C2440的Nand Flash控制器有一个特殊的功能,在S3C2440上电后,Nand Flash控制器会自动的把Nand Flash上的前4K数据搬移到4K内部SRAM中,(此内部RAM被称为Steppingstone)并把0x00000000设置内部SRAM的起始地址,CPU从内部RAM的0x00000000位置开始启动。这个过程不需要程序干涉。程序员需要完成的工作,是把最核心的启动程序放在Nand Flash的前4K中,也就是说,你需要编写一个长度小于4K的引导程序,作用是将主程序拷贝到SDRAM中运行。

3.启动方式:

Samsung S3C2440支持Nor Flash和Nand Flash启动,主要由OM[1:0]这两位来决定从何处启动。具体含义如下:

OM[1:0]=00时,处理器从NAND Flash启动;

OM[1:0]=01时,处理器从16位宽度的ROM启动;

OM[1:0]=10时,处理器从32位宽度的ROM启动;

OM[1:0]=11时,处理器从Test Mode启动。

ARM的启动都是从0地址开始,所不同的是地址的映射不一样。在ARM开电的时候,要想让ARM知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候ARM会通过引脚的电平来判断。

(1)当引脚OM0跟OM1有一个是高电平时,这时地址0会映射到外部nGCS0片选的空间(Bank0),也就是Norflash,程序就会从Norflash中启动,ARM直接取Norflash中的指令运行。

(2)当OM0跟OM1都为低电平,则0地址内部bootbuf(一段4k的SRAM)开始。系统上电,ARM会自动把NANDflash中的前4K内容考到bootbuf(也就是0地址),然后从0地址运行。这时NANDFlash中的前4K就是启动代码(他的功能就是初始化硬件然后在把NANDFlash中的代码复制到RAM中,再把相应的指针指向该运行的地方)

4.启动代码应该做什么?

  由于Nand Flash控制器从Nand Flash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2440的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行。至于将2440当做单片机玩裸跑程序的时候,就不要做这样的事情,当代码小于4K的时候,只要下到nand flash中就会被搬运到内部RAM中执行了。bootloader在某种意义上来说即是一个启动代码,种类有很多(vivi,uboot等),但是功能上无非就是完成一些初始化。bootloader是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的过渡,为运行操作系统提供基本的运行环境,如初始化CPU、堆栈、初始化存储器系统等,其功能类似于PC机的BIOS。

为什么会有这两种启动方式,关键还是两种flash的不同特点造成,NORFLASH容量小,速度快,稳定性好,输入地址,然后给出读写信号即可从数据口得到数据,适合做程序存储器。NANDFLASH总容量大,但是读写都需要复杂的时序,更适合做数据存储器。这种不同就造成了NORflash可以直接连接到arm的总线并且可以运行程序,而NAND flash必须搬移到内存(SDRAM)中运行。

  在实际的开发中,一般可以把bootloader烧入到Norflash,程序运行可以通过串口交互,进行一定的操作,比如下载,调试。这样就很可以很方便的调试你的一些代码。Norflash中的Bootloader还可以烧录内核到Norflash等等功能。

5.存储控制器的作用:

  在2440中分了8个bank,每个bank的基地址由nCGSx来选择,每个bank都接外设之后,就可以通过存储控制器来进行地址上的选择了。每个bank与外设的连接方式不一样,主要看外设是每次进行多少位的数据传输,如果是8位,这样CPU的地址线A0就可以直接接外设的A0,如果是16位,那么CPU的A1就该接到外设的A0,以此类推。nor flash接在bank0,数据线为16位。存储控制器的特性如下:

  大小端设置;

  地址空间:每个bank为128MB (总共1GB);

  除了bank0其余所有banks的数据位宽是可编程的(8/16/32-bit);(bank0是16/32位)

  总共8个memory banks,其中6个bank是接ROM,SRAM等,其余2个bank是接ROM,SRAM,SDRAM等;

7个memory bank的起始地址是固定的;(发现size也是固定的,128MB)

1个memory bank的起始地址和大小是可灵活可变的;

  所有banks的访问周期数是可编程的;

  支持片外等待信号以扩充总线周期;

SDRAM在Power down模式下支持自动刷新。

6.Nand Flash控制器:

 自动启动:系统复位后,boot code搬运到4KB Steppingstone,然后在其内部执行;

Nand Flash存储接口:支持256Words,512Bytes,1KWords和2KBytes Page;

软件模式:用户能直接访问nand flash;

接口:支持8/16-bit Nand flash存储接口;

支持大小端模式;

硬件ECC发生器;

Steppingstone: 4KB SRAM Buffer,在nand flash启动过后可以用作它处.

当系统处在复位状态时,Nand flash控制器从管脚NFCON,GPG13,GPG14,GPG15得到nand flash的一些信息(如page size,bus width等,见下图)。在上电或系统复位之后,则Nand flash控制器将自动加载4KB boot loader代码,之后就是在steppingstone里执行

  注意:在自动启动这个过程中,ECC模块是不发挥作用的。

���

results matching ""

    No results matching ""

    results matching ""

      No results matching ""