11

現在、C で SAM7X256 マイクロコントローラー用のソフトウェアを開発しようとしています。デバイスは contiki OS を実行しており、yagarto ツールチェーンを使用しています。

マップ ファイルを調べているときに (なぜ .text 領域が大きくなったのかを解明しようとするため)、.text 領域の数 kb がアンワインド サポートに割り当てられていることを発見しました (以下を参照)。

.text           0x00116824      0xee4 c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2\libgcc.a(unwind-arm.o)
                0x00116c4c                _Unwind_VRS_Get
                ......   
                0x0011763c                __gnu_Unwind_Backtrace

.text           0x00117708      0x1b0 c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2\libgcc.a(libunwind.o)
                0x00117708                __restore_core_regs
                0x00117708                restore_core_regs
                ....
                0x00117894                _Unwind_Backtrace

.text           0x001178b8      0x558 c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2\libgcc.a(pr-support.o)
                0x00117958                __gnu_unwind_execute
                ...
                0x00117e08                _Unwind_GetTextRelBase

巻き戻しに関する情報を探してみたところ、12が見つかりました。ただし、次のことはまだ不明です。

  1. 巻き戻しサポートが必要な場合と理由は?
  2. 私のコードのどの部分が pr-support.o、unwind-arm.o、および libunwind.o をリンクさせているのですか?
  3. 該当する場合、以下の項目をリンクしないようにするにはどうすればよいですか?

必要に応じて、完全なマップ ファイルへのリンクを含めます。

よろしくお願いいたします。

編集 1: リンカー コマンドの追加

CC       = arm-none-eabi-gcc
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
       -I$(CONTIKI_CPU)/dbg-io \
           -I$(CONTIKI)/platform/$(TARGET) \
           ${addprefix -I,$(APPDIRS)} \
           -DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \
           -Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET)

CFLAGS  += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN  -ffunction-sections

LDFLAGS += -L $(CONTIKI_CPU) --verbose -T $(LINKERSCRIPT) -nostartfiles  -Wl,-Map,$(TARGET).map

$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o project.elf -lc Project.a
4

2 に答える 2

13

この回答のいくつかの部分:

  • アンワインド ライブラリ関数は、一部の GCC ライブラリ関数モジュールの例外テーブルに記載されている例外「パーソナリティ ルーチン」 (__aeabi_unwind_cpp_pr0 など) から取り込まれます。

  • マップ ファイルは、bpapi.o (整数除算関数を含むモジュール) がこの例外コードを取り込むことを示しています。これは最新の YAGARTO にはありませんが、別の整数除算ヘルパー モジュールである _divdi3.o で行っています。64 ビット除算を行う単純な main() を作成することで、巻き戻しコードが引き込まれる効果を再現できます。

  • C コードに (重要な) 例外テーブルが含まれる一般的な理由は、アプリケーションで C と C++ コードを任意に混在させたときに、C コードを介して C++ 例外をスローできるようにするためです。

  • スローしたり、スローする関数を呼び出したりできない関数は、例外テーブルがある場合でも、巻き戻しライブラリが取り込まれないように、CANTUNWIND としてマークされた単純なもののみを必要とする必要があります。実際、CodeSourcery のディストリビューションでは、_divdi3.o は CANTUNWIND とマークされています。

  • 根本的な原因は、YAGARTO の GCC ライブラリ (libgcc.a) が不適切にビルドされていることです。まだ動作するはずなので、まったく間違っているわけではありませんが、組み込みツールチェーンでは予期しないコードの肥大化です。

これについて何かできることはありますか?/DISCARD/ スクリプトを使用しても、GNUリンカにARM例外セクションを無視させる簡単な方法はないようです-テキストセクションへのリンクはそれをオーバーライドします。しかし、できることは、例外パーソナリティ ルーチンのスタブ定義を追加することです。

void __aeabi_unwind_cpp_pr0(void) {}
int main(void) { return *(unsigned long long *)0x1000 / 3; }

スタブなしの 14K と比較して、YAGARTO を使用すると 4K にコンパイルされます。しかし、別の GNU ツール ディストリビューションも調査したい場合があります。

于 2012-12-27T17:49:03.457 に答える
1

GCC には、例外処理を排除するオプションがあります。

-fno-exceptions

確かにyagartoには詳しくありませんが、同様のオプションがあるかもしれません. GCC では、このオプションは標準例外のサポートを犠牲にしてこのオーバーヘッドを排除します。

于 2014-04-19T17:41:45.967 に答える