hotpower 发表于 2006-3-8 16:35:16

通用非典启动文件STARTUP.S源代码(三八节日版)

;/*****************************************************************************/

;/* STARTUP.S: Startup file for SWI Example                                 */

;/*****************************************************************************/

;/* <<< Use Configuration Wizard in Context Menu >>>                        */

;/*****************************************************************************/

;/* This file is part of the uVision/ARM development tools.                   */

;/* Copyright (c) 2005-2006 Keil Software. All rights reserved.               */

;/* This software may only be used under the terms of a valid, current,       */

;/* end user licence from KEIL for a compatible version of KEIL software      */

;/* development tools. Nothing else gives you the right to use this software. */

;/*****************************************************************************/





;/*

; *The STARTUP.S code is executed after CPU Reset. This file may be

; *translated with the following SET symbols. In uVision these SET

; *symbols are entered under Options - ASM - Define.

; *

; *REMAP: when set the startup code initializes the register MEMMAP

; *which overwrites the settings of the CPU configuration pins. The

; *startup and interrupt vectors are remapped from:

; *   0x00000000default setting (not remapped)

; *   0x40000000when RAM_MODE is used

; *

; *RAM_MODE: when set the device is configured for code execution

; *from on-chip RAM starting at address 0x40000000.

; */





; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs



Mode_USR      EQU   0x10

Mode_FIQ      EQU   0x11

Mode_IRQ      EQU   0x12

Mode_SVC      EQU   0x13

Mode_ABT      EQU   0x17

Mode_UND      EQU   0x1B

Mode_SYS      EQU   0x1F



I_Bit         EQU   0x80            ; when I bit is set, IRQ is disabled

F_Bit         EQU   0x40            ; when F bit is set, FIQ is disabled





;// <h> Stack Configuration (Stack Sizes in Bytes)

;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>

;//   <o1> Supervisor Mode   <0x0-0xFFFFFFFF:8>

;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>

;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>

;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>

;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>

;// </h>



UND_Stack_SizeEQU   0x00000080;0x000

SVC_Stack_SizeEQU   0x00000040;0x040

ABT_Stack_SizeEQU   0x00000000;0x000

FIQ_Stack_SizeEQU   0x00000080;0x000

IRQ_Stack_SizeEQU   0x00000080;0x080

USR_Stack_SizeEQU   0x00000400;0x400



Stack_Size      EQU   (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \

                         FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)



                AREA    STACK, NOINIT, READWRITE, ALIGN=3

Stack_Mem       SPACE   Stack_Size



Stack_Top       EQU   Stack_Mem + Stack_Size





;// <h> Heap Configuration

;//   <o>Heap Size (in Bytes) <0x0-0xFFFFFFFF>

;// </h>



Heap_Size       EQU   0x00000000



                AREA    HEAP, NOINIT, READWRITE, ALIGN=3

Heap_Mem      SPACE   Heap_Size





; VPBDIV definitions

VPBDIV          EQU   0xE01FC100      ; VPBDIV Address



;// <e> VPBDIV Setup

;// <i> Peripheral Bus Clock Rate

;//   <o1.0..1>   VPBDIV: VPB Clock

;//               <0=> VPB Clock = CPU Clock / 4

;//               <1=> VPB Clock = CPU Clock

;//               <2=> VPB Clock = CPU Clock / 2

;//   <o1.4..5>   XCLKDIV: XCLK Pin

;//               <0=> XCLK Pin = CPU Clock / 4

;//               <1=> XCLK Pin = CPU Clock

;//               <2=> XCLK Pin = CPU Clock / 2

;// </e>

VPBDIV_SETUP    EQU   0

VPBDIV_Val      EQU   0x00000000





; Phase Locked Loop (PLL) definitions

PLL_BASE      EQU   0xE01FC080      ; PLL Base Address

PLLCON_OFS      EQU   0x00            ; PLL Control Offset

PLLCFG_OFS      EQU   0x04            ; PLL Configuration Offset

