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
//待续
我们先看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
//待续
- iar下.s79的分析
- iar下的MQX库文件编译
- Windows下正确安装IAR的方法
- IAR IDE下的inline函数
- IAR 下的ICF文件配置
- IAR下STM32F103 Boot + APP的编程
- SMARTARM2200 ADS工程在IAR EWARM 5.3上的移植(3)-IAR Linker文件分析
- IAR map文件分析
- TI z-stack 在IAR环境下的错误处理
- IAR下STM8S207单片机各模块的无库例程
- IAR环境下ucosii在STM32上的移植
- IAR下STM8S207单片机各模块的无库例程
- IAR下如何确定某一段代码的执行时间
- IAR下Rebuild all出现error的问题
- IAR环境下stm32上ucos的移植
- 关于IAR环境下工程结构、管理的笔记
- IAR环境下STM32+IAP方案的实现
- IAR环境下STM32+IAP方案的实现
- 解决Tapestry5中文问题 (转)
- J2EE入门视频教程第三讲——IDE使用高级技巧之程序调试
- 网吧XP无盘系统集成优化及母盘封装
- 基于SCA规范的应用服务框架成长记
- 谨以此文献给才毕业2--5年的朋友
- iar下.s79的分析
- 为什么网络上对于google公司的评价均是正面的呢?
- 2007---2008
- 深冬寒思
- J2ME WTK2.3的一个bug
- myeclipse6.01 ssh配置文件
- 《闯关东》群英传
- Linux之线程同步篇
- Debian4.0安装oracle 10g XE的一些记录