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