PLLSTAT_OFS   EQU   0x08            ; PLL Status Offset

PLLFEED_OFS   EQU   0x0C            ; PLL Feed Offset

PLLCON_PLLE   EQU   (1<<0)          ; PLL Enable

PLLCON_PLLC   EQU   (1<<1)          ; PLL Connect

PLLCFG_MSEL   EQU   (0x1F<<0)       ; PLL Multiplier

PLLCFG_PSEL   EQU   (0x03<<5)       ; PLL Divider

PLLSTAT_PLOCK   EQU   (1<<10)         ; PLL Lock Status



;// <e> PLL Setup

;//   <o1.0..4>   MSEL: PLL Multiplier Selection

;//               <1-32><#-1>

;//               <i> M Value

;//   <o1.5..6>   PSEL: PLL Divider Selection

;//               <0=> 1   <1=> 2   <2=> 4   <3=> 8

;//               <i> P Value

;// </e>

PLL_SETUP       EQU   1

PLLCFG_Val      EQU   0x00000024





; Memory Accelerator Module (MAM) definitions

MAM_BASE      EQU   0xE01FC000      ; MAM Base Address

MAMCR_OFS       EQU   0x00            ; MAM Control Offset

MAMTIM_OFS      EQU   0x04            ; MAM Timing Offset



;// <e> MAM Setup

;//   <o1.0..1>   MAM Control

;//               <0=> Disabled

;//               <1=> Partially Enabled

;//               <2=> Fully Enabled

;//               <i> Mode

;//   <o2.0..2>   MAM Timing

;//               <0=> Reserved<1=> 1   <2=> 2   <3=> 3

;//               <4=> 4         <5=> 5   <6=> 6   <7=> 7

;//               <i> Fetch Cycles

;// </e>

MAM_SETUP       EQU   1

MAMCR_Val       EQU   0x00000002

MAMTIM_Val      EQU   0x00000004





; Area Definition and Entry Point

;Startup Code must be linked first at Address at which it expects to run.



;/*****************************************************************************/

;/*             Keil RealView编译器通用非典启动文件STARTUP.S源代码            */

;/*文   件   名 : STARTUP.S                                                   */

;/*改   造   人 : ARM水鸟HotPower@126.com                                 */

;/*版   本   号 : V3.80 (三八节日版) 详细使用说明参见以后将发表的相关文挡   */

;/*菜 农 水潭 :http://hotpower.21ic.org                                    */

;/*改 造 日期 : 2006.3.8   15:38                                          */

;/*改 造地 点 :西安大雁塔村队部                                          */

;/*说      明 :可在ARTX及非ARTX环境下可靠运行,并兼容经典的启动代码      */

;/*注 意事 项 : 本品为违禁药品,毒性太深,服用前请遵医嘱,妇孺禁用          */

;/*               由于服用不当所产生的所有后果,菜农概不负责                  */

;/*增 加 内容 :不初始化变量为0,增强抗干扰的力度,最大限度保持程序的连续性*/

;/*特 别 鸣谢 :ARM老鸟---云中月8888                                        */

;/*****************************************************************************/



RAM_UNINIT      EQU   1;0-变量需要初始化为0(默认)

                         ;1-变量不需要初始化为0





Vectors_FLASH   EQU   0;使用FLASH中断向量(0 经典RAM,1 非典FLASH)

                         ;注意,VICVectAddr0~VICVectAddr15,DefVectAddr的用法

                                               ;在经典时,为向量中断装载地址

                                               ;在非典时,为向量中断自然序号!!!

Vectors_STACK   EQU   0;使用栈区(0 不保护寄存器R12,1 保护寄存器R12)

                         ;注意:当Vectors_FLASH = 0时,Vectors_STACK无意义)



Vectors_ARTX    EQU   0;0-在非ARTX上运行1-在ARTX上运行

Vectors_FIQVICEQU   0;0-不使用快速中断 1-使用快速中断

Vectors_IRQVICEQU   0;0-不使用单向量中断 1-使用单向量中断(不建议使用!!!)

