29

我想为 STM32F217IG 微控制器创建一个项目。

所以我安装了 Eclipse 和GNU for ARM 嵌入式 GCC 交叉编译器。我不认为它是 Code Sourcery 之一。我使用它,因为它支持浮点而 Code Sourcery 不支持。

一旦我这样做了,我就尝试创建一个只有两个源文件的非常小的项目:test.c 和 main.c,它们都只写了以下代码:

#include <stdlib.h>
#include <stdio.h>

int main (void)
{
    printf("Hello, World!");
    return 0;
}

我更改了项目属性中的行命令,将 GCC 替换为 arm-none-eabi-gcc,然后尝试编译项目。

我自己没有创建任何makefile;我在 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++ 通用路径和符号中添加了 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 文件的创建?

4

5 回答 5

33

我查看了您链接的工具包,只是为了阅读以下内容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并为您不需要的东西提供适当的存根。您可能想要遵循本教程,其中_read_write是通过串行端口实现的,其他一切都是存根的。这很可能是您真正想要的。

于 2012-11-05T17:18:11.033 回答
11

我知道这是一个老问题,但我今天在尝试为 STM32 板构建时遇到了这个问题。我拥有的项目有一些链接器脚本(特别是 libs.ld)。在此添加 libnosys.a 条目使链接器满意,我能够继续。

libs.ld:

 GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )
于 2014-02-15T06:32:08.520 回答
6

将您的 C 程序保存为“myprint.c”,我将其编译如下:

arm-none-eabi-gcc myprint.c -lc -specs=nosys.specs

没有错误,输出很好。

于 2015-02-12T02:42:23.313 回答
3

malloc()Eclipse 项目中的free()函数调用也存在这样的问题。我已经为 STM32 微控制器编写了固件,使用 Eclipse + GNU 用于 ARM 嵌入式 GCC 交叉编译器 + STM32CubeMX 用于微控制器外围初始化和链接器脚本制作。

当我在脚本的DISCARD部分添加缺少的字符串libg.a( * ) 和libnosys.a( * ) 时,我的项目已成功构建。.ld

于 2016-10-06T12:49:07.117 回答
0

I had created an RTOS project using CubeMX and added a printf and had the same issue on linking, while debugging using OpenOCD.

I replaced the printf("Hello ARM World!") with trace_puts("Hello ARM World!"); and had the messages appear in the debug console.

于 2018-01-02T01:21:16.103 回答