実装したい USB プロトコルがありますが、それを行う最善の方法について少し迷っています。
USB プロトコルでは、次のようにデータと肯定応答パケットをやり取りします。
Device: data
Host: ACK
Host: reply
Device: ACK
ただし、次のようにパケットが非同期に着信する場合があります。
Device: data #1
Device: data #2
Host: ACK #1
...
USB のすべての詳細を抽象化し、プログラムが実際のデータを処理するだけで、パケット ヘッダーやパケットの確認などを気にする必要がない API が必要です。理想的にはwrite_to_device
、デバイスがパケットを確認するまでブロックする機能read_from_device
、パケットが受信されるまでブロックするis_data_available
機能、およびキューにデータがあるかどうかをすぐに返す機能が存在します。
USB イベントを処理する別のスレッドを実行することを考えています。このスレッドは、すべてのデータのカプセル化と確認応答を処理します。
パケットが着信すると、処理スレッドは ACK パケットを送信し、生データを抽出してパイプに書き込みます。関数(read_from_device
メイン スレッドから呼び出される) は、このパイプから単純に読み取り、データが存在するまで自然にブロックします。しかし、このスキームを使用すると、is_data_available
関数を実装するクリーンな方法が得られなくなります。パイプにデータがあるかどうかを読み取らずに確認する方法はありません。
このようなもの:
[ Main thread ][ Processing thread ]
| Read from pipe || |
| || USB packet comes in |
| || Send ACK packet |
| || Extract data |
| || Write data to pipe |
| Read succeeds || |
| Return data || |
本当の問題はwrite_to_device
関数を実装することです。
[ Main thread ][ Processing thread ]
| Somehow signal write || |
| Wait for write to complete || |
| || Send the data |
| || Wait for ACK packet |
| || Somehow signal that write completed
| Return || |
パケットを送信し、確認パケットを待ってから戻る方法をきれいに実装するにはどうすればよいですか?