简体   繁体   中英

Test in Perl if data is available on Device::SerialPort

I have written a Perl script that reads data from the serial port.

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

The main loop tries to read data from the serial port:

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

But rather than having a $PortObj->read time out (which consumes a lot of time), I want to be able to test if data is available in the buffer, so I can speed up the loop:

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

Can I test the serial buffer for data availability?

EDIT1: I've been spending this morning rewriting the problem to use serial device as a file handle and reading data works, but it is still blocking the loop. This might open up new options to check for data available in the buffer. In pseudo-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;
}

So my question is: What should test_serial_data_available look like?

Since you have a filehandle, you can use select .

select will take an arbitrary number of file descriptors and wait until one of them becomes "ready", where ready is defined by which of the 3 sets select gets contains the filehandle. See perldoc -f select for details.

select accepts a timeout, so if you give it a timeout of 0, it becomes a polling function. So this function will do what you need:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM