<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://tcl.activestate.com/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu Feb 09 08:30:12 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='35'>
<header><title>Enhanced Support for Serial Communications</title><author address="mailto:rolf.schroedter@dlr.de">Rolf Schroedter</author><status type='project' state='final' tclversion="8.4" vote='after'>$Revision: 1.12 $</status><history></history><created day='6' month='jun' year='2001' /></header>
<abstract>Tcl&apos;s support for RS-232 is very rudimentary. Mainly it allows to setup the communication rate [fconfigure -mode] and to read and write data with the standard Tcl functions. Real serial communications are often more complex. Therefore it is proposed to add support for hardware and software flow control, polling RS-232 (modem) status lines, and watching the input and output queue. This is all to be implemented via additional [fconfigure] options.</abstract>
<body><section title="Rationale">
<para>There is an undamped interest in serial communications, because it&apos;s very easy to connect external hardware to a computer using the RS-232 ports.</para>
<para>However Tcl&apos;s support for serial communications is not complete. Real applications often need more than setting the baud rate and to read/write data bytes.</para>
<para>Especially if the external hardware is slow or the communication rate is high one needs support for flow-control (hard- and software). These features are provided by the operating system drivers, but Tcl&apos;s [fconfigure] doesn&apos;t support it.</para>
<para>On the the other hand there are cases that the external hardware makes static use of the RS-232 signals to signal external events via the modem status lines or even to be powered by the RS-232 control lines.</para>
<para>Additionally for non-blocking serial I/O it may be interesting for the Tcl application to know about the status of the input and output queues to read a fixed size block or to support communication timeouts.</para>
<para>At this opportunity it is proposed to move the documentation of the serial port fconfigure options form the <emph style="italic">open.n</emph> man-page to <emph style="italic">fconfigure.n</emph>.</para>
</section>
<section title="Specification">
<para>It is proposed to have following set of [fconfigure] options for serial communications:</para>
<describe><item.d name='-mode baud,parity,data,stop'><para><emph style="italic">(Windows and Unix)</emph>. Already implemented.</para></item.d><item.d name='-handshake mode'><para><emph style="italic">(Windows and Unix)</emph>. This option is used to setup automatic handshake control. Note that not all handshake modes maybe supported by your operating system. The mode parameter is case-independent.</para><para>If mode is <emph style="italic">none</emph> then any handshake is switched off. <emph style="italic">rtscts</emph> activates hardware handshake. For software handshake <emph style="italic">xonxoff</emph> the handshake characters can be redefined with [fconfigure -xchar]. An additional hardware handshake <emph style="italic">dtrdsr</emph> is available only for Windows. There is no default handshake configuration, the initial value depends on your operating system settings. The -handshake option cannot be queried, because the operating system settings may be ambiguous.</para></item.d><item.d name='-xchar {xonChar xoffChar}'><para><emph style="italic">(Windows and Unix)</emph>. This option is used to change the software handshake characters. Normally the operating system default should be DC1 (0x11 hex) and DC3 (0x13 hex) representing the ASCII standard XON and XOFF characters. When queried -xchar returns a list of two characters representing the XON and XOFF characters respectively.</para></item.d><item.d name='-timeout msec'><para><emph style="italic">(Windows and Unix</emph>. This option is used to set the timeout for blocking read operations. It specifies the maximum interval between the receiption of two bytes in milliseconds. For Unix systems the granularity is 100 milliseconds. The -timeout option does not affect write operations or nonblocking reads. This option cannot be queried.</para></item.d><item.d name='-ttycontrol {signal boolean signal boolean ...}'><para><emph style="italic">(Windows and Unix)</emph>. This option is used to setup the handshake output lines permanently or to send a BREAK over the serial line. The <emph style="italic">signal</emph> names are case-independent.</para><para>{RTS 1 DTR 0} sets the RTS output to high and the DTR output to low. For POSIX systems {BREAK 1} sends a break signal (zero-valued bits) for 0.25 to 0.5 seconds and {BREAK 0} does nothing. For Windows the break is enabled and disabled with {BREAK 1} and {BREAK 0} respectively. It&apos;s not a good idea to change the RTS (or DTR) signal with active hardware handshake <emph style="italic">rtscts</emph> (or <emph style="italic">dtrdsr</emph>). The result is unpredictable. The -ttycontrol option cannot be queried.</para></item.d><item.d name='-ttystatus'><para><emph style="italic">(Windows and Unix)</emph>. The -ttystatus option can only be queried. It returns the current modem status and handshake input signals. The result is a list of signal,value pairs with a fixed order, e.g. {CTS 1 DSR 0 RING 1 DCD 0}. The <emph style="italic">signal</emph> names are returned upper case.</para></item.d><item.d name='-queue'><para><emph style="italic">(Windows and Unix)</emph>. The -queue option can only be queried. It returns a list of two integers representing the current number of bytes in the input and output queue respectively.</para></item.d><item.d name='-sysbuffer inSize'><para></para></item.d><item.d name='-sysbuffer {inSize outSize}'><para><emph style="italic">(Windows only, Unix ?)</emph>. This option is used to change the size of Windows system buffers for a serial channel. Especially at higher communication rates the default input buffer size of 4096 bytes can overrun for latent systems. The first form specifies the input buffer size, in the second form both input and output buffers are defined.</para></item.d><item.d name='-pollinterval msec'><para><emph style="italic">(Windows only)</emph>. Already implemented.</para></item.d><item.d name='-lasterror'><para><emph style="italic">(Windows only, Unix?)</emph>. Already implemented for Windows.</para></item.d></describe>
</section>
<section title="Implementation Details">
<para>For Unix (<emph style="italic">termios.h</emph>) systems the proposed changes are very straight forward, because Unix channels can be configured blocking or non-blocking. One only needs to add the serial [fconfigure] options calling the appropriate <emph style="italic">ioctl()</emph> functions to configure the serial port.</para>
<para>For Windows reading and writing files is generally blocking. Especially with activated handshake the serial communication can stop forever. Therefore the Windows implementation needs at least a writing thread preventing Tcl&apos;s main application to block. Additionally Windows provides a reach set of special APIs for serial communication which needs to be translated to [fconfigure] options.</para>
<para>There is one special point about Windows: For making multiple threads accessing a serial port, it needs to be opened with the OVERLAPPED flag set. Tcl detects a serial port only after opening it without the OVERLAPPED flag. Therefore this port has to be reopened, which requires a little change to <emph style="italic">tclWinChan.c</emph> and <emph style="italic">tclWinPort.h</emph>.</para>
<para>Macintosh systems - ?</para>
</section>
<section title="Changed Files">
<describe><item.d name='tclUnixChan.c'><para>Add [fconfigure] options.</para></item.d><item.d name='tclWinPort.h'><para>Declare a new function <emph style="italic">TclWinSerialReopen()</emph></para></item.d><item.d name='tclWinChan.h'><para>Call <emph style="italic">TclWinSerialReopen()</emph> after detecting the serial port.</para></item.d><item.d name='tclWinSerial.c'><para>Partial rewrite of Tcl&apos;s serial driver. The current implementation only performs blocking output. Add [fconfigure] options.</para></item.d><item.d name='fconfigure.n'><para>Serial [fconfigure] options should be documented here.</para></item.d><item.d name='open.n'><para>Serial port filenames are documented here. Add a link to [fconfigure] for additional serial options.</para></item.d></describe>
</section>
<section title="Timeouts">
<para>It has also been proposed to add a [fconfigure -timeout] option specifying read and write timeouts. Together with a blocking read a timeout could be used to wait for an expected number of data bytes from the serial port. There are two arguments against timeouts:</para>
<enumerate><item.e index='1'><para>Adding timeout to blocking I/O at the driver level radically changes the behaviour of write operations. This adds a lot of oddity to serial communications.</para></item.e><item.e index='2'><para>Timeouts can easily be implemented at Tcl level using non-blocking I/O together with Tcl&apos;s event loop. Additional support is given by [fconfigure -queue].</para></item.e></enumerate>
<para>July 03, 2001: On the other hand timeout for read operations can easily be implemented in a cross-platform way by using the VMIN/VTIME settings for Unix and the COMTIMEOUTS for Windows. That&apos;s why the author finally agrees with the -timeout proposal.</para>
</section>
<section title="Restore settings at close ?">
<para>It has also been proposed that Tcl should not restore the original serial ports settings at [close $chan]. IMO it doesn&apos;t hurt, because anyway an application should care about setting up the serial port properly before using. Without restoring a Tcl script could be used as a <emph style="italic">poor</emph> stty, considering however that Tcl does not provide a complete control over serial settings.</para>
<para>So the proposal is to remove the current save/restore mechanism from the Unix implementation for serial ports.</para>
</section>
<section title="Source code patches">
<para>The patches have been uploaded to the sourceforge patch tracker: ID=438509 TIP#35 Patches: Serial Port Enhancements file=tip35patch.tgz</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