Vectors_DEFVICEQU   0;0-不使用默认向量向量 1-使用默认向量向量(ARTX下自动定义)

Vectors_SWIVICEQU   0;0-SWI.S中无Swi_COUNT=0,1-SWI.S中无Swi_COUNT>0



                AREA    RESET, CODE, READONLY

                ARM





; Exception Vectors

;Mapped to Address 0.

;Absolute addressing mode must be used.

;Dummy Handlers are implemented as infinite loops which can be modified.



Vectors         LDR   PC, Reset_Addr         

                LDR   PC, Undef_Addr

                LDR   PC, SWI_Addr

                LDR   PC, PAbt_Addr

                LDR   PC, DAbt_Addr

                NOP

                                IF      Vectors_IRQVIC <> 0

                  LDR   PC, IRQ_Addr;不主张用此句

                                ELSE

                  IF      Vectors_FLASH <> 0;非典FLASH向量

                  B       VIC_Vect_Addr_Table;非典VIC_Vect_Addr_Table

                  ELSE ;经典RAM向量

                  LDR   PC, ;经典直接跳入RAM当前中断向量地址VicVectAddr

                                  ENDIF

                                ENDIF

                LDR   PC, FIQ_Addr





Reset_Addr      DCD   Reset_Handler

Undef_Addr      DCD   Undef_Handler



                          IF      Vectors_SWIVIC <> 0;用户使用了至少1个软中断SWI

                                  IMPORTSWI_Handler

SWI_Addr          DCD   SWI_Handler;用户执行软中断

                ELSE

SWI_Addr          DCD   SWI_Handler;用户未使用了软中断,则死机

                ENDIF

               



PAbt_Addr       DCD   PAbt_Handler

DAbt_Addr       DCD   DAbt_Handler

                DCD   0                      ; Reserved Address



                                IF      Vectors_IRQVIC <> 0

                                  IMPORTIRQ_Handler

IRQ_Addr          DCD   IRQ_Handler;不主张用此句

                ENDIF



                          IF      Vectors_FIQVIC <> 0;用户使用了快速中断

                                  IMPORTFIQ_Handler

FIQ_Addr          DCD   FIQ_Handler;用户执行快速中断

                ELSE

FIQ_Addr          DCD   FIQ_Handler;用户未使用了快速中断,则死机

                ENDIF



Undef_Handler   B       Undef_Handler



   

                IF      Vectors_SWIVIC = 0

SWI_Handler                  B       SWI_Handler;用户未使用了软中断,则死机

                                ENDIF



PAbt_Handler    B       PAbt_Handler

DAbt_Handler    B       DAbt_Handler



                IF      Vectors_DEFVIC = 0

DEF_Handler       B       DEF_Handler;用户未使用了默认中断,则死机

                                ENDIF



                IF      Vectors_FIQVIC = 0

FIQ_Handler                  B       FIQ_Handler;用户未使用了快速中断,则死机

                                ENDIF

   

                                IF      Vectors_IRQVIC = 0

                          IF      Vectors_FLASH <> 0 ;以下进入非典区域(FLASH向量),请游客注意安全!!!

;FLASH中断向量表(RAM中断向量表在VICVectAddr0~VICVectAddr15)(需要16*4=64个字节)

;注意:VICVectAddr0~VICVectAddr15恒为中断向量地址编号0~15,而非经典的动态物理地址

;非典付出的代价就是多执行了4/8条指令,但换来了系统的安全。菜农认为是很值得的。

