3

これから、シリアルポート構成の例をコピーしました

tcgetattr (serialfd, &tty);

cfsetospeed(&tty,B115200);
cfsetispeed(&tty,B115200);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
tty.c_iflag &= ~IGNBRK;
tty.c_lflag = 0;

tty.c_oflag = 0;
tty.c_cc[VMIN]  = 0;
tty.c_cc[VTIME] = 5;

tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~(PARENB | PARODD);
tty.c_cflag |= 0;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;

私の実際のコードは次のようなものです。

char buf[100];
write(serialfd, "PING", strlen("PING"));
fsync(serialfd);

while (1) 
{
    read(serialfd, buf, sizeof(buf));
    printf("length: %d\n", strlen(buf));
}

この場合、length: 6停止することなく無限に印刷されます。変更tty.c_cc[VMIN] = 1tty.c_cc[VTIME] = 0ても読み取れない場合(ブロックインread()

USBからシリアルへのコンバーターでdebian6.0.5を使用しています。私はこのようにシリアルポートを開きます:

serialfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_SYNC);
4

1 に答える 1

2

あなたのコードを見てください

while (1) 
{
    read(serialfd, buf, sizeof(buf));
    printf("length: %d\n", strlen(buf));
}

このループの前にパケットを書き込んだ後、最初の反復で、バッファに読み込まれる利用可能なデータを読み取ります。memset毎回バッファをゼロにするか、への呼び出しの戻り値で指定された読み取りバイト数を使用してバッファをゼロで終了する必要がありますread。次に、再度読み取るたびに無限にループしますが、読み取るデータがないため、後続の読み取りではそれ以上データはコピーされません。ただし、readの呼び出しによってバッファーは変更されないため、バッファーは反復ごとに同じままであるため、出力は反復ごとに同じままになります。

ブロッキングの側面については、次のガイドを読む必要があります(これは、以前にSOで推奨されており、シリアルポートプログラミングの概要として非常に優れています)。

http://www.easysw.com/~mike/serial/serial.html

このセクションでは、VMINとVTIMEをさまざまな値に設定したときに得られる動作について説明します。特に最後の段落では、表示されるブロッキング動作について説明しています。

VMINは、読み取る最小文字数を指定します。0に設定されている場合、VTIME値は、すべての文字が読み取られるのを待機する時間を指定します。これは、Nバイトの読み取り呼び出しがN文字の入力を待機することを意味するものではないことに注意してください。むしろ、タイムアウトが最初の文字に適用され、読み取り呼び出しはすぐに使用可能な文字数(最大でリクエスト)。

VMINがゼロ以外の場合、VTIMEは最初の文字の読み取りを待機する時間を指定します。指定された時間内に文字が読み取られた場合、すべての読み取りは、すべてのVMIN文字が読み取られるまでブロック(待機)されます。つまり、最初の文字が読み取られると、シリアルインターフェイスドライバは文字のパケット全体(合計VMINバイト)を受信することを期待します。許可された時間内に文字が読み取られない場合、読み取りの呼び出しは0を返します。このメソッドを使用すると、シリアルドライバーに正確にNバイトが必要であり、読み取り呼び出しは0またはNバイトを返します。ただし、タイムアウトは最初の文字読み取りにのみ適用されるため、何らかの理由でドライバーがNバイトパケット内の1文字を見逃した場合、読み取り呼び出しは追加の入力文字を待機するために永久にブロックされる可能性があります。

VTIMEは、着信文字を待機する時間を10分の1秒単位で指定します。VTIMEが0(デフォルト)に設定されている場合、オープンまたはfcntlのポートでNDELAYオプションが設定されていない限り、読み取りは無期限にブロック(待機)されます。

于 2012-07-16T21:51:17.990 に答える