作为前一个问题(sbrk function not found when placed in a static library)的衍生产品:
我正在为stm32f407微控制器创建一个裸机应用程序,该应用程序具有ARM Cortex M4内核。我正在尝试创建一个包含基本内容的静态库,如cmsis,HAL函数和中断向量表,并将该静态库链接到我的主应用程序。但是,当中断向量表(名为__isr_vectors
的变量)放在静态库中时,该变量不会在链接中存在。
我可以把发生的事情拼凑起来:链接器有一个对象main.o和一些库。它采用main.o
中找到的所有符号,它采用main.o
使用的库中的所有符号或已被认为必要的其他符号使用的符号。此阶段尚不需要__isr_vectors
变量,因为没有人明确引用此变量,因此链接器会抛出该变量。然后,链接器搜索名为.isr_vector
的所有输入节,以便创建输出节.isr_vector
。但是,到目前为止,没有符号存活,因此输出部分保持为空,而我的二进制文件没有中断表。
我知道让__isr_vector
生存的一个技巧:在main.c
中的虚拟函数中引用它。但是,这有点丑陋且容易出错(在针对同一静态库构建新应用程序时,您可能会忘记这样做)。所以这是我的问题:是否有另一种方法可以使__isr_vector
生存下来,这样我就可以链接到我的静态库中并完成它了?
这些是重现问题的文件和步骤:
vectors.c:
__ attribute __((section(“。isr_vector”),used used))void * __isr_vectors = 0;
main.c中:
void _start(void){}
link.ld:
MEMORY { FLASH(rx):ORIGIN = 0x08000000,LENGTH = 1024K }
ENTRY(_start)
SECTIONS { .isr_vector:ALIGN(4) { KEEP(*(。isr_vector)) }> FLASH
.text : ALIGN(4) { *(.text .text.*) } >FLASH
}
命令:
“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 - mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -o main.c.obj -c main.c “C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 -mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -o vectors.c.obj -c vectors.c
“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 - mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 -mfloat-abi = softfp -mthumb -Wl, - gc-sections -nostartfiles - Wl,-Tlink.ld -Wl,-Map = test_linker.without_library.map main.c.obj vectors.c.obj -o test_linker.without_library.elf
“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-ar.exe cq libtest_linker.lib.a vectors.c.obj
“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-ranlib.exe”libtest_linker.lib.a
“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 - mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 -mfloat-abi = softfp -mthumb -Wl, - gc-sections -nostartfiles - Wl,-Tlink.ld -Wl,-Map = test_linker.with_library.map main.c.obj -o test_linker.with_library.elf libtest_linker.lib.a
答案 0 :(得分:3)
我对您的文件进行了两处更改:
在链接描述文件中,我更改了ENTRY
ENTRY(_start)
到
ENTRY(Reset_Handler)
并在vectors.c中添加了这个函数:
void Reset_Handler(void) {
}
诀窍是Reset_Handler
是翻译单元vectors.c
中的一个函数,而_start
位于其他地方。
现在当Reset_Handler
被链接(由ENTRY
强制执行)时,__isr_vectors
似乎也被考虑了!因此,似乎必须链接该翻译单元中的另一个函数才能“拖拽”该变量。
为了完整起见:
通常Reset_Handler
会引用__isr_vectors
,Reset_Handler
main
最终会引用_start
(在您的情况下是-fdata-sections
)。所以这不仅仅是一种解决方法,无论如何你可能还需要它。
我已将{{1}}添加到编译命令
答案 1 :(得分:2)
我在同一种环境中遇到了这个问题(arm-none-eabi-gcc-cs-5.2.0-3.fc23.x86_64,arm-none-eabi-binutils-cs-2.25-2.fc23。 Fedora 23上的x86_64。
链接器似乎不会尝试读取存档的内容,因为它已经拥有了所需的所有符号。它可能是一种优化或错误。
强制读取“已使用”符号的存档的另一种解决方案是强制链接器ld将__isr_vectors视为未定义的-u __isr_vectors
。
作为gcc选项,-Xlinker -u -Xlinker __isr_vectors
或-Wl,-u,__isr_vectors
。
答案 2 :(得分:1)
这更像是已发布答案的后续内容: 我建议您只需要将链接描述文件中的ENTRY更改为: ENTRY(g_pfnVectors) 我认为这不是一件好事,也不需要更改原始源文件。 如果源文件中不存在g_pfnVectors,则它是我们文件中矢量表本身的名称。适当修改。