VIC_Vect_Addr_Table



               IF Vectors_STACK <> 0;需要堆栈保护中间变量

                  STMFD   SP!, {R12, LR};真保护R12, 假保护LR(用于运算)

                  LDR   R12, VIC_Vect_Addr   ;取VICVectAddr物理地址

                  LDR   R12,       ;取出取VICVectAddr内实际向量中断号(非地址)

                  IFVectors_DEFVIC <> 0

                                  AND   R12, #0x1f      ;防止32个中断序号越界,在此可再做序号越界处理(可省略)

                                  ELSE

                                  AND   R12, #0x0f      ;防止16个中断序号越界,在此可再做序号越界处理(可省略)

                                  ENDIF

                  ADD   R12, #0x02;          ;取偏移量---晕到~~~有中断号该多好呀

                  LDR   R12, ;散转到用户真正的向量中断地址

                  STR   R12, ;将中断向量地址R12写入事先保存的那个LR空间

                                  LDMFD   SP!, {R12, PC};恢复R12,同时PC跳入中断向量地址执行

                ELSE;只需要堆栈保护运算变量

                  LDR   R12, VIC_Vect_Addr;取VICVectAddr物理地址,LDR R12,指令寻址越界

                  LDR   R12,       ;取出取VICVectAddr内实际向量中断号(非地址)

                                  AND   R12, #0x0000000f   ;防止序号越界,在此可再做序号越界处理(可省略)

                  LDR   PC, ;散转到用户真正的向量中断地址

                                ENDIF

;VICVectAddr物理地址(内存VICVectAddr0~VICVectAddr15的当前中断向量值!!!)

VIC_Vect_Addr   DCD   0xFFFFF030;





;用户ROM当前中断向量地址VIC_Vect_Addr0~VIC_Vect_Addr15

;                          IMPORTUserVic_Handler

VIC_Vect_Addr0DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr1DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr2DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr3DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr4DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr5DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr6DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr7DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr8DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr9DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr10 DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr11 DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr12 DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr13 DCD   Reset_Handler            

;                          IMPORTUserVic_Handler

VIC_Vect_Addr14 DCD   Reset_Handler            

                IFVectors_ARTX <> 0

;               ARTX节拍中断装载物理地址

                          IMPORTos_clock_interrupt

VIC_Vect_Addr15 DCD   os_clock_interrupt;ARTX节拍中断向量地址位置            

                ELSE

;               非ARTX某模块中断装载物理地址

;                          IMPORTUserVic_Handler

VIC_Vect_Addr15 DCD   Reset_Handler            

                                ENDIF



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                IFVectors_ARTX <> 0

;               非ARTX非中断向量非典装载物理地址

;                          IMPORTUserVic_Handler

VIC_Vect_Addr16 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr17 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr18 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr19 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr20 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

;               ARTX向量中断非典防御装载物理地址(游客禁入!!!)

VIC_Vect_Addr21 NOP

VIC_Vect_Addr22 NOP

VIC_Vect_Addr23 NOP

VIC_Vect_Addr24 NOP

VIC_Vect_Addr25 NOP

VIC_Vect_Addr26 NOP

VIC_Vect_Addr27 NOP

VIC_Vect_Addr28 NOP

VIC_Vect_Addr29 NOP

VIC_Vect_Addr30 NOP

;               ARTX默认中断非典装载物理地址

                          IMPORTos_def_interrupt;UserDefVic_Handler

VIC_Vect_Addr31 DCD   os_def_interrupt;UserDefVic_Handler            

                ELSE

                IFVectors_DEFVIC <> 0

;               非ARTX非中断向量非典装载物理地址

;                          IMPORTUserVic_Handler

VIC_Vect_Addr16 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr17 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr18 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr19 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr20 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr21 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr22 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr23 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr24 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr25 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr26 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr27 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr28 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr29 DCD   Reset_Handler

;                          IMPORTUserVic_Handler

VIC_Vect_Addr30 DCD   Reset_Handler

;               非ARTX默认中断非典装载物理地址!!!

                          IMPORTDEF_Handler

VIC_Vect_Addr31 DCD   DEF_Handler

                                ENDIF

                                ENDIF

                                ENDIF

                                ENDIF



; Reset Handler



                EXPORTReset_Handler

Reset_Handler   





; Setup VPBDIV

                IF      VPBDIV_SETUP <> 0

                LDR   R0, =VPBDIV

                LDR   R1, =VPBDIV_Val

                STR   R1,

                ENDIF





