Chinaunix首页 | 论坛 | 博客
  • 博客访问: 918018
  • 博文数量: 84
  • 博客积分: 4334
  • 博客等级: 上校
  • 技术积分: 1610
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-27 07:49
文章分类

全部博文(84)

文章存档

2012年(5)

2011年(21)

2010年(58)

分类: 嵌入式

2010-10-23 21:07:53

从NandFlash启动CPU的时候,CPU会自动通过其内部硬件结构复制NandFlash中的前4K代码到cpu的自带SRAM中,注意这是CPU自带的SRAM,区别于本文所讲的SDRAM,本文所指的SDRAM是外接SDRAM,开发板对应的芯片为K4S561632,即内存。
 
一般来说,嵌入式系统都有NandFlash(硬盘)和SDRAM(内存),我们把程序烧到NanFlash中,然后选择从NandFlash启动CPU,CPU启动后会自动复制NandFlash中前4K代码到CPU的SRAM中,这前4K代码接着完成程序从NandFlash复制到SDRAM的任务。
 
参考韦东山大哥的书,做了sdram的实验:
(1)head.S,这个是最关键的,设置SDRAM控制器,来控制外部SDRAM即:K4S561632,然后把程序放在这个芯片里执行的。

@*************************************************************************
@ 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

(2)leds.c
 


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

#define    GPF0_out    (1<<(0*2))
#define    GPF1_out    (1<<(1*2))
#define    GPF2_out    (1<<(2*2))
#define    GPF3_out    (1<<(3*2))

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

int main(void)
{
    int i=0;
    GPFCON = GPF1_out|GPF2_out|GPF3_out|GPF0_out;        // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出

    GPFUP = 0;
    
    while(1){
         for(i=0;i<4;i++){
             GPFDAT = ~(1<             wait(30000);
         }
    }

    return 0;
}

(3)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


阅读(2026) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~