EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
;/******************************************************************************0 V o8 r8 c7 r3 f1 d, w+ i- Y2 g
; * @file startup_Nano100Series.s
3 c( Y' m! ?0 L; * @version V1.00
/ N+ Z ?3 z3 C/ z; * $Revision: 3 $ k3 N1 x |+ u Y; h. D
; * $Date: 14/01/14 4:17p $ . S1 V$ I7 V% O
; * @brief CMSIS ARM Cortex-M0 Core Device Startup File
8 T1 k' F0 _) S# c; *% B* }6 u! q" t7 O; ]
; * @note8 G! x8 b, P/ B. k
; * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
7 j* M& b" B5 r( Q* P: Q2 f;*****************************************************************************/
o- ]3 A" N3 y) \5 N;首先对栈和堆的大小进行定义,并在代码区的起始处建立中断向量表,& l( z+ B7 _6 f: h$ @2 o% K$ s
;其第一个表项是栈顶地址,第二个表项是复位中断服务入口地址。7 N, ~/ z3 G0 g% N- E! [2 e# A
;然后在复位中断服务程序中跳转C/C++标准实时库的__main函数。
5 s3 W! R" d. C/ D; y5 ]& C f;复位中断服务入口地址存放于0x0000_0000处。当M0遇到复位信号后,, j' n! U. V: |6 w C: T
;则从0x0000000处取出复位中断服务入口地址继而执行复位中断服务程序
" R2 k. N+ X0 h+ q;然后跳转__main函数,最后来到C的世界。 & h6 E( O4 M7 K4 A
; <h> Stack Configuration栈配置,为后期跳转到C语言代码存放参数,地址做准备* t7 S8 J ]* e: O3 V3 P
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
1 r2 N/ r5 n0 ^; </h>
" D# i4 b E( {0 V4 P;EQU相当于C语言的define
( c0 O, ]8 a) N5 L+ E. ]: D& EStack_Size EQU 0x00000500;,共1280个字节7 ^" I) ~/ b1 c) `4 C& \! ~
;定义一片区域名为STACK,未初始化段,可读可写,8字节对齐: a' b. B( W$ j* Y* m* H7 R+ x
AREA STACK, NOINIT, READWRITE, ALIGN=3) Z8 u. X1 a l: }0 d
;此指令用于分配一片连续的存储区域并初始化为0。表达式为要分配的字节数。 \. }% A; L8 i6 J+ k8 ?; w7 x
;SPACE可用“%”来代替0 K& C+ b. z Z+ W
Stack_Mem SPACE Stack_Size. w2 Y: `" x6 B
;__initial_sp表示一个标示,编译器计算这个标示的地址.) w/ \! O; A" k1 m- C
__initial_sp 1 ~; [) ~4 v" t" U* ]5 z3 @9 z
; <h> Heap Configuration0 D: i" p; J: D: C5 }$ z( z
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>+ m( B: m. I' L5 N
; </h> 2 p! x6 Q- j7 v$ m _
Heap_Size EQU 0x00000500
& i1 P! X0 D. Q+ Q: Z AREA HEAP, NOINIT, READWRITE, ALIGN=33 ^2 O% T. z4 y2 I' N$ l
__heap_base
2 q! ]) q# B: h( @9 [: aHeap_Mem SPACE Heap_Size# F& N( n, Z8 m
__heap_limit
# w) y1 U8 N1 B X! Z5 ^& X' [ PRESERVE8
+ c& r$ { s+ b. b% R6 a THUMB
6 i7 j. Z# A& g) ^6 z4 G; Vector Table Mapped to Address 0 at Reset
0 T+ R7 J* r- S5 W8 l. f- y T;中断向量表映射到0x00,
* w) {3 h2 x, y' \ AREA RESET, DATA, READONLY1 h" @5 d5 g+ C" w0 t+ {
;使编译器指定一段只读的数据段,段名为reset
; T }0 v7 b* [/ q ;EXPORT __Vectors
/ [$ v( e' R4 o0 X# h9 E ;EXPORT相当于GLOBLE关键字,声明一个全局变量__vector,
% w: B$ j0 c" S# a9 s! {;DCD指令:作用是开辟一段空间,其意义等价于C语言中的地址符“&”; [- F; O+ n, f. a4 E
;异常向量表从0x0000_0000开始,初始位置为Stack_Point所在地,! U, f/ e9 q4 t, c7 b
;自动取传入的地址存入SP寄存器中,其他中断存放中断程序地址,# c& e' U$ O3 z: w
;跳转到ISR中执行程序,具体查看datasheet page 111中描述
__Vectors DCD __initial_sp ; Top of Stack# P1 ]" W4 A5 Q. N, |6 c0 w
;取__initianl_sp地址放入0x00000000,, R/ o7 L. D/ [2 G* [
DCD Reset_Handler ; Reset Handler( E% ]0 O. }$ O8 Z: a. o
DCD NMI_Handler ; NMI Handler+ ?( o) O" ^0 E
DCD HardFault_Handler ; Hard Fault Handler
: K+ ~) s( ^1 K DCD 0 ; Reserved" u6 `6 L5 p: I' t/ c7 }; a
DCD 0 ; Reserved: k( Z6 j; C4 n; p" |- x2 D
DCD 0 ; Reserved
0 i0 E$ n5 X* f DCD 0 ; Reserved
+ k o3 s4 M4 t; D9 o DCD 0 ; Reserved( K7 d4 a" z+ I6 c" d7 s3 W
DCD 0 ; Reserved
/ u8 o. O4 w' n) M DCD 0 ; Reserved; M/ y! u% P8 \- `1 @ j7 [
DCD SVC_Handler ; SVCall Handler0 D8 u7 O& b9 q! t7 x: A
DCD 0 ; Reserved
6 c/ d& o% [, H" I2 i' x5 ^ DCD 0 ; Reserved% T# X. S& N K) ?
DCD PendSV_Handler ; PendSV Handler
' d! h3 _% w! e DCD SysTick_Handler ; SysTick Handler
$ L# ^' L: S+ E5 k8 G! z* g D ; External Interrupts
" W8 |( F$ _4 A5 O9 w Y. t DCD BOD_IRQHandler ; Brownout low voltage detected interrupt ! j+ F( r L3 S
DCD WDT_IRQHandler ; Watch Dog Timer interrupt ) h: o+ X( g' a1 y6 P& k& w
DCD EINT0_IRQHandler ; External signal interrupt from PB.14 pin
3 W+ u9 L' N( m& ]: g' S4 r9 u9 w DCD EINT1_IRQHandler ; External signal interrupt from PB.15 pin, A$ n. \4 {" B V" W4 n$ _
DCD GPABC_IRQHandler ; External interrupt from PA[15:0]/PB[15:0]/PC[15:0] 4 p" q+ U2 o! g* k" T( p7 Z* U
DCD GPDEF_IRQHandler ; External interrupt from PD[15:0]/PE[15:0]/PF[7:0]
4 ~' a; u$ h9 Z4 R DCD PWM0_IRQHandler ; PWM 0 interrupt ^" v8 ]3 S$ \& ~( D+ k0 S1 I
DCD PWM1_IRQHandler ; PWM 1 interrupt
' s/ x* Z, Q; P7 `8 v7 {3 P DCD TMR0_IRQHandler ; Timer 0 interrupt
0 d+ Q+ }% _ j1 } T. p+ ] DCD TMR1_IRQHandler ; Timer 1 interrupt
1 o! l. F p. M9 ]+ C! O DCD TMR2_IRQHandler ; Timer 2 interrupt ! l2 n5 L' Z4 n: s' o# e/ h" B' g
DCD TMR3_IRQHandler ; Timer 3 interrupt
' K5 _/ y& t% a4 S6 A; O DCD UART0_IRQHandler ; UART0 interrupt
7 f" A2 N' D, F7 M. v y1 A DCD UART1_IRQHandler ; UART1 interrupt7 Z4 K8 r' l' D; ~" f6 u% R
DCD SPI0_IRQHandler ; SPI0 interrupt , F; ]2 N3 B6 |: p: @
DCD SPI1_IRQHandler ; SPI1 interrupt
2 A& W4 }* _: L+ A9 a1 \+ l6 B DCD SPI2_IRQHandler ; SPI2 interrupt $ h& L# o, ^! S: ~& c
DCD HIRC_IRQHandler ; HIRC interrupt
2 @# {( e' `2 J- [ DCD I2C0_IRQHandler ; I2C0 interrupt
; t3 E* n T4 q1 I DCD I2C1_IRQHandler ; I2C1 interrupt
9 `+ N! ?0 }/ p* S# c7 n( h DCD SC2_IRQHandler ; SC2 interrupt Y' b0 l# [3 \7 Y# c% |
DCD SC0_IRQHandler ; SC0 interrupt: i6 g: X# W! _; o' C- U6 D
DCD SC1_IRQHandler ; SC1 interrupt" v6 E4 |0 w+ J: ^
DCD USBD_IRQHandler ; USB FS Device interrupt
3 N) s2 ~% z3 U1 w, ?, v+ E DCD 0 ; Reserved 7 V; H% a' ^, M5 l3 @
DCD LCD_IRQHandler ; LCD interrupt
# @9 y+ j& u7 d7 d1 j' o' T; T: h DCD PDMA_IRQHandler ; PDMA interrupt
! o* x& b$ U* K0 H DCD I2S_IRQHandler ; I2S interrupt 8 S0 F1 t( K9 z& i1 |
DCD PDWU_IRQHandler ; Power Down Wake up interrupt
* J" G: n3 A2 f. T, E; U DCD ADC_IRQHandler ; ADC interrupt
: F) b3 n' a H$ m+ H DCD DAC_IRQHandler ; DAC interrupt
- }& S$ t6 D) O DCD RTC_IRQHandler ; Real time clock interrupt
d4 M2 ]: J* R E! v* ^ AREA |.text|, CODE, READONLY
3 ~/ R6 S m* ^0 t1 m' l; Reset Handler
) N* @6 j5 s* \ V2 z;汇编伪指令PROC ENDP 提示编译器子程序开始和结束
- q, E2 c. h5 g9 u; f( U& o: C6 C
Reset_Handler PROC6 O5 P) ?; P( q
;定义全局变量 Reset_Handle [WEAK]表示弱定义可在其他地方优先6 O& C' N' {( ?( X1 R
;以便在C中调用Reset_Handle,有利于后期编写复位程序- X- p- U/ {3 S
EXPORT Reset_Handler [WEAK]
3 y" g: @* G0 ]5 { ;申明main,main在外部定义
) {) }% u. E0 m IMPORT __main
' `# t4 p4 n' B; U5 k6 \3 T# a1 w ;伪指令,提示编译器main标示在外部定义; H8 V, r/ o+ O$ }) s
; 解锁保护寄存器。向RegLockAddr连续写入0x59,0x16,0x88解锁( F6 a8 n. P% C; Y2 W! G$ `
LDR R0, =0x50000100
2 E: N; V3 H# N* g4 g LDR R1, =0x59- S4 {) G/ z( N
STR R1, [R0]
* B1 g; C6 _/ Z" e" s, O# e LDR R1, =0x16
5 | p7 }. m/ B STR R1, [R0]
6 z# S' x7 k8 p1 \7 j LDR R1, =0x88
) K* I1 U! S, B. c- X8 S! h, i STR R1, [R0] ) R Q, ?4 e \/ \8 V2 x
; Init POR具体看手册,& D( l# j" V9 c# k, n7 O
LDR R2, =0x500000604 D- j# t4 w @
LDR R1, =0x00005AA5
# M- D% O* |! a- w$ ^) } STR R1, [R2]
+ U/ K! }% x: i% Q( k. U/ [+ ] ; Lock register写0,锁住保护寄存器2 P( p) ]: n7 H
MOVS R1, #00 E) l& H) c- k s. S
STR R1, [R0]
7 f' Z: ?) y* y7 T* q- i3 z
LDR R0, =__main
* z% _/ E) `% Q ;伪指令,将main地址存入R0中8 s u2 x a! F: ^' n$ Y; e# V/ ]
BX R0
0 }$ Y3 \9 [; p' U7 o" @ ;跳转到R0所在地址的位置,即__main所在程序,BX跳转且切换指令集
. n, ^( Y0 M- u# x J) p ENDP % V& R% A9 |' J0 ?
; Dummy Exception Handlers (infinite loops which can be modified)
! Y7 d/ H% [9 k: c7 D; ?: f& |- V;其他中断入口程序,弱定义,进入死循环,以便后期C程序编写中断子程序" M( o+ h0 g% {6 H. W+ H
NMI_Handler PROC9 U# M: j" E) W+ o+ p
EXPORT NMI_Handler [WEAK]
0 Y6 b1 I6 \3 R5 a! C% y* u B .5 u% T! {. X; e7 r3 C
ENDP
* q/ b4 |9 t4 P( z, a% w- Q" PHardFault_Handler\;连接符
C O3 O5 }5 {6 G PROC% U6 ]0 @3 W8 Q6 e
EXPORT HardFault_Handler [WEAK]
0 O8 L4 \- X) F B .
8 k3 M1 T3 {) r; S ENDP
5 y. u9 d9 ^- d8 J6 }( ?& ?SVC_Handler PROC
0 b0 {& E! X# d# _* F' ` EXPORT SVC_Handler [WEAK]' B' E3 j; v4 z+ X" K' b# n" R
B .3 W2 V" Y. X2 b. \3 @
ENDP( n: i! y7 @ K- [- C$ B
PendSV_Handler PROC/ N! L+ `2 D6 R; q9 l6 A4 l
EXPORT PendSV_Handler [WEAK]. m3 Q+ A8 F; q, q1 o
B .
$ [# R& f0 o& |- { ENDP
' l5 |5 \+ D7 QSysTick_Handler PROC$ j6 N6 E w( f1 E% t) h
EXPORT SysTick_Handler [WEAK]
; I% E7 p& q( C B .
7 j& K4 F: y1 R3 G. M ENDP
2 \ y# ?" W2 y# c" N;缺省中断。不写8 {5 v( g; m+ \) D
Default_Handler PROC ; s6 g6 V. K, c; [& k( K4 l
EXPORT BOD_IRQHandler [WEAK]
6 S( L2 ?; s" i2 R EXPORT WDT_IRQHandler [WEAK]
2 v; U2 e( g/ t& y! ] EXPORT EINT0_IRQHandler [WEAK]5 E1 X! ~! [: W
EXPORT EINT1_IRQHandler [WEAK], ` k; m: Z \" c
EXPORT GPABC_IRQHandler [WEAK]" L# `( r8 P9 F/ t# b( h' w
EXPORT GPDEF_IRQHandler [WEAK]; P, Z& ?+ p8 d8 u, [
EXPORT PWM0_IRQHandler [WEAK] U/ w; O; p. t0 ?) ] G' |) @
EXPORT PWM1_IRQHandler [WEAK]
# p6 _% P5 p1 g/ [; m% j1 d EXPORT TMR0_IRQHandler [WEAK]
& U4 o ^% U4 q9 E( F& _% ^ EXPORT TMR1_IRQHandler [WEAK]
2 ~8 u( `$ u2 U/ o6 I EXPORT TMR2_IRQHandler [WEAK]
6 {9 V, k, ], N) @ EXPORT TMR3_IRQHandler [WEAK]
$ A- x% f {( {6 X* ], ?7 c EXPORT UART0_IRQHandler [WEAK]
4 x- f6 Q& m; x, x9 t EXPORT UART1_IRQHandler [WEAK]. L* a* {' U- @7 e
EXPORT SPI0_IRQHandler [WEAK]: Y, `( J' ^; D
EXPORT SPI1_IRQHandler [WEAK] a1 {2 b0 ]7 Q: i2 a! [. h$ ~7 Q" [
EXPORT SPI2_IRQHandler [WEAK]
5 W" e) Y, i/ o/ M# u EXPORT HIRC_IRQHandler [WEAK]
1 h: B$ w; f5 v k EXPORT I2C0_IRQHandler [WEAK]' S6 P) M9 |$ f$ K+ x `. q. y
EXPORT I2C1_IRQHandler [WEAK]* j* f. E3 d1 C( e u
EXPORT SC2_IRQHandler [WEAK]
- \& c7 _5 x, T. v- l& | EXPORT SC0_IRQHandler [WEAK]" }# Y. K# S* |7 T6 x
EXPORT SC1_IRQHandler [WEAK]! K- m6 w- U n; ?% h' F
EXPORT USBD_IRQHandler [WEAK]
k- f0 ]$ n; ?8 | EXPORT LCD_IRQHandler [WEAK]
0 x8 p% {6 @9 i; ^9 B1 ~ EXPORT PDMA_IRQHandler [WEAK]: l, ?6 N5 b" D3 r0 w6 \
EXPORT I2S_IRQHandler [WEAK]
% u g) N8 }; m5 C4 w" m# H! D EXPORT PDWU_IRQHandler [WEAK]
f' f* d/ K8 Y& t! d EXPORT ADC_IRQHandler [WEAK]
! w6 t6 R) Z8 }8 X( p) t EXPORT DAC_IRQHandler [WEAK]
8 n2 i7 \) L5 K3 u EXPORT RTC_IRQHandler [WEAK]% `& W8 c) D4 ] }
' }9 z/ W* [5 e) i8 G. bBOD_IRQHandler
) x1 R/ e% ^4 L. |2 ]0 F5 k9 CWDT_IRQHandler% q! y q! M m2 _/ h
EINT0_IRQHandler
/ d. @$ t" o7 C* yEINT1_IRQHandler* S& {( n% n4 ?7 K
GPABC_IRQHandler
+ l1 i5 v/ f" _$ M* J, g) U% r1 pGPDEF_IRQHandler
4 l1 ]9 d% r) ~* tPWM0_IRQHandler9 {3 K2 I% U h* f; n
PWM1_IRQHandler9 U0 o B; ~: f4 I# q3 |
TMR0_IRQHandler
& X8 x) @/ @$ y0 q" eTMR1_IRQHandler4 N, v$ m' s6 g# d7 ?$ @, K
TMR2_IRQHandler
D1 y# u. q/ ^TMR3_IRQHandler
) ]- L4 a2 K0 D9 _UART0_IRQHandler
+ E, m$ W3 @3 L& N4 t) T% ^2 s5 ~UART1_IRQHandler
$ h0 S! l+ j3 I+ n+ ?- u' mSPI0_IRQHandler
8 V) R2 ?3 e+ y! u9 G% J; S5 M% fSPI1_IRQHandler
% e. _0 W" G& }" F, {; Z, kSPI2_IRQHandler
- N* y0 w6 @2 H% I$ U; C4 PHIRC_IRQHandler
3 i9 h2 s# {$ ~9 S2 {9 II2C0_IRQHandler- X) C) g$ V5 P: a. s {, z
I2C1_IRQHandler" ?3 j9 i3 G* l* d, b
SC2_IRQHandler
$ x- @3 ]: |2 r$ T1 F, b0 L) v4 ~8 kSC0_IRQHandler ( L0 S ^. q' Z" I ]4 @; Q% h8 r
SC1_IRQHandler9 T, z$ g# c u
USBD_IRQHandler% t+ D( |2 n- j: [( {9 c6 {
LCD_IRQHandler$ N/ Y) M' ]' P; Q9 U2 W9 _
PDMA_IRQHandler& c% N w+ P; l9 x' K
I2S_IRQHandler
1 G* z6 { O8 E0 o IPDWU_IRQHandler
$ k! W+ ?# A6 t9 ^' `. q/ z' ]ADC_IRQHandler
/ o& T1 j& a2 n/ T R3 ODAC_IRQHandler
, I! _8 @8 ?) l4 `' LRTC_IRQHandler
& Q0 h" k2 M6 M5 R5 }) N B .
; S! T; b3 E* L' Q2 |4 K ENDP
$ G3 w ?1 O/ u# d' o; b3 W: S0 @
;缺省对齐方式,具体对齐字节平台相关
& Y, N1 i6 W" { ALIGN 7 c, o! ]; k( r: E( B3 X7 y
; User Initial Stack & Heap; p3 s5 ]6 _( q6 ^
;宏开关,相当C语言IFDEF,定义__MICROLIB则执行,由于为定义执行ELSE分支
8 P* B9 G' z& t IF : DEF:__MICROLIB" ^) Q3 U3 R4 R9 g
; l+ T% W$ g( `9 _7 Y ?
EXPORT __initial_sp
+ H! r) Y7 `: h EXPORT __heap_base
}: Q( ]# S) c3 ` EXPORT __heap_limit
5 P9 [0 S, ?7 k4 x @8 C3 w
5 q: V3 l8 B% I, X ELSE# @. g$ `4 V, u/ g, `8 ]! q/ A' U% a
;外部申明,可用于其他地方初始化栈和堆,调用C之前必须初始化栈
6 o" `9 x9 Q! n1 f: l9 ~5 T IMPORT __use_two_region_memory
& @9 N; a" D" Z+ T$ _/ p4 r1 { EXPORT __user_initial_stackheap( ~, x! G( {6 q
__user_initial_stackheap LDR R0, = Heap_Mem
5 y) n2 V# {0 H) x; |7 f% y; f7 D LDR R1, =(Stack_Mem + Stack_Size). I% E/ e! p; r0 B
LDR R2, = (Heap_Mem + Heap_Size)
0 E5 T p* _6 X1 `$ g) u) ]8 z4 N2 T8 } LDR R3, = Stack_Mem
+ m: g$ F: r) j7 w4 [ BX LR
4 z# v+ y2 H* e" q9 l) I ALIGN
# Q% ` ^, R) q; q5 O/ |" f: ?4 Q
ENDIF 0 j- P( r$ f$ o n6 e/ |
END6 W* p9 @3 X: y
. i1 z! }) N5 D; v% K7 X. D8 t
|