• 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

  • 相关阅读:
    二 .数据库(Data)操作
    一. 数据库(Data)基础
    五种IO/模型
    并发编程 (协程)
    七.并发编程 (线程池,返回值,回调函数)
    六.并发编程 (线程对列)
    五.并发编程 (线程事件)
    四.并发编程 (线程信号量)
    三.并发编程 (线程锁)
    二.并发编程 (程序中线程操作)
  • 原文地址:https://www.cnblogs.com/lyyyuna/p/4123962.html
Copyright © 2020-2023  润新知