如果Device :: SerialPort上有数据,则在Perl中测试

时间:2012-04-28 09:23:48

标签: linux perl serial-port device

我编写了一个从串口读取数据的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应该是什么样的?

1 个答案:

答案 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 ); }