梧桐uuu 发表于 2025-7-25 10:27

链接器生成了veneers过程,导致程序进入HardFault。

在STM32F103上运行RAM中的程序时,链接器生成的veneers过程出现错误代码。STM32F103只有Thumb模式,但链接器生成了ARM模式的veneers过程,导致程序进入HardFault。如何解决这个问题?
20004420 <__display_screen_set_display_function__veneer>:20004420:   e51ff004   ldr   pc,    ; 20004424 <__display_data_get_temp_veneer>20004424:   080002f8   .word   0x080002f8调试时显示如下20004420: 0x04f01fe5          ; <UNDEFINED> instruction: 0xf004e51f20004424: 0x0000f802lsls   r0, r7, #1120004426: 0x00000008lsrs   r0, r0, #32 => jmp 0x080002F8

捉虫天师 发表于 2025-7-25 11:51

STM32F103只支持Thumb模式(Thumb-2指令集)

但链接器生成了ARM模式的veneers(如示例中的e51ff004是ARM指令)

这导致处理器尝试执行ARM指令时进入HardFault

捉虫天师 发表于 2025-7-25 11:52

1. 确保编译器/链接器使用Thumb模式
在编译和链接选项中强制使用Thumb模式:
CFLAGS += -mthumb
LDFLAGS += -mthumb

捉虫天师 发表于 2025-7-25 11:52

修改链接器脚本
在链接器脚本中明确指定Thumb模式:
/* 确保所有代码都是Thumb模式 */
.thumb :
{
    *(.text)
} >RAM

捉虫天师 发表于 2025-7-25 11:52

检查交叉调用veneers
对于从RAM到Flash的调用,确保veneers是Thumb模式。可以尝试:

方法A:使用特定选项
LDFLAGS += --thumb-entry=your_entry_point
方法B:手动指定veneers类型
在某些工具链中,可以指定veneers类型:
LDFLAGS += --veneers=thumb
检查工具链版本
确保你使用的工具链(如GCC ARM Embedded)版本支持STM32F103的正确veneers生成。

捉虫天师 发表于 2025-7-25 11:53

替代方案:手动实现veneers
如果自动生成仍有问题,可以手动实现Thumb模式的veneers:
    .thumb
    .section .ram_veneers
    .align 2
    .global __display_screen_set_display_function__veneer
__display_screen_set_display_function__veneer:
    ldr r12, =0x080002F8
    bx r12
然后在链接器脚本中正确放置这个section。

捉虫天师 发表于 2025-7-25 11:53

反编译生成的二进制,确认veneers指令是Thumb指令(如bx或ldr pc)

检查指令地址是否对齐到2字节边界(Thumb要求)

确保所有跳转都使用Thumb模式的BX或BLX指令

通过以上方法,你应该能够解决因错误类型veneers导致的HardFault问题。

wang6623 发表于 2025-7-28 12:56

链接器配置不当或编译选项错误导致的。

probedog 发表于 2025-7-28 15:04

链接器配置问题,链接器默认生成 ARM 模式的 veneers,但 STM32F103 需要 Thumb 模式。可能是链接脚本或编译器选项未正确指定 Thumb 模式。

classroom 发表于 2025-7-28 16:05

函数指针或跳转表问题?

flycamelaaa 发表于 2025-7-28 19:05

强制链接器生成 Thumb 模式的 veneers。

powerantone 发表于 2025-7-28 22:06

手动处理跨存储区域调用。
页: [1]
查看完整版本: 链接器生成了veneers过程,导致程序进入HardFault。