小言_互联网的博客

STM32启动文件startup_stm32f407xx.s

380人阅读  评论(0)

环境:

代码由来:STM32CUBEMX-linux版V6.5.0 + STM32Cube_FW_F4_V1.27.0 + Makefile方式

目标SOC:STM32F407ZET6


参考

STM32链接脚本 

中容量STM32处理器启动代码的理解

剖析startup_stm32f407xx.s文件

Assembler.pdf


启动文件简介:

         在嵌入式系统中,启动文件是整个系统非常关键的部分,它会进行一些底层的初始化。在此阶段,C语言是没法运行的,所以需要用到汇编语言编写的启动文件去构建C语言程序运行的必要环境,然后再跳转到main函数到达C语言的世界。

        Makefile工程和KEIL工程下的启动文件内容上会有差异,主要体现在堆栈大小和位置的定义上,Makefile工程的在链接脚本中,而KEIL工程的可以在启动文件中找到。


startup_stm32f407xx.s代码分析

        上图是startup_stm32f407xx.s启动文件的开头注释,从中看出作了如下几个事情:

1、设置初始SP(R13)

2、设置初始PC(R15)=Reset_Handler

3、设置中断向量表入口地址,并用异常地址初始化向量表

4、在C库中分支到main,最终调用了main函数

继续往下看,

1、.syntax unified:这条指令设置了指令集语法,不必深究,感兴趣的详见文首参考项“Assembler.pdf“,后面提及的汇编指令都可以在这个pdf找到。

2、.cpu cortex-m4:表示CPU架构为cortex-M4

3、.fpu softvfp:选择要装配的浮点单位为 softvfp 软浮点

4、.thumb:这与 .code 16执行相同的动作

5、.global:定义全局符号,对链接文件可见,g_pfnVectors即中断向量表,Defaule_Handler即默认中断


        .word 指令表示产生32位的值,从注释中可以看出 _sdata, _edata…的意义和定义的位置在链接脚本中,这些变量后面会用到。


Reset_Handler

        在Reset_Handler上方还有一段注释,这里太长就没有截取出来。大概意思是这部分的代码在芯片复位后,会被调用来执行一些必要的操作,然后再调用main函数。

1、.weak:该指令表示定义符号为弱属性,如果符号不存在,将创建它们,如果有其它的同名强定义(不加.weak),就会被同名强定义替代。

2、.type:该指令用于设置一个符号的类型,%function 表示符号是函数名。

3、ldr sp , = _estack:将 _estack赋值给 SP 堆栈指针寄存器,_estack定义在链接脚本中,纪录着 SRAM 的最高地址。

4、将 .data 段从 Flash 复制到 SRAM 中,猜测是为了更高的执行效率。

5、零填充bss段。

6、跳转到 SystemInit,初始化FPU设置,向量表位置和外部存储器的配置。

7、跳转到__libc_init_array,作用是考虑到可能会使用C++代码,所以需要此函数来初始化一些东西。

8、跳转到main函数。

9、当main函数执行退出后执行 bx lr 跳转到LR寄存器(r14,链接寄存器),这时候就从main函数跳出来了。

10、.size:ELF格式下隐含标识一个段的结束。


默认中断服务函数

        注释说明如果处理器接受到一个出乎意料的中断,将会进入到这个死循环中,即Default_Handler

        .section .text.Default_Handler表示定义的是.text段中的Default_Handler段,ax表示权限,allocation and execute,表示该节区可分配并且可执行,progbits是type,不深究。


中断向量表 

        上图为中断向量表部分截图。注释部分,表示中断向量表需要在物理地址0X00000000上,这里可以在编译出的 STM32F407ZET6.map 文件中看出 g_pfnVectors 的起始地址为 0x08000000,刚好为 Flash 的起始地址(定义在链接脚本中),所以的确是在Flash的物理地址0上。

        g_pfnVectors后面的程序意思就是以 g_pfnVectors为初始地址,然后依次以字为单位写入相应的数据。


中断服务函数

         注释部分,表示为每个异常处理都提供了一个弱属性的函数并将其关联到Default_Handler,也就是默认这个弱函数执行与Default_Handler同样的功能。

        如果不重新弱别名,那么就是默认执行Default_Handle,反之执行重写的中断服务函数。

        至此,startup_stm32f407xx.s的启动代码大致分析完毕。在重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。然后进入startup_stm32f407xx.s启动文件,所做的重要内容和文件开头注释中所述一致。


转载:https://blog.csdn.net/qq_41867145/article/details/125739524
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场