いつポーリングメソッドを使用し、いつ割り込みベースのメソッドを使用する必要がありますか?両方を使用できるシナリオはありますか?
関心のあるイベントが次の場合:
その後、割り込みベースのハンドラーが意味をなします。
関心のあるイベントが次の場合:
ポーリングが適している場合があります。
その他の考慮事項には、OSのデバイスドライバーを作成するか、スレッドをサポートしないベアメタルコードを作成するだけかが含まれます。ベアメタルの状況では、CPUがビジーでないときにループすることがよくあるため、何かをポーリングしている可能性もあります。
ポーリングは通常、不必要に多くのCPUサイクルを消費するため、可能な場合は回避する必要があります((a)短時間だけポーリングする場合、または(b)ポーリングループで妥当な時間スリープできる場合を除く) )。 CPUサイクルの浪費は、パフォーマンスの観点から悪いだけでなく、消費電力も増加させます。これは、バッテリー駆動の組み込みアプリケーションの問題になる可能性があります。
ポーリングまたは割り込みを決定するときは、フォローしようとしているイベントの性質とそれに対する応答を完全に理解する必要があります。
割り込みは、何も起きていないときには処理を必要としませんが、何かが起こっているときには注意を払う必要があります。イベントが外部でノイズの多いエッジまたは高速パルスを持っている場合、これは割り込みで大きな頭痛の種になる可能性があります。割り込みのセットアップには注意する必要があります。
この例では、割り込みルーチンは、レーザービームがクリアになったことに応答し、ブロックされたイベントに対して自身をセットアップしています。
BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/
/*Set the beam interrupt for the next clear to blocked event*/
BEAM_INTR_Edge = CLEAR_TO_BLOCKED;
BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/
このコードには2つの弱点があります。1)割り込みフラグがクリアされる前にレーザービームが再びブロックされた場合(BEAM_INTR_FLAG = FALSE;)。割り込みが失われ、コードはレーザービームの状態と同期しなくなります。
2)バックグラウンドルーチンで、またはこのコードがオンになっている優先度よりも高い優先度で割り込みを設定する場合、割り込みを有効にするときは注意が必要です。割り込みフラグが有効になる前に(誤って)すでに設定されている場合、割り込みルーチンは有効になると、おそらく間違ったEdgeに対して誤って呼び出されます。
1)を修正する最も簡単な方法は、割り込みを設定した後、再確認し、発生した場合は割り込みを強制することです。修正するには2)割り込みの有効化を二重チェックの後に移動します。
/*Set the beam interrupt for the next clear to blocked event*/
BEAM_INTR_Edge = CLEAR_TO_BLOCKED;
BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/
/*Double check beam state to see if it has already gone blocked*/
if (BEAM_STATE == BEAM_BLOCKED)
{
BEAM_INTR_FLAG = TRUE; /*Force the interrupt to re-enter the ISR after exiting*/
}
BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/
割り込みを強制すると、システムが同じステートマシンで動作し、手動で強制的に死角をカバーするように強制します。
基本的に:
Set the Edge to detect the next interrupt event
Clear the interrupt flag
if (the event has already occurred)
{
Set the interrupt flag to force the interrupt
}
Enable the interrupt
イベントへの応答の時間を一定にする必要がある場合(たとえば、入力ラインがハイになった後、1ms +/- 10us、イベント信号を送信する)、通常は割り込みが最適です。
イベントへの応答の時間が特定の時間内にある必要がある場合(たとえば、入力ラインがハイになる1ms以内にイベント信号を送信する場合)、割り込みが最適です。
割り込みの問題は、スレッド化について考え始める必要があり、2つのコードが同じデータに同時にアクセスできることです。
割り込みは、何かが起こるのを待っている間、プロセッサが低電力モード(スリープ/アイドルなど)に移行できるようにするのにも適しています。
プロセッサが実行することが1つしかない場合、ポーリングはイベントに非常に厳しい時間応答を与えることができると言いましたが、多くの場合、割り込みハードウェアはイベントに応答するのに数サイクルかかりますが、タイトなポーリングループは実行します。
イベントのタイミングが重要ではなく、ノイズが発生する可能性がある場合(誰かがスイッチを押すなど)、ポーリングを行うと、長期的な移行を逃すことなく簡単にフィルタリングできます。よくある間違いは、設定時に複数回ポーリングすることです。
void fnInitialiseSystem(void)
{
if (MODE_INPUT == MODE_A) /*First polling of the MODE_INPUT*/
{
PR2 = PR2_MODE_A;
}
else
{
PR2 = PR2_MODE_B;
}
OpenTimer2( TIMER_INT_ON &
T2_PS_1_1 &
T2_POST_1_8 );
if (MODE_INPUT == MODE_A) /*Second polling of the MODE_INPUT*/
{
CurrentMode = MODE_A;
PROBE_INT_Edge = CLEAR_TO_BLOCKED;
}
else
{
CurrentMode = MODE_B;
PROBE_INT_Edge = BLOCKED_TO_CLEAR;
}
}
上記の例では、MODE_INPUTは外部スイッチです。MODE_INPUTの2回のポーリングが異なる場合、動作は予期されていません。これらの種類の信号を読み取るときは、フィルタリングを使用して入力の長期的な状態を判断し、フィルタリングされたバージョンでアクションを実行するのが最善です。
たとえば、スイッチのデバウンスでは、定期的に(1msごとに)スイッチをチェックし、それらの数(たとえば16)がフィルターバージョン(スイッチを開く)と異なる場合(スイッチを閉じる)、結果を更新し、必要なアクションを実行します。信号のエイリアシングには注意してください、発振信号は安定しているように見えるかもしれません!
ポーリングと割り込みの使用例は、頻繁に変更されることはありませんが、変更するとノイズが多い入力を使用する場合です。やはりスイッチはこの良い例です。コードはスイッチ状態の変化を確認するために割り込みを設定できます。割り込みが発生すると、スイッチはスイッチ状態が「安定」になるまで定期的にポーリングできます。状態または元の状態に戻ります)。これにより、何も起きていないときの処理オーバーヘッドが低く、何かが起こっているときのノイズフィルタリングという利点が得られます。
実際には両方を使用する必要がある場合があります。たとえば、イベントが散発的であるが、高速バーストが発生する場合。最初に割り込みに応答し、次に割り込みポーリングを再度有効にしてから、別のイベントが既に発生しているかどうかを確認してから、割り込みコンテキストスイッチングのオーバーヘッドの一部を回避する必要があります。 Linux Network Interfaceはこのモードで動作すると思います。
ポーリング対割り込みメソッドを分析しているときに出会ったいくつかの興味深いリンクがあります- http://web.engr.oregonstate.edu/~traylor/ece473/lectures/interrupts.pdf -非常に興味深いリンク http://www.atarimagazines.com/compute/issue149/60_Interrupts_made_easy.php
http://www.electro-tech-online.com/micro-controllers/8440-interrupt-vs-polling.htmlhttp://www.microchip .com/forums/m397196-print.aspxhttp://www.cs.huji.ac.il/course/2006/67630/Lectures/interrupts.pdfhttp ://sunsite.nus.edu.sg/LDP/LDP/tlk/node86.html
これがお役に立てば幸いです。
簡単な答えは、ポーリングが遅すぎる場合に割り込みメソッドを使用することです。 (遅すぎると、ポーリングでデータが失われた場合、割り込み方法が必要になります)
意思決定を促進できる設計上の制約は多数あります。私のアプリには割り込みとポーリングの組み合わせがあります:
低レイテンシが必要な場合は、割り込みが優先されます。ある条件を1秒間にN回ポーリングすると、平均して、実際に発生してから1/Nの半分の時間でその条件を発見できます。
絶対的な決定論的タイミングが必要な場合、ポーリングが好ましい場合があります。本質的に、割り込みは予測不可能な時間に発生する可能性があり、タイミング分析を非常に複雑にしますが、ポーリングされたシステムでは、期限の充足について証明可能なステートメントを作成するのは比較的簡単です。
基本的に、ポーリングモードは、ハードウェアまたはソフトウェアの何らかの理由で割り込みモードが利用できない場合に使用されます。そのため、電力消費、パフォーマンスなどの観点から割り込みモードの方が望ましい(Paul Rに同意)。ポーリングモードは、プロトタイピング、周辺機器が不要なコア、およびテスト目的でも使用できます。
常に割り込みを使用してください。そうすれば、データを失うことはありません。イベント駆動型またはスレッド型のアプリケーションでは、最も遅い信号でも割り込み駆動する必要があります。
ポーリングを使用する必要があるのは、スケジューラを使用していて、ハードウェアのバッファがデータの損失がないことを保証するのに十分な深さである場合のみです。
ポーリングモードは、高頻度のイベントが発生するシステムで役立ちます。割り込みハンドラの開始と終了に関連するオーバーヘッドは、単純なポーリングよりも多くのCPUサイクルを使用します。たとえば、IPルーターでポーリングを使用して、パケット処理に使用できるCPU帯域幅を最大化できます。
Interrupt based design
と比較してpolling based
を使用する方がはるかに優れていますすべてのポーリングでデータが返されることを期待するという意味でポーリングベースに欠陥があるためです。今、あなたは私が単一のポーリングが私にエラーを返したこのケースを回避すると言うかもしれませんが、なぜそれがエラーを返す可能性があるのに何かのためにポーリングするすべてのCPUサイクルを無駄にするのですか?そして、投票が失敗するかもしれないと予想することは、実用的な製品シナリオです。
Interrupt based designs
は、単一の投票に関与する関数のレイヤーが多数ある場合にさらに意味があります。私にとって、それは一般的な慣行です:友人に必要な情報があるかどうか、毎日繰り返し(polling)尋ねますかORあなたが私に必要な情報を手に入れたら、interrupt
と私に言ってくれませんか。私たちは日々の生活の中で正しいことをしていると思いますが、気づきません。
ただし、interrupt based architectures
を実装する場合は、publish-subscribe design principle
を確実に理解する必要があります。また、アプリドメインで実行する場合、割り込みを送信するコードの一部を本当に適切に記述する必要があります。複雑さを1か所に絞り込んでいるので、これは良いことです。
上記に加えて、ポーリングベースのアーキテクチャが無料で提供する他の利点を次に示します。
sw
を設計する場合、およびこの選択肢がある場合は、interrupt
ベースの設計が満たされる可能性があるため、polling
ベースよりも常にinterrupt
ベースの設計を選択する必要があります。リスナーを使用したpolling
ベースの状況に対応しますが、ポーリングベースの設計はinterrupt
ベースの設計を必要とする要件を満たすことはできません。
以下は簡単な比較マトリックスです
-INTERRUPT- -LOOP-
Speed fast slow
Eficiency good poor
CPU waste low high
multitasking yes no
complexity high low
debugging +/- easy easy
critical in time excellent poor
code bloat low impact high impact
ホストをビジーループで長時間待機させることは望ましくありません。また、頻繁に存在しないデータを頻繁にチェックすると、ポーリングが非効率になる可能性があります。そのため、ホストとデバイスが両方とも高速であれば、かなり高速であればポーリングを行います。
主な5つの方法があります。
1)ブラインド
CPUはx msごとにデータをチェックします。 ETCチェックピン12。
2)ポーリング(ビジー/待機)
CPUは常に、UARTパケットの転送後にフラグを立てる。Flagレジスタを常にチェックします。ベストレスポンスタイム)のように、フラグが立てられるのを待っています。そうしないと。
3)割り込み:
CPUは正常に動作し、割り込みが発生すると、CPUはコンテキストをISRに切り替えます。ピン18が立ち下がりエッジを見た場合、ISR(1)を実行します。 ISRがアクティブでない間、悪い応答時間とCPUは何もできません。いつ発生するかわからない緊急アプリでそれを行います。
4)定期的なポーリング:
CPUは処理を行っていますが、ms秒ごとにチェックピン11を実行しています。ブラインドはその間に何も実行していません。緊急のアプリではなく、応答時間が悪いのは、ハードウェアが割り込みを発生させることを信頼していないときに行います。タイマー割り込みを使用して作成できます。
5)ダイレクトメモリアクセス。
高度なインターフェイスアプローチ。メモリとの間でデータを直接転送します。入力はメモリに直接読み込まれます。出力はメモリから直接書き込まれます。両方ともコントローラーを使用します。