For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > January 2005 > EOF on serial port









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author EOF on serial port
S McAfee

2005-01-25, 3:57 am

I've written a program which runs on each of a number of Linux hosts.
Connected to the serial port of each host is a device that periodically
prints a "test result" with a well-defined format. It's the job of my
program to continually read from the serial port, recognize the boundaries
between reports, package them up into separate files, and send them to a
central server.

Occasionally my program registers an end-of-file condition on the file
descriptor associated with the serial port. It re-opens the port without a
problem, but I'd prefer to eliminate the EOFs entirely, both because a) it
generates a syslog warning message each time, and b) I suspect some data is
getting lost between the closing and re-opening. I haven't done much serial
port programming, so I'm unfamiliar with the full range of conditions that
could cause an EOF.

Originally, my program initialized the serial port by setting the input and
output speeds, turning off the ECHO lflag, and turning off the ICRNL iflag.
After browsing the terminal I/O chapter in Stevens' "Advanced Programming in
the UNIX Environment", I modified my code to also turn off the ICANON and
ISIG lflags, and for good measure also set the VMIN and VTIME control
characters to 1 and 0, respectively.

I haven't tested the code yet, but I'm not confident that the new code will
prevent EOFs from being generated. As far as I know, the device on the
other side of the serial port only generates textual characters and an
occasional null character, never a control-D.

Is there any other condition that would cause an EOF on the serial port?


--
Sean McAfee - etzwane@schwag.org
Pascal Bourguignon

2005-01-25, 3:57 am

etzwane@schwag.org (S McAfee) writes:

> I've written a program which runs on each of a number of Linux hosts.
> Connected to the serial port of each host is a device that periodically
> prints a "test result" with a well-defined format. It's the job of my
> program to continually read from the serial port, recognize the boundaries
> between reports, package them up into separate files, and send them to a
> central server.
>
> Occasionally my program registers an end-of-file condition on the file
> descriptor associated with the serial port. It re-opens the port without a
> problem, but I'd prefer to eliminate the EOFs entirely, both because a) it
> generates a syslog warning message each time, and b) I suspect some data is
> getting lost between the closing and re-opening. I haven't done much serial
> port programming, so I'm unfamiliar with the full range of conditions that
> could cause an EOF.
>
> Originally, my program initialized the serial port by setting the input and
> output speeds, turning off the ECHO lflag, and turning off the ICRNL iflag.
> After browsing the terminal I/O chapter in Stevens' "Advanced Programming in
> the UNIX Environment", I modified my code to also turn off the ICANON and
> ISIG lflags, and for good measure also set the VMIN and VTIME control
> characters to 1 and 0, respectively.
>
> I haven't tested the code yet, but I'm not confident that the new code will
> prevent EOFs from being generated. As far as I know, the device on the
> other side of the serial port only generates textual characters and an
> occasional null character, never a control-D.
>
> Is there any other condition that would cause an EOF on the serial port?


man stty
man termios

There's only one character that maps to EOF, but you want to
handle the other that send other signals.

You should probably put the line in RAW mode.

--
__Pascal Bourguignon__ http://www.informatimago.com/

Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
Floyd L. Davidson

2005-01-25, 8:57 am

etzwane@schwag.org (S McAfee) wrote:
....

>I haven't tested the code yet, but I'm not confident that the new code will
>prevent EOFs from being generated. As far as I know, the device on the
>other side of the serial port only generates textual characters and an
>occasional null character, never a control-D.
>
>Is there any other condition that would cause an EOF on the serial port?


Two additional suggestions:

1) http://www.easysw.com/~mike/serial/serial.html

That is the Serial Programming Guide for POSIX Operating Systems,
and is an excellent document.

2) Post the code you use to open and configure the serial
port.

Chances are pretty good that you learn some really odd things about
what your code does!

--
Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@barrow.com
Villy Kruse

2005-01-25, 8:57 am

On Tue, 25 Jan 2005 04:36:51 -0000,
S McAfee <etzwane@schwag.org> wrote:


>
> Occasionally my program registers an end-of-file condition on the file
> descriptor associated with the serial port. It re-opens the port without a
> problem, but I'd prefer to eliminate the EOFs entirely, both because a) it
> generates a syslog warning message each time, and b) I suspect some data is
> getting lost between the closing and re-opening. I haven't done much serial
> port programming, so I'm unfamiliar with the full range of conditions that
> could cause an EOF.
>


The EOF condition is a result of read() returning a count of zero and
when setting the serial port in raw mode these are usualy a result of
a timeout as specified by the VTIME settings in the termios structure.
Thus, after EOF you should just keep on reading.

Villy

S McAfee

2005-01-25, 4:00 pm

In article <87y8ehj1u0.fld@barrow.com>,
Floyd L. Davidson <floyd@barrow.com> wrote:
>etzwane@schwag.org (S McAfee) wrote:
[color=darkred]
>Two additional suggestions:
>
> 1) http://www.easysw.com/~mike/serial/serial.html
>
>That is the Serial Programming Guide for POSIX Operating Systems,
>and is an excellent document.


Will check it out, thanks.

> 2) Post the code you use to open and configure the serial
> port.


OK, here it is. It's in Perl, but it's a pretty thin layer over the POSIX
termios stuff.

Here's the original version of the subroutine that opens and configures the
port:

