Cortex-M3 .s文启动文件分析
(2012-12-06 21:43:49)
标签:
armcontexm3启动文件分析.s文件 |
分类: 计算编程 |
1.
基本概念(CMSIS): Cortex Micro-controller Software Interface
Standard,微控制器软件接口标准。
AREA
STACK, NOINIT, READWRITE,
ALIGN=3
AREA
HEAP, NOINIT, READWRITE,
ALIGN=3
AREA
RESET, DATA, READONLY
//此语句声明RESET数据段
EXPORT
__Vectors
DCD
__initial_sp
; Top of
Stack
DCD
Reset_Handler
; Reset
Handler
DCD
NMI_Handler
; NMI Handler
DCD
HardFault_Handler
; Hard Fault
Handler
DCD
MemManage_Handler
; MPU Fault
Handler
DCD
BusFault_Handler
; Bus Fault
Handler
DCD
UsageFault_Handler
; Usage Fault Handler
DCD
0
;
Reserved
DCD
0
;
Reserved
DCD
0
;
Reserved
DCD
0
;
Reserved
DCD
SVC_Handler
; SVCall
Handler
DCD
DebugMon_Handler
; Debug Monitor
Handler
DCD
0
;
Reserved
DCD
PendSV_Handler
; PendSV
Handler
DCD
SysTick_Handler
; SysTick
Handler
; External
Interrupts
DCD
WDT_IRQHandler
; 16:
Watchdog Timer
DCD
TIMER0_IRQHandler
; 17: Timer0
DCD
TIMER1_IRQHandler
; 18: Timer1
DCD
TIMER2_IRQHandler
; 19: Timer2
DCD
TIMER3_IRQHandler
; 20: Timer3
DCD
UART0_IRQHandler
; 21: UART0
(……省略)
EXPORT
Reset_Handler
[WEAK]
IMPORT
SystemInit
IMPORT
__main
LDR
R0,
=SystemInit
BLX
R0
LDR
R0, =__main
BX
R0
ENDP
IF
:DEF:__MICROLIB
EXPORT
__initial_sp
EXPORT
__heap_base
EXPORT
__heap_limit
ELSE
IMPORT
__use_two_region_memory
EXPORT
__user_initial_stackheap
LDR
R0, =
Heap_Mem
LDR
R1, =
(Stack_Mem + Stack_Size)
LDR
R2, =
(Heap_Mem + Heap_Size)
LDR
R3, =
Stack_Mem
BX
LR
2.
CMSIS标准的文件结构:
a) core_cm.c (stdint.h)
b) system_.c (core_cm, system_)
c) startup_.s
其中core_cm.c以及core_cm中为内核设访问层,其中定义了定义了内核中得外设几丁质以及一些内核的访问及控制函数。
startup_.s文件是系统的启动文件,其包括堆和栈的初始化配置、中断向量表的配置以及将程序引导到main()函数等功能。
system_和system_.c文件则是由ARM公司提供模版,各芯片制造商根据自己芯片的特点来编写的。
3.
注解startup_.s文件
此文件主要完成三项工作:堆栈以及堆的初始化、定位中断向量表、调用Reset Handler
a) 堆栈以及堆的初始化
; Stack Configuration
; Stack Size
(in Bytes)
<0x0-0xFFFFFFFF:8>
;
Stack_Size
EQU
0x00000200
//指明8字节对齐(ALIGN=3)
Stack_Mem SPACE
Stack_Size
__initial_sp
// 此标号有一层隐含的意思那就是在M3中堆栈是满递减堆栈,
//因为它指定了堆栈指针位于堆栈的高地址(在//Stack_Mem之后)
; Heap Configuration
;
Heap Size (in Bytes)
<0x0-0xFFFFFFFF:8>
;
Heap_Size
EQU
0x00000000
__heap_base
Heap_Mem
SPACE
Heap_Size
__heap_limit
以上堆和栈的具体地址可以在工程编译后产生的*.map文件中看到。
b) 定位中断向量表
PRESERVE8
//PRESERVE8指定了以下的代码位8字节对齐
THUMB //THUMB指定了接下来的代码为THUMB指令集
; Vector Table Mapped to Address 0 at
Reset
//导出向量表标号,EXPORT作用类似于C语言中的extern
__Vectors
c) 调用Reset Handler
; Reset Handler
Reset_Handler
PROC
注释:引导程序进入__main(此__main是C_Library中的函数,非main())
d) 堆栈以及堆的初始化行为
; User Initial Stack &
Heap
__user_initial_stackheap
e) ARM m3 C是怎么调用startup.s文件的?
startup.s大部分内容不是被C调用的,而是在C程序之前运行的。m3上电之后会先从0地址处读取MSP,然后从0x4地址处读取复位向量,接着跳转到复位异常服务程序Reset_Handler(这些是m3内核自动做的,不需要编程)。如果你用MDK的话,在工程设置Debug下的run
to
main()上的勾去掉,然后进入调试,你会发现你运行的第一句就是Reset_Handler的第一句。
Reset_Handler就是在startup.s中定义的,它一般会对系统初始化,然后进入main函数。
向量表也是在startup.s中定义的,至于为什么程序编译之后向量表一定在0地址处,是因为向量表的前面会有类似AREA
RESET, CODE,
READONLY的声明。在MDK生成的分散加载文件中,RESET被设置在flash的0地址处,这样就规定了向量表的地址。