2011-02-04 109 views
2

在以下用於嵌入式設備的C程序中,我試圖每當用戶在通過串行電纜連接到我的設備的遠程計算機上顯示一個點(「。」),在她的終端程序中輸入一些字符並點擊ENTER鍵。Linux串行端口I/O問題

我看到的是,一旦檢測到第一個回車符,printf將在無限循環中顯示點。我期待FD_ZERO和FD_CLR「重置」等待條件。

如何?

#include <sys/time.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <stdlib.h> 

main() 
{ 
    int fd1;  /* Input sources 1 and 2 */ 
    fd_set readfs; /* File descriptor set */ 
    int maxfd;  /* Maximum file desciptor used */ 
    int loop=1; /* Loop while TRUE */ 

    /* 
     open_input_source opens a device, sets the port correctly, and 
     returns a file descriptor. 
    */ 
    fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NONBLOCK); 
    if (fd1<0) 
    { 
     exit(0); 
    } 

    maxfd =fd1+1; /* Maximum bit entry (fd) to test. */ 

    /* Loop for input */ 
    while (loop) 
    { 
     FD_SET(fd1, &readfs); /* Set testing for source 1. */ 

     /* Block until input becomes available. */ 
     select(maxfd, &readfs, NULL, NULL, NULL); 

     if (FD_ISSET(fd1, &readfs)) 
     { 
      /* input from source 1 available */ 
      printf("."); 
      FD_CLR(fd1, &readfs); 
      FD_ZERO(&readfs); 
     } 
    } 
} 
+0

你試過看看`select()`的返回值嗎? – 2011-02-04 15:45:12

回答

1

首先,使用適當的函數頭部像int main(void)。其次,FD_SET對於存儲fds有一個上限,換句話說,並不是所有的fds都可以用select進行監控。 (poll沒有這樣的限制。)

第三,也是最後,在你的循環,你只檢查是否存在對FD可用數據,但你從來沒有讀過它。因此,它在下一次迭代中繼續可用。

4

全部FD_CLRFD_ZERO do是重置fd_set,它並沒有清除底層條件。要做到這一點,你需要read()所有的數據,直到沒有任何可用。實際上,如果您只想一次完成一個fd,則最好完全免除select(),只需使用阻止read()即可查看數據何時可用。

請注意,FD_ZEROFD_CLR的功能完全相同,但對於所有的fds。如果你做一個,你不需要另一個。

+1

然後下一個循環迭代再次執行`FD_SET`,撤消`FD_CLR`。 – 2011-02-04 16:01:38