现在的位置: 首页 > 综合 > 正文

ARM裸机开发(三)SDRAM编程

2013年05月30日 ⁄ 综合 ⁄ 共 2748字 ⁄ 字号 评论关闭

     以下裸机程序基于GT2440,编译器为arm-linux-gcc-4.4.3。

      程序结构:程序由sdram.S和main.c两个文件组成,sdram.S文件完成一些初始化工作,如时钟初始化,内存控制器初始化,拷贝第二阶段代码到sdram等;main.c负责循环点亮、熄灭四个LED。

      程序流程:上电时,cpu自动跳到复位异常向量入口,在复位异常处理里首先关闭看门狗,接着初始化系统时钟,初始化内存控制器,拷贝第二阶段代码到sdram,最后跳转到sdram里执行main()函数。

 

sdram.S:

  1 #define MEM_REG_START 0x48000000 
  2 #define SDRAM_BASE   0x30000000
  3 
  4 #define LOCKTIME 0x4C000000 
  5 #define MPLLCON 0x4C000004 
  6 #define UPLLCON 0x4C000008 
  7 #define CLKDIVN 0x4C000014 
  8 #define CAMDIVN 0x4C000018
  9 
 10 #define WTCON 0x53000000
 11 
 12 
 13 .section .text
 14 .global _start
 15 _start:
 16     b reset
 17 
 18 @复位异常处理
 19 reset:
 20     @关闭看门狗
 21     bl disable_watchdog
 22     @初始化时钟
 23     bl init_clock
 24     @初始化内存控制器
 25     bl init_sdram
 26     @拷贝第二阶段代码到SDRAM
 27     bl copy_to_sdram
 28 
 29     ldr pc,=on_sdram
 30 on_sdram:
 31     @设置栈指针
 32     ldr sp,=0x34000000
 33     @跳到main()函数
 34     bl main
 35 loop:
 36     b loop  @死循环
 37 
 38 
 39 disable_watchdog:
 40     ldr r0,=WTCON    
 41     bic r1,r0,#0x20
 42     str r1,[r0]
 43 
 44     mov pc,lr
 45 
 46 init_clock:
 47     ldr r0,=LOCKTIME
 48     ldr r1,=0x00ffffff
 49     str r1,[r0]
 50     @时钟分频1:4:8
 51     ldr r0,=CLKDIVN
 52     ldr r1,=0x05
 53     str r1,[r0]
 54     @异步总线模式
 55     mrc p15,0,r1,c1,c0,0
 56     orr r1,r1,#0xc0000000
 57     mcr p15,0,r1,c1,c0,0
 58     @FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ
 59     ldr r0,=MPLLCON
 60     ldr r1,=0x5c011
 61     str r1,[r0]
 62     @UPLL=48MHZ
 63     ldr r0,=UPLLCON
 64     ldr r1,=0x38022
 65     str r1,[r0]
 66 
 67     mov pc,lr
 68 
 69 copy_to_sdram:
 70     ldr r0,=2048 @要拷贝的代码的起始地址 (源地址)
 71     ldr r1,=SDRAM_BASE  @要拷贝到的地址(目的地址)
 72     add r3,r0,#2*1024  @拷贝大小(2K 73 copy_loop:
 74     ldr r2,[r0],#4
 75     str r2,[r1],#4
 76     cmp r0,r3
 77     bne copy_loop
 78 
 79     mov pc,lr
 80 
 81 init_sdram:
 82     ldr r0,=MEM_REG_START     
 83     adrl r1,mem_cfg_val
 84     add r2,r0,#52  //13个寄存器,每个占4字节(13*4 85 mem_cfg_loop:
 86     ldr r3,[r1],#4
 87     str r3,[r0],#4
 88     cmp r0,r2
 89     bne mem_cfg_loop
 90     
 91     mov pc,lr
 92     
 93 @寄存器配置值
 94 .align 4
 95 mem_cfg_val:
 96     .long 0x22011110 //BWSCON
 97     .long 0x00000700 //BANKCON0
 98     .long 0x00000700 //BANKCON1
 99     .long 0x00000700 //BANKCON2
100     .long 0x00000700 //BANKCON3
101     .long 0x00000700 //BANKCON4
102     .long 0x00000700 //BANKCON5
103     .long 0x00018005 //BANKCON6
104     .long 0x00018005 //BANKCON7
105     .long 0x008c04f4 //REFRESH(HCLK=100MHZ)
106     .long 0x000000b1 //BANKSIZE
107     .long 0x00000030 //MRSRB6
108     .long 0x00000030 //MRSRB7

main.c:

 1 #define GPBCON (*(volatile unsigned long *)0x56000010) 
 2 #define GPBDAT (*(volatile unsigned long *)0x56000014)
 3 #define GPBUP  (*(volatile unsigned long *)0x56000018)
 4 
 5 #define nGPB_OUTPUT ((1<<10)|(1<<12)|(1<<14)|(1<<16))
 6 
 7 //延时函数
 8 void delay()
 9 {
10     int i = 0xffff;
11     int j;
12     for(j=0;j<i;j++);  
13 
14 }
15 
16 //main函数
17 int main(void)
18 {
19     //IO口配置为输出
20     GPBCON = nGPB_OUTPUT;
21 
22     while(1)
23     {
24         GPBDAT = 0x0;//输出低电平(点亮LED)
25         delay();//延时
26         GPBDAT = 0xffffffff;//输出高电平(熄灭LED)
27         delay();//延时
28     }
29 
30     return 0;
31 }

Makefile:

 1 objs := sdram.S main.c
 2 
 3 sdram.bin:$(objs)
 4     arm-linux-gcc -c -o sdram.o sdram.S
 5     arm-linux-gcc -c -o main.o main.c
 6     arm-linux-ld -Tsdram.lds -o sdram_elf 
 7     arm-linux-objcopy -O binary -S sdram_elf sdram.bin
 8 
 9 clean:
10     rm -f sdram_elf sdram.bin *.o

链接脚本sdram.lds:

1 SECTIONS
2 {
3     nand  0x00000000 : {sdram.o}
4     sdram 0x30000000 : AT(2048) {main.o}
5 }

      执行make之后通过BIOS将sdram.bin文件下载到nand flash,从nand flash启动。

 

抱歉!评论已关闭.