alarm / setitimer question and serial record communication
norume at aps.anl.gov
Wed Sep 22 14:39:05 UTC 2004
On Sep 22, 2004, at 8:12 AM, Joel Sherrill <joel at OARcorp.com> wrote:
> Peter Dufault wrote:
>> I have some serial port code that I want to run on both RTEMS and a
>> POSIX system without change, and preferably, because I want to,
>> without any ifdefs.
>> The POSIX termios VMIN / VTIME interface is bizarre in that I can't
>> (though I've looked at it many times) put together a bullet proof
>> interface that handles the remote end disappearing and the local end
>> then recovering while I'm only the termios timeout interface.
>> If you set an initial timeout, then that timeout corresponds only to
>> the first received byte, and the read returns after that one byte.
>> If you set an interbyte timeout, then the first byte timeout has to
>> be infinite since the interbyte timeout won't come into effect until
>> the first byte is received.
>> To work around this I usually set a timeout on the first received
>> byte to know that the remote end is alive, I then check the received
>> byte for consistency, and then I set the interbyte timeout for the
>> balance of the record for the number of bytes I expect. Then, in
>> case the remote end dies after starting to talk and before finishing
>> talking, I wrap it the read call with an alarm that will interrupt
>> the read in the rare case that the remote end dies.
>> This code doesn't work on RTEMS. It seems to work unless the remote
>> device disappears after the first byte is received, but that means it
>> doesn't work. "setitimer" doesn't exist on RTEMS, and "alarm" doesn't
>> interrupt the thread doing a read even if I brute-force enable
>> Am I missing a way to keep this part of my library portable (without
>> ifdefs)? There is one way I don't like, which is to revert to doing
>> single byte I/O using the POSIX initial timeout (the timeout that
>> returns as soon as the timeout elapses or a single byte is received).
>> That approach is OK on an embedded system but isn't OK for a
>> portable POSIX library that doesn't like ifdefs.
vxWorks provides an 'FIOCANCEL' ioctl for this situation. Perhaps we
should add this ioctl to RTEMS. It would mean that the serial code
would be different on POSIX and RTEMS, but interrupting system calls
with signals would be much more complicated and likely to uncover dusty
corners of different implementations.
We ran into this problem when implementing a generic
message-based-instrument I/O driver for EPICS. We found that many
systems did not handle interrupting a system call with an interrupt
very well (we have to provide implementations for vxWorks, RTEMS,
Linux, Solaris, HPUX, Windows/Cygwin, Windows/Native). One big problem
was dealing with 'expected' timeouts (devices whose end-of-message can
be determined only by timing out -- there are some truly horrible
serial devices out there!) and determining how much had been read up
until that point. There is also the worry about output blocking if
flow-control is enabled......
Our current code uses the following:
vxWorks - timer which issues an FIOCANCEL ioctl.
RTEMS - straight POSIX termios (and live with problem noted in the
Windows/Native - not supported yet
Others - poll() and non-blocking read()/write().
Eric Norum <norume at aps.anl.gov>
Advanced Photon Source
Argonne National Laboratory
More information about the users