Chinaunix首页 | 论坛 | 博客
  • 博客访问: 482117
  • 博文数量: 98
  • 博客积分: 3265
  • 博客等级: 中校
  • 技术积分: 1227
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 00:29
文章分类

全部博文(98)

文章存档

2012年(6)

2011年(83)

2010年(9)

分类: 嵌入式

2011-06-11 22:55:41

@******************************************************************************

@ Filecrt0.S

@ 功能:将NAND中的《4KB的程序自动映射片内4kbsram中调用C程序运行

@******************************************************************************      

 

.text

.global _start

_start:

            ldr     r0, =0x53000000     @ WATCHDOG寄存器地址

            mov     r1, #0x0                    

            str   r1, [r0]              @ 写入0,禁止WATCHDOG,否则CPU会不断重启

           

            ldr     sp, =1024*4         @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K

                                        @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K

            bl      main                @ 调用C程序中的main函数

halt_loop:

            b       halt_loop

 

 

 

@*************************************************************************

@ Filehead.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:

    @ Steppingstone4K数据全部复制到SDRAM中去

    @ Steppingstone起始地址为0x00000000SDRAM中起始地址为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            @ 读取设置值,并让r24

    str r4,     [r1], #4            @ 将此值写入寄存器,并让r14

    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

 

 

 

@*************************************************************************

@ Filehead.S

@ 功能:设置SDRAM,将第二部分代码复制到SDRAM,设置页表,启动MMU一,建立映射表格

       表格里面是虚拟地址和物理地址的对应关系

       这种映射关系以1MB为单位

 

二,将映射表格首地址告诉MMU

       映射表格建立在内存SDRAM上,

 

三,启动MMU

       MMU自带权限管理,CACHE功能

 

@       然后跳到SDRAM继续执行

@*************************************************************************       

 

.text

.global _start

_start:

    ldr sp, =4096                       @ 设置栈指针,以下都是C函数,调用前需要设好栈

    bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启

    bl  memsetup                        @ 设置存储控制器以使用SDRAM

    bl  copy_2th_to_sdram               @ 将第二部分代码复制到SDRAM

    bl  create_page_table               @ 设置页表

    bl  mmu_init                        @ 启动MMU

    ldr sp, =0xB4000000                 @ 重设栈指针,指向SDRAM顶端(使用虚拟地址)

    ldr pc, =0xB0004000                 @ 跳到SDRAM中继续执行第二部分代码

    @ ldr pc, =main

halt_loop:

    b   halt_loop

 

 

 

@******************************************************************************

@ Filehead.s

@ 功能:设置SDRAM,将NAND中的程序》4KB的程序复制到SDRAM,然后跳到SDRAM继续执行

Nand

没有地址线,只有8根数据线和控制信号线

在控制信号的作用下,地址线借用数据线

控制信号线直接接到CPU相应引脚上,控制信号线的状态由cpuNAND寄存器设置

 

操作方式:Nand内自己编址,

以字节为单位:256M=268435456b

以页为单位256M=131072

以块为单位256M=2048

 

硬件上对Nand访问,

一,             发命令,CLEDATA BUS

二,             给地址,ALEDATABUS

三,             传输数据,R/WDATABUS

 

2440NAND的访问:即对这四个寄存器的操作

1, NFCMND

2, NFADDR

3, NFDADA

4, NFSTAT

 

@******************************************************************************      

 

.text

.global _start

_start:

                                         @函数disable_watch_dog, memsetup, init_nand, nand_read_llinit.c中定义

            ldr     sp, =4096               @设置堆栈

            bl      disable_watch_dog       @WATCH DOG

            bl      memsetup                @初始化SDRAM

            bl      nand_init               @初始化NAND Flash

 

                                            @NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM

                                            @nand_read_ll函数需要3个参数:

            ldr     r0,     =0x30000000     @1. 目标地址=0x30000000,这是SDRAM的起始地址

            mov     r1,     #4096           @2.  源地址   = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处

            mov     r2,     #2048           @3.  复制长度= 2048(bytes),对于本实验的main.c,这是足够了

            bl      nand_read               @调用C函数nand_read

 

            ldr     sp, =0x34000000         @设置栈

            ldr     lr, =halt_loop          @设置返回地址

            ldr     pc, =main               @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转

halt_loop:

            b       halt_loop

 

 

 

 

1,系统默认分配那几个向量地址

A,当然第一个是复位,复位程序那里禁用掉看门狗,设置各个中断模式的SP位置

注意:调用C函数,首先要设置好堆栈,例如main函数。

B,其他几个中断向量入口地址,当发生相应的中断后,系统自动跳到相应的入口地址处

2,中断处理程序:

a)      计算返回地址

b)      保护现场,压入那个模式的堆栈

c)       中断处理

d)      清除中断标志

e)       恢复现场

f)        中断返回

     

.global _start

_start:    

    b   Reset

HandleUndef:

    b   HandleUndef

 HandleSWI:

    b   HandleSWI

HandlePrefetchAbort:

    b   HandlePrefetchAbort

HandleDataAbort:

    b   HandleDataAbort

HandleNotUsed:

b   HandleNotUsed

HandleIRQ:

    b   HandleIRQ

HandleFIQ:

    b   HandleFIQ

 

Reset:                 

    ldr sp, =4096           @ 设置栈指针,因为以下都是C函数    bl  disable_watch_dog   @ 关闭看门狗否则CPU会不断重启

    msr cpsr_c, #0xd2       @ 进入中断模式

    ldr sp, =3072           @ 设置中断模式栈指针

    msr cpsr_c, #0xd3       @ 进入管理模式

    ldr sp, =4096           @ 设置管理模式栈指针,

                       @ 其实复位之后,CPU就处于管理模式,

    bl  init_led            @ 初始化LEDGPIO管脚

    bl  init_irq            @ 调用中断初始化函数,在init.c

    msr cpsr_c, #0x53       @ 设置I-bit=0,开IRQ中断

    

    ldr lr, =halt_loop      @ 设置返回地址

    ldr pc, =main           @ 调用main函数

halt_loop:

    b   halt_loop

 

HandleIRQ:

    sub lr, lr, #4                  @ 计算返回地址

    stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器

                             @ 注意,此时的sp是中断模式的sp

@ 初始值是上面设置的3072

    ldr lr, =int_return  @ 设置调用EINT_Handle函数的返回地址 

    ldr pc, =EINT_Handle   @ 调用中断服务函数在interrupt.c

int_return:

    ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr

   

void EINT_Handle()

{

    unsigned long oft = INTOFFSET;

    unsigned long val;

    switch( oft )

    {

        // S2被按下

        case 0:

                 case1:

                      。。。。。

}

    //清中断

    if( oft == 5 )

        EINTPEND = (1<<11);   // EINT8_23合用IRQ5

    SRCPND = 1<

    INTPND = 1<

}

 

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