我的场景是关于交叉编译到 Arduino Due(ARM 目标),但我想这是一个通用的 C 弱符号问题。
我想将我的固件分成 3 个部分: 1. 硬件库(CMSIS,中间件)-> libHardware.a 2. 实时操作系统库 -> libOS.a 3. 应用程序代码 -> 链接到上面的 Output.elf。
引用的 CMSIS 实现声明了以下内容:
void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
// ...and a few dozen IRQ handler hook skipped for brevity
CMSIS 设计的想法是让应用程序代码有选择地实施和处理一些 IRQ。
libHardware.a 的 nm 报告
startup_sam3xa.o:
00000000 W SysTick_Handler
...
在我的场景中,我想在 libOS.a 中实现这些 IRQ 处理程序。
我实现了 void SysTick_Handler(void),nm 报告:
cortex_handlers.o:
00000000 T SysTick_Handler
....
然后我将它们链接在一起,这基本上归结为
g++ -o app.elf -Wl,--start-group app.o libHardware.a libOS.a -Wl,--end-group
(分组是必要的,因为操作系统依赖于底层硬件函数。硬件需要调用操作系统提供的 IRQ/main() 函数)
纳米报告:
...
00080124 W SysTick_Handler
...
还是很弱!我希望它使用 libOS.a 中定义的强符号。最后,没有处理 SysTick,这当然会导致灾难性的失败。
另一方面,如果我没有在 libHardware/startup_sam3xa.c 中将它们声明为弱,那么一切正常。如果我选择在 app/app.c 中实现 SysTick_Handler,它也是强链接的。
所以我的问题是:libOS.a 如何实现 libHardware.a 中定义的弱处理程序?或者在这些固件开发场景中,最佳实践是什么?