私の質問は、実際のコーディングの問題よりも教育的なものです。ウェブを検索してみましたが、ほとんど役に立ちませんでした。私はISRの書き方を学び、それらがユーザースレッドとどのように相互作用するかを理解しようとしています。
トリガーされたときに、割り込みソース(UART)から構造体にデータをコピーするISRがある状況を考えてみます。後でこの構造体を読みたいユーザースレッドがあります。私の質問は2つあります。(a)ISRとユーザースレッド間で共通のデータ(構造体など)を共有する方法は何ですか? (b)(上記のように)共有構造体の場合、ISRとユーザースレッド間の同期をどのように実行しますか?
注意:これらのトピックは初めてです。
同期の場合:
ISRでの割り込み処理などの非常に問題とそのようなアクティビティの主な設計上の理由は、コードがないため、いくつかの一般的なロック(ミューテックス、セマフォなど)が解放されるのを待つnotこのリリースを行います。 ISRが実際に来ると、そのアクションに適したコンテキスト(メモリの内容、その他の設定)を取得します。少なくとも、データの状態は一貫しています。これを行う唯一の方法は、他のパーティ(通常のコードとして、ユーザーランドまたはカーネル)がISRが操作するデータ構造を操作する間、ISRの入力を延期することです。これが、すべてのCPUにハードウェア割り込みを有効または無効にする手段がある理由です。この有効化/無効化は、合計(すべてのハードウェア割り込み)または割り込みごと、グループごとにすることができます。これにより、パフォーマンスは向上しますが、主要な原則は変わりません。
したがって、非ISRコードは最初に共通のデータ構造をセットアップし、それぞれの割り込みがまだ表示されない場合(ハードウェアが許可されていないか、CPUがこれを防ぐため)にISRを構成し、終了すると割り込みを有効にします。 ISR以外のコードが共通データを使用して何かを行うと、割り込みを無効にし、共通データを処理して、割り込みを再度有効にします。これが、現在のCPUスタイルで本当に安全な唯一の方法です(他のスタイルのいくつかのエキゾチックな実装は想像できますが、それらは広く普及していません)。
マルチプロセッシングにより、状況はさらに複雑になります。一部のコードが単一のハート(CPU、コア...)の割り込みを無効にしても、他のコードはISRの入力を許可できます。この場合、一般的なデータの追加保護はスピンロックで行われます。あるコードが何らかのハートでスピンロックを取得した場合、別のハートのISRはスピンロックが解放されるのを待って、そのアクティビティを開始できます。スピンロックをすぐに解放します。
多くの実装でこれの詳細があります-たとえば、一部の(ほとんどのUnixライクなシステム、Windowsなど)は、いわゆる「上半分」(真のISR)と「下半分」(上半分以外のアクション)を区別しますが、ユーザープロセスの外部でさらに処理がスケジュールされている); Windowsは下半分のアクションを「据え置きプロシージャー呼び出し」と呼びます。
今後の研究に十分な言葉をいただければ幸いです。 Andrew TanenbaumまたはMorris Bachによるオペレーティングシステムの設計に関する有名な書籍(またはWindowsの同様の書籍、名前はわかりません)、それぞれのオンラインコースなどを参照することをお勧めします。
一般的なデータ構造設計の場合、それは非常に目標固有であり、一般的な目標への準拠を除いて、一般的な推奨事項を指定することはできません。しかし、一種のサイクリックバイトバッファであるUARTを考慮して、.
更新:ユーザースレッドについて言及しました。ほぼすべての実装は、少なくともセキュリティ上の理由により、カーネル内にハードウェアの相互作用を実装する傾向があります。ハードウェアは任意のユーザーの悪意のあるアクションから保護する必要があり、OSも保護する必要があります(ユーザーランドは割り込みを無効にできません)。ただし、XWindowサーバーのような例外はほとんどありません。一般に、カーネルドライバーはユーザーランドとハードウェアの中間を実装し、すべての潜在的な問題はこの中間に分離されます。