All of lore.kernel.org
 help / color / mirror / Atom feed
* tcdrain / TCSBRK / wait_until_sent delay
@ 2005-05-05 15:50 Andy Parkins
  2005-05-05 17:51 ` rich+ml
  2005-05-09  9:15 ` Christer Weinigel
  0 siblings, 2 replies; 19+ messages in thread
From: Andy Parkins @ 2005-05-05 15:50 UTC (permalink / raw)
  To: linux-serial

[-- Attachment #1: Type: text/plain, Size: 2513 bytes --]

Hello,

I wonder if anyone can help me with this as a problem?  I'm trying to send 
commands to a device along a two wire RS485 connection.  I'm using an RS232 
to RS485 converter that changes the buffer direction based on RTS.  With that 
in mind I therefore do things like (error detection left out for brevity)

bit = TIOCM_RTS;
ioctl( fd, TIOCMBIS, &bit );
write( fd, "\xaa", 1 );
tcdrain();
ioctl( fd, TIOCMBIC, &bit );

This triggers the other end to send a response that I read back with 
select/read.  However, what I am reading has the front few bytes corrupted.  
Sticking a scope on the TXD and RTS lines of the serial port shows that

      ______________________________________
RTS __|                                    |_____
       _____ ___ ___ ___
TXD ___|   |_| |_| |_| |_________________________
        S 1 0 1 0 1 0 1 0 s
                           <-----delay---->

There is a small delay between RTS going high and the data starting - no 
problem there, however, when the transmission finishes there is a 2 byte 
delay before RTS goes low.  The device I'm talking to has (apparently) a 
response time of 200us; I'm seeing a delay before restoration of RTS of 2ms. 
write() returns immediately - the delay is coming from tcdrain() - but I 
cannot see from where.

With a bit of digging I've found that tcdrain() simply calls ioctl(TCSBRK,1) 
which I guess ends up in

linux/driver/char/tty_io.c:         tty_ioctl() which calls
linux/driver/char/tty_ioctl.c:      tty_wait_until_sent() which calls
linux/driver/serial/serial_core.c:  uart_wait_until_sent()

uart_wait_until_sent() then sits and waits for /at most/ two characters worth 
of timeout for

linux/driver/serial/8250.c: serial8250_tx_empty()

to tell it that it can return.  It appears (in my very newbie eyes) that 
uart_wait_until_sent() checks for tx_empty() every 1/5th of a byte, I would 
think that would be more than enough.  It takes negligible time for 
serial8250_tx_empty() to call serial_in() to read the UART status register.  
I imagine that the msleep_interruptible() call is well tested in Linux.

My question then is where is the time going?  It seems suspicious that 
uart_wait_until_sent() has an overall timeout of two character times - 
exactly the excess I'm seeing.  Am I right to be suspicious?  Have I 
understood any of this?  Is it unreasonable to expect Linux to do a 200us 
turnaround?



Andy
-- 
Dr Andrew Parkins, M Eng (hons), AMIEE


[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2005-05-10  8:38 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-05 15:50 tcdrain / TCSBRK / wait_until_sent delay Andy Parkins
2005-05-05 17:51 ` rich+ml
2005-05-06  8:01   ` Andy Parkins
2005-05-06 19:14     ` rich+ml
2005-05-07  9:35       ` Andy Parkins
2005-05-07 18:09         ` rich+ml
2005-05-09  8:01           ` Andy Parkins
     [not found]             ` <Pine.LNX.4.58.0505090825470.750@deadrat.localdomain>
2005-05-10  7:44               ` Andy Parkins
2005-05-09  8:16         ` Tosoni
2005-05-09  8:59           ` Russell King
2005-05-09 10:03             ` Tosoni
2005-05-09 10:13               ` Russell King
2005-05-09 15:43                 ` Theodore Ts'o
2005-05-07 10:32       ` Gerald Emig
2005-05-09  9:15 ` Christer Weinigel
2005-05-09  9:22   ` Christer Weinigel
2005-05-09 11:05     ` Andy Parkins
2005-05-09 15:53     ` Andy Parkins
2005-05-09 19:45     ` rich+ml

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.