zoukankan      html  css  js  c++  java
  • ARM裸机开发(三)SDRAM编程

         以下裸机程序基于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启动。

  • 相关阅读:
    变量作用域
    模块化编程-函数
    递归
    变量
    形参和实参
    函数返回值
    node.js+yarn环境centos7快速部署
    LINUX磁盘添加挂载
    分布式存储MINIO集群部署实例
    Docker取消默认https连接
  • 原文地址:https://www.cnblogs.com/lknlfy/p/2662587.html
Copyright © 2011-2022 走看看