; Setup PLL

                IF      PLL_SETUP <> 0

                LDR   R0, =PLL_BASE

                MOV   R1, #0xAA

                MOV   R2, #0x55



;Configure and Enable PLL

                MOV   R3, #PLLCFG_Val

                STR   R3,

                MOV   R3, #PLLCON_PLLE

                STR   R3,

                STR   R1,

                STR   R2,



;Wait until PLL Locked

PLL_Loop      LDR   R3,

                ANDS    R3, R3, #PLLSTAT_PLOCK

                BEQ   PLL_Loop



;Switch to PLL Clock

                MOV   R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)

                STR   R3,

                STR   R1,

                STR   R2,

                ENDIF   ; PLL_SETUP





; Setup MAM

                IF      MAM_SETUP <> 0

                LDR   R0, =MAM_BASE

                MOV   R1, #MAMTIM_Val

                STR   R1,

                MOV   R1, #MAMCR_Val

                STR   R1,

                ENDIF   ; MAM_SETUP





; Memory Mapping (when Interrupt Vectors are in RAM)

MEMMAP          EQU   0xE01FC040      ; Memory Mapping Control

                IF      :DEF:REMAP

                LDR   R0, =MEMMAP

                IF      :DEF:RAM_MODE

                MOV   R1, #2

                ELSE

                MOV   R1, #1

                ENDIF

                STR   R1,

                ENDIF





; Initialise Interrupt System

;...





; Setup Stack for each mode



                LDR   R0, =Stack_Top



;Enter Undefined Instruction Mode and set its Stack Pointer

                MSR   CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit

                MOV   SP, R0

                SUB   R0, R0, #UND_Stack_Size



;Enter Abort Mode and set its Stack Pointer

                MSR   CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit

                MOV   SP, R0

                SUB   R0, R0, #ABT_Stack_Size



;Enter FIQ Mode and set its Stack Pointer

                MSR   CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit

                MOV   SP, R0

                SUB   R0, R0, #FIQ_Stack_Size



;Enter IRQ Mode and set its Stack Pointer

                MSR   CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit

                MOV   SP, R0

                SUB   R0, R0, #IRQ_Stack_Size



;Enter Supervisor Mode and set its Stack Pointer

                MSR   CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit

                MOV   SP, R0

                SUB   R0, R0, #SVC_Stack_Size



;Enter User Mode and set its Stack Pointer

                MSR   CPSR_c, #Mode_USR

                MOV   SP, R0

                SUB   SL, SP, #USR_Stack_Size





; Enter the C code

                IF      RAM_UNINIT = 0;变量需要初始化为0

                  IMPORT__main

                  LDR   R0, =__main

                  BX      R0

                ELSE;变量不需要初始化为0

                  IMPORT __rt_entry

                  EXPORT __main;重载__main()

                  ENTRY

__main

                  B __rt_entry;跳入内核程序

                ENDIF



; User Initial Stack & Heap

                AREA    |.text|, CODE, READONLY



                IMPORT__use_two_region_memory

                EXPORT__user_initial_stackheap

__user_initial_stackheap



                LDR   R0, =Heap_Mem

                LDR   R1, =(Stack_Mem + USR_Stack_Size)

                LDR   R2, = (Heap_Mem +      Heap_Size)

                LDR   R3, = Stack_Mem

                BX      LR





                END

hotpower 发表于 2006-3-8 16:36:39

点击下载通用非典启动文件STARTUP.S源代码

hotpower 发表于 2006-3-8 16:39:24

点击下载测试工程包

e2zone 发表于 2013-6-17 02:30:28

哈哈。。。看不懂,也没人理你。。。。

爱则倾心 发表于 2014-2-28 15:39:08

STM32的启动文件大侠能分析一下吗?想知道如何修改启动代码能做到看门狗复位不初始化RAM,谢谢
页: [1]
查看完整版本: 通用非典启动文件STARTUP.S源代码(三八节日版)