Termios Problem
Mike Siers
mikes at poliac.com
Fri Sep 28 19:05:07 UTC 2001
Hi Thomas,
Thanks for the help. I will add the code and check it out.
However, for completeness I still believe that the termios
code should be updated to initialize the t_dqlen value when
the transmit buffer is empty.
Mike Siers
> -----Original Message-----
> From: Thomas Doerfler [mailto:Thomas.Doerfler at imd-systems.de]
> Sent: Friday, September 28, 2001 1:29 PM
> To: Mike Siers
> Cc: rtems-users at oarcorp.com
> Subject: RE: Termios Problem
>
>
> Hi Mike,
>
> the driver you sent me has a common interrupt function for Rx
> and Tx, so it gets called for Rx events as well as Tx events.
> The key hardware registers you are using there are a
> "Interrupt Status Register" uisr and a corresponding
> "Interrupt Mask Register" uimr.
>
> When the transmitter gets empty, the UART will set the TxRDY
> bit in the status register uisr and you disable any further tx
> interrupts in the mask register uimr. That's ok.
>
> When sometime later a rx interrupt occures, it will be
> processed and then the TXRDY status is checked again in the
> uisr. It will still be set (because Tx is still ready to take
> further data), and therefore the Tx interrupt code will be
> executed again, ALTHOUGH THE Transmitter HAS NOT BECOME EMPTY
> ONCE MORE. This is the code for it:
>
> /* check to see if data needs to be transmitted */
> if ( uart->read.uisr & MCF5206_UART_UISR_TXRDY ) {
> /* disable tx interrupts */
> info->uimr &= ~MCF5206_UART_UIMR_TXRDY;
> uart->write.uimr = info->uimr;
>
> /* put received characters into termios buffer one at a
> time */
> rtems_termios_dequeue_characters(info->ttyp, 1);
> }
>
> I would recommend to check here as an additional condition,
> whether Tx interrupts are enabled at all, so I would change
> the if statement to:
>
> if (( uart->read.uisr & MCF5206_UART_UISR_TXRDY ) &&
> ( uart->read.uimr & MCF5206_UART_UISR_TXRDY )) {
>
> or even more simple:
>
> if ( uart->read.uisr & uart->read.uimr &
> MCF5206_UART_UISR_TXRDY ) {
>
> This should ensure, that there are no additional calls to
> "rtems_termios_dequeue_characters" due to receive interrupts.
>
> Hope this works!
>
> Good luck and Bye,
> Thomas.
>
>
> >
> > Hi Thomas,
> > Attached is the interrupt handler if you want to take a look
> > at it. Basically I think the interrupt handler is getting
> > called when the transmit buffer is empty. So it is passing
> > a one to rtems_termios_dequeue_characters(). This
> increments
> > the t_dqlen value by one and calls the
> rtems_termios_refill_transmitter()
> > function. Under normal circumstances, this function copies
> the
> > t_dqlen value and then sets the t_dqlen value to zero. But
> > if the buffer is empty, the t_dqlen value is not reset to
> zero.
> > So the next transmit request will send more data values than
> > are in the transmit buffer.
> >
> > I could have the BSP's interrupt handler not enable tx
> interrupts
> > when it notices the buffer is empty. But how does the BSP
> know
> > when the transmit buffer is empty without having knowledge
> about
> > the tty data structure?
> >
> > Mike Siers
> >
> >
> > > -----Original Message-----
> > > From: Thomas Doerfler [mailto:Thomas.Doerfler at imd-
> systems.de]
> > > Sent: Friday, September 28, 2001 12:47 PM
> > > To: Mike Siers
> > > Cc: joel at oarcorp.com
> > > Subject: Re: Termios Problem
> > >
> > >
> > > Hello Mike,
> > >
> > > >
> > > > I traced the problem to the following functions. The
> > > transmit interrupt
> > > > handler
> > > > was calling the function
> rtems_termios_dequeue_characters().
> > > This function
> > > > increments a dequeue length variable and then calls the
> > > function
> > > > rtems_termios_refill_transmitter(). The problem is that
> > > when the transmit
> > > > buffer is empty, the dequeue length variable is not
> reset to
> > > zero. So the
> > > > next valid transmit request was sending extra data.
> > > Resetting the dequeue
> > > > length variable to zero, fixes the problem.
> > >
> > > If I got you right, then the termios tx buffer pointers
> and
> > > t_dqlen run somewhat out of sync. I think this might
> happen,
> > > when you call rtems_termios_dequeue_characters() with a
> "len"
> > > parameter, that is bigger than it should be. Keep in mind,
> > > that you always should set the "len" parameter to the
> number
> > > of bytes that have been actually sent out. So when you
> have
> > > sent three bytes, len should be 3 (and not the maximum
> number
> > > of characters that the hardware is able to send out in
> after
> > > one service). When you get "empty" transmit interrupts
> (maybe
> > > they signal, that the transmitter IS empty, and not HAS
> JUST
> > > BECOME empty), then you should not call
> > > rtems_termios_dequeue_characters() at all.
> > >
> > > Hm. Maybe that helps a bit. I am currently working with
> rtems-
> > > 4.5.0, so there is no coldfire bsp included. If you like,
> you
> > > can send me the coldfire "console" module and I might have
> a
> > > look at it (out of curiosity).
> > >
> > > Bye,
> > > Thomas.
> > >
> > > >
> > > > Any thoughts? Should this problem be fixed with a
> simple
> > > change to
> > > > the termios code? Or should I have to make the fix in
> the
> > > BSP code
> > > > to ensure that transmit iterrupts are not enabled when
> the
> > > buffer is empty.
> > > >
> > > > Thanks
> > > > Mike Siers
> > > >
> > > >
> > > >
> > >
> > > --------------------------------------------
> > > IMD Ingenieurbuero fuer Microcomputertechnik
> > > Thomas Doerfler Herbststrasse 8
> > > D-82178 Puchheim Germany
> > > email: Thomas.Doerfler at imd-systems.de
> > > PGP public key available at: http://www.imd-
> > > systems.de/pgp_key.htm
> > >
> > >
>
> --------------------------------------------
> IMD Ingenieurbuero fuer Microcomputertechnik
> Thomas Doerfler Herbststrasse 8
> D-82178 Puchheim Germany
> email: Thomas.Doerfler at imd-systems.de
> PGP public key available at: http://www.imd-
> systems.de/pgp_key.htm
>
>
More information about the users
mailing list