STM32启动文件startup_stm32f407xx.s

本文深入解析了STM32F407的启动文件startup_stm32f407xx.s,详细阐述了其在系统启动时的角色,包括设置堆栈指针、初始化中断向量表、复制数据段到SRAM、调用C库及main函数等关键步骤。此外,还介绍了默认中断服务函数和中断向量表的实现,为理解STM32的中断处理机制提供了清晰的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:

代码由来: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启动文件,所做的重要内容和文件开头注释中所述一致。

### STM32F4xx 初始化文件 `IT.c` 的作用 对于STM32F4系列微控制器而言,`IT.c` 文件主要用于定义中断服务例程 (ISR),即当特定事件发生时执行的代码片段。这些 ISR 函数通常用于响应硬件中断请求,如定时器溢出、外部输入变化或其他外设产生的信号。 每个 ISR 都会关联到具体的外设或功能模块上,在实际应用开发中,开发者可以根据需求修改这些函数的内容以实现定制化的逻辑处理[^1]。 ```c void TIM2_IRQHandler(void) { if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) != RESET) { // 清除TIM更新中断标志位 __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE); // 用户自定义操作... } } ``` 此段代码展示了如何编写一个简单的定时器中断服务程序,其中包含了清除相应的中断标志以及用户可以添加的具体业务逻辑。 ### 启动文件 `startup_stm32f407xx.s` 的作用及用法 启动文件 `startup_stm32f407xx.s` 是整个应用程序加载过程中的第一个被执行的部分。它负责完成如下几项重要任务: - 设置堆栈指针(SP) - 复制只读数据段 (.rodata 和 .data) - 对未初始化的数据区 (.bss) 进行清零 - 跳转至主函数 (`main`) 开始正常的应用流程 - 定义并映射所有可能发生的异常和服务调用表入口地址 该汇编文件通过一系列指令实现了上述功能,并提供了默认的异常处理器模板供进一步扩展使用[^2]。 例如,在遇到严重错误的情况下,默认情况下会跳转到名为 `HardFault_Handler` 的位置;如果希望捕获此类情况以便调试,则可以在项目里重写这个函数来加入额外的日志记录或者其他诊断措施[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值