2012-02-10 15 views
18

これまで、私はRAMとフラッシュの両方がチップに直接格納された8ビットAVRとMSP430で多くの作業を行ってきました。あなたがプログラムをコンパイルしてダウンロードするとき、それは「ちょうどうまくいく」のようなもので、実際に変数がどこにどのように格納されるか心配する必要はありません。マイクロコントローラで外部メモリを使用する方法

今私はマイクロコントローラ(TI Stellaris LM3S9D92)にいくつかの外部メモリを追加したいと思っていますが、コードをどのように使用するのかは完全にはわかりません外部RAM。どのように他の周辺機器と同様に外部バスを設定するのか分かりますが、私が混乱させるのは、プロセッサがどのように外部メモリと通信するのか、またいつ内部のものと通信するのかを把握する方法です。

私が知る限り、外部RAMは内部SRAMと同じアドレス空間にマップされています(内部は0x20000000から開始し、外部は0x60000000から開始します)。

int* x= 0x20000000; 
int* y= 0x60000000; 

は、xとyは、それぞれ内部および外部RAMの(32ビットint型を仮定して)最初の4つのバイトを指すことになります:私はこのような何かを書いた場合には、ということですか?もしそうなら、私はこのような何かなかった場合、どのような:

int x[999999999999]; //some super big array that uses all the internal ram 
int y[999999999999]; //this would have to be in external ram or it wouldn't fit 

を私はメモリの各タイプがあるか、私はそれがすべて間違っているとハードウェア持たない場所の境界に関する何かを伝えるために必要があるだろうと想像しますそれはそれ自身で出てくるのですか?リンカスクリプトはこれを処理しますか?彼らはメモリマッピングと何か関係があると知っていますが、私は正確に何がわかりません。 ARMクロスコンパイラをセットアップする方法を読んだ後、私はwinavr(avr-gcc)のようなものが私のためにこのように多くのことをやっていたので、それに対処する必要はないと感じました。

私はこのようなものと正しい軌道にいるかどうか誰かが私に教えてもらえれば、ちょっと散歩に申し訳ありませんが、本当に感謝します。将来の読者のために

更新

私はhttp://www.bravegnu.org/gnu-eprog/index.htmlをグーグルでの別の数時間後にこれを見つけました。ここの答えと組み合わせると、それは私を大いに助けました。

+0

http://electronics.stackexchange.com/でお問い合わせください。また、[Stellarisのデータシート](http://www.ti.com/lit/ds/spms257a/spms257a.pdf)も参照してください。 –

答えて

11

一般的に、それは正確にどのように動作するかです。あなたはハードウェアを適切にセットアップしなければならないし、ハードウェアがすでに固定アドレスにハードコードされているかもしれない。

同じ質問をすることができます。ハードウェアは、私が0x21000010をアドレス指定するためのバイトを書き込むと(私はこれを作った)、それはUARTの送信保持レジスタであり、その書き込みはバイトユアート?その答えは、そのように論理にハードコードされているからです。または、ロジックにオフセットがある可能性があります。これは、他のコントロールレジスタの内容に0x10を加えたものでも可能です。 0x21000000から0x90000000へのコントロールレジスタ(それ自身はいくつかのハードコードされたアドレスを持っている)を変更し、0x90000010に書き込み、そしてもう一つのバイトはuartから出ます。

私はその特定の部分を見なければならないでしょうが、外部メモリをサポートしていれば、理論的にはプロセッサアドレス空間のどのアドレスがその外部メモリにマップされ、読み書き外部メモリへのアクセスが発生します。

Intelベースのコンピュータ(PC)は、1つの大きなフラットなアドレス空間を好む傾向があります。Linuxボックス(ある場合)またはWindowsまたはMacの場合は他のコマンドでlspciコマンドを使用してください。カードにはアドレス空間の塊が与えられています。あなたがCPU /オペレーティングシステムの保護を経て、そのスペースのアドレスに書き込もうとすると、プロセッサーを介してプロセッサーを介してpciコントローラーとビデオカードに入ってしまいます。ピクセル。既にavrとmsp430でこれを処理しています。アドレス空間のいくつかのアドレスはフラッシュであり、いくつかはRAMであり、CPUコアの外側にあるいくつかのロジックがあり、CPUコアのアドレスバスを調べ、そのアクセスをどこに送るかを決定します。これまでのところ、フラッシュバンクとラムバンクとロジックはチップの境界内にすべて自己完結していますが、これはロジックがアドレスに応答するにはあまり遠すぎず、外部メモリサイクルを作成します完了したか、結果が読み込みに戻ってくると、内部メモリサイクルが完了し、次のことに進みます。

これは意味がありますか、それを悪化させますか?

+0

それは私には理にかなっていますが、私はまだそれほど得られないことがあります.Cの外部/内部RAMに変数を手動で割り当てる必要がありますか?私はスタックが内部/外部の境界を飛び越えるのに十分なほどスマートであるとは思っていませんが、大量のグローバル変数を宣言すればどうでしょうか? 「この変数を内部のラムに入れれば、そうでなければ外部のラムに生かせる」といったような言い方がありますか? – nightrain

+0

これらの種類の質問は外部メモリに固有のものではなく、あなたがどのプラットフォームにいても、あなたのメモリを管理する必要があります。おそらく、リンカの制御を引き継いで、そのメモリに配置したい場所を配置する必要があります。組み込みシステムで実行している場合は、スタックを使用して何かに衝突しないことを保証するためにスタックとヒープを管理する必要があります。大量のグローバル化はそれを行うための1つの安全な方法ですが、必ずしもメモリ効率的ではありません。 –

+1

のgnu/gccツールには、あなたが書いたリンカスクリプトがあります。あるいは、コンパイラのどこかに埋め込まれていて、おそらくあなたが選んだプロセッサやシステムタイプに基づいてスクリプトが選択されます。あなたはそれを無効にすることができますし、独自のものを使用します。 gnu/gccリンカスクリプトは、作成および使用するのに苦労する可能性のある設定可能で強力なものです。各ファイルの場所を手作業で調整することも、関数や変数を使用することもできます。通常は、スタックを最速のメモリに入れたいと思っています。 –

0

予約語レジスタを使用して、変数を内部メモリの場所に配置することをコンパイラに示すことができます。 register int iInside; 注意してください。コンパイラーは、使用可能なレジスター・ストレージのバイト数を知っています。使用可能なすべてのスペースがなくなっても問題はありません。

レジスタ変数は、カウンターなど非常に頻繁に使用されるものに対してのみ使用します。

+0

「内部RAM」はCPUレジスタを意味しません。また、OPは最大の反対をしたい:外部メモリ(μCとは別のチップ) –