ISRが実行中で、別の割り込みが発生するとどうなりますか?最初の割り込みは割り込みを受けますか? 2番目の割り込みは無視されますか?または、最初のISRが完了したときに起動しますか?
[〜#〜] edit [〜#〜]これをAtmel AVRでどのように機能させるのかを質問するために、質問に含めるのを忘れました(ただし、タグに含めました)。
通常、割り込みサービスルーチンは、ほとんどのシステムでそれ自体が割り込みを受けることなく完了するまで続行します。ただし、複数のデバイスがマイクロプロセッサに割り込む可能性がある、より大きなシステムがある場合、priority問題が発生する可能性があります。
現在の割り込み内で割り込み有効フラグも設定すると、さらに優先度が高い割り込みを許可できます。 1つが実行されています。この「割り込みの割り込み」は、ネストされた割り込みと呼ばれます。これは、元のサービスルーチンの実行を停止し、stackにレジスタの別のシーケンスを格納することによって処理されます。これはネストされたサブルーチンに似ています。各割り込みによってスタックポインタが自動的にデクリメントされ、その後RETURN命令によってインクリメントされるため、2番目の割り込みが完了した後、最初の割り込みサービスルーチンが再開され、割り込みは適切な順序で処理されます。割り込みは、スタックに使用できるメモリの量によってのみ制限される任意の深さにネストできます。
たとえば、次の図では、スレッドAが実行されています。割り込みIRQxにより、割り込みハンドラーIntxが実行され、IRQyとそのハンドラーIntyによってプリエンプトされます。 Intyは、スレッドBを実行させるイベントを返します。 Intxは、スレッドCを実行させるイベントを返します。
ハードウェア割り込みの場合、優先割り込みコントローラーチップ(PIC)は、CPUに独自のアドレスを提示するデバイスのタスクを単純にするように設計されたハードウェアチップです。 PICは、それに接続されているデバイスの優先度も評価します。最新のPICは、必要なレベルよりも低い割り込みの生成を防ぐようにプログラムすることもできます。
AVRハードウェアは、グローバル割り込みフラグを[〜#〜] sreg [〜#〜 ]割り込みベクトルに入る前。したがって、通常、割り込みはハンドラーが終了するまでハンドラー内で無効のままですが、RETI命令(割り込みハンドラーの通常の関数エピローグの一部としてコンパイラーによって発行されます)最終的にさらに割り込みを再度有効にします。そのため、通常、割り込みハンドラはネストしません。ほとんどの割り込みハンドラーでは、これが望ましい動作です。一部の場合は、無限再帰割り込み(UART interrupts、またはレベルでトリガーされる外部割り込み)。
まれな状況では、ネストされた割り込みがグローバル割り込みフラグを割り込みハンドラでできるだけ早く再有効化することで望まれるかもしれませんが、絶対に必要以上に他の割り込みを延期しないようにするため。これは、割り込みハンドラの先頭でsei()命令を使用して実行できますが、コンパイラが生成した関数プロローグ内に、グローバル割り込みを無効にして実行するいくつかの命令が残っています。コンパイラーは、ハンドラーを次のように宣言することにより、割り込みハンドラーの先頭にSEI命令を挿入するように指示できます。
ISR(XXX_vect, ISR_NOBLOCK)
{
...
}
ここで、XXX_vectはMCUタイプの有効な割り込みベクトルの名前です。
また、Atmel AVRでの割り込みの詳細については、この アプリケーションノート を参照してください。
割り込みが機能する方法:
コードは「グローバル割り込み有効」ビットを設定します。これがないと、割り込みは発生しません。
何かが発生して割り込みが発生すると、フラグが設定されます。
割り込みフラグが通知されると、「グローバル割り込み有効」ビットがクリアされます。
適切なISRが実行されます。
「グローバル割り込み有効」ビットがリセットされます。
これで、手順2に戻りますnless ISR中に割り込みフラグが既に設定されています。その後、手順3に戻ります。
つまり、最初のISRが終了すると、2番目のISRが実行されます。
お役に立てれば!