Mini2440学习笔记(三)——SDRAM(续)

SDRAM例程:

Nand Flash启动CPU时,CPU会自动将Nand Flash开始的4K数据复制到4KB的内部Ram中(起始地址0),然后地址0开始执行。

本例程先用汇编设置好SDRAM,将程序从内部Ram复制到SDRAM,然后跳转到SDRAM执行。

源代码包括sdram.Sgpio.cs3c2440.h,编译为二进制文件后烧写到NandFlash运行

sdram.S如下:

@*****************************************
@ File name   : sdram.S
@ Project name: sdram
@ Author      : Bob
@ Date        : 2011-7-9
@ Description : 设置SDRAM,将steppingstone中的程序复制到sdram,然后跳转到sdram执行。
@*****************************************

.data
.equ MEM_CTL_BASE, 0x48000000  @ 存储器控制器的寄存器首地址
.equ SDRAM_BASE,   0x30000000  @ sdram的起始地址

.text
.global _start
_start:
    bl disable_watch_dog
    bl memsetup
    bl copy_steppingstone_to_sdram
    ldr pc, =on_sdram   @ 跳转到on_sdram,这是sdram中的地址

on_sdram:
    ldr sp, =0x34000000       @设置栈
    bl main
halt_loop:
    b halt_loop

@ 禁止watch dog
disable_watch_dog:
    mov r1, #0x53000000    @ watch dog 寄存器的地址
    mov r2, #0x0
    str r2, [r1]
    mov pc, lr            @返回

@ 将steppingstone的内容全部复制到sdram
copy_steppingstone_to_sdram:
    mov r1, #0            @ r1存放steppingstone的起始地址
    ldr r2, =SDRAM_BASE   @ r2存放sdram的起始地址
    mov r3, #4*1024       @ steppingstone的大小时4KB
1:
    ldr r4, [r1],#4     @ 从steppingstone中读取4Byte,[r1]->r4,r1=r1+4
    str r4, [r2],#4     @ 将4Byte复制到sdram,r4->[r2],r2=r2+4
    cmp r1, r3    @ 判断是否复制完4KB,r1等于4*1023时,复制结束
    bne 1b        @ 如果不相等,跳回1处
    mov pc, lr    @ 返回

@ 设置存储器控制器的寄存器
memsetup:
    mov r1, #MEM_CTL_BASE  @ r1存放存储器控制器的寄存器首地址
    adrl r2, mem_cfg_val   @ r2存放mem_cfg_val的起始地址
    add r3, r1,#52       @ r3=r1+52,r3存放mem_cfg_val的结束地址,有13个寄存器,13*4=52
1:
    ldr r4, [r2],#4
    str r4, [r1],#4
    cmp r1, r3
    bne 1b
    mov pc, lr

@ 存储器控制器的13个寄存器的值
.align 4   @ 以下数据都以4Byte对齐
mem_cfg_val:
    .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      @ MRSRB6

 

说明:
ldr

当第二个操作数前面没有“=”时,表示内存访问指令,从内存中读取4Byte数据到寄存器,语法格式如下:

ldr{条件目的寄存器, 存储器地址

如果第二个操作数前面有“=”,表示大范围地址读取伪指令,用于加载32位的立即数或一个地址到指定寄存器,语法格式如下:

ldr 目的寄存器, =32位立即数/地址

 

str:

内存访问指令,从源寄存器将一个32位数据传送到存储器中,语法格式如下:

str{条件源寄存器, 存储器地址

 

adrl r2, mem_cfg_val

adrl是中等范围地址读取伪指令,将基于pc相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,在汇编编译器编译源程序时,adrl伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。这条代码会替换为:

30000050: e28f2018  add r2, pc, #24 ; 0x18

30000054: e1a00000  nop (mov r0,r0)

adrl伪指令格式:

adrl{cond}   register, expr

地址表达式expr的取值范围:

当地址值是字节对齐时,其取指范围为: -64K64K

当地址值是字对齐时,其取指范围为: -256K256K

 

nop

空操作伪指令,在汇编是替换成ARM中的空操作,例如mov r0, r0

 

cmp

比较指令,格式如下:

cmp{条件操作数1, 操作数2

用与将一个寄存器的内容和另一寄存器的内容或立即数进行比较,然后更新CPSR中条件标志位的值,标志位表示操作数1和操作数2的关系(大于、小于、相等)。

 

bne 1b

b(跳转指令)+ne(条件:不相等),如果CPSRZ位为0(不相等),就跳转到后面的1标号处。

b表示向后搜索,已经执行过的代码为‘后’;

f表示向前搜索,还未执行的代码为‘前’。

 

mov  pc, lr

从子程序返回。lr为子程序链接寄存器(r14),当执行bl子程序调用指令时,lr会备份pc(程序计数器r15)。

 

.align

指定对齐方式,gnu汇编命令都以一个点开头。

 

.equ

赋值命令,格式如下:

.equ symbol, expression

设置symbol的值为expression

 

.long

定义一个4Byte的数据。

 

程序源代码:

sdram

  

参考:

韦东山:《嵌入式Linux应用开发完全手册》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值