Jak zrestartować ttyusb *

12

Mam dwa urządzenia, które stale przesyłają dane przez ttyUSB0 i ttyUSB1. Mam skrypty php, które używają tych danych. Problem, na który wpadam, polega na tym, że czasami kanał po prostu się zawiesza. Najlepszym sposobem, jaki widziałem, aby to naprawić, jest odłączenie płyty BUB od komputera i podłączenie jej ponownie. Szukam jednak sposobu na zautomatyzowanie tej akcji. Czy istnieje sposób, aby powiedzieć linuxowi, aby zasadniczo wysunął płytę BUB, a następnie jakoś ją podniósł?

emilyk
źródło
1
Wypróbuj rozwiązanie w tym drugim wątku: stackoverflow.com/questions/21580750/…

Odpowiedzi:

11

Mam ten sam problem co ty, ale w innym kontekście (otwieram konsolę szeregową na Linux-ie). Łącze szeregowe czasami przestaje odpowiadać i muszę fizycznie odłączyć konwerter szeregowy USB.

Poniższe wydaje się rozwiązać mój problem, ale nie zawsze.

  1. Znajdź sterownik powiązany z urządzeniem 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
    

    Możesz zobaczyć, że /dev/ttyUSBużywa usbserial. Teraz wykop trochę dalej:

    [my-pc] # lsmod | grep usbserial

      usbserial              37173  1 pl2303
    

    W moim przypadku mój konwerter USB na szeregowy to Prolific PL2303. Jeśli masz adapter FTDI, myślę, że powinieneś zobaczyć ftdi_siozamiast pl2303.

  2. Zwolnij sterownik

    sudo modprobe -r pl2303 #lub nazwę pasującą do twojej konfiguracji

    sudo modprobe -r usbserial

  3. Załaduj ponownie sterownik

    sudo modprobe pl2303 #lub nazwę pasującą do twojej konfiguracji

  4. Uruchom ponownie komunikację szeregową

sdive
źródło
Próbuję tego i wszystko jest takie samo w moim systemie, jak opisujesz. Jednak gdy wykonuję krok 2, napisane jest „FATAL: Moduł usbserial jest w użyciu”. i nie pozwala mi tego wyłączyć. Jakieś pomysły?
emilyk
1
Próbowałem znaleźć sposób, aby określić, które urządzenie / proces używa modułu usbserial bez powodzenia. Czy możesz wypróbować „rmmod --force usbserial”?
sdive
7

Dzięki odpowiedzi sdive ciągle otrzymywałem komunikat „FATAL: Moduł usbserial jest w użyciu”.

W końcu rozwiązałem problem z kilkoma wskazówkami z odpowiedzi LiLo tutaj: /ubuntu//a/661/379851

Ale zamiast używać jakiegoś kodu C, napisałem odpowiednik Pythona, który również znajduje przedmiotową magistralę i urządzenie:

#!/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

Po prostu zapisz to jako reset_usb.py lub coś, a następnie uruchom w następujący sposób:

sudo python reset_usb.py driver_name

Gdzie nazwa_kierowcy jest wyjściem

lsmod | grep usbserial

W moim przypadku był to cp210x, więc uruchamiam go w następujący sposób:

sudo python reset_usb.py cp210x
Piotr
źródło
Czy naprawdę konieczne jest ioctl (f, USBDEVFS_RESET, 0) odpowiedniego urządzenia na / dev / bus / usb / xxx / rrr? Czy nie wystarczy pozwolić aplikacji na zamknięcie () i otwarcie () urządzenia / dev / ttyUSBx, gdy wykryje, że dane już nie docierają?
Per Lindberg,
1

Oto moja odpowiedź na moduł ftdi_sio. Kroki są dostosowane z powyższej odpowiedzi i linku z komentarza w pierwotnym pytaniu.

Nie udało mi się usunąć modułu:

% 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.

Więc używam następującej sztuczki:

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

Który rzeczywiście został zweryfikowany przez:

% 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

Następnie łatwo było usunąć moduł:

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

A potem po prostu:

# modprobe ftdi_sio

Nie jest jasne, dlaczego ftdi_sio jest w tak złym stanie, może nadal jest błędem, jak w:

Ale wygląda na to, że jądro 4.9.20 nadal zawiera zły ftdi_siomoduł.

malat
źródło