このトピックはずっと前に議論されたことを知っています (リンク:割り込みとイベントの違い) にもかかわらず、私は答えが適切であるとは考えていません。その理由は次のとおりです。イベントと割り込みについて話すとき、イベントという用語はソフトウェアではなくハードウェアに関する何かを意味します。また、その説明によれば、イベントは予測可能であり、突然発生するものではありませんが、目覚めのイベントの場合、これは当てはまりません。このイベントは「予期された」ものではなく、自発的なものだからです. たとえば、stm32 データシートを見ると、いわゆるウェイクアップ イベント イネーブル レジスタがあることがわかります。この「イベント」には、実行される特定のコードやソフトウェアに関連するものは含まれません。
1 に答える
イベントは、通常、システムまたはアプリケーション プログラミングで見られる、より高度な抽象化レイヤーの概念です。それらは必ずしもハードウェアに基づいているわけではありませんが、純粋にソフトウェアによってトリガーされる可能性があります。この用語の単一の定義はなく、かなり広いです。
一方、割り込みは常に、最下位レベルでハードウェアによってトリガーされます。さらに別の用語はハードウェア例外です。上位層のコアとマイクロコントローラーは、異常な状態 (無効な命令、ゼロ除算、メモリ アクセス エラーなど) が発生したときに、コアまたは監視ハードウェアによってスローされるものとしてそれらを分離することがよくあります。一方、割り込みソースは、予想されるハードウェアの動作またはエラー状態のいずれかです。
割り込みとハードウェア例外では、割り込みベクタ テーブルと呼ばれることが多いハードウェア ルックアップ テーブルにハンドラ関数を登録する必要があります。割り込みが発生すると、ハードウェアは、呼び出す関数のアドレスを見つけるためにこのテーブルに移動します。このような関数は、割り込みサービス ルーチン(ISR) と呼ばれます。ISR が呼び出される前に特定のレジスタがハードウェアによってスタックされ、ISR が終了したときにレジスタを復元するために特別なリターン命令が使用される、割り込み用の特別な呼び出し規則があります。
ただし、イベントはソフトウェア コールバック関数を使用します。通常、アプリケーションはイベントの作成時に関数ポインターを渡します。これは通常、アプリケーション プログラミングや Rapid Application Development (RAD) ツールで使用される方法です。組み込みシステムでは、アプリケーションがドライバー内で発生する特定の事柄に対して多数のコールバックを登録できるようにすることで、似たようなものを作成し、ドライバーにコールバックを呼び出させることができます。ただし、ドライバーはハードウェア上の最下位レベルのコードですが、それでもソフトウェアであり、ソフトウェアによって設計された呼び出しを実行します。
ただし、「イベント」は非常に広い用語であるため、場合によっては、イベントはより広範な API 関数と一緒に使用できるオブジェクトです。そして、それらは必ずしもコールバック関数を持っているわけではありません - それらは本質的に単なるフラグです。たとえば、Windows OS では、アプリケーション プログラマは実行中のスレッドに何かを通知するイベントを作成できます。その後、スレッドは CPU の有効なスリープ機能を利用して、イベントが受信されるまで待機できます。これは、スレッドを正常に終了させることで、スレッドを適切に停止する通常の方法の 1 つです。
割り込みとイベントに共通しているのは、どちらも効果的ではあるが非決定論的な実行につながるということです。割り込み/イベントが発生していない場合、プログラムは他のことを行うことができ、割り込みの代替であるフラグのポーリングを使用する必要はありません。しかし、起動すると、現在の実行を中止し、別の何かを実行して中断します。また、現在の呼び出しスタックに加えて、スタックに余分な呼び出しをプッシュするため、プログラムが最も深い呼び出しレベルにあるときに発生すると、断続的なスタック オーバーフローなどの非常に微妙なエラーが発生する可能性があります。
割り込みと、場合によってはイベントに関するもう 1 つの問題は、ほとんどの場合、割り込みが個別のスレッドとして機能し、スレッド セーフの問題がすべて発生することです。セマフォまたはアトミック アクセスを保証することにより、競合状態のバグから ISR/コールバックと共有される変数を保護する必要があります。そうしないことは、組み込みシステムでこれまでで最も一般的なエラーだと思います。これも信じられないほど微妙なバグを作成します。