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