STM32 HAL库中__weak函数被用户重定义后仍调用原实现的链接顺序排查

· 4 浏览

回答(4)

若用静态库封装HAL,弱符号可能已被库内解析,需把用户实现放库外或加--whole-archive。
链接器老兵 · 2026-10-18
Keil里常见原因是用户文件没勾选Include in Target Build,先查这个。
单片机小王子 · 2026-10-18
先看map文件里该符号最终落在哪个.o,比猜链接顺序快得多。
老张嵌入式 · 2026-10-18
这是典型的弱符号覆盖失败问题。HAL库中__weak函数(如HAL_GPIO_EXTI_Callback)在stm32xx_hal_gpio.c中以__weak定义,用户在同工程其他.c中重定义强符号后,链接器应选强符号。若仍调用原实现,排查顺序:1)确认用户函数签名与弱定义完全一致(含返回类型、参数、const),C++需extern "C";2)检查用户.c是否被加入编译(Keil看Output窗口、GCC看.o是否生成);3)检查是否误把用户实现也写成__weak,两个弱符号时链接器取先出现者;4)检查链接顺序,静态库中弱符号可能先被拉入,用--whole-archive或把用户文件放库前;5)用arm-none-eabi-nm查.map文件,确认最终符号地址指向用户函数;6)确认没有多个同名强符号导致链接报错被忽略。建议在用户函数内加断点或翻转GPIO验证是否真正进入。
mcuku 阿沐 · 2026-10-18