The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Device::SerialPort - Linux/POSIX emulation of Win32::SerialPort functions.

SYNOPSIS

use Device::SerialPort;

Constructors

     # $quiet and $lockfile are optional
$PortObj = new Device::SerialPort ($PortName, $quiet, $lockfile)
     || die "Can't open $PortName: $!\n";

     # not implemented yet
$PortObj = start Device::SerialPort ($Configuration_File_Name)
     || die "Can't start $Configuration_File_Name: $!\n";

     # $Configuration_File_Name not implemented yet
     # if you use this, expect future changes
$PortObj = tie (*FH, 'Device::SerialPort', $PortName)
     || die "Can't tie using $PortName: $!\n";

Configuration Utility Methods

$PortObj->alias("MODEM1");

     # before using start, restart, or tie
     # not implemented yet
$PortObj->save($Configuration_File_Name)
     || warn "Can't save $Configuration_File_Name: $!\n";

     # currently optional after new, POSIX version expected to succeed
$PortObj->write_settings;

     # rereads file to either return open port to a known state
     # or switch to a different configuration on the same port
     # not implemented yet
$PortObj->restart($Configuration_File_Name)
     || warn "Can't reread $Configuration_File_Name: $^E\n";

Device::SerialPort->set_test_mode_active(1);	# test suite use only

    # exported by :PARAM
nocarp || carp "Something fishy";
$a = SHORTsize;			# 0xffff
$a = LONGsize;			# 0xffffffff
$answer = yes_true("choice");		# 1 or 0
OS_Error unless ($API_Call_OK);	# prints error

Configuration Parameter Methods

   # most methods can be called two ways:
$PortObj->handshake("xoff");           # set parameter
$flowcontrol = $PortObj->handshake;    # current value (scalar)

   # The only "list context" method calls from Win32::SerialPort
   # currently supported are those for baudrate, parity, databits,
   # stopbits, and handshake (which only accept specific input values).
@handshake_opts = $PortObj->handshake; # permitted choices (list)

   # similar
$PortObj->baudrate(9600);
$PortObj->parity("odd");
$PortObj->databits(8);
$PortObj->stopbits(1);	# POSIX does not support 1.5 stopbits

   # these are essentially dummies in POSIX implementation
   # the calls exist to support compatibility
$PortObj->buffers(4096, 4096);	# returns (4096, 4096)
@max_values = $PortObj->buffer_max;	# returns (4096, 4096)
$PortObj->reset_error;		# returns 0

   # true/false parameters (return scalar context only)
   # parameters exist, but message processing not yet fully implemented
$PortObj->user_msg(ON);	# built-in instead of warn/die above
$PortObj->error_msg(ON);	# translate error bitmasks and carp

$PortObj->parity_enable(F);	# faults during input
$PortObj->debug(0);

   # true/false capabilities (read only)
   # most are just constants in the POSIX case
$PortObj->can_baud;			# 1
$PortObj->can_databits;		# 1
$PortObj->can_stopbits;		# 1
$PortObj->can_dtrdsr;			# 0 currently
$PortObj->can_handshake;		# 1
$PortObj->can_parity_check;		# 1
$PortObj->can_parity_config;		# 1
$PortObj->can_parity_enable;		# 1
$PortObj->can_rlsd;    		# 0 currently
$PortObj->can_16bitmode;		# 0 Win32-specific
$PortObj->is_rs232;			# 1
$PortObj->is_modem;			# 0 Win32-specific
$PortObj->can_rtscts;			# 1
$PortObj->can_xonxoff;		# 1
$PortObj->can_xon_char;		# 0 use stty
$PortObj->can_spec_char;		# 0 use stty
$PortObj->can_interval_timeout;	# 1 currently
$PortObj->can_total_timeout;		# 0 currently
$PortObj->can_ioctl;			# automatically detected by eval

