关于stm32启动文件的解析

文件获取

启动文件可以在ST官网上获取,startup_stm32f10x_hd.s

文件Description:

描述了启动文件主要完成的工作:

  1. 设置SP,也就是初始栈顶指针。
  2. 设置初始PC的值,设置为复位处理函数的地址。
  3. 设置中断向量表的各个中断服务函数的入口地址。
  4. 配置系统时钟。
  5. 调用C库函数_main()初始化用户,跳转到main()函数

涉及到的汇编指令

  1. EQU:伪指令。其作用相当于#define,给数字常量定义一个符号名。
  2. AREA:汇编一个新的代码段或者数据段。
  3. SPACE:分配内存空间。
  4. PRESERVES:将当前文件按8字节对齐。
  5. EXPORT:声明一个标号,可以被外部文件使用。
  6. IMPORT:标号来自外部文件,类似extern。
  7. DCD:以字为单位分配内存,4字节对齐,并初始化这些内存。
  8. PROC:表示子程序的开端。
  9. ENDP:表示子程序的结束。
  10. WEAK:弱定义,如果外部文件也声明了一个标号,那么以外部文件的优先。
  11. B:跳转。
  12. ALIGN:地址对齐。默认4字节对齐。

WEAK的补充:

启动文件中的内容,一般内核都有所规定,那么为了编译通过,即使芯片厂家不使用那些功能,也会使用WEAK占位。而且通过使用WEAK,也能够使得大部分功能给用户进行二次开发,同时WEAK的内容芯片可以做一个sample,指示用户按sample来进行改写。

在RTOS的源码中就会大量采用这种操作,在编写库函数时,以允许用户自己实现覆盖。

WEAK中,如果用户优先实现了,那么在链接的时候,优先会选用强符号的内容。

链接阶段的补充:

编译阶段可以帮助我们找到语法的错误,那么链接阶段,就会帮我们把有效的程序进行链接。注意是有效的,比如我们写了一个WEAK或者从没有调用的函数,那么就不会被链接到最终的文件当中。

链接阶段也会对变量进行初始化操作,将不同的内容放入不同的内存。若一些定义了并没有赋值的变量,也是由链接帮助我们写0然后放入ZI段中。以及一些已经初始化的值,也会放入对于的data段中。这部分可以结合RT-Thread手册来看具体的数据在哪个区。

堆和栈的占位

修改启动文件:

如果是原厂自带的启动文件一般是不可修改的,但是实际开发中都需要修改启动文件。首先就是1KB的栈不一定够用,而且在单片机的开发中一般都不使用堆,除非Linux这类操作系统。那么512字节的堆空间基本上都必须去除,或者降至最低(去除的话有可能编译不通过,厂家的规范需要有一个堆的占位)。

以及一般来说使用了 IAP + APP 的话,需要重新定位中断向量表的偏移地址。

向量表

直到这边的 DCD _initial_sp才开始真正初始化栈。

中断向量表中每个中断处理函数的位置都是被内核厂家定好的,但是具体的芯片厂家不一定会全部使用,不需要的一般都会写一个0来占位,防止编译不通过。

EXPORT:将三个标识符声明为可被外部引用。

_Vectors:表示向量表的起始地址。向量表起始地址强制性为栈顶指针。第二位为复位处理函数。

DCD:每行都会生成4字节的二进制地址。以此排列下去就是各种系统中断的地址。

DCD 0:这是因为 Cortex-M 的向量表长度必须固定为 16 个字,所以若没用到的异常入口用 DCD 0 来占位。

_Vectors_End:向量表的结束地址。

SystemInit和_main()

AREA:定于一块代码段,只能读。

Reset_Handler:通过Reset_Handler来配置系统时钟和跳转到_main()函数。

Systeminit函数一般是用于配置系统时钟的。

_main()函数最终会跳转到C语言的main函数,开始执行APP的程序。

Systeminit补充

该函数位于配套的.c文件当中,一般都是用于配置系统时钟。芯片厂家一般都会帮写好,通过宏定义来确定具体初始化的时钟源。

这些宏定义可以发现是位于config.h这个头文件当中。

默认中断处理

堆栈的初始化

如果定义了使用 MICROLIB,这个是在keil中配置的,那么就将栈顶指针,堆的起始和结束地址EXPORT,外部可以使用。然后就由_main()函数来完成堆栈的初始化操作。

CMSIS统一标准的定义:

这个是内核和其他芯片厂家规定好的,那么按照这个协议去编写的驱动的可移植性和通用性比较好。

  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值