SMARTARM2200 ADS工程在IAR EWARM 5.3上的移植(1)-启动代码(cstartup.s)分析

手上有块ZLG的SMARTARM2200(LPC2220)的板子,其中的例子都是基于ADS的,想都移植到IAR上去,同时好好研究下IAR,ARM,uCOSII。我用的IAR版本是IAR EWARM5.3.
从Micrium网站上下了uCOSII LPC2148的例子作为模板,修改好的工程可以从http://download.csdn.net/source/1485629上得到。这个工程只含有uCOS及其实例任务,FS,TCP-IP,GUI什么的之后会陆续加入,文章的描述可能与此有差异,如有疑问欢迎与我交流shevsten#gmail.com(#换为@)

启动文件:cstartup.s 
;
;********************************************************************************************************
;                                    EXCEPTION VECTORS & STARTUP CODE
;
; File      : cstartup.s
; For       : ARM7 or ARM9
; Toolchain : IAR EWARM V5.10 and higher
;********************************************************************************************************
;
;开始进行了一些宏定义,供下面的代码调用,如ARM的7种模式对应寄存器值还有LPC2220寄存器地址(之后会用到)
;********************************************************************************************************
;                                           MACROS AND DEFINIITIONS
;********************************************************************************************************

                                ; Mode, correspords to bits 0-5 in CPSR
MODE_BITS DEFINE 0x1F  ; Bit mask for mode bits in CPSR
USR_MODE DEFINE 0x10  ; User mode
FIQ_MODE DEFINE 0x11  ; Fast Interrupt Request mode
IRQ_MODE DEFINE 0x12  ; Interrupt Request mode
SVC_MODE DEFINE 0x13  ; Supervisor mode
ABT_MODE DEFINE 0x17  ; Abort mode
UND_MODE DEFINE 0x1B  ; Undefined Instruction mode
SYS_MODE DEFINE 0x1F  ; System mode
 
;Extenal bus controller Definitions     
PINSEL2        DEFINE          0xE002C014
BCFG0           DEFINE          0xFFE00000
BCFG1           DEFINE          0xFFE00004
BCFG2           DEFINE          0xFFE00008
BCFG3           DEFINE          0xFFE0000C

;这边使用了DEFINE这个关键字,和EQU相比,其作用域更大,相当于全局的。EQU只在定义的模块内有效,而DEFINE定义的宏在其他文件中同样有效,详情请参考EWARM_AssemblerReference.ENU.pdf。

;ARM异常向量
;********************************************************************************************************
;                                            ARM EXCEPTION VECTORS
;********************************************************************************************************

;SECTION-段声明(也可用RSEG)  .intvec-复位及中断向量  CODE-代码段
;NOROOT表示如果这个段里的标号没引用就被linker舍弃,ROOT则一定不舍弃
;如果注释掉PUBLIC  __vector_0x14,那么编译后在map文件里就看不到第二行了
;__vector                0x80000000         Code  Gb  cstartup.o [1]
;__vector_0x14       0x80000014         Code  Gb  cstartup.o [1]
;(2)表示字节对齐数,为2的幂,(2)表示4字节对齐,(3)表示8字节对齐

    SECTION .intvec:CODE:NOROOT(2)

;声明可以被外部引用的标号
    PUBLIC  __vector
    PUBLIC  __iar_program_start
    PUBLIC  __vector_0x14
;引用外部声明的标号,这些标号定义在os_cpu_a.asm(uCOSII移植文件)中

    IMPORT  OS_CPU_ARM_ExceptUndefInstrHndlr
    IMPORT  OS_CPU_ARM_ExceptSwiHndlr
    IMPORT  OS_CPU_ARM_ExceptPrefetchAbortHndlr
    IMPORT  OS_CPU_ARM_ExceptDataAbortHndlr
    IMPORT  OS_CPU_ARM_ExceptIrqHndlr
    IMPORT  OS_CPU_ARM_ExceptFiqHndlr

;告诉编译器为arm指令,也可以用CODE32 

    ARM

;异常向量表

__vector:

