É possível redefinir a conexão de um dispositivo USB, sem desconectar/conectar fisicamente do PC?
Especificamente, meu dispositivo é uma câmera digital. Estou usando gphoto2
, mas ultimamente recebo "erros de leitura do dispositivo", então gostaria de tentar fazer uma redefinição de software da conexão.
Pelo que posso dizer, não há módulos do kernel sendo carregados para a câmera. O único que parece relacionado é usbhid
.
Salve o seguinte como
usbreset.c
Execute os seguintes comandos no terminal:
Compile o programa:
Obtenha o Bus and Device ID do dispositivo USB que você deseja redefinir:
Torne nosso programa compilado executável:
Execute o programa com privilégio sudo; faça a substituição necessária para
<Bus>
e<Device>
ids conforme encontrado executando olsusb
comando:Fonte do programa acima: http://marc.info/?l=linux-usb&m=121459435621262&w=2
Eu não me encontrei em suas circunstâncias específicas antes, então não tenho certeza se isso fará o suficiente, mas a maneira mais simples que encontrei para redefinir um dispositivo USB é este comando: (Não são necessários aplicativos externos)
Esse é o real que eu uso para redefinir meu Kinect, já que libfreenect parece não ter API para colocá-lo de volta no modo de suspensão. Está na minha caixa do Gentoo, mas o kernel deve ser novo o suficiente para usar a mesma estrutura de caminho para sysfs.
O seu obviamente não seria,
1-4.6
mas você pode extrair esse caminho do dispositivo do seu log do kernel (dmesg
) ou pode usar algo comolsusb
obter os IDs do fornecedor e do produto e, em seguida, usar um comando rápido como este para listar como os caminhos se relacionam com diferentes fornecedores /pares de ID do produto:Isso irá redefinir todas as portas conectadas USB1/2/3[1]:
Acredito que isso resolverá seu problema. Se você não quiser redefinir todos os terminais USB, você pode usar o ID de dispositivo apropriado de
/sys/bus/pci/drivers/ehci_hcd
Notas: [1]: os
*hci_hcd
drivers do kernel normalmente controlam as portas USB.ohci_hcd
euhci_hcd
são para portas USB1.1,ehci_hcd
são para portas USB2 exhci_hcd
são para portas USB3. (consulte https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire) )I've created a Python script that simplifies the whole process based on answers here.
Save the script below as reset_usb.py or clone this repo.
Usage:
Script:
Eu precisava automatizar isso em um script python, então adaptei a resposta extremamente útil do LiLo para o seguinte:
No meu caso, era o driver cp210x (que eu poderia dizer de
lsmod | grep usbserial
), então você poderia salvar o trecho acima como reset_usb.py e depois fazer isso:Isso também pode ser útil se você ainda não tiver a configuração do compilador AC em seu sistema, mas tiver o python.
Since the APT package usbutils provides the usbreset binary you can just reset the USB device by:
Estou usando uma espécie de marreta recarregando os módulos. Este é o meu script usb_reset.sh:
E este é o meu arquivo de serviço systemd /usr/lib/systemd/system/usbreset.service que executa usb_reset.sh depois que meu gerenciador de exibição foi iniciado:
A maneira mais rápida de redefinir será redefinir o próprio controlador USB. Fazer isso forçará o udev a cancelar o registro do dispositivo na desconexão e o registro estará de volta assim que você habilitá-lo.
Isso deve funcionar para a maioria dos ambientes de PC. No entanto, se você estiver usando algum hardware personalizado, poderá simplesmente percorrer os nomes dos dispositivos. Com este método você não precisa descobrir o nome do dispositivo por lsusb. Você também pode incorporar em um script automatizado.
Como o caso especial da questão é um problema de comunicação do gphoto2 com uma câmera em USB, existe uma opção no gphoto2 para redefinir sua conexão USB:
Talvez essa opção não existisse em 2010 quando a pergunta foi feita.
Eu fiz um script python que redefinirá um dispositivo USB específico com base no número do dispositivo. Você pode descobrir o número do dispositivo no comando lsusb.
por exemplo:
Nesta string 004 é o número do dispositivo