It appears that VTIME does not work. I set both VMIN and VTIME and I never get a timeout. The read continues to happily block forever.

Also, when looking at VTIME handling down in the code, I see in termios.c the function fillBufferPoll(). It looks to me like that function expects (*tty->handler.poll_read) to return in less than tty->vtimeTicks in every case. I don't see how that is guaranteed.

If (*tty->handler.poll_read) blocks until a byte shows up, then VTIME is basically meaningless. I don't see any code that sends VTIME or vtimeTicks down to the underlying handler, so I don't see how the timeout could possibly be honored.

Or maybe there's something I don't understand...


Here is the function:

static void
fillBufferPoll (struct rtems_termios_tty *tty)
{
  int n;

  if (tty->termios.c_lflag & ICANON) {
    for (;;) {
      n = (*tty->handler.poll_read)(tty->device_context);
      if (n < 0) {
        rtems_task_wake_after (1);
      } else {
        if  (siprocPoll (n, tty))
          break;
      }
    }
  } else {
    rtems_interval then, now;

    then = rtems_clock_get_ticks_since_boot();
    for (;;) {
      n = (*tty->handler.poll_read)(tty->device_context);
      if (n < 0) {
        if (tty->termios.c_cc[VMIN]) {
          if (tty->termios.c_cc[VTIME] && tty->ccount) {
            now = rtems_clock_get_ticks_since_boot();
            if ((now - then) > tty->vtimeTicks) {
              break;
            }
          }
        } else {
          if (!tty->termios.c_cc[VTIME])
            break;
          now = rtems_clock_get_ticks_since_boot();
          if ((now - then) > tty->vtimeTicks) {
            break;
          }
        }
        rtems_task_wake_after (1);
      } else {
        siprocPoll (n, tty);
        if (tty->ccount >= tty->termios.c_cc[VMIN])
          break;
        if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
          then = rtems_clock_get_ticks_since_boot();
      }
    }
  }
}


Or, maybe there's something I don't understand...

Thanks.



On 10-Sep-19 10:18 AM, Joel Sherrill wrote:
On Tue, Sep 10, 2019 at 12:09 AM Benjamin Ellsworth
<2gigspambuc...@gmail.com> wrote:

Hello,

The code I'm working with currently does a read() on a device that has
been opened with an open() call (a UART if that matters).  It nicely
blocks waiting for a character (potentially forever).

I now need that read to be interrupted...  I looked for pselect() so it
can block until I tell it to stop (via signal from another thread), but
that doesn't seem to be supported.  I looked at the classic work-around
using a pipe in a select call, but pipe() isn't supported and select
apparently only works on sockets (and the comments in the select header
make it sound like even that is a bad idea).

What version? I thought select() on termios devices was added at least
to the master.

You are right that it historically hasn't worked.

pipe() is supported. psxpipe01 is the test. Not sure about the use case
you have in mind.

I can probably make things work with timeouts--basically making it into
a polling loop, but I can't see a way to make the read timeout.  I dug
down into the rtems read functions, but didn't see any way to make them
timeout, nor did I see a way to cleanly interrupt them.

read() on a UART should be able to do non-blocking or timeout on read()
with the VMIN and VTIME support from termios. There should be examples
of this around the net.

If anyone has any suggestions/ideas/pointers, I'd appreciate them.

--joel


Thanks.

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to