2009-08-27 28 views
1

字符我有一個​​選擇呼叫似乎並不在串行端口上檢測到的字符不返回。有什麼我失蹤?select()調用時端口

如果我刪除上面塊中的read()代碼,select將返回一段時間,直到現有的端口緩衝區被清空,然後再檢測不到任何更多內容。

我正在將字符流式傳輸到端口,並且運行minicom顯示端口上的連續輸入流。

任何人都可以看到什麼毛病此代碼?

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

它返回之前,選擇()修改RFDS以表明其描述符已經準備好用於讀取數據。

對於您的情況,在達到1ms超時後第一次返回並且描述符中沒有可用數據時,它將從rfds集中移除您的描述符,以指示沒有數據可用。然後,當你在循環中再次調用select()時,rfds是一個空集,所以在這之後它甚至不會再費心檢查你的描述符。

在每次選擇循環時,都需要先選擇FD_SET(fd1,& rfds)。

+0

......還是保留單獨的fd_set並memcpy的到你傳遞給選擇臨時FD_SET()。如果您有很多套接字,每次調用FD_SET都很昂貴。在這種情況下,memcpy速度更快。 – 2009-08-27 22:33:02

+0

謝謝你們。我實施了這兩個建議,現在它工作正常。我一直在用115200波特率的高容量輸入流使用這段代碼,它顯然從不超時並且除去了描述符。當我去間歇性的流時,似乎代碼剛剛壞掉了。再次感謝。 – 2009-08-28 14:46:55