您的位置:首页 > 其它

ARM底层学习笔记-存储管理器及sdram的使用

2013-12-19 16:25 471 查看
什么是存储管理器?

存储管理器是片内模块,与arm模块一起被集成在2440这种芯片中,arm cpu模块要访问外部的sdram或网卡/Nor等,就需要通过存储管理器来完成,其作用类似于PC上的南桥。

存储管理器工作:

根据配置信息决定访问哪些设备,

1.片选信号;

2.bank选择信号;

3.列地址信号 ;

4.行地址信号等待;

想访问一个存储介质芯片,需要哪些条件:

1.地址线;

2.数据线8/16/32bits,即数据宽度;

3.时钟频率;

4.芯片相关,如sdram行地址,列地址,bank等,其地址是多少位,有多少个bank等;

这些条件都是配置信息。

我们需要做哪些工作才能使用存储管理器?

1.数据位宽看原理图;

2.配置存储管理器——行/列/bank/刷新周期查看芯片手册;

3.使用;

注:由于CPU的访问是以byte为单位,而内存是以nbits为单位,如32bits的内存每组数据都是以32bits为单位。那么如果CPU发出数据请求,第0个byte的数据,对应内存中第0个byte位置会返回第0个32bits的数据;第1个byte的数据,对应内存中第1个byte位置会返回第0个32bits的数据;第2个byte的数据,对应内存中第2个byte位置会返回第0个32bits的数据;第3个byte的数据,对应内存中第3个byte位置会返回还是第0个32bits的数据。这个问题会导致不同位的内存与同一个CPU连接时,地址线连接方式不同。

sram访问比较快但是比较贵大小较小,不需要刷新 ;sdram访问比较复杂,因此会慢,但比较便宜,大小较大,而且需要刷新,否则会丢数据。

2440有两种启动方式:

1.Nor启动;

2.Nand启动;

如果硬件上连接有Nor,且选择从Nor启动,这系统的0地址即为Nor的起始地址,系统启动是就从这个地址开始执行;如果硬件连接有Nand,且选择使用Nand启动,那么不论有没有Nor其0地址都失效,系统的0地址为片内sram(在汇编中叫steppingstone)的起始地址,系统会将Nand的前4k拷贝到片内sram,然后从片内0地址开始执行。选用Nand启动时程序启动过程为:1.上电,Nand前4k拷到片内sram的0地址开始启动;2.关看门狗,初始化存储管理器;3把代码拷贝到sdram,继续执行;最后一步在存储管理器被初始化之后开始拷贝代码到sdram中执行,原因是,Nand中要执行的程序可能很大,而片内sram空间有限,因此后面的内容拷贝到sdram中执行。

链接地址:运行时,程序“应该”所处的位置。

以下代码源码来自韦东山老师的资料,仅供学习参考。

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

.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
c代码文件:

#define	GPFCON		(*(volatile unsigned long *)0x56000050)
#define	GPFDAT		(*(volatile unsigned long *)0x56000054)

#define	GPF4_out	(1<<(4*2))
#define	GPF5_out	(1<<(5*2))
#define	GPF6_out	(1<<(6*2))

void  wait(volatile unsigned long dly)
{
	for(; dly > 0; dly--);
}

int main(void)
{
	unsigned long i = 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;
	}

	return 0;
}
makefile文件:

sdram.bin : head.S  leds.c
	arm-linux-gcc  -c -o head.o head.S
	arm-linux-gcc -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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: