Re: Some questions on writing data to a serial port?
- From: Barry Margolin <barmar@xxxxxxxxxxxx>
- Date: Thu, 13 Sep 2007 21:33:16 -0400
In article <fcbmqu$hkq$1@xxxxxxxxxxxxxxxx>,
Jef Driesen <jefdriesen@xxxxxxxxxxxxxxxxxxx> wrote:
For one of my applications, I'm writing a small library for the
communication with a device attached to a serial port. The library is
very simple (open, close, configure, read, write) and is only a small
wrapper around the platform specific (termios, win32) API. Almost
everything works, but I'm having some problems with writing data.
Under linux, I'm using this code for writing:
int serial_write (serial_t fd, const void* buffer, unsigned int count)
{
int nbytes = 0;
while (nbytes < count) {
int n = write (fd, buffer + nbytes, count - nbytes);
if (n < 0)
return -1; // Error during write call.
nbytes += n;
}
return nbytes;
}
While testing (with a virtual device provided by ttypatch [1] and a real
serial port without a device attached), I noticed the write *always*
succeeds (immediately after the first write call). Is this the expected
behavior when there is nothing receiving the data at the other end? I
Yes.
suppose the data is buffered somewhere (by the OS or the serial driver),
but not actually send. Because sometimes ioctl (fd, TIOCOUTQ, &bytes)
That's the reason. The kernel buffers writes to most types of devices.
For example, if you try to write to a network file system, it may
succeed even when the server is down, because it simply writes to the
buffer cache, which is flushed to the server asynchronously.
shows there is data waiting in the output queue and close (fd) takes a
long time to finish in that case. If I add tcdrain (fd) before returning
in serial_write, it never returns. I would expect write to return an
error instead of the behavior I described. Or am I doing something wrong?
[1] http://ttypatch.sourceforge.net/
If I compare with the windows version (see code below), the function
blocks until everything is written (optionally a timeout can be
configured). But if the function returns successfully, the output queue
is always empty, just as I expected.
BTW, is it possible to implement a timeout when writing data, similar to
windows? Orherwise my application would become unresponsive (when using
tcdrain) if there is no device present.
You could put the descriptor in non-blocking mode. Then if you try to
write while the buffer is full, you'll get an error (errno ==
EWOULDBLOCK). You can then use select() to wait for the buffer to
drain, with a timeout.
int serial_write (serial_t fd, const void* buffer, unsigned int count)
{
DWORD dwWritten = 0;
if (!WriteFile (serial, buffer, count, &dwWritten, NULL))
return -1;
return dwWritten;
}
--
Barry Margolin, barmar@xxxxxxxxxxxx
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
.
- Follow-Ups:
- Re: Some questions on writing data to a serial port?
- From: Jef Driesen
- Re: Some questions on writing data to a serial port?
- From: Jef Driesen
- Re: Some questions on writing data to a serial port?
- From: David Schwartz
- Re: Some questions on writing data to a serial port?
- References:
- Some questions on writing data to a serial port?
- From: Jef Driesen
- Some questions on writing data to a serial port?
- Prev by Date: Re: make and PATH
- Next by Date: Debugging broken pipe
- Previous by thread: Some questions on writing data to a serial port?
- Next by thread: Re: Some questions on writing data to a serial port?
- Index(es):
Relevant Pages
|