* Handling RTS
@ 2008-01-09 18:17 JZabalza
2008-01-09 20:35 ` Chris Doré
0 siblings, 1 reply; 8+ messages in thread
From: JZabalza @ 2008-01-09 18:17 UTC (permalink / raw)
To: linux-serial
Hello list
I have a RS485 device connect to a PC serial port. To handle half duplex
transmision I must activate/deactivate RTS line. I think this is a very
common practice.To do this I have these functions
int set_to_write( int _port)
{
int nStatus;
if ( ioctl( _port, TIOCMGET, &nStatus ) < 0)
{
return -1;
}
else
{
nStatus |= TIOCM_RTS;
if ( ioctl( _port, TIOCMSET, &nStatus ) < 0)
{
return -2;
}
}
return 0;
}
int set_to_read( int _port )
{
int nStatus;
if ( ioctl( _port, TIOCMGET, &nStatus ) < 0)
{
return -1;
}
else
{
nStatus &= ~TIOCM_RTS;
if ( ioctl( _port, TIOCMSET, &nStatus ) < 0)
{
return -2;
}
}
return 0;
}
To send bytes I have this code
set_to_write(port);
write(port,"bytes to send",len);
tcdrain(port)
set_to_read(port);
All is running succesfully but when I put oscilloscope I can see 10 mS (or
more) latency time from set_to_write() to write() begin to send
characters. I know this is a Linux userland issue but, is there another
way to do this from driver, similar a cflag CRTSCTS to activate RTS/CTS
protocol?.
If there is not another way, which shall be the best strategy to implement
this (activate RTS when uart is transmiting data and deactivate when
transmision is finish. It would be another protocol different but similar
to RTS/CTS protocol) on linux driver (modifying serial_core.c to accept a
new CFLAG?) ?
thank you very munch for your help.
José Luis Zabalza
-
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread* RE: Handling RTS 2008-01-09 18:17 Handling RTS JZabalza @ 2008-01-09 20:35 ` Chris Doré 2008-01-10 8:27 ` JZabalza 0 siblings, 1 reply; 8+ messages in thread From: Chris Doré @ 2008-01-09 20:35 UTC (permalink / raw) To: linux-serial > -----Original Message----- > From: linux-serial-owner@vger.kernel.org [mailto:linux-serial- > owner@vger.kernel.org] On Behalf Of JZabalza@cemitec.com > Sent: January 9, 2008 1:18 PM > > If there is not another way, which shall be the best strategy to implement > this (activate RTS when uart is transmiting data and deactivate when > transmision is finish. It would be another protocol different but similar > to RTS/CTS protocol) on linux driver (modifying serial_core.c to accept a > new CFLAG?) ? What UART are you using? Some newer UARTs have built-in capabilities for the RTS framing. So instead of having to toggle RTS manually, you can flip a bit and let the UART do it for you whenever it transmits...unless that won't work for you. .Chris ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Handling RTS 2008-01-09 20:35 ` Chris Doré @ 2008-01-10 8:27 ` JZabalza 2008-01-14 15:05 ` Chris Doré 0 siblings, 1 reply; 8+ messages in thread From: JZabalza @ 2008-01-10 8:27 UTC (permalink / raw) To: linux-serial linux-serial-owner@vger.kernel.org escribió el 09/01/2008 21:35:43: > > -----Original Message----- > > From: linux-serial-owner@vger.kernel.org [mailto:linux-serial- > > owner@vger.kernel.org] On Behalf Of JZabalza@cemitec.com > > Sent: January 9, 2008 1:18 PM > > > > If there is not another way, which shall be the best strategy to implement > > this (activate RTS when uart is transmiting data and deactivate when > > transmision is finish. It would be another protocol different but similar > > to RTS/CTS protocol) on linux driver (modifying serial_core.c to accept a > > new CFLAG?) ? > > What UART are you using? Some newer UARTs have built-in capabilities for > the RTS framing. So instead of having to toggle RTS manually, you can flip > a bit and let the UART do it for you whenever it transmits...unless that > won't work for you. > Thanks for your response. I have a PC, so dmesg said serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A How I said, I just handle RTS but from userland. This means a big latency between RTS activation and begin out data. I want only reduce this latency activating RTS on driver. My question is, is this *protocol* implemented actually or I must implement them. Thank you very munch. José Luis Zabalza - To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Handling RTS 2008-01-10 8:27 ` JZabalza @ 2008-01-14 15:05 ` Chris Doré 2008-01-21 11:57 ` JZabalza 0 siblings, 1 reply; 8+ messages in thread From: Chris Doré @ 2008-01-14 15:05 UTC (permalink / raw) To: linux-serial > From: linux-serial-owner@vger.kernel.org [mailto:linux-serial- > owner@vger.kernel.org] On Behalf Of JZabalza@cemitec.com > Sent: January 10, 2008 3:27 AM > To: linux-serial > Subject: RE: Handling RTS > > Thanks for your response. I have a PC, so dmesg said > > serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A > > How I said, I just handle RTS but from userland. This means a big > latency between RTS activation and begin out data. I want only reduce this > latency activating RTS on driver. My question is, is this *protocol* > implemented actually or I must implement them. I'm not an expert on the current 8250 driver, but I believe you will have to implement your 485 control. We may have done this in one of our drivers, but in my quick search I can't find one that doesn't take advantage of the extra features supplied by the UARTs we use. Best of luck, Chris ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Handling RTS 2008-01-14 15:05 ` Chris Doré @ 2008-01-21 11:57 ` JZabalza 2008-01-24 13:42 ` Tosoni 0 siblings, 1 reply; 8+ messages in thread From: JZabalza @ 2008-01-21 11:57 UTC (permalink / raw) To: linux-serial, linux-serial-owner linux-serial-owner@vger.kernel.org escribió el 14/01/2008 16:05:03: > > From: linux-serial-owner@vger.kernel.org [mailto:linux-serial- > > owner@vger.kernel.org] On Behalf Of JZabalza@cemitec.com > > Sent: January 10, 2008 3:27 AM > > To: linux-serial > > Subject: RE: Handling RTS > > > > Thanks for your response. I have a PC, so dmesg said > > > > serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A > > > > How I said, I just handle RTS but from userland. This means a big > > latency between RTS activation and begin out data. I want only reduce this > > latency activating RTS on driver. My question is, is this *protocol* > > implemented actually or I must implement them. > > I'm not an expert on the current 8250 driver, but I believe you will have to > implement your 485 control. > I'm not an expert too, but my question is, if is posible and good idea modify common layer of serial linux driver (serial_core.c) to implement a **walky-talky** protocol with RTS line, this is, activate RTS when there are chars to transmit and deactivate when there is not any character. Thanks. José Luis Zabalza - To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Handling RTS 2008-01-21 11:57 ` JZabalza @ 2008-01-24 13:42 ` Tosoni 2008-01-25 9:37 ` JZabalza 0 siblings, 1 reply; 8+ messages in thread From: Tosoni @ 2008-01-24 13:42 UTC (permalink / raw) To: JZabalza, 'linux-serial', linux-serial-owner It has been known since long ago that this behaviour (which is required to properly handle many RS485 devices) is not implemented by the serial driver. So yes, you will have to implement it. There are several ways to do it, by creating a new line discipline as suggested by Russell King, or a new termios behaviour, or a new serial ioctl. In any case you will also need to add support for this in the 8250 driver itself. You can do this - by using special features of 82950 uarts (I did this once), - or by implementing RTS toggleing in software, which (1) is more difficult because there is no UART interrupt at the end of the byte serialization process, (2) is more flexible because you may want to handle a configurable delay between RTS rise/data/RTS fall, (3) is the only way with the 16C550 and earlier devices. Jean-Pierre Tosoni > -----Original Message----- > From: linux-serial-owner@vger.kernel.org > [mailto:linux-serial-owner@vger.kernel.org]On Behalf Of > JZabalza@cemitec.com > Sent: Monday, January 21, 2008 12:57 PM > To: linux-serial; linux-serial-owner@vger.kernel.org > Subject: RE: Handling RTS > > > linux-serial-owner@vger.kernel.org escribió el 14/01/2008 16:05:03: > > > > From: linux-serial-owner@vger.kernel.org [mailto:linux-serial- > > > owner@vger.kernel.org] On Behalf Of JZabalza@cemitec.com > > > Sent: January 10, 2008 3:27 AM > > > To: linux-serial > > > Subject: RE: Handling RTS > > > > > > Thanks for your response. I have a PC, so dmesg said > > > > > > serial8250: ttyS0 at I/O 0x3f8 (irq = 4) > is a 16550A > > > > > > How I said, I just handle RTS but from userland. > This means a > big > > > latency between RTS activation and begin out data. I want > only reduce > this > > > latency activating RTS on driver. My question is, is this > *protocol* > > > implemented actually or I must implement them. > > > > I'm not an expert on the current 8250 driver, but I believe > you will > have to > > implement your 485 control. > > > > I'm not an expert too, but my question is, if is > posible and good > idea modify common layer of serial linux driver (serial_core.c) to > implement a **walky-talky** protocol with RTS line, this is, > activate RTS > when there are chars to transmit and deactivate when there is not any > character. > > Thanks. > > > José Luis Zabalza > > - > To unsubscribe from this list: send the line "unsubscribe > linux-serial" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > - To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Handling RTS 2008-01-24 13:42 ` Tosoni @ 2008-01-25 9:37 ` JZabalza 2008-01-28 9:27 ` Tosoni 0 siblings, 1 reply; 8+ messages in thread From: JZabalza @ 2008-01-25 9:37 UTC (permalink / raw) To: 'linux-serial'; +Cc: Tosoni linux-serial-owner@vger.kernel.org escribió el 24/01/2008 14:42:14: Thank you very munch for your response Jean-Pierre. I think you understand me. > It has been known since long ago that this behaviour (which is required to > properly handle many RS485 devices) is not implemented by the serial driver. > > So yes, you will have to implement it. > There are several ways to do it, by creating a new line discipline as > suggested by Russell King, or a new termios behaviour, or a new serial > ioctl. Yes, but, I am confused. A line discipline is oriented to translate data not to handle flow control protocol , isn't It? > > In any case you will also need to add support for this in the 8250 driver > itself. You can do this > - by using special features of 82950 uarts (I did this once), > - or by implementing RTS toggleing in software, which > (1) is more difficult because there is no UART interrupt > at the end of the byte serialization process, > (2) is more flexible because you may want to handle a > configurable delay between RTS rise/data/RTS fall, > (3) is the only way with the 16C550 and earlier devices. > Yes, but it's only for 8250 uart. I think that all uarts have RTS pin. I know it's not true, but For example this code snipet from serial_core.c static void __uart_start(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct uart_port *port = state->port; if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf && !tty->stopped && !tty->hw_stopped) port->ops->start_tx(port); } is it posible activate RTS just before start_tx() call using uart_update_mctrl() function? This shall be used by all uarts, isn't it? Is it posible implement RTS handling on serial_core.c module to be common to all uarts? Thanks in avance José Luis Zabalza - To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: Handling RTS 2008-01-25 9:37 ` JZabalza @ 2008-01-28 9:27 ` Tosoni 0 siblings, 0 replies; 8+ messages in thread From: Tosoni @ 2008-01-28 9:27 UTC (permalink / raw) To: JZabalza, 'linux-serial'; +Cc: Jean-Pierre TOSONI Please note that the subject has been discussed in deep several times : http://www.spinics.net/lists/linux-serial/msg00303.html http://www.mail-archive.com/linux-serial@vger.rutgers.edu/msg00407.html Also the driver CRISV10.C once had some provision for RTS toggle (at least this was true three years ago). I gave you some of my code below, which diverts from the CRISV10 ioctl in a compatible way. I can send you all the code offline if you wish (not sure it will help more although). > Yes, but, I am confused. A line discipline is oriented to translate data > not to handle flow control protocol , isn't It? > - A line discipline defines a way to manage the transmission line, not merely data translation but mainly the protocol. So it is a good place to enforce half duplex for example. > Is it posible implement RTS handling on serial_core.c module to be common to all uarts? > This shall be used by all uarts, isn't it? > - Well, yes. But some people won't want the feature, so it must be configurable in some way. hence the need for an ioctl (callable from user space or from a line discipline, whatever). > is it posible activate RTS just before start_tx() call using uart_update_mctrl() function? > - I am not familiar with this part of the driver, but there is a problem mainly with the RTS drop, because we don't know for sure when the UART serializer is empty. So the implementation on the 8250 requires to start a timer when the driver's buffer becomes empty. It's no easy because some uarts have fifo's of their own. - Also, I have encountered cases where a parametrized delay was needed between RTS and data, so it would be great if your new IOCTL has parameters to do this (even if you only implement the 'zero delay' case) just like I have done in my own implementation, and the CRISV10 driver does the full implementation. - Also, pay attention to this use of RTS that may go in the way of flow control by RTS (CRTSCTS flag), you may want to disable flow control when you activate RTS toggling. Here is what I am using for a 82950 device. The ioctl can be used for any UART but my implementation applies only to the 82950, so, I don't need to change the RTS in the transmission data path: ///// in 8250.c: //////////////////// added in uart_ops serial8250_pops: .ioctl = serial8250_ioctl, then: static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) { struct uart_8250_port *up = (struct uart_8250_port *)port; int ret = -ENOIOCTLCMD; switch (cmd) { case TIOCSERSETRS485: if (up->port.type == PORT_16C950) { // arg may be 1 or struct rs485_control * // in order to be crisv10 compatible /* HERE, STUFF to activate built-in 16C950 RTS toggle */ ... return 0; } // else, it may be the RTS-TOGGLE kind of RS485 device, needs // more work to support. See crisv10.c. break; default: break; } return ret; } ///// misc defines which should be included in linux standard headers //////// /* in asm-i386/ioctls.h */ #ifndef TIOCSERSETRS485 #define TIOCSERSETRS485 0x5461 /* enable rs-485 */ #define TIOCSERWRRS485 0x5462 /* write rs-485 */ #endif ///////////// sample use ///////////////////// #include <stdio.h> //#include "ioctls.h" #include <linux/termios.h> //#include <sys/ioctl.h> #ifndef TIOCSERSETRS485 #define TIOCSERSETRS485 0x5461 /* enable rs-485 */ #define TIOCSERWRRS485 0x5462 /* write rs-485 */ #endif main(int c,char **v) { int fd,i; char t[1000]; if (c != 3) { fprintf(stderr,"usage: %s /dev/ttySxxx 0-or-1\n",v[0]); exit(1); } fd = open(v[1],2); if(fd < 0) { perror(v[1]); exit(1); } i = ioctl(fd,TIOCSERSETRS485,atoi(v[2])); if(i < 0) { perror("TIOCRS485"); } printf("%s set to %s\n",v[1],atoi(v[2]) ? "RS485 auto turnaround using DTR" : "normal full-duplex mode"); close(fd); } > -----Original Message----- > From: JZabalza@cemitec.com [mailto:JZabalza@cemitec.com] > Sent: Friday, January 25, 2008 10:38 AM > To: 'linux-serial' > Cc: Tosoni > Subject: RE: Handling RTS > > > linux-serial-owner@vger.kernel.org escribió el 24/01/2008 14:42:14: > > Thank you very munch for your response Jean-Pierre. I think > you understand > me. > > > It has been known since long ago that this behaviour (which > is required > to > > properly handle many RS485 devices) is not implemented by > the serial > driver. > > > > So yes, you will have to implement it. > > There are several ways to do it, by creating a new line > discipline as > > suggested by Russell King, or a new termios behaviour, or a > new serial > > ioctl. > > > Yes, but, I am confused. A line discipline is oriented to > translate data > not to handle flow control protocol , isn't It? > > > > > > In any case you will also need to add support for this in the 8250 > driver > > itself. You can do this > > - by using special features of 82950 uarts (I did this once), > > - or by implementing RTS toggleing in software, which > > (1) is more difficult because there is no UART interrupt > > at the end of the byte serialization process, > > (2) is more flexible because you may want to handle a > > configurable delay between RTS rise/data/RTS fall, > > (3) is the only way with the 16C550 and earlier devices. > > > > Yes, but it's only for 8250 uart. I think that all uarts have > RTS pin. I > know it's not true, but > > For example this code snipet from serial_core.c > > static void __uart_start(struct tty_struct *tty) > { > struct uart_state *state = tty->driver_data; > struct uart_port *port = state->port; > > if (!uart_circ_empty(&state->info->xmit) && > state->info->xmit.buf > && > !tty->stopped && !tty->hw_stopped) > port->ops->start_tx(port); > } > > is it posible activate RTS just before start_tx() call using > uart_update_mctrl() function? > > This shall be used by all uarts, isn't it? > > Is it posible implement RTS handling on serial_core.c module > to be common > to all uarts? > > Thanks in avance > > > > > > > > > José Luis Zabalza > > - To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-01-28 9:27 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-01-09 18:17 Handling RTS JZabalza 2008-01-09 20:35 ` Chris Doré 2008-01-10 8:27 ` JZabalza 2008-01-14 15:05 ` Chris Doré 2008-01-21 11:57 ` JZabalza 2008-01-24 13:42 ` Tosoni 2008-01-25 9:37 ` JZabalza 2008-01-28 9:27 ` Tosoni
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox