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

来源:互联网 发布:软件ico图标 编辑:程序博客网 时间:2024/06/06 07:22
 根据各方面资料,整理了一下··未完待续

;下面是对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