您的位置:首页 > 编程语言

四极管:2410启动代码分析之 vector.s详解一

2011-12-20 10:47 645 查看
 根据各方面资料,整理了一下··未完待续
;下面是对ARM处理器模式寄存器对应值的常数定义,ARM处理器中有一个CPSR程序状态寄存器,它的后;;五位决定目前的处理模式

USERMODE  EQU 0x10 ;//用户模式

FIQMODE   EQU 0x11 ;//FIQ模式

IRQMODE   EQU 0x12 ;//IRQ模式

SVCMODE   EQU 0x13 ;//管理模式

ABORTMODE  EQU 0x17 ;//中止模式

UNDEFMODE  EQU 0x1B ;//未定义

MODEMASK   EQU 0x1F ;//系统模式

I_BIT   EQU 0x80 ;//

F_BIT   EQU 0x40

T_BIT   EQU 0x20

NOINT              EQU 0xc0

;**********************************************************

;检查是否使用tasm.exe进行编译

;ARM处理器有两种工作状态

;1、ARM:32位 这种工作状态下执行字对准的ARM指令

;2、Thumb16位 这种工作状态执行半字对准的Thumb指令

;因为处理器分为16位 32位两种工作状态。程序的编译器也是分为16位和32位两种编译方式,所以下面的程序用于根据处理器工作状态确定为编译器编译方式

;code16伪指令指示汇编编译器后面的指令为16位的Thumb指令

;code32伪指令指示汇编编译器后面的指令为32位的arm指令

; 这段代码是为了统一目前处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译) 

 GBLL    THUMBCODE ;设置一个全局逻辑变量,注意EQU所定义的宏与变量的区别

    [ {CONFIG} = 16 ;if config==16 这里表示你的目前处于领先的16位编译方式 

THUMBCODE SETL {TRUE} ;//一方面把THUMBCODE设置为TURE

    CODE32 ;//另一方面暂且把处理器设置为ARM模式。以方便初始化

    |   ;else

THUMBCODE SETL {FALSE};设置THUMBCODE 为false

    ]

    [ THUMBCODE  ;//if THUMBCODE == TRUE

    CODE32   ;for start-up code for Thumb mode,转入32位编译方式

    ]

   

 MACRO ;一个根据THUMBCODE把PC寄存器的值保存到LR的宏 

 MOV_PC_LR;宏名称

 [ THUMBCODE  ;如果定义了THUMBCODE,则

     bx lr  ;在ARM模式中要使用到BX指令跳转到THUMB指令,并转换模式。BX指令会根据PC最后1位赖确定是否进入thumb状态

 |    ;否则

  mov pc, lr  ;如果目标地址也是ARM指令的话就采用这种方式

 ]

 MEND ;宏定义结束标志

     

;******************************************************

 AREA reset, CODE, READONLY ;//定义一个代码段:用于处理复位操作

 ENTRY 

 

 EXPORT __ENTRY

__ENTRY 

ResetEntry

 b SYS_RST_HANDLER;复位异常  

 b UDF_INS_HANDLER

 b SWI_SVC_HANDLER

 b INS_ABT_HANDLER

 b DAT_ABT_HANDLER

 b .

 b IRQ_SVC_HANDLER;外部中断请求

 b FIQ_SVC_HANDLER

;******************************************************

;=======================================================

;下面这个宏是用于第一次查表过程的实现中断向量的重定向

;这段程序用于把中断服务程序的首地址装载到PC中,有人称之为“加载程序”

;本初始化程序定义了一个数据区(在文件最后)。34个字空间,存放相应中断服务程序的首地址。每个字;空间都有一个标号,以;Handle***命名

;在向量中断模式下使用"加载程序"来执行中断服务程序。

;这里就必须讲一下向量中断模式和非向量中段模式的概念

;向量中断模式是当CPU读取位于0x18处的IRQ中断指令的时候,系统自动读取对应于该中断源确定的地址上的·

;指令取代0x18处的指令,通过跳转指令系统就直接跳转到相应的地址

;函数中  节省了中断处理时间提高了中断处理速度标  例如ADC中断向量地址为0xc0,则在0xc0处放如下代码:ldr PC,=HandlerADC 当;ADC中断产生的时候系统会自动跳转到Handler ADC函数中

;非向量的中断模式处理方式是一种传统的中断处理方法,当系统产生中断的时候,系统将interrupt

;pending寄存器中对应标志位置位,然后跳转到位于0x18处的统一中断

;函数中该函数通过读取interrupt pending寄存器中对应标志位来判断中断源,并根据优先级关系再跳到对应中断源的处理代码中。

 MACRO    ;通过定义一个宏,统一处理各异常处理程序与异常向量地址的映射

$HandlerLabel HANDLER $HandleLabel

