2009-08-27 9 views
1

シリアルポートの文字を検出しないような選択呼び出しがあります。私が行方不明のものはありますか?ポート上の文字が選択されたときにselect()コールが返されない

上記のブロックにあるread()コードを削除すると、既存のポートバッファーが空になり、それ以上のものが検出されなくなるまで、selectがしばらく戻ります。

私はポートに文字をストリーミングしています。実行中のミニコムは、ポート上で連続入力ストリームを示しています。

誰でもこのコードで何か問題が見えることはありますか?

int main(void) 

{ 


    int ret; 
    char buf[1280]; 
    fd_set   m_Inputs; // fd_set for the select call for com input 

    int   m_maxFD; // max FD for select() call. 

    struct timeval tv; 



    int fd1; 
    fd1 = open("/dev/ttyXR6", O_RDWR | O_NOCTTY | O_NONBLOCK); 

    fcntl(fd1, F_SETFL, 0); 

    struct termios options; 

    tcgetattr(fd1, &options); // Get the current options for the port... 

    // Set the baud rates... 
    cfsetispeed(&options, B9600); 
    cfsetospeed(&options, B9600); 

    // Enable the receiver and set local mode... 
    options.c_cflag |= (CLOCAL | CREAD | CS8); 
    options.c_cflag &= ~PARENB; // ignore parity 
    options.c_cflag &= ~CSTOPB; // 1 stop bit (2 if set) 
    options.c_cflag &= ~CSIZE; // clear the size bits 
    options.c_cflag &= ~CRTSCTS; //No hard flow control 
    options.c_cflag &= ~HUPCL; //Hang Up on last Close 
    options.c_cflag |= CS8;  // reset the size to 8 bits/char 
    options.c_cc[VMIN]=1; 
    options.c_cc[VTIME] = 1; 
    options.c_oflag = 0; 
    options.c_lflag = 0;  //ICANON; 
    // Set the new options for the port... 
    tcsetattr(fd1, TCSANOW, &options); 

    // test to make sure the characters are coming in on the port 

    for (short i =0; i < 60; i++) 
    { 
    ret = read(fd1, buf, 32); 
    buf[ret] = '\0'; 
    cout << buf; 
    usleep(500); 
    } 

    fd_set   rfds; // fd_set for the select call for com input 

    FD_ZERO(&rfds); 

    FD_SET(fd1, &rfds); 


    cout << endl << "FD1 = " << fd1 << endl; 

    while (1) 
    { 
    tv.tv_sec = 0; 

    tv.tv_usec = 1000; 

    ret = select(fd1 + 1, &rfds, NULL, NULL, &tv); 


    if (ret > 0) 

    { 
     ret = read(fd1, buf, 127); 
     buf[ret] = '\0'; 
     cout << buf; 
    } 
    usleep(500); 
    } 

    return 0; 

} 

答えて

7

select()は、rfdsを変更して、どのディスクリプタにデータの準備ができているかを示します。

あなたのケースでは、1msのタイムアウトに達し、ディスクリプタでデータが利用できなくなったときに最初に戻ってくると、データセットが使用できないことを示すためにrfdsセットからディスクリプタが削除されます。次に、ループの次回にselect()を呼び出すと、rfdsは空のセットになります。そのあとでも、あなたの記述子をもうチェックする必要はありません。

ループを通過するたびに選択する前に、FD_SET(fd1、& rfds)を呼び出す必要があります。

+0

...別のfd_setとmemcpyを、一時的なfd_setに格納しておき、select()に渡します。あなたがたくさんのソケットを持っているならば、毎回FD_SETを呼び出すことは費用がかかります。このような場合、memcpyは高速です。 –

+0

ありがとうございます。私は両方の提案を実装し、今は正常に動作します。私はこのコードを115200ボーの大容量入力ストリームで使用していましたが、明らかにタイムアウトしてディスクリプタを削除したことはありません。断続的なストリームに行ったとき、コードが破損したように見えました。再度、感謝します。 –

関連する問題