3-STM32启动文件详解

启动文件


启动文件简介


startup_stm32f429_439xx.s是STM32的启动文件
刚开始我一直认为STM32程序开始执行是从main函数开始。后来网上查查不是。原来在执行main函数之前,需要先执行一段汇编程序和完成C语言资源硬件的初始化工作**。就是一下几个功能:

1–初始化栈指针MSP=_initial_sp。

2–初始化复位程序计数寄存器值=Reset_Handler。

3–初始化异常/ 中断向量表。

4–系统时钟配置。

5–C库函数_main初始化用户堆栈的调用。

2、文件启动步骤

1-在启动的时候,先对堆栈的大小定义,并在代码区的起始位置建立异常中断向量表。然后在复位中断中服务程序中跳转执行C标准库_main函数,以上这些完成后,跳转到主程序中的main函数执行相关函数应用。但是假如STM32F429单片机被设置成从内部flash启动的,这时候,片内Flash被映射到程序启动空间,异常/中断向量表实际的开始地址为0x8000000(查看STM32F4参考手册可得到),则栈顶地址存放在0x8000000处,复位中断存放在0x8000004处,若STM32F4遇到复位信号,则从0x8000004处取出复位中断服务入口地址,继而执行中断服务函数,绕后跳转到_main函数,最终进入main函数。由此我们可以得到下面这个图:
在这里插入图片描述

启动代码讲解

1–栈(Stack)

 Alt
在startup_stm32f429_439xx.s文件中,将栈的大小设为0x00000400(1KB)F429是0x30000(192KB),Stack_Mem为栈名,不初始化可读可写,8字节对齐。Stack_Size是栈的大小,__initial_sp表示结束地址(栈顶地址,栈是由高字节向低字节生长的)。
栈的主要作用是用于局部变量、函数调用、函数形参的开销大小应小于内部RAM大小,考虑到局部变量的需求,防止栈溢出。
EQU:宏定义的伪指令,相当于等于,类似与 C 中的 define;
AREA:告诉汇编器汇编一个新的代码段或者数据段;
SPACE:用于分配一定大小的内存空间,单位为字节;这里的大小等于Stack_Size。
DCD:数据定义( Data Definition )伪指令,单位是字(4字节);
伪指令(Pseudo instruction):用于告诉汇编器如何进行汇编的指令,不生成可执行代码。

总结如下图:

在这里插入图片描述

2–堆(Heap)

在这里插入图片描述
在栈的代码后面便是初始化堆的代码,其中堆的大小设为0x00000200(512B),栈名为Heap_ Mem,不初始化,可读可写,8(23)字节对齐。Heap_Size为堆的大小,__heap_base为堆的起始地址,__heap_limit为堆的结束地址,因为堆是由低地址向高地址生长的。
堆的作用是用于malloc()函数申请的动态内存的分配。

3–中断向量表

在这里插入图片描述
PRESERVE8: 指定当前文件的堆栈按照 8 字节对齐
THUMB: 表示后面指令为 THUMB 指令。 THUBM 是 ARM 以前的指令集, 16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集, THUMB-2 是 32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超级
在这里插入图片描述

EXPORT: 声明一个标号具有全局属性,可被外部的文件使用。如果是 IAR 编译器,则使用的是 GLOBAL 这个指令
在这里插入图片描述
——Vectors是异常/中断向量表的起始位置,_Vectors_End是中断向量表的结束位置,
vectors__Size中断向量表的大小。
以上总结:
在这里插入图片描述
STM32F42XX/STM32F43XX部分中断向量表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4–复位中断服务程序

在这里插入图片描述
定义一个名为.text代码段,可读

在这里插入图片描述
复位中断服务程序是系统上电后第一个执行的程序,调用Systemlnit函数初始化系统时钟,
然后调用C库函数_mian,最终调用 main 函数进入C程序的世界。
LDR:从存储器加载字到一个寄存器。
BL:跳转到由寄存器/标号给出的地址,并把跳转前的下条指令地址保存到链接寄存器。
BLX:跳转到由寄存器给出的地址,并根据寄存器的LSE确定处理器的状态,还要把跳转前的下条指令地址保存到链接寄存器。
BX:跳转到由寄存器/标号给出的地址,不用返回。
WEAK:表示弱定义,如果外部文件优先定义了该标号,则首先引用该标号,可以在C语言中重新定义中断服务程序;如果在启动文件之外没有重新定义中断服务程序,则在对应的异常/中断向量表位置处存储的是汇编文件定义的中断服务程序入口地址。如果在启动文件外,在另外一个C文件中重新定义了中断服务程序,则在对应的异常/中断向量表位置处存储的是C文件中的中断服务程序入口地址。需要注意的是,启动文件中的中断服务程序的名称和C文件中重新定义的中断服务程序名称必须保持一致。
IMPORT:表示该标号来自外部文件,跟C语言中的关键字EXTERN类似。这里表示
Systemlnit 和_main 这两个函数均来自外部的文件。
Systemlnit是一个标准的库函数,在system_stm32f4xx.c这个库文件中定义,主要作用是配置系统时钟,在调用这个函数之后,STM32F429的系统时钟被配置为180MHz。
main是一个标准的C库函数,主要作用是初始化用户堆栈,最终调用main函数进入C
程序的世界。在C应用程序中,必须有一个main函数。需要注意的是,_main不是用户C程序的main 函数。

5–异常和中断服务程序

在这里插入图片描述
在这里插入图片描述

6–用户堆栈初始化

在这里插入图片描述

  • 22
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南山府嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值