Re: Some questions on writing data to a serial port?



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 ***
.



Relevant Pages

  • Re: Some questions on writing data to a serial port?
    ... int serial_write ... while (nbytes < count) { ... See my topic "Recalculate timeout after selectwhen reading from serial port?" ... 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. ...
    (comp.unix.programmer)
  • Re: Some questions on writing data to a serial port?
    ... int serial_write ... while (nbytes < count) { ... O_NONBLOCK) to implement a timeout. ... buffer cache, which is flushed to the server asynchronously. ...
    (comp.unix.programmer)
  • RS232 Redirector Program in C using Linux
    ... developing linux aps as well as in the serial port), ... failed to get current settings ... the int handler ... nbytes = write; ...
    (comp.os.linux.development.apps)
  • Some questions on writing data to a serial port?
    ... I'm writing a small library for the communication with a device attached to a serial port. ... int serial_write ... while (nbytes < count) { ... While testing (with a virtual device provided by ttypatch and a real serial port without a device attached), I noticed the write *always* succeeds. ...
    (comp.unix.programmer)
  • Re: Select returns without having any data in serial port buffer
    ... I have opened a serial port and then blocked on a select system call. ... but select returns even if no data is comming from other end. ... buffer and this continues very fast. ... int retval,cErr; ...
    (comp.unix.programmer)