29

STM32F217IGマイクロコントローラーのプロジェクトを作成したいと思います。

そこで、EclipseとGNUforARM組み込みGCCクロスコンパイラをインストールしました。私はそれがCodeSourceryのものではないと思います。浮動小数点をサポートし、Code Sourceryはサポートしないため、私はそれを使用しました。

それを行ったら、test.cとmain.cの2つのソースファイルだけを使用して、非常に小さなプロジェクトを作成してみました。両方に次のコードのみが記述されています。

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

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

プロジェクトプロパティのlineコマンドを変更して、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では、それを行うための2つの解決策があるようです。

まず、プロジェクトのプロパティ→ 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

これは私のPCでは問題なくリンクしますが、それが本当に必要なものであるかどうかは別の話です(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

Eclipseプロジェクトの関数呼び出しにもこのような問題がありmalloc()ました。free()Eclipse+GNUを使用してARM組み込みGCCクロスコンパイラー+STM32CubeMXを使用してマイクロコントローラー周辺の初期化とリンカースクリプトを作成するSTM32マイクロコントローラー用のファームウェアを作成しました。

スクリプトのDISCARDセクションに欠落している文字列libg.a(*)とlibnosys.a(* )を追加すると、プロジェクトは正常にビルドされました。.ld

于 2016-10-06T12:49:07.117 に答える
0

CubeMXを使用してRTOSプロジェクトを作成し、printfを追加しましたが、OpenOCDを使用してデバッグしているときに、リンクに関して同じ問題が発生しました。

printf( "Hello ARM World!")をtrace_puts( "Hello ARM World!");に置き換えました。メッセージがデバッグコンソールに表示されました。

于 2018-01-02T01:21:16.103 に答える