iar下.s79的分析

来源:互联网 发布:生活记账软件排名 编辑:程序博客网 时间:2024/06/11 09:54
 
iar下.s79的分析
BSP目录中的是和硬件平台代码相关的函数和定义。其他的则是平台无关的(这里说明一下,我指的是在ARM平台上, 说它相关是指2138相关)。
我们先看LPC2138_RAM.xcl这个文件

//*************************************************************************
// XLINK command file template for EWARM/ICCARM
//
// Usage:  xlink  -f lnkarm  <your_object_file(s)>
//                -s <program start label>  <C/C++ runtime library>
//
// $Revision: 1.3 $
//*************************************************************************

//*************************************************************************
//
// -------------
// Code segments - may be placed anywhere in memory.
// -------------
//
//   INTVEC     -- Exception vector table.
//   SWITAB     -- Software interrupt vector table.
//   ICODE      -- Startup (cstartup) and exception code.
//   DIFUNCT    -- Dynamic initialization vectors used by C++.
//   CODE       -- Compiler generated code.
//   CODE_I     -- Compiler generated code declared __ramfunc (executes in RAM)
//   CODE_ID    -- Initializer for CODE_I (ROM).
//
// -------------
// Data segments - may be placed anywhere in memory.
// -------------
//
//   CSTACK     -- The stack used by C/C++ programs (system and user mode).
//   IRQ_STACK  -- The stack used by IRQ service routines.
//   SVC_STACK  -- The stack used in supervisor mode
//                 (Define other exception stacks as needed for
//                 FIQ, ABT, UND).
//   HEAP       -- The heap used by malloc and free in C and new and
//                 delete in C++.
//   INITTAB    -- Table containing addresses and sizes of segments that
//                 need to be initialized at startup (by cstartup).
//   CHECKSUM   -- The linker places checksum byte(s) in this segment,
//                 when the -J linker command line option is used.
//   DATA_y     -- Data objects.
//
// Where _y can be one of:
//
//   _AN        -- Holds uninitialized located objects, i.e. objects with
//                 an absolute location given by the @ operator or the
//                 #pragma location directive. Since these segments
//                 contain objects which already have a fixed address,
//                 they should not be mentioned in this linker command
//                 file.
//   _C         -- Constants (ROM).
//   _I         -- Initialized data (RAM).
//   _ID        -- The original content of _I (copied to _I by cstartup) (ROM).
//   _N         -- Uninitialized data (RAM).
//   _Z         -- Zero initialized data (RAM).
//
// Note:  Be sure to use end values for the defined address ranges.
//        Otherwise, the linker may allocate space outside the
//        intended memory range.
//*************************************************************************


//************************************************
// Inform the linker about the CPU family used.
//************************************************

-carm

//*************************************************************************
// Segment placement - General information
//
// All numbers in the segment placement command lines below are interpreted
// as hexadecimal unless they are immediately preceded by a '.', which
// denotes decimal notation.
//
// When specifying the segment placement using the -P instead of the -Z
// option, the linker is free to split each segment into its segment parts
// and randomly place these parts within the given ranges in order to
// achieve a more efficient memory usage. One disadvantage, however, is
// that it is not possible to find the start or end address (using
// the assembler operators .sfb./.sfe.) of a segment which has been split
// and reformed.
//
// When generating an output file which is to be used for programming
// external ROM/Flash devices, the -M linker option is very useful
// (see xlink.pdf for details).
//*************************************************************************


//*************************************************************************
// Read-only segments mapped to ROM.
//*************************************************************************

-DROMSTART=40000040
-DROMEND=40005FFF

//************************************************
// Address range for reset and exception
// vectors (INTVEC).
// The vector area is 32 bytes,
// an additional 32 bytes is allocated for the
// constant table used by ldr PC in cstartup.s79.
//************************************************

-Z(CODE)INTVEC=40000000-4000003f

//************************************************
// Startup code and exception routines (ICODE).
//************************************************

-Z(CODE)ICODE,DIFUNCT=ROMSTART-ROMEND
-Z(CODE)SWITAB=ROMSTART-ROMEND

//************************************************
// Code segments may be placed anywhere.
//************************************************

-Z(CODE)CODE=ROMSTART-ROMEND

//************************************************
// Original ROM location for __ramfunc code copied
// to and executed from RAM.
//************************************************

-Z(CONST)CODE_ID=ROMSTART-ROMEND

//************************************************
// Various constants and initializers.
//************************************************

-Z(CONST)INITTAB,DATA_ID,DATA_C=ROMSTART-ROMEND
-Z(CONST)CHECKSUM=ROMSTART-ROMEND

//*************************************************************************
// Read/write segments mapped to RAM.
//*************************************************************************

-DRAMSTART=40006000
-DRAMEND=40007FFF

//************************************************
// Data segments.
//************************************************

