serial.pl 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Device::SerialPort;
  5. use Time::HiRes qw(gettimeofday);
  6. sub pp($$);
  7. if(@ARGV != 4) {
  8. printf("Usage: perl serial.pl serial-device baudrate outfile initial-hex-msg\n");
  9. exit(1);
  10. }
  11. my $ser = $ARGV[0];
  12. my $baud = $ARGV[1];
  13. my $fil = $ARGV[2];
  14. my $hm = $ARGV[3];
  15. my $fd;
  16. open($fd, ">$fil") || die("Can't open $fil for writing\n");
  17. select $fd;
  18. $| = 1;
  19. my $serport = new Device::SerialPort ($ser);
  20. die "Can't open $ser: $!\n" if(!$serport);
  21. $serport->reset_error();
  22. $serport->baudrate($baud);
  23. $serport->databits(8);
  24. $serport->parity('none');
  25. $serport->stopbits(1);
  26. $serport->handshake('none');
  27. my $interval = 2.0; # Seconds
  28. my $nto = gettimeofday();
  29. my $nfound;
  30. $hm=~ s/ //g;
  31. $hm = pack('H*', $hm);
  32. while (1) {
  33. my ($rout, $rin) = ('', '');
  34. vec($rin, 0, 1) = 1; # stdin
  35. vec($rin, $serport->FILENO, 1) = 1;
  36. my $to = $nto - gettimeofday();
  37. if($to > 0) {
  38. $nfound = select($rout=$rin, undef, undef, $to);
  39. die("Select error $nfound / $!\n") if($nfound < 0);
  40. }
  41. if($to <= 0 || $nfound == 0) { # Timeout
  42. $serport->write($hm);
  43. pp("S>", $hm);
  44. $nto = gettimeofday() + $interval;
  45. }
  46. if(vec($rout, 0, 1)) {
  47. my $buf = <STDIN>;
  48. die "EOF on STDIN\n" if(!defined($buf) || length($buf) == 0);
  49. $buf=~ s/[ \r\n]//g;
  50. $buf = pack('H*', $buf);
  51. $serport->write($buf);
  52. pp("X>", $buf);
  53. }
  54. if(vec($rout, $serport->FILENO, 1)) {
  55. my $buf = $serport->input();
  56. die "EOF on $ser\n" if(!defined($buf) || length($buf) == 0);
  57. pp("S<", $buf);
  58. }
  59. }
  60. sub
  61. pp($$) {
  62. my ($prompt, $txt) = @_;
  63. my ($s, $ms) = gettimeofday();
  64. my @t = localtime($s);
  65. my $tim = sprintf("%02d:%02d:%02d.%03d", $t[2],$t[1],$t[0], $ms/1000);
  66. for(my $i = 0; $i < length($txt); $i += 16) {
  67. my $a = substr($txt, $i, 16);
  68. my $h = unpack("H*", $a);
  69. $a =~ s/[\r\n]/./g;
  70. $a =~ s/\P{IsPrint}/\./g;
  71. $h =~ s/(....)/$1 /g;
  72. printf $fd "%s %s %04d %-40s %s\n", $prompt, $tim, $i, $h, $a;
  73. }
  74. print $fd "\n";
  75. }