我编写了一个从串口读取数据的Perl脚本。
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
应该是什么样的?
答案 0 :(得分:1)
由于您有文件句柄,因此可以使用select
。
select
将获取任意数量的文件描述符并等待其中一个变为“就绪”,其中ready由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 ); }