2016-11-22 16 views
0

ここで関連するすべての質問を読みましたが、解決策が見つかりませんでした。無限ループ外でSerialReadがうまく動作しない

シリアルポートから1バイトずつ読み取ろうとしています。

  • 私は無限ループで、いくつかのバイトが利用可能であるかどうかをチェックすると、常にうまく動作し、それまでに送信したものを表示します。
  • しかし、私は無限ループの外側をチェックすると、ただ1バイトをキャッチして表示し、シリアルポートを閉じます。ここで

それはそう起こらない理由私は理解していない私のコード

// Checks if 1 data byte is available in the RX buffer at the moment 
int serialHasChar(int fd) 
{ 
    struct pollfd fds; 
    fds.fd = fd; 
    fds.events = (POLLIN | POLLPRI); // POLLIN : There is data to read, POLLPRI: There is urgent data to read 
    if(poll(&fds, 1, 0) > 0) 
    { 
     return 1; 
    } 
    else 
    { 
     return 0; 
    } 
} 

int serialOpen(const char *port, const uint baud) 
    { 
     int fd = -1; 

    fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY); 

    if (fd == -1) 
    { 
     printf("[ERROR] Couldn't open port \"%s\": %s\n", port, strerror(errno)); 
     return -1; 
    } 
    else 
    { 
     printf("Serial port %s successfully opened\n", port); 
    } 

    struct termios options; 
    tcgetattr(fd, &options);  // Get the current attributes of the Serial port 
    options.c_iflag = IGNPAR; 
    options.c_oflag = 0; 
    options.c_lflag = 0; 
    options.c_cflag = B115200 | CS8 | CLOCAL | CREAD; 
    tcflush(fd, TCIFLUSH);   
    tcsetattr(fd, TCSANOW, &options); 

    return fd; 
} 

void serialClose(int fd) 
{ 
    tcflush(fd, TCIOFLUSH); 
    close(fd); 
     printf("Serial port successfully closed\n"); 
} 


// Receive one byte 
uint8_t serialReadChar(int fd) 
{ 
    uint8_t ch; 
    //tcflow(fd, TCOON); 
    read(fd, &ch, 1); 
    //tcflow(fd, TCOOFF); 
    printf("One byte received : 0x%.2x\n", ch); 
    return ch; 
} 

int main() 
{ 
    uint8_t bytes = 0; 
    uint8_t ch = 0; 

    // Open serial port 
    int fd = serialOpen("/dev/ttyAMA0", 115200); 

    // This works 
    while(1) 
    { 
     if (serialHasChar(fd)) { 
    ch = serialReadChar(fd); 
     } 
    } 

    /* This doesn't work 
    while(serialHasChar(fd) == 0); 

    while(serialHasChar(fd)) 
    { 
     ch = serialReadChar(fd); 
     bytes++; 
     //bytes = serialNumOfAvailableBytes(fd); 
    } 
    */ 

    serialClose(fd); 

    return 0; 
} 

です!誰か助けてくれますか? おかげ

UPDATE: 私は

+0

機能の結果をチェックしてみませんか? – Olaf

+0

最新のコンピュータは高速ですが、シリアルポートは遅いです。したがって、1バイトを読み込むと、serialHasChar()は再びfalseになります。 whileループは終了します。 –

+0

@Olaf、ご返信ありがとうございます。私はその機能の結果を読んだ。動作すると、受信したすべてのバイト数が表示されます。そうでない場合は、最初に受信したバイトが表示されます。私はあなたが正しくなることを願っています。 –

答えて

0

上記のコードでserialHasChar()関数では動作しませんコードとして、それは全く同じではない動作するコードの定義を追加しました。

serialHasCharがヌル以外の値を返すとすぐに、serialReadCharを呼び出します。

while(1) 
{ 
    if (serialHasChar(fd)) { 
    ch = serialReadChar(fd); 
    } 
} 

しかしコード(動作しないもの)を、以下にそれは少し違う:それは非NUL値を返すまで、あなたはserialHasCharを呼び出します。しかし、serialReadCharを呼び出すのではなく、serialHasCharをもう一度呼び出すと、動作するスニペットのようになります。

while(serialHasChar(fd) == 0); 

while(serialHasChar(fd)) 
{ 
    ch = serialReadChar(fd); 
} 

あなたはおそらくこれが必要:コードは、単に追加のループなしでは動作しません

while(serialHasChar(fd) == 0); 

while(serialHasChar(fd)) 
{ 
    ch = serialReadChar(fd); 
    bytes++; 
    while(serialHasChar(fd) == 0); 
} 
+0

私はあなたの提案を試みましたが、残念ながらそれは動作しませんでした。 –

0

はこれを試してみてください。

利用可能なすべてのバイトがシリアルインターフェイスから読み込まれると、新しいデータがポートに到着した場合でもループを残し、バイトを再度読み取ることはありません。

ほとんどのシリアルポートはデータを転送することができるよりもはるかに速く読めるので、バッファ内のバイトがすぐに、つまり既に気付いたように最初のバイトの後に実行されます。 次に、次のバイトが利用可能になるまでギャップをブリッジする必要があります。

作業中のソリューションでは、ほとんどの場合serialHasChar(fd)から0が得られますので、serialReadChar(fd)は呼び出さずにループを続行します。

+0

お返事ありがとうございます。それは仕事をしましたが、(1)と同じです。それは決してループから抜け出すことはありません。新しい文字が受信されるまで、すべての繰り返しは終了しないため、while条件をチェックすると常に真となります。 –

+0

シリアルポートでキャラクターが利用できるのを待っている間に、他のことをしたいと思っています。とった。 – user2443447

+0

私の心には2つのことが起こります。 1.マルチスレッド化。一方のスレッドが入力を待機している間に他方のスレッドが処理を行います。 2.非同期入出力とポーリング。どちらも複雑なロジックが必要です。 – user2443447

0

while(serialHasChar(fd) == 0); 

do 
{ 
    ch = serialReadChar(fd); 
} while(serialHasChar(fd)); 
+0

ご返信ありがとうございます。なぜそれがこのように起こったのか、私は明確に説明しました。しかし、追加のループを追加する必要があり、プログラムをブロックしたくない場合(これはリアルタイムプログラムの一種なので)、どうすれば実現できますか? –

+0

* "私はプログラムをブロックしたくない(リアルタイムプログラムの一種なので)" * - 偽の推論。 ** read()**はシステムバッファからのみデータをコピーします。 CPUサイクルを浪費してデータ用のシステムバッファをポーリングすると、プロセスのタイムスライスが実際に消費されるため、プログラムの実行が遅くなります。 – sawdust

関連する問題