8

私は、イベントベースとポーリングベースの両方の組み込みシステムを作成した経験があります(プリエンプティブOSのない小さなMCUの場合)。

イベントベースのシステムでは、タスクは通常、キューでイベント(メッセージ)を受信し、それらを順番に処理します。

ポーリングベースのシステムでは、タスクは特定の間隔でステータスをポーリングし、変更に応答します。

どのアーキテクチャが好きですか?両方が共存できますか?

更新:ポイントが作成されました

POLL
BASED-タイミングの側面に関連する緊密な結合(@Lundin)
*キューを使用してイベントシステムと共存できます(@ embedded.kyle)
*小規模なプログラムに最適(@Lundin)

イベントベース
+長期的にはより柔軟なシステム(@ embedded.kyle)
-RTOSエディションは複雑さを追加します(@Lundin)
*小さなプログラム=ステートマシン制御(@Lundin)
*キューと「スーパーループ」を使用して実装できます(コントローラー/メイン内)(@ embedded.kyle)
*真の「イベント」のみがhw割り込みイベントです(@Lundin)

関連する質問
*有限状態マシン(@ embedded.kyle) のさまざまなスケジューリングアルゴリズムの比較を探しています

関連情報
*「裸のスレッドの代わりにアクティブオブジェクトを使用することをお勧めします」(@Miro)
http://www.drdobbs.com/parallel/prefer-using-active-objects-instead-of-n/225700095*
「スレッドを正しく使用する=分離+非同期メッセージ」(@Miro) http://www.drdobbs.com/parallel/use-threads-correctly-isolation-asynch/215900465

4

3 に答える 3

5

流行語のスピッターがあなたに伝えようとしていることにもかかわらず、ベアボーンMCUプラットフォームには「イベント駆動型」のようなものは実際にはありません。受け取ることができる真のイベントの種類は、ハードウェア割り込みだけです。

アプリケーションの性質とそのリアルタイム要件に応じて、割り込みが適切な場合と適切でない場合があります。一般に、ポーリングシステムを使用すると、決定論的なリアルタイムを実現する方がはるかに簡単です。ただし、ポーリングのみに依存するシステムは、すべてのタイミングの側面が緊密に結合されるため、保守が非常に困難です。

遅いLCDを起動しようとしたとします。空のループでCPUサイクルを焼き付けている間にタイマーを繰り返しポーリングする代わりに、その間にバスを介してデータを受信することを決定する可能性があります。次に、受信したデータをLCDに印刷します。このような設計により、LCDの起動時間とシリアルバスの間に緊密な結合が作成され、シリアルバスとデータの印刷の間に別の緊密な結合が作成されました。オブジェクト指向の観点からは、これらのことはまったく関係がありません。将来のある時点でシリアルバスを高速化すると、印刷しようとしたときに起動が完了していないため、突然LCD印刷のバグが発生する可能性があります。

小さなプログラムでは、上記の例のようにポーリングを使用することはまったく問題ありません。しかし、プログラムが成長する可能性がある場合、ポーリングはそれを非常に複雑にし、緊密な結合は最終的に多くの奇妙で致命的なバグにつながります。

一方、マルチスレッドとRTOSは非常に多くの複雑さを追加し、それがバグにつながる可能性もあります。線を引く場所を決めるのは簡単ではありません。

個人的な経験から、LOCが20〜30k未満のプログラムは、単純なステートマシンを超えて、スケジューリングやマルチタスクの恩恵を受けることはないと思います。プログラムがそれより大きくなる場合は、マルチタスクRTOSを検討します。

また、ローエンドのMCU(8ビターおよび16ビター)は、OSの実行にはほど遠いです。8ビットまたは16ビットプラットフォームで複雑さを処理するためにOSが必要であることがわかった場合は、最初に間違ったMCUを選択した可能性があります。私は、32ビターよりも小さいものにOSを導入しようとする試みには懐疑的です。

于 2012-09-07T07:47:06.887 に答える
3

実際、イベント駆動型プログラミングとスレッドを組み合わせることができ、結果として得られるパターンは「アクティブオブジェクト」または「アクター」として広く知られています。

アクティブオブジェクト(アクター)は、カプセル化されたイベント駆動型のステートマシンであり、イベントを相互に送信することにより、非同期的に相互に通信します。アクティブオブジェクトは、すべてのイベントを独自の実行スレッドで処理するため(少なくとも概念的には、協調スケジューラが使用されている場合)、設計上、ほとんどの同時実行の危険を回避します。

アクターとアクティブオブジェクトは、汎用コンピューティングで(再び)大流行しています(Erlang、Scala、Akkaを検索できます)。Herb Sutterは、「アクティブオブジェクト」パターンを説明するいくつかの優れた記事を書いています。「裸のスレッドの代わりにアクティブオブジェクトを使用することを好む」(http://www.drdobbs.com/parallel/prefer-using-active-objects-instead -of-n / 225700095)および「スレッドを正しく使用する=分離+非同期メッセージ」(http://www.drdobbs.com/parallel/use-threads-correctly-isolation-asynch/215900465)

これらの記事の最初の部分でハーブが言っていることは次のとおりです。

「生のスレッドを直接使用することは、いくつかの理由で問題になります...アクティブオブジェクトは、プログラムのセマンティックレベルを上げて表現できる高レベルの抽象化とイディオムを提供することにより、スレッドのコードと操作について推論する能力を劇的に向上させます私たちの意図はより直接的です。すべての優れたパターンと同様に、私たちのデザインについて話すためのより良い語彙も得られます。アクティブオブジェクトは目新しいものではないことに注意してください。UMLとさまざまなライブラリがアクティブクラスのサポートを提供しています。」

ですから、これは本当に新しいことではありません。しかし、特に組み込みシステムコミュニティではあまり知られていないのは、アクティブオブジェクトは組み込みシステムに完全に適用できるだけでなく、実際には組み込みに完全に一致し、従来のRTOSよりも軽量であるということです。

私は10年以上にわたってイベント駆動型のアクティブオブジェクトを使用しており、組み込みシステム用のアクティブオブジェクトフレームワークのQPファミリを作成しました(http://www.state-machine.com/を参照)。ポーリングの「スーパーループ」や生のRTOSに戻ることは決してありません。

于 2012-09-17T22:05:01.057 に答える
1

手元のアプリケーションに最も適したアーキテクチャを好みます。

両方とも、マルチレベルのキューアーキテクチャで共存できます。1つのキューは、メインループで実行されているポーリングベースで機能します。もう1つは、優先度の高いイベントを処理する可能性が最も高いものですが、割り込みベースのプリエンプションを使用して機能します。

さまざまなスケジューリングアルゴリズムの詳細な説明と比較については、このSOの質問に対する私の回答を参照してください。

于 2012-09-06T14:33:14.087 に答える