snifer

【嵌入式】[原创]基于S3C44B0的启动程序设计

0
阅读(4703)

最近嵌入式系统竞赛进入了冲刺期,大家都在努力啊,38的高温,伤不起。

下午帮一个同学解答了一个S3C44B0的启动程序设计的问题,今天写出来与大家共勉。

S3C44B0启动程序设计流程图如下,我会针对一般选手的问题一步一步介绍这个系统:


        下面的代码是S3C44B0的启动程序源代码及其解释:

   # *****************************************************************

  # 文件名: INIT.S 

  # 说明:   S3c44B0启动文件    *

  # *****************************************************************

  #==========================================================

# 寄存器定义及其位定义

  #==========================================================

  .equ   INTMSK,  0x01e0000c

  .equ   WTCON,  0x01d30000 

  .equ   CLKCON,  0x01d80004

  .equ   LOCKTIME,  0x01d8000c

  .equ   FIQMODE,  0x11

  .equ   IRQMODE,  0x12

  .equ   SVCMODE,  0x13

  .equ   ABORTMODE,  0x17

  .equ   UNDEFMODE,  0x1b

  .equ   MODEMASK,  0x1f

  .equ   NOINT,  0xc0

#==================================================

  # 中断处理宏

  #==================================================

    .macro HANDLER HandleLabel

    sub      sp, sp, #4        @ 栈空间递减保存跳转地址

    stmfd   sp!, {r0}        @ 保存工作寄存器r0到栈

    ldr      r0, =\HandleLabel   @ 载入中断入口地址所在位置到r0

    ldr      r0, [r0]        @ 载入中断入口地址到r0

    str      r0, [sp,#4]       @ 保存中断入口地址到栈

    ldmfd   sp!, {r0,pc}        @ 恢复工作寄存器并跳转到中断函数

    .endm

#==========================================================

# 设置ARM7中断和异常向量

#==========================================================

ENTRY:

    b   ResetHandler  @ S3C44B0复位后从此处执行

    b   HandlerUndef        @ 未定义异常向量

    b   HandlerSWI          @ 软中断向量

    b   HandlerPabort       @ 取指异常向量

    b   HandlerDabort       @ 取数据异常向量

    b   .                   @ 保留

    b   HandlerIRQ  @ 中断向量

    b   HandlerFIQ  @ 快速中断向量

#==========================================================

  # 设置44B0中断向量表

  #==========================================================

  VECTOR_BRANCH:

  ldr pc,=HandlerEINT0      @ mGA H/W interrupt    vector table

  ldr pc,=HandlerEINT1      @

  ……  @ 省略

  ldr pc,=HandlerADC       @ mGKB

  ……  @ 省略

      b .

#==========================================================

# 中断向量处理宏

#==========================================================

  HandlerFIQ:  HANDLER HandleFIQ

HandlerIRQ:  HANDLER HandleIRQ

HandlerUndef:  HANDLER HandleUndef

HandlerSWI:  HANDLER HandleSWI

HandlerDabort:  HANDLER HandleDabort

HandlerPabort:  HANDLER HandlePabort

HandlerADC:  HANDLER HandleADC

  ……  @ 省略

HandlerEINT1:  HANDLER HandleEINT1

HandlerEINT0:  HANDLER HandleEINT0

#==========================================================

  # 中断向量处理宏

#==========================================================

ResetHandler:

    ldr      r0,=WTCON        @ 看门狗禁止

    ldr      r1,=0x0  

    str      r1,[r0]

    ldr      r0,=INTMSK

    ldr      r1,=0x07ffffff    @ 所有中断禁止

    str      r1,[r0]

  #================================================== 

# 设置时钟控制控制器

  #==================================================

    ldr  r0, =LOCKTIME

    ldr  r1, =0xfff

    str  r1, [r0]

    ldr      r0, =CLKCON 

    ldr      r1, =0x7ff8      @ 所有模块的时钟开启

    str      r1, [r0]

  #==================================================

  # 设置存储区控制器

  #==================================================

    ldr      r0, =SMRDATA

    ldmia   r0, {r1-r13}

    ldr      r0, =0x01c80000

    stmia   r0, {r1-r13}

  #==================================================

# 初始化栈空间

  #==================================================

    ldr      sp, =SVCStack  @ 切换到超级用户栈空间

    bl      InitStacks

  #==================================================

  # 引入外部符号, 符号定义在链接脚本文件中

  #==================================================

  .extern  Image_RO_Limit    @ 只读区域大小

    .extern  Image_RW_Base            @ 可读写存储区域起始地址

.extern  Image_ZI_Base     @ 清零区域起始地址

.extern  Image_ZI_Limit    @ 清零区域大小

#==================================================

  # 初始化C代码需要使用的存储区

  #==================================================

  LDR  r0, =Image_RO_Limit   @ 获取只读区域大小

  LDR  r1, =Image_RW_Base    @ 获取可读写区域起始地址

  LDR  r3, =Image_ZI_Base    @ 获取清零区域起始地址

  CMP     r0, r1        @ 比较只读区域和可读写区域是否重叠

  BEQ     LOOP1

LOOP0:

  CMP     r1, r3         @ 拷贝程序中.data数据段内容到读写区域

    LDRCC   r2, [r0], #4

    STRCC   r2, [r1], #4

    BCC     LOOP0

LOOP1:

    LDR     r1, =Image_ZI_Limit   @ 从清零区域顶部开始

    MOV     r2, #0

LOOP2:

    CMP     r3, r1                 @ 清零

  STRCC   r2, [r3], #4

  BCC     LOOP2

  #===========================

  # 进入C语言程序入口

  #===========================

#   .extern __main

#   BL      __main

#==========================================================

# 初始化栈空间的函数

#==========================================================

InitStacks:

    mrs      r0, cpsr

    bic      r0, r0, #MODEMASK

    orr      r1, r0, #UNDEFMODE | NOINT

    msr      cpsr_cxsf, r1 

    ldr      sp, =UndefStack  @ 设置未定义异常栈空间

 

    orr      r1, r0, #ABORTMODE|NOINT

    msr      cpsr_cxsf, r1        

    ldr      sp, =AbortStack  @ 设置异常栈空间

    orr      r1, r0, #IRQMODE|NOINT

    msr      cpsr_cxsf, r1        

    ldr      sp, =IRQStack  @ 设置中断栈空间


 orr      r1, r0, #FIQMODE|NOINT

    msr      cpsr_cxsf, r1        

    ldr      sp, =FIQStack  @ 设置快速中断栈空间

    bic      r0, r0, #MODEMASK|NOINT

    orr      r1, r0, #SVCMODE

    msr      cpsr_cxsf, r1

    ldr      sp, =SVCStack  @ 设置超级用户栈空间

    mov      pc,lr   @ 函数返回

   

#==========================================================

# 存储区相关寄存器设置值

#==================================================== 

SMRDATA:

  .long 0x11110101  @ 存储区访问宽度控制寄存器

  .long 0x00000600  @ BANK0 控制寄存器

  .long 0x00007FFC  @ BANK1 控制寄存器

  .long 0x00007FFC  @ BANK2 控制寄存器

  .long 0x00007FFC  @ BANK3 控制寄存器

  .long 0x00007FFC  @ BANK4 控制寄存器

  .long 0x00007FFC  @ BANK5 控制寄存器

  .long 0x00018000  @ BANK6 控制寄存器

  .long 0x00018000  @ BANK7 控制寄存器

  .long 0x00860459  @ SDRAM刷新控制寄存器

  .long 0x10  @ SDRAM存储区大小

  .long 0x20  @ BANK6 SDRAM模式寄存器

  .long 0x20  @ BANK7 SDRAM模式寄存器

equ  STARTADDRESS,  0xc7fff00

#==========================================================

# 栈空间定义

#==========================================================

.equ  UserStack,  STARTADDRESS-0x500      @ c1(c7)ffa00

.equ  SVCStack,  STARTADDRESS-0x500+256      @ c1(c7)ffb00

.equ  UndefStack,  STARTADDRESS-0x500+256*2     @ c1(c7)ffc00

.equ  AbortStack,  STARTADDRESS-0x500+256*3     @ c1(c7)ffd00

.equ  IRQStack,  STARTADDRESS-0x500+256*4     @ c1(c7)ffe00

.equ  FIQStack,  STARTADDRESS-0x500+256*5     @ c1(c7)fff00

#========================================================= 

# ARM中断向量入口定义

#==========================================================

.equ  HandleReset,  STARTADDRESS

.equ  HandleUndef,  STARTADDRESS+4

.equ  HandleSWI,  STARTADDRESS+4*2

.equ  HandlePabort,  STARTADDRESS+4*3

.equ  HandleDabort,  STARTADDRESS+4*4

.equ  HandleReserved,  STARTADDRESS+4*5

.equ  HandleIRQ,  STARTADDRESS+4*6

.equ  HandleFIQ,  STARTADDRESS+4*7

#==========================================================

# S3C44B0中断向量入口定义

#==========================================================

.equ  HandleADC,      STARTADDRESS+4*8

……  @ 省略

.equ   Handle EINT4567,  STARTADDRESS+4*29

.equ  Handle EINT3,  STARTADDRESS+4*30

.equ  Handle EINT2,  STARTADDRESS+4*31

.equ  Handle EINT1,  STARTADDRESS+4*32

.equ  Handle EINT0,  STARTADDRESS+4*33  @ 0xc1(c7)f 

这就是S3C44B0的启动程序设计的全过程,相信大家对我这个能认真看一遍的话就一定能够整个过程,为大家后续的处理奠定基础,大家不要忘记投票哦。