Operating Methods

  ($count_in, $string_in) = $PortObj->read($InBytes);
  warn "read unsuccessful\n" unless ($count_in == $InBytes);

  $count_out = $PortObj->write($output_string);
  warn "write failed\n"		unless ($count_out);
  warn "write incomplete\n"	if ( $count_out != length($output_string) );

  if ($string_in = $PortObj->input) { PortObj->write($string_in); }
     # simple echo with no control character processing

  $PortObj->write_drain;  # POSIX replacement for Win32 write_done(1)
  $PortObj->purge_all;
  $PortObj->purge_rx;
  $PortObj->purge_tx;

      # controlling outputs from the port
  $PortObj->dtr_active(T);		# sends outputs direct to hardware
  $PortObj->rts_active(Yes);		# return status of ioctl call
					# return undef on failure

  $PortObj->pulse_break_on($milliseconds); # off version is implausible
  $PortObj->pulse_rts_on($milliseconds);
  $PortObj->pulse_rts_off($milliseconds);
  $PortObj->pulse_dtr_on($milliseconds);
  $PortObj->pulse_dtr_off($milliseconds);
      # sets_bit, delays, resets_bit, delays
      # returns undef if unsuccessful or ioctls not implemented

  $PortObj->read_const_time(100);	# const time for read (milliseconds)
  $PortObj->read_char_time(5);		# avg time between read char

Methods used with Tied FileHandles

    # will eventually tie with $Configuration_File_Name
$PortObj = tie (*FH, 'Device::SerialPort', $Portname)
     || die "Can't tie: $!\n";             ## TIEHANDLE ##

print FH "text";                           ## PRINT     ##
$char = getc FH;                           ## GETC      ##
syswrite FH, $out, length($out), 0;        ## WRITE     ##
## $line = <FH>;                           ## READLINE  ## not yet supported
## @lines = <FH>;                          ## READLINE  ## not yet supported
printf FH "received: %s", $line;           ## PRINTF    ##
read (FH, $in, 5, 0) or die "$^E";         ## READ      ##
sysread (FH, $in, 5, 0) or die "$^E";      ## READ      ##
close FH || warn "close failed";           ## CLOSE     ##
undef $PortObj;
untie *FH;                                 ## DESTROY   ##

## $PortObj->linesize(10);		# with READLINE not yet supported
## $PortObj->lastline("_GOT_ME_");	# with READLINE, list only

Destructors

$PortObj->close || warn "close failed";
    # release port to OS - needed to reopen
    # close will not usually DESTROY the object
    # also called as: close FH || warn "close failed";

undef $PortObj;
    # preferred unless reopen expected since it triggers DESTROY
    # calls $PortObj->close but does not confirm success
    # MUST precede untie - do all three IN THIS SEQUENCE before re-tie.

untie *FH;

Methods for I/O Processing (not yet implemented)

$PortObj->are_match("text", "\n");	# possible end strings
$PortObj->lookclear;			# empty buffers
$PortObj->write("Feed Me:");		# initial prompt
$PortObj->is_prompt("More Food:");	# new prompt after "kill" char

my $gotit = "";
until ("" ne $gotit) {
    $gotit = $PortObj->lookfor;	# poll until data ready
    die "Aborted without match\n" unless (defined $gotit);
    sleep 1;				# polling sample time
}

printf "gotit = %s\n", $gotit;		# input BEFORE the match
my ($match, $after, $pattern, $instead) = $PortObj->lastlook;
    # input that MATCHED, input AFTER the match, PATTERN that matched
    # input received INSTEAD when timeout without match
printf "lastlook-match = %s  -after = %s  -pattern = %s\n",
                         $match,      $after,        $pattern;

$gotit = $PortObj->lookfor($count);	# block until $count chars received

$PortObj->are_match("-re", "pattern", "text");
    # possible match strings: "pattern" is a regular expression,
    #                         "text" is a literal string

DESCRIPTION