;绝对跳转,跳转到相应的异常处理程序,PC总是指向当前指令的下两条指令的地址,即PC的值为当前指令的地址值加8个字节。
;所以LDR PC, [PC,#24]跳转到24+8=32字节后,第一行LDR PC, [PC,#24]就是跳转到__iar_program_start(相当于reset_handler)
    LDR     PC, [PC,#24]    ; Absolute jump can reach 4 GByte
    LDR     PC, [PC,#24]    ; Branch to undef_handler
    LDR     PC, [PC,#24]    ; Branch to swi_handler
    LDR     PC, [PC,#24]    ; Branch to prefetch_handler
    LDR     PC, [PC,#24]    ; Branch to data_handler
__vector_0x14:
    DC32    0               ; Reserved
    LDR     PC, [PC,#24] ; Branch to irq_handler
    LDR     PC, [PC,#24] ; Branch to fiq_handler
;DC32指的是定义32位的常量,同理还有DC16 DS32等数据类型    
    DC32    __iar_program_start
    DC32    OS_CPU_ARM_ExceptUndefInstrHndlr
    DC32    OS_CPU_ARM_ExceptSwiHndlr
    DC32    OS_CPU_ARM_ExceptPrefetchAbortHndlr
    DC32    OS_CPU_ARM_ExceptDataAbortHndlr
    DC32    0
    DC32    OS_CPU_ARM_ExceptIrqHndlr
    DC32    OS_CPU_ARM_ExceptFiqHndlr

;********************************************************************************************************
;                                   LOW-LEVEL INITIALIZATION
;********************************************************************************************************

;定义各种模式STACK,具体大小位置是由linker文件(相当于ADS中的分散加载)决定的,之后在详细介绍。这些STACK都定义在内部RAM中,以CSTACK为例,地址为0x40000040

    SECTION FIQ_STACK:DATA:NOROOT(3)
    SECTION IRQ_STACK:DATA:NOROOT(3)
    SECTION SVC_STACK:DATA:NOROOT(3)
    SECTION ABT_STACK:DATA:NOROOT(3)
    SECTION UND_STACK:DATA:NOROOT(3)
    SECTION CSTACK:DATA:NOROOT(3)
;定义text代码段   

 SECTION text:CODE:NOROOT(2)
;强制__vector被引用,这样__vector就一定会被link了

 REQUIRE __vector
;引用外部C main函数   
 EXTERN  ?main

;声明__iar_program_start和lowlevel_init标号
    PUBLIC  __iar_program_start
    PUBLIC  lowlevel_init

;__iar_program_start内容,实际上就是系统复位后首先运行的代码

__iar_program_start:

;********************************************************************************************************
;                                    STACK POINTER INITIALIZATION
;********************************************************************************************************

;初始化堆栈指针,就不详细描述了,主要就是对CPSR寄存器的操作,请参考ARM相关资料   

    MRS     r0,cpsr                             ; Original PSR value
    BIC     r0,r0,#MODE_BITS            ; Clear the mode bits
    ORR     r0,r0,#SVC_MODE            ; Set SVC mode bits
    MSR     cpsr_c,r0                          ; Change the mode
    LDR     sp,=SFE(SVC_STACK)        ; End of SVC_STACK

    BIC     r0,r0,#MODE_BITS            ; Clear the mode bits
    ORR     r0,r0,#UND_MODE            ; Set UND mode bits
    MSR     cpsr_c,r0                           ; Change the mode
    LDR     sp,=SFE(UND_STACK)        ; End of UND_STACK

    BIC     r0,r0,#MODE_BITS             ; Clear the mode bits
    ORR     r0,r0,#ABT_MODE              ; Set ABT mode bits
    MSR     cpsr_c,r0                           ; Change the mode
    LDR     sp,=SFE(ABT_STACK)         ; End of ABT_STACK

    BIC     r0,r0,#MODE_BITS              ; Clear the mode bits
    ORR     r0,r0,#FIQ_MODE              ; Set FIQ mode bits
    MSR     cpsr_c,r0                           ; Change the mode
    LDR     sp,=SFE(FIQ_STACK)          ; End of FIQ_STACK

    BIC     r0,r0,#MODE_BITS              ; Clear the mode bits
    ORR     r0,r0,#IRQ_MODE              ; Set IRQ mode bits
    MSR     cpsr_c,r0                           ; Change the mode
    LDR     sp,=SFE(IRQ_STACK)           ; End of IRQ_STACK

    BIC     r0,r0,#MODE_BITS               ; Clear the mode bits
    ORR     r0,r0,#SYS_MODE              ; Set System mode bits
    MSR     cpsr_c,r0                           ; Change the mode
    LDR     sp,=SFE(CSTACK)               ; End of CSTACK

;********************************************************************************************************
;                                   ADDITIONAL INITIALIZATION
;********************************************************************************************************
;这段初始化代码是我添加的,主要用来设置外部总线控制器,使外接的PSRAM等外设能正常工作,这样程序的readwrite段就能在RAM中运行了
lowlevel_init:
;Initial extenal bus controller.
    LDR     R0, =PINSEL2
    LDR     R1, =0x0f814914
    STR     R1, [R0]
   
; 定义总线速度控制字       
    LDR     R0, =BCFG0
    LDR     R1, =0x1000ffef
    STR     R1, [R0]
   
    LDR     R0, =BCFG1
    LDR     R1, =0x1000ffef
    STR     R1, [R0]
    
    LDR     R0, =BCFG3
    LDR     R1, =0x10001460
    STR     R1, [R0]


;********************************************************************************************************
;                           CONTINUE TO ?main FOR ADDITIONAL INITIALIZATION
;********************************************************************************************************

;跳转到C代码中的main函数   

 LDR     r0,=?main
    BX      r0

    END

你可能感兴趣的:(SMARTARM2200 ADS工程在IAR EWARM 5.3上的移植(1)-启动代码(cstartup.s)分析)