sub open_serial_port {
open SERIAL, '</dev/ttyS0' or die "Can't open serial port: $!\n";
my $serialfd = fileno SERIAL;
my $termios = POSIX::Termios->new();
defined $termios->getattr($serialfd)
or die "Unable to get serial port terminal characteristics\n";
$termios->setispeed(B38400);
$termios->setospeed(B38400);
$termios->setlflag($termios->getlflag() & ~ECHO);
$termios->setiflag($termios->getiflag() & ~ICRNL);
defined $termios->setattr($serialfd)
or die "Unable to set serial port terminal characteristics\n";
}

After browsing Stevens' book, I changed the setlflag call to this:

$termios->setlflag($termios->getlflag() & ~(ECHO | ICANON | ISIG));

....and added these calls:

$termios->setcc(VMIN, 1);
$termios->setcc(VTIME, 0);

(Both before the setattr call, of course.)


--
Sean McAfee -- etzwane@schwag.org
S McAfee

2005-01-25, 4:00 pm

In article <slrncvceht.2eo.vek@station02.ohout.pharmapartners.nl>,
Villy Kruse <nobody> wrote:
>The EOF condition is a result of read() returning a count of zero and
>when setting the serial port in raw mode these are usualy a result of
>a timeout as specified by the VTIME settings in the termios structure.
>Thus, after EOF you should just keep on reading.


Hmm. I've never heard of continuing to read from a descriptor after read
returns zero, but I suppose it makes sense in the context of raw mode. Is
it then not possible for a descriptor attached to a terminal in raw mode to
reach "true" end-of-file? If it is, how does one distinguish end-of-file
from a simple timeout?


--
Sean McAfee -- etzwane@schwag.org
Lew Pitcher

2005-01-25, 4:00 pm

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

S McAfee wrote:
> In article <slrncvceht.2eo.vek@station02.ohout.pharmapartners.nl>,
> Villy Kruse <nobody> wrote:
>
>
>
> Hmm. I've never heard of continuing to read from a descriptor after read
> returns zero, but I suppose it makes sense in the context of raw mode. Is
> it then not possible for a descriptor attached to a terminal in raw mode to
> reach "true" end-of-file?


This depends on how you define a "true" end of file on an /infinite
capacity/ stream data source.

> If it is, how does one distinguish end-of-file
> from a simple timeout?


If, by this, you mean "how can a program determine if it has encountered
a pause in the data flow or has encountered a true 'no more data'
condition", then the answer is that it can't make that determination
/absolutely/. The best it can do is /guess/ that /this/ pause is too
long to be temporary, and /that/ pause was too short to be EOF.

OTOH, if you're asking what distinguishes EOF from timeout, the answer
is "nothing". That distinction is up to you, in that you select the
critera that the program will use to determine EOF. I can think of a
couple of different ways to indicate EOF, but they might not be correct
for your circumstances:

1) Simple timeout. If there's not been traffic for an extended period of
time (*you* define how long), then we take that as evidence of having
processed all the available data ("no more data" implies "end of
file")

2) Out-of-band signal, like loss of DSR (Data Set Ready) or DTD (Data
Terminal Detect). These indicate that the physical source of the data
is no longer physically connected to the system. Here, "no longer
connected" implies "no more data", which implies "end of file".

Basically, 'raw' serial device resources always have data; they never
reach "end of file". So, EOF becomes a philosophical condition rather
than a real one, and you have to choose what constitutes a "no more
data" condition that EOF would indicate.


- --

Lew Pitcher, IT Consultant, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFB9oboagVFX4UWr64RAvL/AJ9rAccomQW58Nxdq5tfXZOJilr2BwCffjEk
QtRwJ3JL1ts+TOkwPWPHMts=
=2qC0
-----END PGP SIGNATURE-----
Floyd L. Davidson

2005-01-26, 3:59 am

etzwane@schwag.org (S McAfee) wrote:
>Lew Pitcher <Lew.Pitcher@td.com> wrote:


>
>OK, I think I get it. It seems my mistake was equating "read(2) returns
>zero" with "end-of-file" (per my definition above). The issue may have
>become moot with my new code that sets the VTIME and VMIN control
>characters, but just to be sure:
>
>Given a file descriptor attached to a serial device in noncanonical mode
>with VTIME and VMIN set to 0 and 1 respectively, can a read(2) call on that
>descriptor ever return zero? If so, what does it mean? Would the following
>be an appropriate tack to take?


If VTIME is set to 0, the timer is disabled. Hence read()
will block forever if no data arrives, assuming link integrity
is maintained. If an error occurs, read() will return -1.

Note that of course if read() is called with a byte count of 0,
it will return 0, so it is possible for a loop to do exactly
that even with VMIN set greater than 1 and the timer turned off.

>n = read(serialfd, mybuf, sizeof(mybuf));
>
>if (n == 0) {
> /* can't happen */
> fprintf(stderr, "serial read returned zero!\n");
> abort();
>}
>
>--
>Sean McAfee -- etzwane@schwag.org


--
Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@barrow.com
Barry Margolin

2005-01-26, 3:59 am

In article <10vcrknlbodq0ed@news.supernews.com>,
etzwane@schwag.org (S McAfee) wrote:

> In article <slrncvceht.2eo.vek@station02.ohout.pharmapartners.nl>,
> Villy Kruse <nobody> wrote:
>
> Hmm. I've never heard of continuing to read from a descriptor after read
> returns zero, but I suppose it makes sense in the context of raw mode. Is
> it then not possible for a descriptor attached to a terminal in raw mode to
> reach "true" end-of-file? If it is, how does one distinguish end-of-file
> from a simple timeout?


What is the "end" of a raw serial line? The only end-like condition is
when a dialup line is hung up, but that sends a SIGHUP signal rather
than reading as EOF. EOF on cooked serial lines is just a high-level
user interface mechanism, it's not really the end of anything.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com