3,嵌入式Linux之存储管理器
1, 配置s3c440的存储管理器来访问外部的存储设备 比如 SDRAM DM9000网卡 等等
2, 配置存储管理器:
需要哪些参数①地址线 ②数据线 ③时钟/频率 ④要访问的芯片的相关的设置
S3c440的存储控制的芯片的信息
存储控制器13个寄存器分别是:
BWSCON :
Bwscon
位
描述
初始状态
ST7
[31]
决定SRAM的使用UB或LB对bank7。
1, 不使用 UB/LB(这个引脚被专用于nWBE[3:0])
2, 使用UB/LB(这个引脚专用于nBE[3:0])
0
WS7
[30]
决定等待状态对bank7
0=等待取消 1=等待开启
0
DW7
[29:28]
决定数据总线宽度对bank7
00 = 8 bit 01=16bit 10 = 32 bit 11= reserved
0
…
ST1
[7]
Determines WAIT status for bank 2.
0 = WAIT disable 1 = WAIT enable
0
WS7
[6]
Determines data bus width for bank 2.
00 = 8-bit 01 = 16-bit, 10 = 32-bit 11 = reserved
0
DW7
[5:4]
Determines SRAM for using UB/LB for bank 1.
0 = Not using UB/LB (The pins are dedicated nWBE[3:0])
1 = Using UB/LB (The pins are dedicated nBE[3:0])
0
BANK0~5控制寄存器
相应的参数设置:
BANK6~7控制寄存器:
相关的参数设置:
REFRESH控制寄存器:
REFRESH相关的参数设置:
BANKSIZE控制寄存器:
BANKSIZE相关的参数:
MRSRB6~7控制寄存器:
MRSRB6~7相关的参数:
3,用储存控制寄存器来访问SDRAM实例:
1),原理图SDRAM的原理图
2),将上一节的点亮led的程序考到SDRAM中
汇编文件 start.S文件代码:
@*************************************************************************
@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个寄存器的设置值
.long0x22011110@ BWSCON 0x48000000// 10 00 10 00 00 00 01 00 01 00 01 00 01 00 00
.long0x00000700@ BANKCON0 0x48000004// 01 11 00 00 00 00
.long0x00000700@ BANKCON1 0x48000008// 01 11 00 00 00 00
.long0x00000700@ BANKCON2 0x4800000C// 01 11 00 00 00 00
.long0x00000700@ BANKCON3 0x48000010// 01 11 00 00 00 00
.long0x00000700@ BANKCON4 0x48000014// 01 11 00 00 00 00
.long0x00000700@ BANKCON5 0x48000018// 01 11 00 00 00 00
.long0x00018005@ BANKCON6 0x4800001C// 01 10 00 00 00 00 00 01 01
.long0x00018005@ BANKCON7 0x48000020// 01 10 00 00 00 00 00 01 01
.long0x008C07A3@ REFRESH 0x48000024// 10 00 11 00 00 00 01 11 10 10 00 11
.long0x000000B1@ BANKSIZE 0x48000028// 10 11 00 01
.long0x00000030@ MRSRB6 0x4800002C// 11 00 00
.long0x00000030@ MRSRB7 0x48000030// 11 00 00
点灯的c语言文件代码:
#define GPFCON (*(volatileunsignedlong*)0x56000050)
#define GPFDAT (*(volatileunsignedlong*)0x56000054)
#define GPF4_out (1<<(4*2))
#define GPF5_out (1<<(5*2))
#define GPF6_out (1<<(6*2))
void wait(volatileunsignedlong dly)
{
for(; dly >0; dly--);
}
int main(void)
{
unsignedlong 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;
}
return0;
}
编译makefile文件代码:
sdram.bin : start.S leds.c
arm-linux-gcc -c -o start.o start.S
arm-linux-gcc -c -o leds.o leds.c
arm-linux-ld -Ttext0x30000000 start.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