2016-08-06 22 views
0

私はLPC2138 socを使用して、ベアメタルのARMプロジェクトを開発中です。私はI2C用のIRQ割り込みハンドラを書いています。しかし、それは正しく返されません。ハンドラは、単一の割り込みに対して繰り返し呼び出されています。GCCでARM IRQハンドラが正しく動作しない

私はこの問題の詳細なデバッグ分析を行っています。

ARM7TDMIリファレンスマニュアルには、次のことが明確に記載されています。

しかし、コードを逆アセンブルすると、GCCによって生成されたコードがCPSRレジスタを復元しないことがわかりました。また、最後には未知の値です。

enter image description here

私は、次の

void I2C0_IRQ_handler(void) __attribute__ ((interrupt("IRQ"))); 

などのIRQハンドラは、SこれはGCCのバグですか、私は何か間違ったことをしたのか宣言していますか

私はプロジェクトを構築するために使用しているコンパイラ、アセンブラ、リンカフラグは次のとおりです。

CFLAGS := -mcpu=arm7tdmi-s -g3 -Wall -I. -gdwarf-2 
AS_FLAGS := -mcpu=arm7tdmi-s -g3 -gdwarf-2 
LD_FLAGS := -Wl,-Map,$(TARGET:%.hex=%).map -nostartfiles 
+3

どのように正しく動作しないのですか。あなたはあなたが期待しているものと比べてどのような行動を見ますか?'VICVectAddr = 0;'が割り込みをクリアしていると仮定すると、このコードは3つの引用符で囲まれたすべてのステップを適切に実行しています(ヒント: 'subs pc、...'が実際に何を実行しているかを読む) – Notlikethat

+0

@Notlikethat I2Cの開始条件が生成する必要があります。その働き。しかし、割り込みルーチンの後、コントロールは中断されたコードに戻りません。アセンブリコードにステップ2がありません。 – sreeyesh

+0

私が言ったように、ステップ2_is_はそのコードで 'subs pc ...'によって実行されます。 LPC213xのマニュアルを見つけて、VICで割込みを確認していますが、割込みは明らかにレベルでトリガされています.I2Cコントローラのエンドで割込みを行うことは何もしていません(13.9節参照)。したがって、あなたが戻ってくると、ただちに同じ割り込みをもう一度やり直して、無限になります。 – Notlikethat

答えて

4

あなたの分析は、二つの致命的な欠陥がある:第一に、あなたは、CPUコアの観点からそれを見ています、第二に、それは間違っています。

第2の欠陥はまず、なぜARM7TDMIマニュアルにそのような奇妙な過度に特定の言い回しがあるのか​​わかりませんが(実際にはこれらのことを別々に行うことはできません)、すべての3つの側面はすべてsubs pc, lr, #4行コード。 subs pc, lr is specifically an exception return instruction - SPSRからCPSRをアトミックに復元し、固定アップLRアドレスに戻ります。 CPUの割り込み禁止フラグがCPSRにあるので、そのSPSR値のIビットがクリアであると仮定すると(あなたがここに来るためにIRQを取ったとすれば...)、IRQも自動的にマスク解除されます過程の中で。

したがって、CPUコアの観点からは、のコードでは、あなたのコードは例外ハンドラが必要とするすべてのことを(つまり、同じポイントで同じ状態で実行を再開します。 IRQが起きたときにコンパイラに間違いがないことは間違いありません。しかし、ではありません。なぜなら、コアを越えた周辺の方法はまだ割り込みを主張しているからです。したがって、IRQから戻った後に次に行うことは、即座に同じIRQを即座に再び受け入れることです。広告の無限を繰り返します。

少なくとも、割り込みコントローラまではコアを超えています。 VICVectAddracknowledges the interrupt at the VICに書き込んだだけですが、VIC自体を優先して保留中の割り込みに優先させ、次の割り込みを提供するだけです。これは外部ソースがまだアサートされているため(優先順位の高いIRQが他の場所から来ていないと仮定して)同じもの。

実際にはを処理して割り込みを行い、何らかの処理を進めるには、I2Cペリフェラルにサービスを提供する必要があります。 the LPC213x manualの13.9節では、各割り込み条件に対して何を行う必要があるのか​​を概説していますが、アサートされた割り込みをクリアするには、I2C0CONCLRのSICフィールドを書き込む必要があります。

+0

それは本当に私の問題を解決し、新しいことを学ぶのに役立った。あなたの答えから、私があなたの努力を理解し、私の質問に答えてくれた時間を理解することができます。それは本当にありがとうございました:)もちろん、私の上位投票。 – sreeyesh

関連する問題