我想为STM32F217IG微控制器创建一个项目。
然后我安装了Eclipse和GNU for ARM embedded GCC cross compiler。我不认为这是Code Sourcery。我使用它,因为它支持浮点,而Code Sourcery则不支持。
一旦我这样做了,我尝试创建一个只有两个源文件的小项目:test.c和main.c,只用两个文件编写:
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
printf("Hello, World!");
return 0;
}
我更改了项目属性中的line命令,用arm-none-eabi-gcc替换GCC,然后尝试编译项目。
我自己没有创建任何make文件;我在Eclipse中使用了自动创建。
该建筑看起来很好,但是当谈到链接器时,我在控制台中遇到以下错误:
make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc -o"test3" ./main.o ./test3.o
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'
collect2: ld returned 1 exit status
make: *** [test3] Erreur 1
我在网上看了一下,发现这可能是一个系统调用问题。但我不知道如何在Linux上将这个库添加到我的项目中。
真的吗?如果是,我该如何解决?如果没有,那会是从哪里来的?
正如有人建议的那样,我尝试“链接”C运行时库。在Eclipse上,似乎我有两个解决方案:
首先在项目属性→ C / C ++ →构建→设置→交叉链接器→文库。我只是添加了字母c
,然后错误没有改变,但命令行末尾有-lc
:
make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc -o"test3" ./main.o ./test3.o -lc
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'
collect2: ld returned 1 exit status
make: *** [test3] Erreur 1
但我不知道它是否真的意味着添加C运行时库。
其次,我在项目属性→ C / C ++ general →路径和符号→库中添加了libc.a库,并且这是我得到的(完全不同的):
make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc -o"test3" ./main.o ./test3.o -l"C:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a"
c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld.exe: cannot find -lC:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a
collect2: ld returned 1 exit status
make: *** [test3] Erreur 1
然后它仍然不起作用,但它是搜索的好方法吗?
哦,这是一个非常有趣的事实:
我只在调试模式下得到错误。如果我处于发布模式,一切都没问题,我没有任何错误(除非我添加了libc.a然后我认为这不是好事)。这是否意味着问题是.elf文件创建?
答案 0 :(得分:28)
我查看了您链接的工具包,只是为了阅读readme.txt
中的以下内容:
此工具链针对Cortex-R / M裸机开发而构建和优化。
换句话说,此工具链专门为嵌入式系统配置,可能根本没有运行任何操作系统。在这种情况下,没有系统可以提供例如printf()
应该写的标准输出,没有文件系统等等 - 如果你想使用它们,你必须链接到提供这些基本服务的某个库。
也就是说,您的工具包提供了librdimon.a
库,它提供了所有这些基本服务。该库实际上是libgloss编译的一部分。如果要链接它,请尝试以下命令:
arm-none-eabi-gcc --specs=rdimon.specs -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c
这在我的电脑上链接得很好,但是你真正想要的是另一个故事(你希望在哪里看到printf()
输出?)。
对于你的芯片你应该寻找一个库,它将标准输出重定向到串口或通过JTAG提供调试输出。或者,您也可以使用自定义功能,例如将调试输出发送到串行控制台而不是printf()
- 这取决于您。
如果您决定使用printf()
,建议您阅读libgloss
文档。
另外,我建议四处寻找专为STM32系列捆绑的工具链。正确配置所有这些基本内容(C库,链接器脚本等)需要一些经验。
编辑:许多嵌入式系统并不真正使用标准C库,从头开始。如果您想这样做,则应将-nostdlib
传递给gcc
调用。当然,你将不再拥有像printf()
这样的东西。
编辑2:另一种方法是使用不带newlib
的标准库(libgloss
),并为不需要的东西提供适当的存根。您可能需要关注this tutorial,其中_read
和_write
是通过串口实现的,其他所有内容都是存根的。这很可能是你真正想要的。
答案 1 :(得分:9)
我知道这是一个古老的问题,但今天我在尝试构建STM32主板时遇到了这个问题。我的项目有一些链接器脚本(特别是libs.ld)。在libnosys.a中添加一个条目就满足了链接器,我能够继续。
libs.ld:
GROUP(
libgcc.a
libg.a
libc.a
libm.a
libnosys.a
)
答案 2 :(得分:6)
将您的C程序保存为&#34; myprint.c&#34;,我将其编译如下:
arm-none-eabi-gcc myprint.c -lc -specs = nosys.specs
没有错误,输出也没问题。
答案 3 :(得分:3)
Eclipse项目中的malloc()
和free()
函数调用也存在这样的问题。我为STM32微控制器编写了固件,使用Eclipse + GNU for ARM嵌入式GCC交叉编译器+ STM32CubeMX进行微控制器外围初始化和链接器脚本制作。
当我在libg.a
脚本的 DISCARD 部分添加了缺少的字符串libnosys.a
(*)和.ld
(*)时,我的项目已成功构建
答案 4 :(得分:0)
我使用CubeMX创建了一个RTOS项目并添加了一个printf,并在使用OpenOCD进行调试时遇到了相同的链接问题。
我用trace_puts替换了printf(“Hello ARM World!”)(“Hello ARM World!”);和 将消息显示在调试控制台中。