This module provides an object-based user interface essentially identical to the one provided by the Win32::SerialPort module.

Initialization

The primary constructor is new with a PortName specified. This will open the port and create the object. The port is not yet ready for read/write access. First, the desired parameter settings must be established. Since these are tuning constants for an underlying hardware driver in the Operating System, they are all checked for validity by the methods that set them. The write_settings method updates the port (and will return True under POSIX). Ports are opened for binary transfers. A separate binmode is not needed.

$PortObj = new Device::SerialPort ($PortName, $quiet, $lockfile)
     || die "Can't open $PortName: $!\n";

There are two optional parameters for new. Failure to open a port prints an error message to STDOUT by default. Since other applications can use the port, one source of failure is "port in use". There was originally no way to check this without getting a "fail message". Setting $quiet disables this built-in message. It also returns 0 instead of undef if the port is unavailable (still FALSE, used for testing this condition - other faults may still return undef). Use of $quiet only applies to new.

The $lockfile parameter has a related purpose. It will attempt to create a file (containing just the current process id) at the location specified. This file will be automatically deleted when the $PortObj is no longer used (by DESTROY). You would usually request $lockfile with $quiet true to disable messages while attempting to obtain exclusive ownership of the port via the lock. Lockfiles are VERY preliminary in Version 0.05. I know of intermittent timing problems with uugetty when attempting to use a port also used for logins.

The second constructor, start is intended to simplify scripts which need a constant setup. It executes all the steps from new to write_settings based on a previously saved configuration. This constructor will return undef on a bad configuration file or failure of a validity check. The returned object is ready for access.

     # NOT yet implemented
$PortObj2 = start Win32::SerialPort ($Configuration_File_Name)
     || die;

The third constructor, tie, will combine the start with Perl's support for tied FileHandles (see perltie). Device::SerialPort will implement the complete set of methods: TIEHANDLE, PRINT, PRINTF, WRITE, READ, GETC, READLINE, CLOSE, and DESTROY. Tied FileHandle support is new with Version 0.04 and the READ and READLINE methods are not yet supported. The implementation attempts to mimic STDIN/STDOUT behaviour as closely as possible. Currently, the port name is used in place of a $Configuration_File_Name.

$PortObj2 = tie (*FH, 'Device::SerialPort', $PortName)
     || die;

The tied FileHandle methods may be combined with the Device::SerialPort methods for read, input, and write as well as other methods. The typical restrictions against mixing print with syswrite do not apply. Since both (tied) read and sysread call the same $ob->READ method, and since a separate $ob->read method has existed for some time in Device::SerialPort, you should always use sysread with the tied interface (when it is implemented).

    Certain parameters SHOULD be set before executing write_settings. Others will attempt to deduce defaults from the hardware or from other parameters. The Required parameters are:

    baudrate

    Any legal value.

    parity

    One of the following: "none", "odd", "even". If you select anything except "none", you will need to set parity_enable.

    databits

    An integer from 5 to 8.

    stopbits

    Legal values are 1 and 2.

    handshake

    One of the following: "none", "rts", "xoff".

Some individual parameters (eg. baudrate) can be changed after the initialization is completed. These will be validated and will update the port as required.

$PortObj = new Device::SerialPort ($PortName) || die "Can't open $PortName: $!\n";

$PortObj->user_msg(ON);
$PortObj->databits(8);
$PortObj->baudrate(9600);
$PortObj->parity("none");
$PortObj->stopbits(1);
$PortObj->handshake("rts")

$PortObj->write_settings;

$PortObj->baudrate(300);

$PortObj->close;

undef $PortObj;  # closes port AND frees memory in perl

Use alias to convert the name used by "built-in" messages.

$PortObj->alias("FIDO");

