Un cambio en el pin DTR se puede (eventualmente) evitar usando la línea de comando
stty -F /dev/ttyUSB0 -hupcl
Esto tiene el efecto de hacer que DTR se encienda; y posteriormente, cuando el puerto se abre y se cierra, el DTR no se ve afectado.
Fuente:https://raspberrypi.stackexchange.com/questions/9695/disable-dtr-on-ttyusb0/27706#27706
Y hay un código allí para hacer lo mismo desde python a través de termios
, esto se puede hacer antes de abrir el puerto a través de pyserial:
import termios
path = '/dev/ttyACM0'
# Disable reset after hangup
with open(path) as f:
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
El OP estaba ejecutando esto en una Raspberry Pi, pero lo probé en Linux Mint en x86_64, funcionó. No sé cómo se ve afectado el RTS.
La razón por la que encuentro esto útil es para la comunicación con un Arduino Nano, que tiene un chip USB-> serie a bordo, y normalmente el Arduino se reinicia cada vez que abre el puerto serie desde Linux (el borde ascendente de DTR provoca el reinicio). Para algunas aplicaciones, esto no es un problema, pero es claramente útil evitar esto para otras aplicaciones, y no es tan fácil quitar ese pequeño capacitor del Arduino que conecta el DTR para reiniciarlo.
Aún obtendrá un solo reinicio cuando se ejecute el comando stty (después de conectar el cable USB). Pero al menos puede seguir abriendo y cerrando el puerto serie después de eso sin más reinicios.
No tengo idea de por qué querrías hacer esto, pero esto se puede hacer con bastante facilidad modificando el controlador del kernel de Linux para tu consola serie para que no alterne RTS. Por ejemplo, para el controlador de la serie 8250 en drivers/tty/serial/8250/
podría cambiar cada escritura en el registro MCR (UART_MCR) para asegurarse de que el bit 1 (la máscara es UART_MCR_RTS) nunca se establezca.
Dado que está abstraído en el espacio de usuario, no tendrá suerte si quiere hacer esto sin modificar el controlador del kernel.
Si tengo el mismo problema, lo intentaría parcheando el ftdi_sio
controlador del núcleo. Solo necesita descomentar un pequeño fragmento de código en ftdi_dtr_rts()
así:
static void ftdi_dtr_rts(struct usb_serial_port *port, int on) {
...
/* drop RTS and DTR */
if (on)
set_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- HERE
else
clear_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- and HERE
}
y la línea de protocolo de enlace RTS ya no se cambia en open()
llame. Tenga en cuenta que es posible que el uart ya no funcione con el protocolo de enlace de hardware RTS / CTS, siempre que su controlador kernel modificado esté cargado. Pero aún puede controlar el estado de la línea de protocolo de enlace RTS manualmente llamando, por ejemplo:
int opins = TIOCM_RTS;
ioctl(tty_fd, TIOCMBIC, &opins);
Probé esto con el Ctrl+A+G
comando de picocom 2.3a, ejecutando Kubuntu 16.04 de 64 bits y adaptador uart usb basado en Ftdi FT2232H.
Puede encontrar más detalles sobre este tema aquí.