http://qs1969.pair.com?node_id=88966
Category: Miscellaneous
Author/Contact Info bikeNomad, Ned Konz, ned@bike-nomad.com, http://bike-nomad.com/perl
Description: This module makes it possible to use Perl programs that were written to use Win32::SerialPort or Device::SerialPort on the other kind of operating system without changing the source text. Just include the module and run your existing code:
perl -MAnySerialPort mySerialProgram.pl

It aliases the symbol table and provides a translating constructor.

Save it as AnySerialPort.pm somewhere on your Perl @INC path.

# Lets serial port programs written for either Windows or Unix
# work on the other kind of system without modification.
# By Ned Konz, ned@bike-nomad.com, http://bike-nomad.com
# This script must have only LF line endings to work cross-platform.
# usage:
#  perl -MAnySerialPort myProgram.pl
#
# This will map port names between Linux and Windows; if your system d
+oesn't
# use the same mappings, you can call
# Device::SerialPort::mapPorts
# or
# Win32::SerialPort::mapPorts
# to change it:
# Device::SerialPort->mapPorts('COM1:' => '/dev/magicSerial0',
#         'COM2' => '/dev/magicSerial1');
use strict;
package AnySerialPort;
use vars '@ISA';

BEGIN
{
 my %portMap;
 my $oldNew;
 my $onWindows = 0;

 if ($^O eq 'MSWin32') # running on Win32
 {
  $onWindows = 1;
  eval "use Win32::SerialPort";
  *main::Device::SerialPort:: = *main::Win32::SerialPort::;
  $oldNew = \&Win32::SerialPort::new;
  $INC{'Device/SerialPort.pm'} = $INC{'Win32/SerialPort.pm'};
  %portMap = ('/dev/ttyS0' => 'COM1:',
     '/dev/ttyS1' => 'COM2:',
     '/dev/ttyS2' => 'COM3:',
     '/dev/ttyS3' => 'COM4:',
    );
 }
 else # running on Unix
 {
  eval "use Device::SerialPort";
  *main::Win32::SerialPort:: = *main::Device::SerialPort::;
  $oldNew = \&Device::SerialPort::new;
  $INC{'Win32/SerialPort.pm'} = $INC{'Device/SerialPort.pm'};
  %portMap = ('COM1:'=> '/dev/ttyS0',
     'COM2:'=> '/dev/ttyS1',
     'COM3:'=> '/dev/ttyS2',
     'COM4:'=> '/dev/ttyS3',
    );
 }

 die "$@\n" if $@;
 @ISA = 'Device::SerialPort';

 # Hook the constructor so we can map the port names
 # and class if needed
 *main::Device::SerialPort::new = sub {
  my $class = shift;
  my $portName = shift;
  if ($onWindows != ($class eq 'Win32::SerialPort'))
  {
   $portName = $portMap{$portName} || $portName;
   $class = $onWindows ? 'Win32::SerialPort' : 'Device::SerialPort';
  }
  $oldNew->($class, $portName, @_);
 };

 # Gets and/or modifies the port mapping
 # Returns a hash
 sub Device::SerialPort::mapPorts
 {
  my $self = shift;
  %portMap = (%portMap, @_);
 }
}

1;
Replies are listed 'Best First'.
Re: Platform-independent Serial Port code
by Anonymous Monk on Jan 22, 2016 at 10:04 UTC
    Hello bikeNomad,

    we would like to use this in our (Perl-licensed) application but would like to be sure that your code has the same license since you did not state anything above or your home node...

    KR

      bikeNomad hasn't been in these hallowed halls in the last decade and is therefore unlikely to see your message. His contact info is on the home node and his website (and at the top of this thread too). HTH.

        Thank you. I am fully aware of that and have prodded him by mail as well but think it should be discussed in public :)

      If you're open to using modules from CPAN, you can check out Control::CLI. For serial port connections, it will use "Win32::SerialPort or Device::SerialPort for Serial port access respectively on Windows and Unix systems". That let's you write one code that can be used on either platform. And the module's author does include license and copyright information in the documentation.

      And there's a chance that you might get better support (like bug fixes) by using the CPAN module than using bikeNomad's code posted on this site.

      Just tossing out an alternative for you to consider.

      Ned just replied by Email, stating
      As far as I am concerned, the code is in the public domain. Enjoy! Hope this helps.
      so this case is closed. Thanks to dasgar for suggesting using Control::CLI that I was not aware of.