This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Fwd: termios - bad behaviour with VMIN]


On Thu, 2003-03-20 at 20:22, Jonathan Larmour wrote:
> Gary Thomas wrote:
> > No response to this either.  Jonathan - I am most interested in this.  
> 
> Sorry, firstly I was away all of last week, and then I had already started 
> looking at this yesterday and then started again today, but then my e-mail 
> went wrong and I couldn't send anything most of the day :-(.
> 

Understood (and after this morning's trouble with disk drives, I
*really* understand).

> > which tells me that if I have a termios device in non-canonical
> > mode and I set VMIN, then a read to that device will not be
> > satisfied until at least VMIN characters arrive.  Currently,
> > this does not happen; it returns 0, with no error, if there
> > are no characters available.
> 
> I can see that would be the case, yes. The driver was originally written 
> only to support MIN = 0, TIME = 0. Recently I tried to get MIN > 0 
> working, but was doing it blind and waiting for someone else to confirm 
> (which they didn't, but I thought I'd found the bug so checked it in). But 
> clearly it still wasn't right.
> 
> > This patch fixes it and gives what I think is proper behaviour:
> > 
> > Index: io/serial/current/src/common/termiostty.c
> > ===================================================================
> > RCS file: /misc/cvsfiles/ecos/packages/io/serial/current/src/common/termiostty.c,v
> > retrieving revision 1.4
> > diff -u -5 -p -r1.4 termiostty.c
> > --- io/serial/current/src/common/termiostty.c	14 Feb 2003 11:50:12 -0000	1.4
> > +++ io/serial/current/src/common/termiostty.c	9 Mar 2003 15:39:58 -0000
> > @@ -659,11 +659,18 @@ termios_read(cyg_io_handle_t handle, voi
> >          cyg_uint32 dbc_len = sizeof( dev_buf_conf );
> >          res = cyg_io_get_config( chan,
> >                                   CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
> >                                   &dev_buf_conf, &dbc_len );
> >          CYG_ASSERT( res == ENOERR, "Query buffer status failed!" );
> > -        *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
> > +        if (dev_buf_conf.rx_count > 0) {
> > +            // Adjust length to be max characters currently available
> > +            *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
> > +        } else if (t->c_cc[VMIN] == 0) {
> > +            // No chars available - don't block
> > +            *len = 0;
> > +            return ENOERR;
> > +        }
> 
> This isn't quite right. You've got to respect VMIN != 0 no matter what in 
> non-canonical mode. The way this is written, it can return fewer than VMIN 
> bytes if there are more than 0 but fewer than VMIN bytes available in the 
> buffer at the time it's called. This might not affect your app of course.
> 
> But the solution is tricky, because we then only want to read a maximum of 
> *len bytes out of the lower level serial buffer, but not return until 
> there are more than VMIN of them in there, and for VMIN > *len we need to 
> take a different approach to the way the code works now.
> 
> Unfortunately the way the cyg_io interface is structured I can't see any 
> simple way to do this without either having to create and manage a new 
> intermediate buffer to store characters, or perhaps add a special 
> set_config primitive that allows us to block until a certain number of 
> bytes are in the buffer. The latter isn't very clean, but would save a lot 
> of hassle and would probably be what I'd choose.
> 
> I was thinking about trying to solve this, but I think it'll take a bit 
> long for something I'm not actively meant to be working near anyway. So 
> I'll let you choose between fixing, bugzilla'ing, or adding a big FIXME 
> with all the above in a comment :-). Actually, if you bugzilla, a single 
> line FIXME with the bug number would probably be a good idea - no need for 
> a ChangeLog or ecos-patches message for something that trivial.
> 
> [ I've also noticed that MAX_INPUT should be defined in limits.h to be the 
> size of the input serial buffer, which unfortunately has to be determined 
> programmatically beacuse it requires a call to serial_get_config with 
> CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO. I'll just bugzilla that not myself. ]
> 
> > @@ -752,14 +759,11 @@ termios_read(cyg_io_handle_t handle, voi
> >                  }
> >                  if ( t->c_iflag & INLCR )
> >                      c = '\r';
> >                  returnnow = true; // FIXME: true even for INLCR?
> >              } // else if
> > -        } else { // non-canonical mode
> > -            if ( t->c_cc[ VMIN ] && (size+1 >= t->c_cc[ VMIN ]) )
> > -                returnnow = true;
> > -        } // else
> > +        } // if 
> >  
> >  #ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
> >          if ( (t->c_lflag & ISIG) && (t->c_cc[ VINTR ] == c) ) {
> >              discardc = true;
> >              if ( 0 == (t->c_lflag & NOFLSH) )
> > @@ -789,10 +793,16 @@ termios_read(cyg_io_handle_t handle, voi
> >              if ( t->c_lflag & ECHO ) {
> >                  clen = 1;
> >                  // FIXME: what about error or non-blocking?
> >                  termios_write( handle, &c, &clen );
> >              }
> > +        }
> > +
> > +        if ( (t->c_lflag & ICANON) == 0 ) {
> > +            // Check to see if read has been satisfied
> > +            if ( t->c_cc[ VMIN ] && (size >= t->c_cc[ VMIN ]) )
> > +                returnnow = true;
> >          }
> 
> This bit makes sense.

It's also the part that fixed the bug I was after.

I'll see what I can do to help you iron out the other parts as well.
If you want, I can back out the changes at the top which are arguably
incorrect.

-- 
------------------------------------------------------------
Gary Thomas                 |
MLB Associates              |  Consulting for the
+1 (970) 229-1963           |    Embedded world
http://www.mlbassoc.com/    |
email: <gary at mlbassoc dot com>  |
gpg: http://www.chez-thomas.org/gary/gpg_key.asc
------------------------------------------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]