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

    技术2024-12-18  9

    手上有块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 CPSRMODE_BITS DEFINE 0x1F  ; Bit mask for mode bits in CPSRUSR_MODE DEFINE 0x10  ; User modeFIQ_MODE DEFINE 0x11  ; Fast Interrupt Request modeIRQ_MODE DEFINE 0x12  ; Interrupt Request modeSVC_MODE DEFINE 0x13  ; Supervisor modeABT_MODE DEFINE 0x17  ; Abort modeUND_MODE DEFINE 0x1B  ; Undefined Instruction modeSYS_MODE DEFINE 0x1F  ; System mode ;Extenal bus controller Definitions      PINSEL2        DEFINE          0xE002C014BCFG0           DEFINE          0xFFE00000BCFG1           DEFINE          0xFFE00004BCFG2           DEFINE          0xFFE00008BCFG3           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

    最新回复(0)