5

私は多くの有用なスレッドといくつかのチュートリアルを研究しましたが、非常に単純であるべき何かについてまだいくつかの問題があります。参考までに、私が熟読したいくつかのスレッドを次に示します。

読み取り関数呼び出しでタイムアウトを実装するには?

Cでシリアルポートを開き、読み書きする方法

いずれにせよ、私には少し問題があります。データを受信すると、コードは正常に動作します。そうしないと、read() 関数が停止し、プログラムから抜け出す唯一の方法は kill -9 を使用することです (注: シグナル処理を使用して、シリアル データを読み取っているスレッドに終了するよう通知します。これはそうではありません。信号処理を削除しても、read() 呼び出しは停止します)。私がやろうとしているのは、一度にチャンクをブロックして読み取る読み取りを行うことです (したがって、CPU 使用率を節約します)。ただし、読み取りがデータを受信しない場合は、タイムアウトしたくありません。

ポートに適用する設定は次のとおりです。

struct termios serial_struct;
serial_struct.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
serial_struct.c_iflag = IGNPAR;
serial_struct.c_oflag = 0;
serial_struct.c_lflag = 0;
serial_struct.c_cc[VTIME] = 1;  // timeout after .1s that isn't working
serial_struct.c_cc[VMIN] = 64;  // want to read a chunk of 64 bytes at a given time

次に、これらの設定を tcsetattr() で設定し、ポートが tcgetattr() を介して設定を受信したことを確認します。読み取りがブロックされているように見え、64 バイトが受信されるまで待機しているように見えるため、設定が競合している可能性があると考えていますが、タイムアウトに関しては何もしません。select() を使用してタイムアウトに対処できることは理解していますが、複数のシステムコールを回避したいと考えています。

いつものように、助けてくれてありがとう。

4

1 に答える 1

7

man 3 termiosから:

最小 > 0; TIME > 0: TIME は、タイマーの制限を 10 分の 1 秒で指定します。入力の最初の 1 バイトが利用可能になると、さらに 1 バイトが受信されるたびにタイマーが再起動されます。read(2) は、要求されたバイト数または MIN バイトの小さい方が読み取られたとき、またはバイト間タイムアウトが期限切れになったときに戻ります。タイマーは最初のバイトが使用可能になった後にのみ開始されるため、少なくとも 1 バイトが読み取られます。

少なくとも 1 バイトのデータが受信されるまで、タイマーは開始しないことに注意してください。その最初のデータ バイトを受信した後、連続するデータ バイトを受信する間に TIME 10 秒のギャップがある場合、読み取りはタイムアウトします。

于 2013-08-06T02:16:05.453 に答える