Linux (Ubuntu 12.04) でシリアル ポートを読み書きしようとしています。このポートでは、特定のタスクが完了するたびに、相手側のマイクロコントローラーが 1 または 3 バイトを爆破します。デバイスへの読み取りと書き込みは正常に実行できますが、問題は、現在、読み取りが少し「危険」であることです。
do
{
nbytes = read(fd, buffer, sizeof(buffer));
usleep(50000);
} while(nbytes == -1);
つまり、デバイスが何を送信しているかを簡単に監視するために、バッファを 0.5 秒ごとにポーリングします。空の場合は、このループでアイドル状態になります。何かまたはエラーを受け取ると、キックアウトします。次に、一部のロジックが 1 つまたは 3 つのパケットを処理し、それを端末に出力します。通常、0.5 秒は、何かがバッファーに完全に表示されるのに十分な長さのウィンドウですが、最終的にそれを見る人間が遅いとは思わないほど速いです。
「いつも」がキーワードです。途中でバッファを読み取った場合、3バイトを爆破します。私は悪い読み取りを取得します。バッファには 1 バイトまたは 2 バイトが含まれ、パケット処理で拒否されます (3 バイト パケットの最初のパケットをキャッチすると、意図的に送信された 1 バイト値にはなりません)。
私が検討/試した解決策:
一度に 1 バイトずつ読み込み、3 バイト送信の一部である場合は追加のバイトを供給することを考えました。ただし、これにより、できれば回避したいいくつかの醜いループが作成されます (read() は、直前の読み取りのバイト数のみを返すため)。
自分のバッファーにロードする前に、現在バッファーにあるバイト数を確認するために、0 バイトを読み取ろうとしました (例: nbytes = read(fd, buffer, 0);)。 0 を返します。
自分のバッファにロードする前にポートバッファの内容を覗くことができれば、私の問題の多くは簡単に解決できるようです。しかし、 read() は、読み取るように指示したバイト数まで破壊的です。
送信を受信している途中ではなく、ユーザーに遅く見えないように十分に高速に、このバッファから読み取るにはどうすればよいですか? 私のシリアル メッセンジャーは送信側スレッドと受信側スレッドに分かれているため、プログラム ループがどこかでブロックされ、残りの半分が無視されることを心配する必要はありません。
助けてくれてありがとう。