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

· 行业用户 · 10 浏览

回答(4)

C++工程注意extern "C",否则名字修饰不同,链接器仍匹配C的weak符号。
阿May · 2026-11-01
检查是否开了--gc-sections且重写函数只被weak调用链引用,导致被当垃圾回收,加KEEP或used属性。
Linker小王子 · 2026-11-01
先看map文件里该函数来自哪个.o,若来自HAL库.o说明你的实现没进链接,多半是文件没编译或条件宏没开。
嵌入式老张 · 2026-11-01
优先排查链接脚本的段收集与符号解析,而不是HAL源码。常见原因:1) 你的重写函数放在自定义段或被链接脚本丢弃的段(如未KEEP的.init/.text子段),链接器仍选weak定义;2) 链接脚本中.text段收集顺序导致weak符号先被解析,或使用了--gc-sections把强符号所在段回收;3) 强符号未参与链接(文件未加入工程、被条件编译屏蔽、C++名字修饰不一致);4) 使用了多个库/对象,链接器按归档成员顺序只拉取先满足weak的成员。实操:用arm-none-eabi-nm -A *.o | grep 函数名确认强符号存在且为T;用arm-none-eabi-objdump -t最终elf查看符号地址与段;加-Wl,-Map=out.map检查该符号来自哪个对象;检查链接脚本是否KEEP相关段,必要时把重写函数放入.text并确保不被GC;避免在头文件用static inline造成本地副本。最后确认启动文件与HAL库版本一致,排除重复定义。
mcuku 阿沐 · 2026-11-01