私はGCC 4.3を使用してARM7TDMIプロジェクトに取り組んでいますが、特定のケースで長い呼び出しを使用するようにコンパイラに指示するのは難しいです。gccのRAMとROMのセクション間のlong_calls
ビルドプロセスは、ELF実行ファイル(最も関連LDFLAGSは-Wl,--gc-sections -Wl,-static -Wl,-n -nostdlib
が含まれ、カスタムリンカスクリプト)にそれらのすべてをリンクし、その後、(最も関連するCFLAGSは-Os -ffunction-sections -fdata-sections -mthumb -mthumb-interwork
を含め)各.Cソースファイルの再配置可能ELFオブジェクトファイルを生成するarm-eabi-gcc
を実行します。その後、ELFファイルはarm-eabi-objcopy -O binary
でraw実行可能ファイルに変換され、起動時にカスタムブートローダがROMからRAM(コードとデータの両方を含む単一のSRAM)にコピーします。だから、すべてがRAMから実行され、.rodata
がRAMに存在し、すべてが素早く進み、起動後にROMを完全に無視します。
これを変更しようとしています。特定の選択されたROデータと選択機能のテキストは、ROMにのみ存在し、必要に応じて実行時にアクセスできます。私は、リンカースクリプトを変更して、2つの新しいセクション".flashdata"
と".flashtext"
を知りました。どちらもROMの固定アドレスに置く必要があります。私はまた__attribute__((__section__(".flashdata")))
と__attribute__((__section__(".flashtext"),__long_call__))
を適切にCコードに振りかけました。古いobjcopyには-R .flashdata -R .flashtext
が追加されています。ブートローダーが適切な処理を実行できるように2つの出力ファイルがあり、ROMセクションは予想されるメモリマップされた場所に表示されます。
このすべてが正常に動作します - 私は.flashdata
セクションにタグ付けされた文字列をprintfのできる、と私は__section__(".flashtext")
属性の隣にあるため__long_call__
属性の長い呼び出しを使用するために知っている(RAMの不足しているコードから.flashtext
関数を呼び出すことができます)。そのROMベースの関数は、他のROMベースの関数を喜んでショートコールすることができ、RAMベースの呼び出し元に戻すことができます。
ROMベースの機能からRAMベースの機能にコールするときに問題が発生します。これは、長い呼び出しでなければなりません。私はどこでも長い呼び出しを使いたくないので、私はCFLAGSの中で-mlong_callsを望んでいません。私がすべての機能をROMに集めてrom.c
にまとめると、そのファイルを-mlong-calls
で構築することができます。しかし、私はそれを避け、機能を一般的に目的別にグループ化しておくことを強く望み、ROMから実行するのに適切な場所に少数のタグを付けるだけです。
なお、これはgcc3.4では十分ではなかった。 -mlong-calls
を使ってコンパイラに正しいことを考えさせましたが、それはヘルパーとの長いジャンプを実行するだけだったので、それに続くことはできませんでした_call_via_rX
...すべてRAMにあり、長い呼び出しでしかアクセスできませんでした。 This was fixed in the linker in gcc 4.0, but not backported to anything in the 3.x tree。
私は今gcc 4.3を使用しているので、私は今RAMに戻ってコールバックすることができます。 ROMベースの関数でコードに何らかのタグを付けて、長い呼び出しを使用するようにすればさらに良いでしょう。 #pragma long_calls
がありますが、宣言にのみ影響しますので、__attribute__((__long_call__))
の代わりに使用できます。それは悲しいことに、魔法のように、コンパイル時に発生したすべての関数呼び出しに対して長い呼び出しを使用するよう強制しません。
組織的には、実行速度の遅いコードをすべてコンテキスト内で1つのファイルにグループ化し、一般カテゴリの他のコードから分離するのは正しいことではありません。私がまだ考えていない選択肢があると教えてください。なぜ、-ffunction-sectionsでないのですか、コードが自動的に別のセクションにあるという事実(.text
対.flashtext
)は私の問題を自動的に解決しますか?
ところで、コンパイラが再配置を管理するのに十分なスペースを残さない短い呼び出しを使用していることがわかったときのリンカのエラーは、relocation truncated to fit: R_ARM_THM_CALL against symbol
foo 'が.text.fooセクションで定義されていますobjs/foo.o (and the section
.text.foo is used instead of
.text because of
-CFLAGSの「関数セクション」)。