2012-04-28 39 views
2

我已經編寫了一個從串口讀取數據的Perl腳本。如果數據在設備上可用,用Perl進行測試:: SerialPort

use Device::SerialPort; 
$PortObj = new Device::SerialPort ($PortName, $quiet, $lockfile); 
$PortObj->read_const_time(500); # timeout waiting for data after 500ms 
... 

主循環嘗試從串口讀取數據:

while (1) { 
    ($count, $data) = $PortObj->read($frameLength); 
    process_my_data($data); 
    do_something_entirely_different_that_needs_being_done; 
} 

但不具有一個$ PortObj->讀超時(這會消耗大量的時間),我想能夠測試數據是否在緩衝器中可用,這樣我就可以加快循環:

while (1) { 
    if (test_serial_data_available) { ($count, $data) = $PortObj->read($frameLength); } 
    do_something_entirely_different_that_needs_being_done; 
} 

我可以測試數據可用性串行緩衝器?

EDIT1:我已經早上花重寫問題使用串行設備的文件句柄和讀取數據的作品,但它仍然是堵塞循環。這可能會打開新的選項來檢查緩衝區中可用的數據。 在僞的Perl:

use Symbol qw(gensym); 
my $handle = gensym(); 
my $PortObj = tie(*$handle, "Device::SerialPort", $PortName); 

while (1) { 
    my $frameData; 
    if (test_serial_data_available) { my $readLength = read($handle , $frameData , $frameLength); } 
    do_something_entirely_different_that_needs_being_done; 
} 

所以我的問題是:我應該test_serial_data_available是什麼樣子?

回答

1

既然你有一個文件句柄,你可以使用select

select將採取任意數量的文件描述符並等待,直到其中一個變爲「準備就緒」,其中就緒由3組select中的哪一組定義,其中包含文件句柄。有關詳細信息,請參見perldoc -f select

select接受超時,所以如果你給它一個超時值0,它就成爲一個輪詢函數。所以這個功能會做你需要的:

sub poll { 
    my ($fh) = @_; 
    my $in = ''; 
    vec($in,fileno($fh),1) = 1; 
    return select($in,undef,undef,0); 
} 

# ... 

if (poll($handle)) { my $readLength = read($handle , $frameData , $frameLength); } 
+0

:o)Thnx!在這個問題上我一直在苦苦掙扎。 – jippie 2012-04-28 12:56:32

相關問題