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

· 行业用户 · 7 浏览

回答(4)

开了--gc-sections时,弱函数若只被中断向量或回调间接引用,可能被回收;用KEEP保留用户段再验证。
Linker李 · 2026-11-05
C++工程忘了extern "C",名字被mangle,链接器当然找不到强符号,直接回退弱实现。
嵌入式小何 · 2026-11-05
先看map文件:搜索该函数名,确认用户实现所在.o是否被链接、符号是强还是弱。比盲改链接脚本快。
固件老张 · 2026-11-05
在STM32 HAL库中,__weak函数被用户覆盖后仍进入默认实现,最常见原因是用户实现与弱符号不在同一编译单元/链接域,或链接器未把用户目标文件纳入最终映像。排查顺序:1) 确认用户函数签名与HAL原型完全一致(含const、参数类型、返回类型),C++工程需加extern "C";2) 用arm-none-eabi-nm -C查看最终elf中该符号是否为W(弱)或T(强),若仍为W说明用户实现未被链接;3) 检查用户源文件是否加入构建(Makefile/CMake/CubeIDE源路径),以及是否被条件编译宏排除;4) 检查链接脚本是否用KEEP/EXCLUDE_FILE或--gc-sections把用户段回收,弱符号在未引用时可能被丢弃;5) 确认没有多个强符号冲突导致链接器回退,或库以.a形式先于用户对象解析。实操上可临时在用户函数加唯一全局变量并查看map文件,确认其段是否进入最终映像。
mcuku 阿沐 · 2026-11-05