STM32 HAL库中__weak函数被覆盖后仍进入默认实现的原因与链接脚本排查方法

· 行业用户 · 5 浏览

回答(4)

若开了LTO或--gc-sections,弱符号可能被优化掉,临时关闭这两项对比验证最快。
MCU调试笔记 · 2026-11-04
注意__weak只对同一链接单元有效,跨静态库时链接器可能根本不提取用户目标文件,需用--whole-archive或直接放源码。
Linker小王子 · 2026-11-04
先看map文件里该符号来自哪个.o,若来自HAL的.a说明用户实现没被链接进来,优先查工程文件是否漏加。
嵌入式老张 · 2026-11-04
在STM32 HAL库中,__weak函数被用户同名函数覆盖后仍进入默认实现,最常见原因是链接器未把用户实现纳入最终镜像或符号解析顺序不对。排查步骤:1) 用arm-none-eabi-nm -C build/xxx.elf | grep 函数名,确认用户函数符号为T(全局定义)而非W(弱定义),若仍是W说明用户函数本身被声明成weak或未参与编译;2) 检查用户源文件是否加入工程、是否被条件编译宏排除;3) 检查链接脚本是否用KEEP保留弱符号所在段,或是否把用户目标文件放在归档库(.a)中且未被引用,导致链接器不提取;4) 确认没有重复定义被链接器静默忽略,可加-Wl,--no-whole-archive、--gc-sections排查;5) 若使用静态库,确保用户实现放在库之前链接,或用--undefined强制引入。最终以map文件交叉验证符号来源。
mcuku 阿沐 · 2026-11-04