У меня есть два устройства, которые непрерывно подают данные через ttyUSB0 и ttyUSB1. У меня есть PHP-скрипты, которые используют эти данные. Проблема, с которой я сталкиваюсь, заключается в том, что иногда корм просто зависает. Лучший способ, который я видел, чтобы это исправить, это отключить плату BUB от компьютера и снова подключить ее. Однако я ищу способ автоматизировать это действие. Есть ли способ сказать linux, чтобы он по существу извлек плату BUB, а затем каким-то образом снова поднял ее?
3 ответа
У меня та же проблема, что и у вас, но в другом контексте (я открываю последовательную консоль на Linux-коробке). Последовательная связь иногда перестает отвечать, и мне приходится физически отключать USB-последовательный преобразователь.
Ниже, кажется, решить мою проблему, но не всегда.
Найдите драйвер, связанный с вашим устройством 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
Вы можете видеть, что
/dev/ttyUSB
используетusbserial
. Теперь копайте немного дальше:[my-pc] # lsmod | grep usbserial
usbserial 37173 1 pl2303
В моем случае мой конвертер USB-последовательный - это Prolific PL2303. Если у вас есть адаптер FTDI, я думаю, вы должны увидеть
ftdi_sio
вместоpl2303
.Выгрузить драйвер
sudo modprobe -r pl2303 # или имя, соответствующее вашей конфигурации
sudo modprobe -r usbserial
Перезагрузите драйвер
sudo modprobe pl2303 # или имя, соответствующее вашей конфигурации
Перезапустите вашу последовательную связь
С ответом sdive я продолжал получать сообщение «FATAL: модуль usbserial используется».
Я наконец решил проблему с некоторыми рекомендациями из ответа LiLo здесь:https://askubuntu.com/a/661/379851
Но вместо того, чтобы использовать некоторый C-код, я написал Python-эквивалент, который также находит нужную шину и устройство:
#!/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
Просто сохраните это как reset_usb.py или что-то еще, а затем запустите его так:
sudo python reset_usb.py driver_name
Где имя_драйвера это выход
lsmod | grep usbserial
В моем случае это был cp210x, поэтому я запускаю его так:
sudo python reset_usb.py cp210x
Вот мой ответ для модуля ftdi_sio
. Шаги адаптированы из приведенного выше ответа и ссылки из комментария в исходном вопросе.
Я не мог получить модуль для удаления:
% 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.
Поэтому я использую следующий трюк:
% sudo dmesg | grep ttyUSB0
[ 4.784615] usb 3-2.4: FTDI USB Serial Device converter now attached to ttyUSB0
Что действительно было подтверждено:
% 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
Тогда было легко удалить модуль:
# echo -n "3-2.4:1.0" > /sys/bus/usb/drivers/ftdi_sio/unbind
# rmmod ftdi_sio
# rmmod usbserial
А потом просто:
# modprobe ftdi_sio
Непонятно, почему ftdi_sio находится в такой плохой форме, может быть, все еще ошибка, как в:
Но, похоже, ядро 4.9.20 все еще содержит плохой модуль ftdi_sio
.