You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F072 Flash应用重定位失败:ENTRY指令作用及启动地址疑问

STM32链接脚本ENTRY指令作用及Flash偏移启动问题解答

一、ENTRY(Reset_Handler)的真实作用

ENTRY指令是链接器与加载器的逻辑入口标记,核心作用有两点:

  • 告诉链接器,将Reset_Handler标记为程序的逻辑起始点,供调试器启动程序时定位执行入口,或给操作系统等加载器指明程序启动位置。
  • 避免链接器因Reset_Handler未被其他代码直接引用而将其优化(不过你的脚本中已经用KEEP(*(.isr_vector))保护了向量表,这个作用在此场景下不突出)。

关键要明确:它完全不影响STM32的硬件启动流程。STM32上电是硬件硬逻辑,必须先从0x00000000取栈顶地址加载到MSP,再从0x00000004(映射到Flash默认起始地址0x08000004)取第一条指令执行,这个过程和链接脚本的ENTRY指令没有任何关联。

二、仅靠链接脚本能否让MCU从0x08000800启动?

不行,因为STM32的启动地址是硬件固化的,必须从0x08000004取第一条指令。仅修改链接脚本将代码放到0x08000800,MCU仍会去默认地址查找指令,必然无法正常运行。

要实现从0x08000800启动,有两种可行方案:

方案1:在默认Flash起始地址放置跳转代码

在0x08000000开始的前2KB区域,编写极简汇编启动代码:

.section .isr_vector_default,"x"
.global __Vectors_default
__Vectors_default:
    .word 0x20004000  ; 与链接脚本中_estack一致的栈顶地址
    .word Reset_Handler_default

Reset_Handler_default:
    LDR R0, =0x08000804
    BX R0  ; 直接跳转到偏移后的Reset_Handler

之后在链接脚本中配置这段代码到默认Flash区域,保留原有偏移区域的配置即可。

方案2:配置NVIC向量表偏移寄存器(SCB->VTOR)

先从默认地址执行一段初始化代码,修改SCB->VTOR寄存器,将向量表偏移指向0x08000800,后续所有中断与复位都会使用新向量表:

  1. 在0x08000000区域放置临时Reset_Handler:
Reset_Handler_temp:
    LDR R0, =0xE000ED08  ; SCB->VTOR寄存器地址
    LDR R1, =0x08000800  ; 新向量表起始地址
    STR R1, [R0]
    LDR R0, =0x08000804  ; 跳转到偏移后的Reset_Handler
    BX R0
  1. 主程序代码与向量表仍放在0x08000800区域,链接脚本保持你当前的配置即可。

注意:临时Reset_Handler要足够精简,确保放在前2KB区域内,不覆盖主程序的偏移区域。

补充:你的链接脚本说明

你修改了FLASH的ORIGIN到0x08000800,这会将.isr_vector与.text都放到该偏移地址,这部分配置是正确的,但必须配合上述两种方案之一,才能绕开硬件启动的固定地址限制,让程序正常运行。


内容的提问来源于stack exchange,提问作者Evox402

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:07:39