我正在使用 SystemWorkbench 4 stm32 对 STM32F413 微控制器进行编程。中断向量在程序集启动文件中定义为弱别名,如下所示:
.weak TIM1_UP_TIM10_IRQHandler
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
并在如下对象中引用:
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.....
.word TIM1_UP_TIM10_IRQHandler
.....
所以这g_pfnVectors
是一个 IRQ Handler 函数的地址列表。它们被声明为弱别名,因此如果用户未定义它们,则使用默认处理程序。
我已经定义了这样的处理程序:
extern "C" {
void TIM1_UP_TIM10_IRQHandler() {
if (SU_TIM->SR & TIM_SR_UIF) {
SU_TIM->SR &= ~TIM_SR_UIF;
...
}
}
}
这适用于正常的编译器优化标志,但是我想尝试一下,如果我得到更小和可能更快的代码-flto
(主要是为了尝试它,并不真正需要它)。但是当使用 编译时-flto
,g++ 会忽略我对处理程序的实现,只使用默认处理程序,我的处理程序根本不在代码中。
所以我试图通过添加__attribute__((used))
到函数定义中来强制g++包含该函数,但它仍然没有编译。但是,如果我给它另一个名字,那么它就会包含在二进制文件中。此外,如果我删除了弱别名并且只在启动文件中引用了处理程序,它也可以工作。
所以不知何故,弱别名不适用于 g++ 链接时间优化。也许有人可以告诉我错误是什么以及我在这里做错了什么。
编辑:
我查看了在生成的 .elf 文件中使用 nm 创建了哪些符号,并将其TIM1_UP_TIM10_IRQHandler
导出为具有 DefaultHandler 地址的弱符号。但是,当仅查看包含该TIM1_UP_TIM10_IRQHandler
函数的编译单元中的 .o 文件时,它会在文本部分 (T) 中作为符号导出。因此,由于某种原因,链接器选择保留弱符号,即使存在同名的强符号。