Termios Problem
Thomas Doerfler
Thomas.Doerfler at imd-systems.de
Fri Sep 28 18:28:51 UTC 2001
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