2012-07-16 92 views
3

接收來自this我複製的例如用於串行端口配置:無限循環從串口

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()中阻止)

我使用debian 6.0.5與usb串行轉換器。我打開串口是這樣的:

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

read()不產生nul結尾的緩衝區。使用返回值。 – wildplasser 2012-07-16 22:23:12

回答

2

看看你的代碼

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

你已經寫之前,這個循環中,然後在第一次迭代你讀它被讀入現有的數據包的緩衝。您需要或者memset您的緩衝區每次零或零終止您的緩衝區使用讀取字節計數給您的read調用的返回值中給出。然後,你循環無限次,每次再次讀取 - 但隨後的讀取將不會複製更多的數據,因爲沒有可讀的數據。但是,由於讀取的調用,緩衝區保持不變,因此每次迭代時打印的輸出都保持不變,因爲緩衝區在每次迭代中保持不變。

至於阻塞方面,你應該閱讀下面的指南(已建議在此之前,是作爲介紹串口編程非常好)

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

本節中描述的行爲將VMIN和VTIME設置爲各種值時會得到。特別是最後一段解釋你看到的阻塞行爲。

VMIN指定要讀取的最小字符數。如果將 設置爲0,則VTIME值指定等待每讀取一個 字符的時間。請注意,這並不意味着N 字節的讀取呼叫將等待N個字符進入。相反,超時將對第一個字符應用 ,讀取呼叫將返回可立即使用的字符的數字 (最多你請求的號碼)。

如果VMIN不爲零,VTIME指定等待讀取第一個字符的時間。如果在給定的時間內讀取了一個字符,則任何讀取 都會阻塞(等待),直到讀取所有VMIN字符。也就是說,一旦 第一個字符被讀取,串行接口驅動程序期望 接收一個完整的字符包(VMIN字節總數)。如果在允許的時間內沒有讀取 字符,則讀取 的呼叫返回0.此方法允許您告訴串行驅動程序您需要的確實是N個字節,任何讀取調用將返回0或N個字節。但是, 超時只適用於讀取第一個字符,所以如果對於某些 原因驅動程序錯過了N字節數據包中的一個字符,則 讀取調用可能永遠阻止等待附加輸入 個字符。

VTIME指定在十分之一秒內等待傳入字符的時間量。如果VTIME設置爲0(默認值),則讀取將 無限期地阻塞(等待),除非在端口 上使用open或fcntl設置NDELAY選項。