|
;/*****************************************************************************/
;/* 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:
; * 0x00000000 default setting (not remapped)
; * 0x40000000 when 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_Size EQU 0x00000080;0x000
SVC_Stack_Size EQU 0x00000040;0x040
ABT_Stack_Size EQU 0x00000000;0x000
FIQ_Stack_Size EQU 0x00000080;0x000
IRQ_Stack_Size EQU 0x00000080;0x080
USR_Stack_Size EQU 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_FIQVIC EQU 0;0-不使用快速中断 1-使用快速中断
Vectors_IRQVIC EQU 0;0-不使用单向量中断 1-使用单向量中断(不建议使用!!!)
Vectors_DEFVIC EQU 0;0-不使用默认向量向量 1-使用默认向量向量(ARTX下自动定义)
Vectors_SWIVIC EQU 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, [PC, #-0x0FF0];经典直接跳入RAM当前中断向量地址VicVectAddr
ENDIF
ENDIF
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
IF Vectors_SWIVIC <> 0;用户使用了至少1个软中断SWI
IMPORT SWI_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
IMPORT IRQ_Handler
IRQ_Addr DCD IRQ_Handler;不主张用此句
ENDIF
IF Vectors_FIQVIC <> 0;用户使用了快速中断
IMPORT FIQ_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, [R12] ;取出取VICVectAddr内实际向量中断号(非地址)
IF Vectors_DEFVIC <> 0
AND R12, #0x1f ;防止32个中断序号越界,在此可再做序号越界处理(可省略)
ELSE
AND R12, #0x0f ;防止16个中断序号越界,在此可再做序号越界处理(可省略)
ENDIF
ADD R12, #0x02; ;取偏移量---晕到~~~有中断号该多好呀
LDR R12, [PC, R12, LSL #2];散转到用户真正的向量中断地址
STR R12, [SP, #0x04];将中断向量地址R12写入事先保存的那个LR空间
LDMFD SP!, {R12, PC};恢复R12,同时PC跳入中断向量地址执行
ELSE;只需要堆栈保护运算变量
LDR R12, VIC_Vect_Addr;取VICVectAddr物理地址,LDR R12,[PC, -xxx]指令寻址越界
LDR R12, [R12] ;取出取VICVectAddr内实际向量中断号(非地址)
AND R12, #0x0000000f ;防止序号越界,在此可再做序号越界处理(可省略)
LDR PC, [PC, R12, LSL #2];散转到用户真正的向量中断地址
ENDIF
;VICVectAddr物理地址(内存VICVectAddr0~VICVectAddr15的当前中断向量值!!!)
VIC_Vect_Addr DCD 0xFFFFF030;
;用户ROM当前中断向量地址VIC_Vect_Addr0~VIC_Vect_Addr15
; IMPORT UserVic_Handler
VIC_Vect_Addr0 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr1 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr2 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr3 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr4 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr5 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr6 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr7 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr8 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr9 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr10 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr11 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr12 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr13 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr14 DCD Reset_Handler
IF Vectors_ARTX <> 0
; ARTX节拍中断装载物理地址
IMPORT os_clock_interrupt
VIC_Vect_Addr15 DCD os_clock_interrupt;ARTX节拍中断向量地址位置
ELSE
; 非ARTX某模块中断装载物理地址
; IMPORT UserVic_Handler
VIC_Vect_Addr15 DCD Reset_Handler
ENDIF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IF Vectors_ARTX <> 0
; 非ARTX非中断向量非典装载物理地址
; IMPORT UserVic_Handler
VIC_Vect_Addr16 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr17 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr18 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr19 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr20 DCD Reset_Handler
; IMPORT UserVic_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默认中断非典装载物理地址
IMPORT os_def_interrupt;UserDefVic_Handler
VIC_Vect_Addr31 DCD os_def_interrupt;UserDefVic_Handler
ELSE
IF Vectors_DEFVIC <> 0
; 非ARTX非中断向量非典装载物理地址
; IMPORT UserVic_Handler
VIC_Vect_Addr16 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr17 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr18 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr19 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr20 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr21 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr22 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr23 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr24 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr25 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr26 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr27 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr28 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr29 DCD Reset_Handler
; IMPORT UserVic_Handler
VIC_Vect_Addr30 DCD Reset_Handler
; 非ARTX默认中断非典装载物理地址!!!
IMPORT DEF_Handler
VIC_Vect_Addr31 DCD DEF_Handler
ENDIF
ENDIF
ENDIF
ENDIF
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; Setup VPBDIV
IF VPBDIV_SETUP <> 0
LDR R0, =VPBDIV
LDR R1, =VPBDIV_Val
STR R1, [R0]
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, [R0, #PLLCFG_OFS]
MOV R3, #PLLCON_PLLE
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
; Wait until PLL Locked
PLL_Loop LDR R3, [R0, #PLLSTAT_OFS]
ANDS R3, R3, #PLLSTAT_PLOCK
BEQ PLL_Loop
; Switch to PLL Clock
MOV R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
ENDIF ; PLL_SETUP
; Setup MAM
IF MAM_SETUP <> 0
LDR R0, =MAM_BASE
MOV R1, #MAMTIM_Val
STR R1, [R0, #MAMTIM_OFS]
MOV R1, #MAMCR_Val
STR R1, [R0, #MAMCR_OFS]
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, [R0]
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 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|