您的位置:首页 > 其它

STM32启动文件分析

2017-12-24 17:42 603 查看
Cortex-M3内核有3种情况:

1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;

2、 通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;

3、 通过boot引脚设置可以将中断向量表定位于内置Bootloader区,运行ISP烧录程序;

注意:选则boot区时,记得要改分散加载文件

Cortex-M3内核规定,起始地址必须存放栈顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。

从分散加载文件中可以分析出,我们确实是这么做的将RESET段放在了程序最开始的地方。

有了这些理论基础之后,就可以开始启动文件代码了,先看RESET段。

                AREA    RESET, DATA, READONLY

                EXPORT  __Vectors

                EXPORT  __Vectors_End

                EXPORT  __Vectors_Size

__Vectors       DCD     __initial_sp               ; Top of Stack//将__initial_sp作为栈顶指针

                       DCD     Reset_Handler              ; Reset Handler//程序会将该地址最为复位向量,并开始执行

                       DCD     NMI_Handler                ; NMI Handler

                       DCD     HardFault_Handler          ; Hard Fault Handler

.............................(等)

__Vectors_End

__Vectors_Size  EQU  __Vectors_End - __Vectors

既然一开始需要栈顶地址,那必须要定义名为栈的RW段,接下来看看STACK段和HEAP段。

Stack_Size      EQU     0x00000400                

                AREA    STACK, NOINIT, READWRITE, ALIGN=3 

Stack_Mem       SPACE   Stack_Size 

__initial_sp

Heap_Size       EQU     0x00000200                            

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3

__heap_base

Heap_Mem        SPACE   Heap_Size

__heap_limit

接下来我们来看代码段。            

                AREA    |.text|, CODE, READONLY                  

; Reset handler

Reset_Handler    PROC                               

                 EXPORT  Reset_Handler             [WEAK]                 

      IMPORT  __main                                 

      IMPORT  SystemInit                                 

                 LDR     R0, =SystemInit ;调用系统初始化函数,初始化时钟(和外部SRAM)

                 BLX     R0                               

                 LDR     R0, =__main              ;将加载域拷贝到相应的执行域

                 BX      R0                                 

                 ENDP

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC

                EXPORT  NMI_Handler                [WEAK]

                B       .

                ENDP

.............................(等)

                B       .

                ENDP

                ALIGN

注意:由于Reset_Handler中已经开始调用C语言了,如果分散加载文件设定的执行域在外部SRAM,那么栈段地址会在外部SRAM中。此时外部SRAM还没有初始化,在SystemInit程序执行完,POP的时候就会因此而跑飞。

为了应对该问题,我们进行如下改动:

Reset_Handler   PROC

                EXPORT  Reset_Handler             [WEAK]

                IMPORT  __main

                IMPORT  SystemInit
MOV    R0, #0x20000000
ADD     R0, #0x10000
MOV    SP, R0
 ; 不要担心SP指针不是原先想要设定的地址,在__main中还会重新设置SP指针

                LDR     R0, =SystemInit

                BLX     R0   

                LDR     R0, =__main

                BX      R0

                ENDP

后面还有一部分代码,在__main中将被调用,因此不在这里进行分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: