2012-02-09 6 views
2

基本的な、ベアメタルのCortex-M3プログラミング情報を探しているときに、次のようなものに似た何かが出てきました(ここでの大きな答え、後で説明します)。ARMリンカは、例外テーブルの停止位置をどのように知っていますか?

/* vectors.s */ 
.cpu cortex-m3 
.thumb 

.word 0x20002000 /* stack top address */ 
.word _start  /* 1 Reset */ 
.word hang  /* 2 NMI */ 
.word hang  /* 3 HardFault */ 
.word hang  /* 4 MemManage */ 
.word hang  /* 5 BusFault */ 
.word hang  /* 6 UsageFault */ 
.word hang  /* 7 RESERVED */ 
.word hang  /* 8 RESERVED */ 
.word hang  /* 9 RESERVED*/ 
.word hang  /* 10 RESERVED */ 
.word hang  /* 11 SVCall */ 
.word hang  /* 12 Debug Monitor */ 
.word hang  /* 13 RESERVED */ 
.word hang  /* 14 PendSV */ 
.word hang  /* 15 SysTick */ 
.word hang  /* 16 External Interrupt(0) */ 
.word hang  /* 17 External Interrupt(1) */ 
.word hang  /* 18 External Interrupt(2) */ 
.word hang  /* 19 ... */ 

.thumb_func 
.global _start 
_start: 
    bl notmain 
    b hang 

.thumb_func 
hang: b . 

これは私には理にかなって、私はそれが何をするかを理解しますが、どのような私には意味がないことは、リンカどこ例外テーブルを知っている(またはCPUが、私はどの...よく分からない)方法です実際のコードが始まります。 Cortex-M3のドキュメントからは、テーブルに任意の数の外部割り込みがあると思われます。

これはどのように機能し、学習するために私は何を読む必要がありますか?

答えて

2

これは私のコードであり、プログラマーは何が起こっているのかを知る必要のあるリンカーではありません。皮質mは異なるベクトルテーブルを持ち、非常に長くて、多くの個々の割り込みベクトルがあります。ある日、1つのフレーバーから、上記はちょっと速かったです。リセットベクトル以外のものを使用しない場合は、より多くのメモリ位置を焼き付けてテーブル全体を作成する必要がありますか?おそらくない。定義されていない例外やアボートなどをカバーできるだけの深さにすると、制御されたハングでトラップすることができます。リセットと1つの割り込みだけが必要だが、その割り込みがテーブルのかなり深い場合は、両方をカバーするために巨大なテーブルを作るか、紛失したスペースを回復するためにそれらの間にいくつかのコードを入れておいてください。

あなたが特定のCortex-MコアのCortex-M0、皮質-M3とarmv7-のためのCortex-M4だけでなく、おそらくARMのARMため、TRM、テクニカルリファレンスマニュアルに行く必要がより読み/学ぶためにm(皮質-mはすべてarmv7-mファミリ)。 ARM ARMはARMアーキテクチャリファレンスマニュアルを意味しますが、ファミリ全体について一般的に語りますが、コアの細部まで幅広くカバーしているわけではありません。通常、ARM用のプログラミングではARM ARMと適切なTRMが必要です(何か低asmや特定のレジスタのようなレベル)。すべては、アーキテクチャの左側の見出しにある腕のウェブサイトinfocenter.arm.comまたはCortex-Mシリーズプロセッサーを参照してください。

これらのコアは十分に新しいもので、元の回転数を超えている可能性があります。いくつかの古いコアでは、特定のコアのTRMを取得することをお勧めします。 ARM11のMpcoreを使用してください。たとえば、ベンダーがマニュアルの古いマーキングにもかかわらずコアの1.0(r1p0)を使用していて、違いがある場合はrev 1.0マニュアルを使用してください。ベンダーはいつもあなたが購入/使用されているrevを教えていないので、これを問題のプログラムにするかどうか、あるいは正誤表があなたに適用されているかどうか分からないときに問題になることがあります。 (Linuxはこれを理解していないためにARMに関連する間違いがたくさんあり、一般的に間違って適用されたり間違ったコアに適用されたり、不適切なコアで間違ったタイミングで使用された命令など)。

私はおそらく、最初に1つを取得した後にカットアンドペーストして、修正したり変更したりするのを煩わせることなく、そのcortex-m3のハンドラを書きました。

コア(CPU、ロジック)は、サポートされている割り込みの数を明確に把握しており、ベクタテーブルの完全な構成を把握しています。コアのエッジに制御信号があり、このような事態を変える可能性があり、ベンダーがそれらを一方向に束縛したりプログラマブルにしたりする可能性があります。そのコアのロジックがどういうものであっても、必要に応じてコードをハードウェアにマッチさせるのはプログラマの責任です。これはすべてそのコアのTRMに記述されます。ロジックにハード

EDIT

は、これらのイベントまたは割り込みのそれぞれのオフセットアドレスまたはあろう。したがって、割り込みまたはイベントが発生すると、そのアドレスからのメモリ読み出しが実行されます。

これはちょうどフラッシュメモリのバンクであり、アドレスを入力して読み込みストローブをフリックさせ、いくつかのデータが出力されます。あなたがそれらを文脈に入れるまで、これらのビットは何も意味しません。そのアドレスにロード命令を実行するコードを作成するか、そのアドレスに分岐することができ、フェッチサイクルが命令を見つけることを望むその場所を読み込み、イベントにそのハードコードされたものがある場合は、アドレス0x10のメモリサイクルを引き起こすことができますそのアドレスで読み取りが行われ、ハンドラのアドレスを見つけることが望まれます。それは単なる記憶にすぎません。ファイルシステム上のファイルと同じように、ディスク上のバイトだけです。それがjpegの場合、特定のバイトがピクセルである可能性があります。ディスク上のファイルがプログラムの場合、オフセットのバイトが命令の場合があります。そのちょうど1バイト。

