
1
;=========================================
2
; NAME: 2440INIT.S
3
; DESC: C start up codes
4
; Configure memory, ISR ,stacks
5
; Initialize C-variables
6
; HISTORY:
7
; 2002.02.25:kwtark: ver 0.0
8
; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
9
; 2003.03.14:DonGo: Modified for 2440.
10
;
注释来源于网络和自己的整理。
powered by armboy@qq.com
11
;=========================================
12
GET option.inc ;
类似于
C
语言包含头文件,
GET
也可用
INCLUDE
代替(视编译器是否支持)
13
GET memcfg.inc
14
GET 2440addr.inc
15
16
BIT_SELFREFRESH EQU (1<<22) ;
定义
SDRAM
自刷新标志位
17
18
;Pre-defined constants
预定义
6
种工作模式
19
USERMODE EQU 0x10 ;
用户模式
20
FIQMODE EQU 0x11 ;
快速中断模式
21
IRQMODE EQU 0x12 ;
中断模式
22
SVCMODE EQU 0x13 ;
监管模式
23
ABORTMODE EQU 0x17 ;
异常中断模式
24
UNDEFMODE EQU 0x1b ;
未定义模式
25
26
MODEMASK EQU 0x1f ;
模式掩码
27
NOINT EQU 0xc0 ;
取消中断
28
29
;The location of stacks;
设置
6
种工作模式的堆栈的起始地址
30
;
在
option.inc
中定义了
_STACK_BASEADDRESS EQU 0x33ff8000
31
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
32
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
33
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
34
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
35
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
36
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
37
38
;
检查在
tasm.exe
里是否设置了采用
THUMB(16
位
)
代码
(armasm -16 ...@ADS 1.0)
39
;
判断是不是
thumb
指令。
40
GBLL THUMBCODE ;
定义
THUMBCODE
全局变量
(
逻辑型
)
41
[ {CONFIG} = 16 ;
如果发现是用
16
位代码的话
42
THUMBCODE SETL {TRUE} ;
把
THUMBCODE
设置为
TURE
43
CODE32
44
| ;
否则是
ARM
模式
45
THUMBCODE SETL {FALSE}
46
]
47
;
宏定义
MOV_PC_LR
,作用:子程序返回
48
MACRO ;
宏定义
49
MOV_PC_LR
50
[ THUMBCODE ;
在目标地址是
THUMB
指令
,
在
ARM
模式中
51
bx lr ;
要用
BX
指令转
THUMB
使跳到
THUMB
指令
,
并转换模式
52
|
53
mov pc,lr ;
否则,就是目标地址是
ARM
模式,就直接把函数返回地址赋给
PC
54
]
55
MEND
56
;
宏定义
MOVEQ_PC_LR
,作用:带相等条件判断的子程序返回
。与宏定义
57
;MOV_PC_LR
类似
58
MACRO
59
MOVEQ_PC_LR
60
[ THUMBCODE
61
bxeq lr
62
|
63
moveq pc,lr
64
]
65
MEND ;
宏定义结束
66
;===============================================================
67
;
下面这个宏是用于第一次查表过程的实现中断向量的重定向
,
你会发现
68
;
在
_ISR_STARTADDRESS=0x33FF_FF00
里定义的第一级中断向量表
69
;
是采用型如
Handle***
的方式的
.
而在程序的
ENTRY
处
(
程序开始处
)
采用的是
70
;b Handler***
的方式
.
71
;
在这里
Handler***
就是通过
HANDLER
这个宏和
Handle***
进立联系的
.
72
;
这种方式的优点就是正真定义的向量数据在内存空间里
,
而不是在
ENTRY
处
73
;
的
ROM(FLASH)
空间里
,
这样
,
我们就可以在程序里灵活的改动向量的数据了
.
74
;
其中
HANDLER
是一个宏,用于查找中断处理程序的入口地址。这些地址存放在
75
;
由
HandleXXX
指向的表项中,该表定位在
RAM
高端,基地址为
_ISR_STARTADDRESS
。
76
;
假如
_ISR_STARTADDRESS
为
0x800000000,
当
IRQ
中断时
,
根据
b HandlerFIQ,
先跳转
77
;
再根据
^ _ISR_STARTADDRESS
基地址
+HandleIRQ
的偏移地址
(4*6)
得到的中断地址
78
;0x80000000+0x00000024=0x80000024
79
;===============================================================
80
MACRO
81
$HandlerLabel HANDLER $HandleLabel
82
$HandlerLabel
83
sub sp,sp,#4 ;
减少
sp(
用于存放转跳地址
)
实质上是在计算返回地址
84
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push
85
;because it return to original address)
86
ldr r0,=$HandleLabel;
将
HandleXXX
的址址放入
r0
87
ldr r0,[r0] ;
把
HandleXXX
所指向的内容
(
也就是中断程序的入口
)
放入
r0
88
str r0,[sp,#4] ;
把中断服务程序
(ISR)
压入栈
.
89
ldmfd sp!,{r0,pc};
用出栈的方式恢复
r0
的原值和为
pc
设定新值
(
完成了到
ISR
的转跳
)
90
MEND
91
;===============================================================
92
;
在这里用
IMPORT
伪指令
(
和
c
语言的
extren
一样
)
引入
|Image$$RO$$Base|,
93
;|Image$$RO$$Limit|...
等比较古怪的变量是编译器生成的。
94
;RO, RW, ZI
这三个段都保存在
Flash
中,但
RW
,
ZI
在
Flash
中
第
1
页