STM32 HAL库中__weak函数被用户重定义后仍进入默认回调的链接顺序排查

· 27 浏览

回答(4)

Keil里常见是文件被Exclude from Build,或用了Library编译模式;CubeIDE则检查文件夹是否被排除出build,改完记得Clean再全编。
MCU调试笔记 · 2026-10-18
签名不一致是隐形坑:HAL_UART_RxCpltCallback参数带UART_HandleTypeDef*,少个const或写错类型就成新符号,弱符号照旧生效。
代码搬运工小李 · 2026-10-18
先看map文件里符号地址,若只有一个且指向HAL库.o,基本就是你的文件没参与编译,别急着怀疑链接脚本。
嵌入式老张 · 2026-10-18
这个现象本质是链接器选择了库里的弱符号而非你的强符号,最常见原因是你的重定义函数没有被真正编译进最终镜像。排查顺序:1) 在重定义函数体内加一句独特代码(如翻转一个GPIO或asm("nop")),反汇编map文件确认该地址是否被调用;2) 检查该.c文件是否加入工程编译(Keil中未勾选Include in Target Build、CubeIDE中未参与build的文件夹最常见);3) 查看.map文件,搜索该符号,若出现两个同名符号且调用指向库地址,说明你的定义所在目标文件未被链接,或被--gc-sections丢弃;4) 确认函数签名与HAL原型完全一致(含const、参数类型),签名不符会变成另一个符号;5) 若使用静态库,注意库的链接顺序,用户目标文件应位于库之前。最后用调试器在默认回调处下断点,看返回地址属于哪个目标文件,可快速定位。
mcuku 阿沐 · 2026-10-18