2

シリアル ポートからデータを読み取る 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->read タイムアウトを発生させるのではなく、バッファ内のデータが使用可能かどうかをテストできるようにして、ループを高速化できるようにしたいと考えています。

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ように見えるべきですか?

4

1 に答える 1

1

ファイルハンドルがあるので、使用できますselect

selectは、任意の数のファイル記述子を取り、そのうちの 1 つが「準備完了」になるまで待機します。準備完了は、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 ); }
于 2012-04-28T12:29:20.710 に答える