-Z(DATA)DATA_I,DATA_Z,DATA_N=RAMSTART-RAMEND

//************************************************
// __ramfunc code copied to and executed from RAM.
//************************************************

-Z(DATA)CODE_I=RAMSTART-RAMEND

//************************************************
// ICCARM produces code for __ramfunc functions in
// CODE_I segments. The -Q XLINK command line
// option redirects XLINK to emit the code in the
// CODE_ID segment instead, but to keep symbol and
// debug information associated with the CODE_I
// segment, where the code will execute.
//************************************************

-QCODE_I=CODE_ID

//*************************************************************************
// Stack and heap segments.
//*************************************************************************

-D_CSTACK_SIZE=200
-D_IRQ_STACK_SIZE=80
-D_FIR_STACK_SIZE=80
-D_SVC_STACK_SIZE=40
-D_ABT_STACK_SIZE=40
-D_UND_STACK_SIZE=40
-D_HEAP_SIZE=200

-Z(DATA)CSTACK+_CSTACK_SIZE=RAMSTART-RAMEND
-Z(DATA)IRQ_STACK+_IRQ_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)FIR_STACK+_FIR_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)SVC_STACK+_SVC_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)ABT_STACK+_ABT_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)UND_STACK+_UND_STACK_SIZE=RAMSTART-RAMEND
-Z(DATA)HEAP+_HEAP_SIZE=RAMSTART-RAMEND

//*************************************************************************
// ELF/DWARF support.
//
// Uncomment the line "-Felf" below to generate ELF/DWARF output.
// Available format specifiers are:
//
//   "-yn": Suppress DWARF debug output
//   "-yp": Multiple ELF program sections
//   "-yas": Format suitable for debuggers from ARM Ltd (also sets -p flag)
//
// "-Felf" and the format specifiers can also be supplied directly as
// command line options, or selected from the Xlink Output tab in the
// IAR Embedded Workbench.
//*************************************************************************

// -Felf

 

这个文件类似于我们以前在ADS里面使用的散列文件。指示了你文件系统编译的时候的段地址。-DROMSTART=40000040  -DROMEND=40005FFF 这2句是定义了只读存储器的其实地址和结束地址。-D_CSTACK_SIZE=200定义了堆栈的大小。

 

系统开始的时候是在lpc2XXX_cstartup.s79这个文件开始的。
下面我尽量讲注释写明白,不对的地方还请提出来。这个文件只是设置了异常向量表,和初始化了堆栈的地址

;-----------------------------------------------------------------------------
; This file contains the startup code used by the ICCARM C compiler.
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; All code in the modules (except ?RESET) will be placed in the ICODE segment.
;
; $Revision: 1.56 $
;
;-----------------------------------------------------------------------------
//ICODE      -- Startup (cstartup) and exception code. ICODE 是启动和异常代码段
;
; Naming covention of labels in this file:
; 在这个文件中的标号命名约定
;  ?xxx   - External labels only accessed from assembler.只能从装配中访问的外部标号。
;  __xxx  - External labels accessed from or defined in C.从C或在C文件中被定义过的外部标号。
;  xxx   - Labels local to one module (note: this file contains 关联到某个模块的标号。
;           several modules).
;  main   - The starting point of the user program. 用于程序的开始主程序。
;

;---------------------------------------------------------------
; Macros and definitions for the whole file  文件中的定义和宏
;---------------------------------------------------------------

; Mode, correspords to bits 0-5 in CPSR 对应于cpsr 中的模式位,即最低6位
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
 

;---------------------------------------------------------------
; ?RESET
; Reset Vector. 重启向量(其实启动也是这个)
; Normally, segment INTVEC is linked at address 0. 一般来说,INTVEC是被连接到0地址的。
; For debugging purposes, INTVEC may be placed at other  可能在调试的时候,为了方便这个代码被放到了其他地址。
; addresses.
; A debugger that honors the entry point will start the 即使INTVEC 不在0地址,调试器将根据入口点正常的启动程序。
; program in a normal way even if INTVEC is not at address 0.
;---------------------------------------------------------------

        MODULE ?RESET  定义模块名称
        COMMON INTVEC:CODE:NOROOT(2)  
        PUBLIC  __program_start  公共标号。
        EXTERN ?cstartup   外部标号
        IMPORT  OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER
        IMPORT  OS_CPU_ARM_EXCEPT_SWI_HANDLER
        IMPORT  OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER
        IMPORT  OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER
        IMPORT  OS_CPU_ARM_EXCEPT_IRQ_HANDLER
        IMPORT  OS_CPU_ARM_EXCEPT_FIQ_HANDLER                从C语言中导入的函数
  CODE32                 ; Always ARM mode after reset      指示CODE32 ADS中为CODE

        org 0x00         定义下一句代码的位置。