Version 0.04 adds pulse methods for the RTS, BREAK, and DTR bits. The pulse methods assume the bit is in the opposite state when the method is called. They set the requested state, delay the specified number of milliseconds, set the opposite state, and again delay the specified time. These methods are designed to support devices, such as the X10 "FireCracker" control and some modems, which require pulses on these lines to signal specific events or data. Timing for the active part of pulse_break_on is handled by POSIX::tcsendbreak(0), which sends a 250-500 millisecond BREAK pulse.

$PortObj->pulse_break_on($milliseconds);
$PortObj->pulse_rts_on($milliseconds);
$PortObj->pulse_rts_off($milliseconds);
$PortObj->pulse_dtr_on($milliseconds);
$PortObj->pulse_dtr_off($milliseconds);

In Version 0.05, these calls and the rts_active and dtr_active calls verify the parameters and any required ioctl constants, and return undef unless the call succeeds. You can use the can_ioctl method to see if the required constants are available. On Version 0.04, the module would not load unless asm/termios.ph was found at startup.

Configuration and Capability Methods

The Win32 Serial Comm API provides extensive information concerning the capabilities and options available for a specific port (and instance). This module will return suitable responses to facilitate porting code from that environment.

    Binary selections will accept as true any of the following: ("YES", "Y", "ON", "TRUE", "T", "1", 1) (upper/lower/mixed case) Anything else is false.

    There are a large number of possible configuration and option parameters. To facilitate checking option validity in scripts, most configuration methods can be used in two different ways:

    method called with an argument

    The parameter is set to the argument, if valid. An invalid argument returns false (undef) and the parameter is unchanged. The function will also carp if $user_msg is true. The port will be updated immediately if allowed (an automatic write_settings is called).

    method called with no argument in scalar context

    The current value is returned. If the value is not initialized either directly or by default, return "undef" which will parse to false. For binary selections (true/false), return the current value. All current values from "multivalue" selections will parse to true.

    method called with no argument in list context

    Methods which only accept a limited number of specific input values return a list consisting of all acceptable choices. The null list (undef) will be returned for failed calls in list context (e.g. for an invalid or unexpected argument). Only the baudrate, parity, databits, stopbits, and handshake methods currently support this feature.

Exports

Nothing is exported by default. The following tags can be used to have large sets of symbols exported:

:PARAM

Utility subroutines and constants for parameter setting and test:

LONGsize	SHORTsize	nocarp		yes_true
OS_Error
:ALL

All of the above. Except for the test suite, there is not really a good reason to do this.

NOTES

The object returned by new is NOT a Filehandle. You will be disappointed if you try to use it as one.

e.g. the following is WRONG!!____print $PortObj "some text";

This module uses POSIX termios extensively. Raw API calls are very unforgiving. You will certainly want to start perl with the -w switch. If you can, use strict as well. Try to ferret out all the syntax and usage problems BEFORE issuing the API calls (many of which modify tuning constants in hardware device drivers....not where you want to look for bugs).

With all the options, this module needs a good tutorial. It doesn't have one yet.

KNOWN LIMITATIONS

The current version of the module has been tested with Perl 5.003 and above. It was initially ported from Win32 and was designed to be used without requiring a compiler or using XS. Since everything is (sometimes convoluted but still pure) Perl, you can fix flaws and change limits if required. But please file a bug report if you do.

The read method, and tied methods which call it, currently can use a fixed timeout which approximates behavior of the Win32::SerialPort read_const_time and read_char_time methods. It is used internally by select. If the timeout is set to zero, the read call will return immediately.

$PortObj->read_const_time(500);	# 500 milliseconds = 0.5 seconds
$PortObj->read_char_time(5);		# avg time between read char

The timing model defines the total time allowed to complete the operation. A fixed overhead time is added to the product of bytes and per_byte_time.

Read_Total = read_const_time + (read_char_time * bytes_to_read)

Write timeouts and read_interval timeouts are not currently supported.

BUGS

The module does not reliably open with lockfiles. Experiment if you like.

With all the currently unimplemented features, we don't need any more. But there probably are some.

