Como reiniciar o ttyusb *

12

Eu tenho dois dispositivos que alimentam dados continuamente através do ttyUSB0 e ttyUSB1. Eu tenho scripts php que estão usando esses dados. O problema que estou enfrentando é que, às vezes, o feed congela. A melhor maneira que eu já vi para corrigir isso é desconectar a placa BUB do computador e conectá-la novamente. No entanto, estou procurando uma maneira de automatizar essa ação. Existe uma maneira de dizer ao linux para ejetar essencialmente a placa BUB e, de alguma forma, buscá-la novamente?

emilyk
fonte
1
Tente a solução neste outro thread: stackoverflow.com/questions/21580750/…

Respostas:

11

Estou tendo o mesmo problema que você, mas em um contexto diferente (abro um console serial em uma caixa Linux). O link serial às vezes fica sem resposta e eu tenho que desconectar fisicamente o conversor serial USB.

O abaixo parece resolver o meu problema, mas nem sempre.

  1. Encontre o driver associado ao seu 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
    

    Você pode ver que /dev/ttyUSBusa usbserial. Agora cave um pouco mais:

    [my-pc] # lsmod | grep usbserial

      usbserial              37173  1 pl2303
    

    No meu caso, meu conversor USB-serial é um PL2303 da Prolific. Se você tem um adaptador FTDI, acho que você deve verftdi_sio vez de pl2303.

  2. Descarregar o driver

    sudo modprobe -r pl2303 #ou o nome que corresponde à sua configuração

    sudo modprobe -r usbserial

  3. Recarregue o driver

    sudo modprobe pl2303 #ou o nome que corresponde à sua configuração

  4. Reinicie sua comunicação serial

sdive
fonte
Estou tentando isso e tudo no meu sistema é o mesmo que você descreve. No entanto, quando sigo a etapa 2, ele diz "FATAL: o módulo usbserial está em uso". e não me deixará desativá-lo. Alguma ideia?
Emilyk
1
Eu estava tentando encontrar uma maneira de definir qual dispositivo / processo usa o módulo usbserial sem sucesso. Você pode tentar "rmmod --force usbserial"?
Sdive 28/05
7

Com a resposta do sdive, eu continuava recebendo "FATAL: o módulo usbserial está em uso".

Finalmente resolvi o problema com algumas orientações da resposta de LiLo aqui: /ubuntu//a/661/379851

Mas, em vez de usar algum código C, escrevi um equivalente em python que também encontra o barramento e o dispositivo em questão:

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

Salve isso como reset_usb.py ou algo assim e execute-o assim:

sudo python reset_usb.py driver_name

Onde driver_name é a saída de

lsmod | grep usbserial

No meu caso, era cp210x, então eu o executo assim:

sudo python reset_usb.py cp210x
Pedro
fonte
É realmente necessário ioctl (f, USBDEVFS_RESET, 0) o dispositivo correspondente em / dev / bus / usb / xxx / yyy? Não é suficiente apenas permitir que o aplicativo feche () e abra () o dispositivo / dev / ttyUSBx quando detecta que os dados não chegam mais?
Por Lindberg
1

Aqui está a minha resposta para o módulo ftdi_sio. As etapas são adaptadas da resposta acima e do link de um comentário na pergunta original.

Não foi possível remover o 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.

Então, eu uso o seguinte truque:

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

O que de fato foi 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

Então foi fácil remover o módulo:

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

E então simplesmente:

# modprobe ftdi_sio

Não está claro por que o ftdi_sio fica em tão mau estado, talvez ainda seja um bug como em:

Mas parece que o kernel 4.9.20 ainda contém um ftdi_siomódulo ruim .

malat
fonte