__program_start:
  ldr     pc, [pc,#24]    ; Absolute jump can reach 4 GByte  //这个句子是将当前指针指到下面  0x000000020 在ADS里的写发是b reset_handler 跳到标号。
;  ldr     b,  ?cstartup   ; Relative branch allows remap, limited to 32 MByte
                                ; Vectors can be enabled by removing the comments below or by
                                ; using #pragma vector from C code.
        org     0x04
        ldr     pc, [pc,#24]    ; Branch to undef_handler //同上

        org     0x08
        ldr     pc, [pc,#24]    ; Branch to swi_handler

        org     0x0c
        ldr     pc, [pc,#24]    ; Branch to prefetch_handler

        org     0x10
        ldr     pc, [pc,#24]    ; Branch to data_handler

  org     0x18
  ldr     pc, [pc,#24] ; Branch to irq_handler

  org     0x1c
  ldr     pc, [pc,#24] ; Branch to fiq_handler

                          ; Constant table entries (for ldr pc) will be placed at 0x20
                                ; Exception vectors can be specified in C code by #pragma vector or by filling
                                ; in the vectors below. The vector address is the ARM vector number + 0x20.
  org     0x20
        dc32    ?cstartup    //这个就是?cstartup 的地址
  org     0x24
        dc32    OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER   //这些代码被包装在ucos中,在os_Init()时被定义到真正的执行地址
  org     0x28
        dc32    OS_CPU_ARM_EXCEPT_SWI_HANDLER
  org     0x2c
        dc32    OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER
  org     0x30
        dc32    OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER
  org     0x38
        dc32    OS_CPU_ARM_EXCEPT_IRQ_HANDLER
  org     0x3c
        dc32    OS_CPU_ARM_EXCEPT_FIQ_HANDLER

        ENDMOD  //模块的结束  //上面总共是64字节的内容  注意噢,下面的初始化的时候会用到这个知识


;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
  MODULE ?CSTARTUP   启动模块

  RSEG IRQ_STACK:DATA(2)     RSEG是重新定义段地址  RSEG---再定位段选择指令再定位段选择指令为RSEG,用于选择一个已在前面定义过的再定位段作为当前段。格式: RSEG 段名段名必须是在前面已经声明过的再定位段。
  RSEG ABT_STACK:DATA:NOROOT(2)   NOROOT(2) 是指
  RSEG UND_STACK:DATA:NOROOT(2)
  RSEG FIR_STACK:DATA:NOROOT(2)
  RSEG SVC_STACK:DATA:NOROOT(2)
  RSEG CSTACK:DATA(2)
  RSEG ICODE:CODE:NOROOT(2)

  PUBLIC ?cstartup
  EXTERN ?main

; Execution starts here.  执行代码在这里开始
; After a reset, the mode is ARM, Supervisor, interrupts disabled.

  CODE32
?cstartup

; Add initialization nedded before setup of stackpointers here

;在下面的代码中,将切换到各个模式中然后定义当前状态的sp值。
; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.

                mrs     r0,cpsr                             ; Original PSR value   将cpsr中的值放入r0
                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits  清除模式位
                orr     r0,r0,#IRQ_MODE                     ; Set IRQ mode bits    置入IRQ模式位
                msr     cpsr_c,r0                           ; Change the mode      将r0中的值放到cpsr_c 这个时候模式就已经转换位irq模式了,每一个模式都右自己的 sp.
                ldr     sp,=SFE(IRQ_STACK) & 0xFFFFFFF8     ; End of IRQ_STACK   这里的SFE 是iar内置函数目的是取道这个段的地址。&0xFFFFFFF8是为了数据对齐。ldr 指令是要求32位对齐的。

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#ABT_MODE                     ; Set Abort mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(ABT_STACK) & 0xFFFFFFF8     ; End of ABT_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#SVC_MODE                     ; Set Supervisor mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(SVC_STACK) & 0xFFFFFFF8     ; End of SVC_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#UND_MODE                     ; Set Undefined mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(UND_STACK) & 0xFFFFFFF8     ; End of FIR_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#FIQ_MODE                     ; Set FIR mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(FIR_STACK) & 0xFFFFFFF8     ; End of FIR_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) & 0xFFFFFFF8        ; End of CSTACK


#ifdef __ARMVFP__
; Enable the VFP coprocessor.
                mov     r0, #0x40000000                 ; Set EN bit in VFP
                fmxr    fpexc, r0                       ; FPEXC, clear others.

; Disable underflow exceptions by setting flush to zero mode.
; For full IEEE 754 underflow compliance this code should be removed
; and the appropriate exception handler installed.
                mov     r0, #0x01000000          ; Set FZ bit in VFP
                fmxr    fpscr, r0                       ; FPSCR, clear others.
#endif

; Add more initialization here


; Continue to ?main for more IAR specific system startup

                ldr     r0,=?main  在这里跳转到 main 函数的开始。
                bx      r0

                LTORG

                ENDMOD

                END

//待续
原创粉丝点击