Cómo reiniciar ttyusb *

12

Tengo dos dispositivos que están alimentando datos continuamente a través de ttyUSB0 y ttyUSB1. Tengo scripts php que usan estos datos. El problema con el que me encuentro es que a veces la alimentación se congela. La mejor manera que he visto para solucionar esto es desconectar la placa BUB de la computadora y volver a enchufarla. Sin embargo, estoy buscando una manera de automatizar esta acción. ¿Hay alguna manera de decirle a Linux que esencialmente expulse la placa BUB y luego, de alguna manera, la levante de nuevo?

emilyk
fuente
1
Pruebe la solución en este otro hilo: stackoverflow.com/questions/21580750/…

Respuestas:

11

Tengo el mismo problema que tú pero en un contexto diferente (abro una consola serie en una caja de Linux). El enlace serie a veces deja de responder y tengo que desconectar físicamente el convertidor USB-serie.

Lo siguiente parece resolver mi problema, pero no siempre.

  1. Encuentre el controlador asociado a su dispositivo ttyUSBx.

    [my-pc] # cat / proc / tty / drivers

    /dev/tty             /dev/tty        5       0 system:/dev/tty
    /dev/console         /dev/console    5       1 system:console
    /dev/ptmx            /dev/ptmx       5       2 system
    /dev/vc/0            /dev/vc/0       4       0 system:vtmaster
    rfcomm               /dev/rfcomm   216 0-255 serial
    usbserial            /dev/ttyUSB   188 0-253 serial
    ttyprintk            /dev/ttyprintk   5       3 console
    serial               /dev/ttyS       4 64-111 serial
    pty_slave            /dev/pts      136 0-1048575 pty:slave
    pty_master           /dev/ptm      128 0-1048575 pty:master
    unknown              /dev/tty        4 1-63 console
    

    Puedes ver que /dev/ttyUSBusos usbserial. Ahora profundiza un poco más:

    [my-pc] # lsmod | grep usbserial

      usbserial              37173  1 pl2303
    

    En mi caso, mi convertidor de USB a serie es un Prolific PL2303. Si tiene un adaptador FTDI, creo que debería verlo en ftdi_siolugar de pl2303.

  2. Descargue el controlador

    sudo modprobe -r pl2303 #o el nombre que coincide con su configuración

    sudo modprobe -r usbserial

  3. Vuelva a cargar el controlador

    sudo modprobe pl2303 #o el nombre que coincide con su configuración

  4. Vuelva a iniciar su comunicación en serie

sdive
fuente
Estoy intentando eso, y todo está igual en mi sistema como usted describe. Sin embargo, cuando sigo el paso 2, dice "FATAL: el módulo usbserial está en uso". y no me deja deshabilitarlo. ¿Algunas ideas?
emilyk
1
Intenté encontrar una manera de definir qué dispositivo / proceso usa el módulo usbserial sin éxito. ¿Puedes probar "rmmod --force usbserial"?
sdive
7

Con la respuesta de sdive seguí recibiendo "FATAL: el módulo usbserial está en uso".

Finalmente resolví el problema con alguna guía de la respuesta de LiLo aquí: /ubuntu//a/661/379851

Pero en lugar de usar un código C, escribí un equivalente en Python que también encuentra el bus y el dispositivo en cuestión:

#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE
import fcntl
driver = sys.argv[-1]
print "resetting driver:", driver
USBDEVFS_RESET= 21780

try:
    lsusb_out = Popen("lsusb | grep -i %s"%driver, shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().split()
    bus = lsusb_out[1]
    device = lsusb_out[3][:-1]
    f = open("/dev/bus/usb/%s/%s"%(bus, device), 'w', os.O_WRONLY)
    fcntl.ioctl(f, USBDEVFS_RESET, 0)
except Exception, msg:
    print "failed to reset device:", msg

Simplemente guarde esto como reset_usb.py o algo y luego ejecútelo así:

sudo python reset_usb.py driver_name

Donde driver_name es la salida de

lsmod | grep usbserial

En mi caso, era cp210x, así que lo ejecuto así:

sudo python reset_usb.py cp210x
Peter
fuente
¿Es realmente necesario ioctl (f, USBDEVFS_RESET, 0) el dispositivo correspondiente en / dev / bus / usb / xxx / aaa? ¿No es suficiente dejar que la aplicación cierre () y abra () el dispositivo / dev / ttyUSBx cuando detecte que los datos ya no llegan?
Por Lindberg el
1

Aquí está mi respuesta para el módulo ftdi_sio. Los pasos se adaptan de la respuesta anterior y el enlace de un comentario en la pregunta original.

No pude eliminar el módulo:

% sudo rmmod ftdi_sio
rmmod: ERROR: Module ftdi_sio is in use
% sudo modprobe -r ftdi_sio
modprobe: FATAL: Module ftdi_sio is in use.

Entonces uso el siguiente truco:

% sudo dmesg | grep ttyUSB0
[    4.784615] usb 3-2.4: FTDI USB Serial Device converter now attached to ttyUSB0

Lo que de hecho fue verificado por:

% tree /sys/bus/usb/drivers/ftdi_sio     
/sys/bus/usb/drivers/ftdi_sio
├── 3-2.4:1.0 -> ../../../../devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2.4/3-2.4:1.0
├── bind
├── module -> ../../../../module/usbserial
├── uevent
└── unbind

2 directories, 3 files

Entonces fue fácil quitar el módulo:

# echo -n "3-2.4:1.0"  > /sys/bus/usb/drivers/ftdi_sio/unbind
# rmmod ftdi_sio 
# rmmod usbserial 

Y luego simplemente:

# modprobe ftdi_sio

Esto no está claro por qué ftdi_sio se pone en tan mal estado, tal vez todavía sea un error como en:

Pero parece que el kernel 4.9.20 todavía contiene un ftdi_siomódulo defectuoso .

malat
fuente