これらのアドレスはロジックから直接生成されます。最近のロジックは、プログラミング言語(通常はverilogまたはvhdlまたは出力としてverilogまたはvhdlを生成するいくつかの高レベル言語)を使用して書かれています。あなたは文字通り、いくつかのアドレス

x = (unsigned int *)0x1234; 

たり、構造や配列または他のプログラミングスタイルのいくつかの並べ替えを使用することを選択したが、一度かもしれないをハードコーディングすることを選択するかもしれないあなたの好きな言語でプログラムを書くした場合よりも異なるんコンパイルされ、それはまだいくつかの固定アドレスまたはオフセット産終わる:

unsigned int vector_table[256]; 
... 
handler_address = vector_table[interrupt_base+interrupt_number]; 
... 

をだから、プログラマとして、この低レベルでは、あなたがあれば、いつハードウェアがこれらのアドレスのいずれかを読みに行くと、なぜされて知っている必要があります。割込みを有効にしないために割込みを使用しない場合は、通常は割込みハンドラのアドレスを保持する可能性のあるメモリの場所が、現在使用できるメモリの場所になります。あなたが多くの、ほとんどすべての私の例で私は今までにリセットの必要性を参照してください、残りの私は使用しないでください。誤ってアライメントのとれていないアクセスを実行すると、私は誤って未定義の命令ハンドラやデータアボートにぶつかるかもしれませんが、通常はそこにハンドラを配置するのに十分な心配はありません。私はクラッシュするか、とにかくハングするので、私がそこに着いたら、その橋を渡ってその問題を解決します。だから私は、Cortex-Mスタックアドレスのための必要最小限と通常コンテンツだとリセットアドレス:

.cpu cortex-m3 
.thumb 

.word 0x20002000 /* stack top address */ 
.word _start  /* 1 Reset */ 

.thumb_func 
.global _start 
_start: 
    bl notmain 
    b hang 

.thumb_func 
hang: b . 

そして、はい、絶対に私はNMIのためのメモリ位置に2つのワード命令のBL notmainを配置しています。 NMIが発生するならば、CPUはその場所を読み込み、それがハンドラのアドレスであると仮定し、そのアドレスで命令をフェッチしようとします。それは、それが無効なアドレスであり、上記の場合には別のアドレスがどこかにあるデータアボートを引き起こし、データアボートの無限ループになるかもしれないことを知るかもしれません。偶然にも、その命令の1つが私たちのプログラムのアドレスのように見える場合は、基本的にはプログラムの途中にジャンプします。プログラムの途中でジャンプすると、クラッシュすることがよくあります。クラッシュは何ですか?本当に? cpuはメモリからバイトを読み込み、命令がアライメントの合っていないアクセスを行うように指示した場合にそれらを命令として解釈するか、またはそれらのバイトが有効な命令ではないか、または無効なメモリアドレスを読み取らせてベクタテーブルに戻ります。またはコードスペースの途中でジャンプして書き込みや読み込みをしている乱雑なアドレスがフラッシュバンクを消去したり、バイトを変更してuartを吐き出したり、gpio入力ポートを出力ポート(本当に運が良ければ地面か何かに駆け寄ってチップを溶かす)

私が奇妙なことを見ていたら(うまくいけない、または臭いがない、チップが溶けているのを見て)、ベクトルテーブルのハングを指す数十の項目を投げるかもしれません。ポートから何かを吐き出すか、gpio/ledをオンにします。私の奇妙なことが今このリードになるか、ハンドラの中で出力されるようになったら、何が起きているのか分からなければなりません。あるいは、アプリケーションの最後のいくつかの変更について考えると、など

雑草の中にそれは戻ってと言っに戻り、「コンピュータのdoesntのは、あなたがそれがやりたい何、それはあなたがはそれを行うにはに言ったことありません」。そこにバイトを置くと、適切な場所に正しいバイトを配置しなかった場合(正しい場所にベクトル・アドレスを、適切なことをする命令、正しい場所に正しいデータを置いた場合)、それをそのまま解釈しますすることができます/クラッシュします。

+0

私はそれが割り込みベクタテーブルであることを理解していますが、それは必要になる可能性があるため、スパース/完全であることが理解できますが、CPUやその他のこと特定の行のチャンクは割り込みベクタテーブルであり、それに続く行は割り込みベクタテーブルではありません。セクションを分けるのは何ですか?ファイル内のベクタテーブルは最初になければなりませんか? 「最初の.thumb_funcディレクティブより前のすべてのもの」と定義されていますか? – Mark

+0

または、単にベクトルテーブルを終了し、その残りの部分をコード用のスペースとして使用していますか? I.たとえば、NMI割り込みの後にテーブルを終了し、BusFault割り込みが発生した場合、何らかの命令やデータがベクタテーブルのそのスロットを占有していたため、何か不思議な場所にジャンプしますか? – Mark

1

答えはありません。あなたのCPUによって生成されたすべてのものをトラップするのに十分な数のベクタを置くのはプログラマの責任です。あなたがそれを台無しにすると、CPUはベクタテーブルの後に何かをロードしようとするかもしれません(あなたの_startコードからの命令のように)、ベクトルのように扱い、それにジャンプしようとします。

関連する問題