xiayulei 发表于 2013-9-29 19:36:51

存储控制器

.equ    MEM_CTL_BASE,    0x48000000               @c语言中的宏定义,#define MEM_CTL_BASE 0x48000000,注意的是这里中间有个小逗号","
.equ    SDRAM_CTL_BASE,    0x30000000

.text
.global _start
_start:
    bl    disable_watch_dog   
@关闭看门狗
    bl    memsetup      
@存储控制器设置
    bl    cp_steppingstone_to_sdram
@将内部sram上的4K(也就是起步石上的4K程序)拷贝到SDRAM中继续执行,上面两步在起步石上执行。
    ldr    pc, =on_sdram
    @跳转到 sdram中执行,今天忘了写这句,结果死活不对劲,因为下面用了标号on_sdram
on_sdram:            
    ldr    sp, =0x34000000
@在调用C之前,一定要设置好栈,也就是C函数返回地址。
@sdram的起始地址,0x34000000,也即是c语言函数返回的地址,因为调用C的时候,需要保存一些东西,那么
@就该以程序开始执行的初始位置,网上看见有的依然还是4096,那就错了,因为4096不是sdram中程序运行的初
@始位置,而你却把c的返回地址设在那里,这肯定会出事的,当然,不会让地球毁灭。
    bl main      
loop:         
    b    loop
disable_watch_dog:
    ldr    r1,    =0x53000000
@这里,有的用的指令是mov r1,#0x53000000.注意的是,数据从内存到cpu寄存器仅能L/S,而mov只能在寄存器
@之间进行数据的传输,或者将立即数方式寄存器,比如ldr r0,0x34000,但是别mov r0,0x34000(表示把0x34000
@地址上的数据传给寄存器r0;当然,ldr也可以作为伪指令,有点像ARM的ldr,伪指令时,表示把一个地址装入某个
@寄存器,ldr,=0x56,这与mov很相似,不过mov的长度是2^8 = 512;如果实际中ldr伪指令未超过512,则转换成mov指令。
    mov    r2,    #0x0
    str    r2,   
    mov    pc,    lr
cp_steppingstone_to_sdram:   @将起步石上的4K拷贝到sdram中
    ldr    r1,    =0x0
@内部sram起始地址为0,也就是steppingstone 起始地址为0
    ldr    r2,    =SDRAM_CTL_BASE
@sdram起始地址 0x30000000
    mov    r3,    #0x1000
@后面程序循环结束条件,也就是4KB大小,或者说是结束地址为4096
l:
    ldr r4,    ,    #4@类似C的指针操作,int n = *p ++;注意一个指针是4个字节,从源地址读取4字节的数据,并让源地址+4
    str    r4,    ,    #4 @将读取的4字节数据放入目的地址,并让目的地址+4
    cmp    r1,    r3 @循环条件判断
    bne    l
    mov    pc,lr

memsetup:                                  @存储控制器设置
    ldr    r1, =MEM_CTL_BASE       @存储控制器寄存器初始地址
    adrl    r2,    mem_cfg_val      
@相当于数组首地址,unsigned long mem_cfg_val;adrl 将相对于程序或相对于寄存器的地址载入寄存器中,类
@似adr,不过期范围要别ldr窄,比adr宽。链接: http://www.cnblogs.com/elect-fans/archive/2012/05/12/2497387.html
    add    r3,    r1,    #52         
L:
    ldr    r4,    , #4         @52 = 13 *4(13个存储控制寄存器,每个是4字节的)
    str    r4,    , #4
    cmp    r1,    r3
    bne    L
    mov pc,lr
.align 4                           @对齐方式,有align N /align 2^N两种方式,一般gas可能会选成后面这个方式
mem_cfg_val:
    .word    0x22011110
    .word    0x00000700
    .word    0x00000700
    .word    0x00000700
    .word    0x00000700
    .word    0x00000700
    .word    0x00000700
    .word    0x00018005
    .word    0x00018005
    .word    0x008c07a3
    .word    0x000000b1
    .word    0x00000030
    .word    0x00000030
请问:后面mem_cfg_val的这十三个 值是怎样算出来的,看芯片手册了,但不知道是怎么来的,恳请天嵌入的相关工作人员解释一下,小弟大恩不言谢了。

页: [1]
查看完整版本: 存储控制器