2013-06-07 7 views
6

Cファイルに.co_stackというセクションを作成し、その領域を定義するためにpulStackという配列を作成しました。あなたは、私が2ヶ所でスタックサイズを定義し終わる見ることができるように、スタックのセクションを定義するCファイルからリンカスクリプトへのシンボルのインポート

#define STACK_SIZE  0x00003000  /*!< Stack size (in Words)   */ 
__attribute__ ((section(".co_stack"))) 
unsigned long pulStack[STACK_SIZE]; 

私のgccのリンカスクリプトは、この

.co_stack : { 
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4; 
    _fstacksize = 0x00003000 * 4;  
    . = (_fstackptr - _fstacksize); 
    *(.co_stack .co_stack.*) 
} 

のように見えます。 私の.cファイルではSTACK_SIZE、私の.ldファイルでは_fstacksizeのいずれかです。

どうすればこのように定義できますか?

変数pulStackSizeを次のように作成します。

const unsigned long pulStackSize = sizeof(pulStack); 

は、私がこれを行う場合、私は48Kバイトで溢れたスタックを言ってエラーが出る

_fstacksize = STACK_SIZE * 4; 

として.ldファイルに_fstacksizeを定義したいです。

シンボルを.cから.ldファイルにインポートするにはどうすればよいですか?

+0

STACK_SIZEにはシンボルがありません。これはMACROです。あなたはEXTERN – neagoegab

答えて

10

(より一般的な質問に、「CおよびLDスクリプトの間で値を共有するためにどのように?」)いくつかのソリューション:

1)(注:このソリューションのために、私はあなたが最近のバージョンを使用していることを前提としていますGNU ld、docs here:http://www.math.utah.edu/docs/info/ld_3.html

絶対値は、セクションコンパウンドの外に定義することで(スクリプトの最初の部分など)、スクリプト内のシンボルに関連付けることができます。それをexternとして定義することで、Cでシンボルをインポートすることができます。あなたがCに必要な値は、シンボルのアドレスであることに注意してください:

スクリプト:

StackSize = 0x00003000 * 4; /* the size */ 
.co_stack : { 
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4; 
    _fstacksize = StackSize;  
    . = (_fstackptr - _fstacksize); 
    *(.co_stack .co_stack.*) 
} 

C:

extern long StackSize; 
#define STACK_SIZE (((size_t)&StackSize)/sizeof(long)) 

このソリューションでは、得られた値の使用に制限を課すことがあり、例えばほとんどのコンパイラは、このような行受け入れることはありません。

long my_stack[STACK_SIZE]; 

をいますが、スクリプト内で記号「my_stack」を定義し、としてそれをインポートすることができますので、あなたは、もはやそれを必要としない「のextern長いmy_stack [];」 。とにかくそれは許容できる限界だと私は思う。

2)もう1つの方法は、スクリプトの最初とセクションとにある2つのシンボルを定義し、Cで "extern char"としてインポートすることです。バイト単位のセクションのサイズは、 2つのアドレス。このソリューションは、(1)の同じ制限を持っています

3)リンカが十分スマートでない場合は、CのようにSTACK_SIZEマクロを展開して、コンパイル時に適切なスクリプトを生成することができます。

a)ファイル "stacksize"を作成します。stacksize.h「ラインの#includeを追加)

#define STACK_SIZE 0x3000 

Bを含む "" スクリプトの冒頭で、あなたが必要なときSTACK_SIZEを使用しています。としてスクリプトを保存し、 "ldscript.c" H。

C ))あなたのメイクファイル(または同等のコンパイル手順でプリプロセッサを呼び出すあなたはGCCを使用している場合、コマンドは次のとおりです。

gcc -P -E ldscript.c -o ldscript.ld 

いくつかのバージョンのgccは、入力ファイルの拡張子に特別な意味を与えることに注意してください、私が使用することをお勧めので。 ".c"は、最も安全な方法です。

d)Cプリプロセッサで生成されたファイル "ldscript.ld"をリンクスクリプトとして使用します。

+0

を使ってldファイルにインポートできます。 (1)と(2)は適用できません。スタックの最後のアドレスをベクタテーブルに定義する必要があるからです。私はあなたが(2)で言及した理由でこれを行うことはできません。私は(3)をやってみましたが、ldscript.ldは生成されませんでした。代わりに、 "arm-none-eabi-gcc.exe:警告:ldsource.script:リンカー入力ファイルがリンクされていないため未使用です"というメッセージが表示されます。したがって(3)も役に立たない。最後に(4)正しいと思われた。しかし、私は "= _fstackptr - SIZEOF(.co_stack);" SIZEOF()はOUTPUTセクションにのみ適用されますが、入力セクションのサイズが必要です。 –

+0

@dexkid Uhm、いくつかの異なる入力ファイル拡張子で(3)を試しました。 ".ld"(INPUTとして)を除いて、すべて動作しました。あなたのgccのバージョンはおそらくldスクリプトとして ".source"拡張を解釈します!鉱山は実際には ".src"と ".ld"を使用します。入力ファイルの別の拡張子を選択することをお勧めします(例:「.c」、これはかなり奇妙です)。もし成功すれば私に知らせてください。 –

+1

PS:私は数年間トリック(3)を使用しています... –

関連する問題