__Please send comments and bug reports to wcbirthisel@alum.mit.edu.

Win32::SerialPort & Win32API::CommPort

Win32::SerialPort Functions Not Currently Supported

($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $PortObj->status;
$LatchErrorFlags = $PortObj->reset_error;

$PortObj->read_interval(100);		# max time between read char
$PortObj->write_char_time(5);
$PortObj->write_const_time(100);

Functions Handled in a POSIX system by "stty"

xon_limit	xoff_limit	xon_char	xoff_char
eof_char	event_char	error_char	stty_intr
stty_quit	stty_eof	stty_eol	stty_erase
stty_kill	is_stty_intr	is_stty_quit	is_stty_eof
is_stty_eol	is_stty_erase	is_stty_kill	stty_clear
is_stty_clear	stty_bsdel	stty_echo	stty_echoe
stty_echok	stty_echonl	stty_echoke	stty_echoctl
stty_istrip	stty_icrnl	stty_ocrnl	stty_igncr
stty_inlcr	stty_onlcr	stty_isig	stty_icanon

Win32::SerialPort Functions Not Ported to POSIX

modemlines	transmit_char

Win32API::CommPort Functions Not Ported to POSIX

init_done	fetch_DCB	update_DCB	initialize
are_buffers	are_baudrate	are_handshake	are_parity
are_databits	are_stopbits	is_handshake	xmit_imm_char
is_baudrate	is_parity	is_databits	is_write_char_time
debug_comm	is_xon_limit	is_xoff_limit	is_read_const_time
is_xoff_char	is_eof_char	is_event_char	is_read_char_time
is_read_buf	is_write_buf	is_buffers	is_read_interval
is_error_char	is_xon_char	is_stopbits	is_write_const_time
is_binary	is_status	write_bg	is_parity_enable
is_modemlines	read_bg		read_done	write_bg
xoff_active	is_read_buf	is_write_buf	xon_active
write_done	suspend_tx	resume_tx	break_active

"raw" Win32 API Calls and Constants

A large number of Win32-specific elements have been omitted. Most of these are only available in Win32::SerialPort and Win32API::CommPort as optional Exports. The list includes the following:

:STAT

The Constants named BM_*, MS_*, CE_*, and ST_*

:RAW

The API Wrapper Methods and Constants used only to support them including PURGE_*, SET*, CLR*, EV_*, and ERROR_IO*

:COMMPROP

The Constants used for Feature and Properties Detection including BAUD_*, PST_*, PCF_*, SP_*, DATABITS_*, STOPBITS_*, PARITY_*, and COMMPROP_INITIALIZED

:DCB

The constants for the Win32 Device Control Block including CBR_*, DTR_*, RTS_*, *PARITY, *STOPBIT*, and FM_*

Compatibility

This code implements the functions required to support the MisterHouse Home Automation software by Bruce Winter. It does not attempt to support functions from Win32::SerialPort such as stty_emulation that already have POSIX implementations or to replicate Win32 idosyncracies. However, the supported functions are intended to clone the equivalent functions in Win32::SerialPort and Win32API::CommPort. Any discrepancies or omissions should be considered bugs and reported to the maintainer.

AUTHORS

Based on Win32::SerialPort.pm, Version 0.8, by Bill Birthisel

Ported to linux/POSIX by Joe Doss for MisterHouse

Currently maintained by: Bill Birthisel, wcbirthisel@alum.mit.edu, http://members.aol.com/Bbirthisel/

SEE ALSO

Win32API::CommPort

Win32::SerialPort

Perltoot.xxx - Tom (Christiansen)'s Object-Oriented Tutorial

COPYRIGHT

Copyright (C) 1999, Bill Birthisel. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 28 July 1999.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 1292:

You can't have =items (as at line 1298) unless the first thing after the =over is an =item

Around line 1375:

You can't have =items (as at line 1385) unless the first thing after the =over is an =item