stm32启动文件详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32启动文件详解

一、启动文件的作用

1.初始化堆栈指针 SP;

2.初始化程序计数器指针 PC;

3.设置堆、栈的大小;

4.设置异常向量表的入口地址;

5.配置外部 SRAM作为数据存储器(这个由用户配置,一般的开发板可没有外部SRAM);

6.设置 C库的分支入口__main(最终用来调用 main函数);

7.在 3.5版的启动文件还调用了在 system_stm32f10x.c文件中的SystemIni()函数配置系统时钟。

二、汇编指令

三、启动代码

1.stack ----- 栈

Stack_Size EQU 0x00000400 ; 栈的大小

AREA STACK, NOINIT, READWRITE,ALIGN=3 Stack_Mem SPACE Stack_Size ; 分配栈空间

__initial_sp ; 栈的结束地址(栈顶地址) 分配名为STACK,不初始化,可读可写,8(2^3)字节对齐的1KB空间。

栈:局部变量,函数形参等。栈的大小不能超过内部SRAM大小。

AREA:汇编一个新的代码段或者数据段。STACK段名,任意命名;NOINIT表示不初始化;READWRITE可读可写;ALIGN=3(2^3= 8字节对齐)。

__initial_sp紧挨了SPACE放置,表示栈的结束地址,栈是从高往低生长,结束地址就是栈顶地址。

2.heap ----- 堆

Heap_Size EQU 0x00000200 ; 堆的大小(512Bytes)

AREA HEAP, NOINIT, READWRITE,ALIGN=3

__heap_base ; 堆的起始地址

Heap_Mem SPACE Heap_Size ; 分配堆空间

__heap_limit ; 堆的结束地址

分配名为HEAP,不初始化,可读可写,8(2^3)字节对齐的512字节空间。__heap_base堆的起始地址,__heap_limit堆的结束地址。堆由低向高生长。动态分配内存用到堆。

PRESERVE8 -- 指定当前文件的堆/栈按照 8 字节对齐。

THUMB-- 表示后面指令兼容 THUMB 指令。THUBM 是ARM 以前的指令集,16bit;现在 Cortex-M 系列的都使用 THUMB-2 指令集,THUMB-2 是32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超级。

3.向量表

AREA RESET, DATA, READONLY

EXPORT __Vectors

EXPORT __Vectors_End

EXPORT __Vectors_Size

定义一个名为RESET,可读的数据段。并声明 __Vectors、__Vectors_End 和__Vectors_Size 这三个标号可被外部的文件使用。

__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 WWDG_IRQHandler ; Window Watchdog

.

.

.

__Vectors_End

__Vectors_Size EQU __Vectors_End - __Vectors ;向量表大小

__Vectors 为向量表起始地址,__Vectors_End 为向量表结束地址,两个相减即可算出向量表大小。

向量表从 Flash 的 0x0 地址开始放置,以 4 个字节为一个单位,地址 0 存放的是栈顶地址,0x04 存放的是复位程序的地址,以此类推。从代码上看,向量表中存放的都是中断服务函数的函数名,可我们知道 C 语言中的函数名就是一个地址。

4.复位程序

AREA |.text|, CODE, READONLY

定义一个名为.text,可读的代码段

Reset_Handler PROC ;复位子程序开始

EXPORT Reset_Handler [WEAK]

IMPORT __main

IMPORT SystemInit

LDR R0, =SystemInit

BLX R0

LDR R0, =__main

BX R0

ENDP ;子程序结束

复位子程序是系统上电后第一个执行的程序,调用 SystemInit ()函数初始化系统时钟,然后调用 C 库函数_main。

备注:

__main() 和 main()

当所有的系统初始化工作完成之后,就需要把程序流程转入主应用程序,即呼叫主应用程序。最简单的一种情况是:

IMPORT main

B main

直接从启动代码跳转到应用程序的主函数入口,当然主函数名字可以由用户随便定义。

在ARM ADS环境中,还另外提供了一套系统级的呼叫机制。

IMPORT __main

B __main

__main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()。所以说,前者是库函数,后者就是我们自己编写的main()主函数;

因此我们用的 B __main其实是执行库函数,然后该库函数再调用我们的main() 函数,因此在单步调试时会看到先要跑一段程序(其实是库函数),然后再单步到我们自己的main函数(这个同时也说明如果有B __main 则就对应必须有main函数,否则编译出错),如果我们用 B main来进入我们的主函数的话,那在单

相关文档
最新文档