$HandlerLabel                   ;标号

 sub sp,sp,#4        ;decrement sp(to store jump address)减少SP(用于存放跳转地址)

    ;把工作寄存器压入栈

 stmfd sp!,{r0}        ;PUSH the work register to stack(lr does not push because it return to original address)

 ldr     r0,=$HandleLabel;load the address of HandleXXX to r0将Handlexxx的地址放入r0

 ldr     r0,[r0]         ;load the contents(service routine start address) of HandleXXX; 把Handlexxx所指向的内容(也就是中断程序入口)放入R0

 str     r0,[sp,#4]      ;store the contents(ISR) of HandleXXX to stack把中断服务程序(ISR)压入栈

 ldmfd   sp!,{r0,pc}     ;POP the work register and pc(jump to ISR)用出栈的方式恢复r0的原值和为pc设定新值(也就完成了到ISR的跳转)

 MEND

;从上面的代码可以总结出,接收到IRQ中断请求后程序的执行流程是:

(1)、执行完当前指令,程序自动跳转到0x18地址;

(2)、从0x18程序跳转到IRQ_SVC_HANDLER;

(3)、从IRQ_SVC_HANDLER;再到SDRAM高端异常矢量表

(4)、从SDRAM高端异常矢量表跳转到IRQ_SERVICE异常处理程序;

(5)、由IRQ_SERVICE最后进入中断服务程序,完成中断处理任务后返回。

;UDF_INS_HANDLER

; stmfd sp!, {r0-r3, lr}

; ldr r0, =UdfInsVector

; mov lr, pc

; ldr pc, [r0]

; ldmfd sp!, {r0-r3, pc}^

;SWI_SVC_HANDLER

; stmfd sp!, {r0-r3, lr}

; ldr r0, =SwiSvcVector

; mov lr, pc

; ldr pc, [r0]

; ldmfd sp!, {r0-r3, pc}^

;INS_ABT_HANDLER

; sub lr, lr, #4

; stmfd sp!, {r0-r3, lr}

; ldr r0, =InsAbtVector

; mov lr, pc

; ldr pc, [r0]

; ldmfd sp!, {r0-r3, pc}^

;DAT_ABT_HANDLER

; sub lr, lr, #4

; stmfd sp!, {r0-r3, lr}

; ldr r0, =DatAbtVector

; mov lr, pc

; ldr pc, [r0]

; ldmfd sp!, {r0-r3, pc}^

;IRQ_SVC_HANDLER

; sub lr, lr, #4

; stmfd sp!, {r0-r12, lr} 

; mrs r0, spsr

; stmfd sp!, {r0}

; ldr r0, =IrqSvcVector

; ldr pc, [r0] 

;FIQ_SVC_HANDLER

; sub lr, lr, #4

; stmfd sp!, {r0-r12, lr} 

; mrs r0, spsr

; stmfd sp!, {r0}

; ldr r0, =FiqSvcVector

; ldr pc, [r0]

UDF_INS_HANDLER HANDLER UdfInsVector

SWI_SVC_HANDLER HANDLER SwiSvcVector

INS_ABT_HANDLER HANDLER InsAbtVector

DAT_ABT_HANDLER HANDLER DatAbtVector

IRQ_SVC_HANDLER HANDLER IrqSvcVector

FIQ_SVC_HANDLER HANDLER FiqSvcVector

    

;*******************************************************

SYS_RST_HANDLER

 mrs r0, cpsr    ;enter svc mode and disable irq,fiq

 bic r0, r0, #MODEMASK

 orr r0, r0, #(SVCMODE :OR: I_BIT :OR: F_BIT)

 msr cpsr_c, r0

 

; IMPORT InitSystem

 b InitSystem

 

InitSystem_exit 

 

;**************************************************** 

;初始化堆栈

 ;Do not use DRAM,such as stmfd,ldmfd......

 ;SVCstack is initialized before

 ;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'

 

 mrs r0, cpsr

 bic r0, r0, #(MODEMASK|NOINT)

 

 orr r1, r0, #UNDEFMODE|NOINT

 msr cpsr_cxsf, r1  ;UndefMode

 ldr sp, =UndefStack

 

 orr r1, r0, #ABORTMODE|NOINT

 msr cpsr_cxsf, r1  ;AbortMode

 ldr sp, =AbortStack

 

 orr r1, r0, #IRQMODE|NOINT

 msr cpsr_cxsf, r1  ;IRQMode

 ldr sp, =IRQStack

 

 orr r1, r0, #FIQMODE|NOINT

 msr cpsr_cxsf, r1  ;FIQMode

 ldr sp, =FIQStack 

  

; orr r1, r0, #SVCMODE  ;enable irq,fiq

 orr r1, r0, #SVCMODE|NOINT ;disable irq, fiq

 msr cpsr_cxsf,r1  ;SVCMode

 ldr sp, =SVCStack

 ;USER mode is not initialized.

 ;未初始化用户模式栈,程序使用SVC模式

;**************************************************** 

 adr r0, ResetEntry

 ldr r2, BaseOfROM

 cmp r0, r2

 ldreq r0, TopOfROM

 beq InitRam 

 ldr r3, TopOfROM



 ldmia r0!, {r4-r7}

 stmia r2!, {r4-r7}

 cmp r2, r3

 bcc %B0

 

 sub r2, r2, r3

 sub r0, r0, r2    

  

InitRam 

 ldr r2, BaseOfBSS

 ldr r3, BaseOfZero 

0

 cmp r2, r3

 ldrcc r1, [r0], #4

 strcc r1, [r2], #4

 bcc %B0 

 mov r0, #0

 ldr r3, EndOfBSS



 cmp r2, r3

 strcc r0, [r2], #4

 bcc %B1

 

;****************************************************

;设置IQR处理程序入口, 在配置好RAM后设置 

; IMPORT IRQ_SERVICE

 ldr r0, =IrqSvcVector 

 ldr r1, =IRQ_SERVICE  

 str r1, [r0]

;****************************************************

;

_main

__main

 EXPORT _main

 EXPORT __main

; 从这里跳转到我亲爱的main函数 

; IMPORT PortInit

; IMPORT TimerInit

; IMPORT LedDisp

; bl PortInit

; ldr r0, =0x1d20014

; ldr r1, [r0]

;0 

; bic r1, r1, #0xe

; str r1, [r0]

; mov r2, #0x100000

;1

; subs r2, r2, #1

; bne %B1

; orr r1, r1, #0xe

; str r1, [r0]

; mov r2, #0x100000

;2

; subs r2, r2, #1

; bne %B2

; b %B0 

 

; bl TimerInit

;1

; bl LedDisp

; b %B1

 

 ldr lr, GotoMain

 MOV_PC_LR

 GBLS MainEntry

MainEntry SETS "Main"

 IMPORT $MainEntry

GotoMain DCD $MainEntry

 EXPORT DisableInt

DisableInt

 mrs r0, cpsr

 orr r0, r0, #NOINT

 msr cpsr_cf, r0

 MOV_PC_LR

 

 EXPORT EnableInt

EnableInt

 mrs r0, cpsr

 bic r0, r0, #NOINT

 msr cpsr_cf, r0

 MOV_PC_LR

 

;save cpsr and disable int, r0 = address to save cpsr

 EXPORT EnterCritical

EnterCritical  

 mrs r1, cpsr

 str r1, [r0]

 orr r1, r1, #NOINT

 msr cpsr_cxsf, r1  

 MOV_PC_LR

;restore cpsr, r0 = address to restore cpsr 

 EXPORT ExitCritical

ExitCritical

 ldr r1, [r0]

 msr cpsr_cxsf, r1 

 MOV_PC_LR 

 EXPORT outportb

outportb strb r0, [r1]

 MOV_PC_LR

 

 EXPORT outportw

outportw strh r0, [r1]

 MOV_PC_LR

 

 EXPORT outportl

outportl str r0, [r1]

 MOV_PC_LR

 

 EXPORT inportb

inportb ldrb r0, [r0]

 MOV_PC_LR

 EXPORT inportw

inportw ldrh r0, [r0]

 MOV_PC_LR

 EXPORT inportl

inportl ldr r0, [r0]

 MOV_PC_LR

;***********************************************

 IMPORT |Image$$RO$$Base| ; ROM code start 

 IMPORT |Image$$RO$$Limit| ; RAM data starts after ROM program

 IMPORT |Image$$RW$$Base| ; Pre-initialised variables

 IMPORT |Image$$ZI$$Base| ; uninitialised variables

 IMPORT |Image$$ZI$$Limit| ; End of variable RAM space

BaseOfROM DCD |Image$$RO$$Base|

TopOfROM DCD |Image$$RO$$Limit|

BaseOfBSS DCD |Image$$RW$$Base|

BaseOfZero DCD |Image$$ZI$$Base|

EndOfBSS DCD |Image$$ZI$$Limit|

 

;***********************************************

; IMPORT UserStack

; IMPORT SVCStack

; IMPORT UndefStack

; IMPORT AbortStack

; IMPORT IRQStack

; IMPORT FIQStack

 

; IMPORT SysRstVector

; IMPORT UdfInsVector

; IMPORT SwiSvcVector

; IMPORT InsAbtVector

; IMPORT DatAbtVector

; IMPORT ReservedVector

; IMPORT IrqSvcVector

; IMPORT FiqSvcVector

 

;*********************************************** 

 

 END

 

 

作者:四极管  广西师范大学 电子工程学院大学生科技创新基地 邮箱: yangxingbo-0311@163.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息