Pular para o conteúdo

Como reiniciar o USB sem tirar o cabo

Dica publicada em C/C++ / Avançado
Fábio Berbert de Paula fabio
Hits: 17.871 Categoria: C/C++ Subcategoria: Avançado
  • Indicar
  • Impressora
  • Denunciar
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Como reiniciar o USB sem tirar o cabo

Nesta dica veremos como reiniciar um dispositivo USB sem a necessidade de desconectar/conectar o cabo do PC. Isso pode ser bem útil em casos onde o dispositivo plugado apresenta instabilidade. Li relatos de que isso ocorre em algumas câmeras digitais.

No meu caso, estou desenvolvendo scripts para teste de UI em dispositivos Android e após algumas horas conectado ao PC, meu celular começava a apresentar comunicação instável com o adb (Android Debugger Bridge). Antes desta solução, minha única saída era desconectar/conectar o cabo, o que inviabilizava a execução do script de forma automática.

Solução 1 - Resetando todos os dispositivos USB

O programa abaixo reinicia todos os dispositivos USB conectados ao PC.

#include <stdio.h>
#include <usb.h>

int main(void)
{
      struct usb_bus *busses;
      usb_init();
      usb_find_busses();
      usb_find_devices();
      busses = usb_get_busses();
      struct usb_bus *bus;
      int c, i, a;
 ;     /* ... */
      for (bus = busses; bus; bus = bus->next) {
        struct usb_device *dev;
        int val;
        usb_dev_handle *junk;
        for (dev = bus->devices; dev; dev = dev->next) {
          char buf[1024];
          junk = usb_open ( dev );
          usb_get_string_simple(junk,2,buf,1023);
          if ( junk == NULL ){
            printf("Can't open %p (%s)\n", dev, buf );
          } else {
            val = usb_reset(junk);
            printf( "reset %p %d (%s)\n", dev, val, buf );
          }
          usb_close(junk);
        }
      }
}
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Salve o código acima num arquivo e compile-o. Salvei como usb_reset_all.c:

gcc -o usb_reset_all usb_reset_all.c

Agora basta executar e conferir o resultado nos logs:

./usb_reset_all

$ sudo tail -f /var/log/syslog


Fonte: Resetting the USB Bus under linux - ClearChain

Solução 2 - Resetando apenas um dispositivo

Se você deseja escolher o dispositivo a ser reiniciado, utilize o código a seguir.

#include <stdio.h> #include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>

void main(int argc, char **argv)

{

   const char *filename;

   int fd;

   filename = argv[1];

   fd = open(filename, O_WRONLY);

   ioctl(fd, USBDEVFS_RESET, 0);

   close(fd);

   return;

}

Salve o código acima num arquivo e compile-o. Salvei como usb_reset_one.c:

gcc -o usb_reset_one usb_reset_one.c

Antes de executá-lo devemos identificar o dispositivo a ser reiniciado. No meu caso um celular da Samsung:

lsusb
Bus 001 Device 002: ID 046d:c408 Logitech, Inc. Marble Mouse (4-button)
Bus 001 Device 003: ID 045e:009d Microsoft Corp. Wireless Optical Desktop 3.0
Bus 004 Device 110: ID 04e8:6866 Samsung Electronics Co., Ltd
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Ou seja, dispositivo 110 do barramento 004.

Sendo assim:

./usb_reset_one /dev/bus/usb/004/110

Fonte: How to reset a USB device without unplugging Linux from the command line | Linux world

Fico por aqui. Sei que trata-se de uma necessidade pouco comum, mas espero que ajude quem por ventura venha a precisar.

O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Reproduzindo somente áudio com o mplayer

Como evitar que o CSS do teu site fique armazenado em cache

Crack Attack! Jogo para quem tem QI (estilo Tetris Attack)

Como gerenciar sua conta Twitter via linha de comando

Como converter imagens PNG/JPEG para SVG em linha de comando

Usando o realloc

Ebook - Advanced Linux Programming

C++ vs Java

Assembly inline no GCC com sintaxe Intel

Compiladores C/C++ e Fortran

#1 Comentário enviado por rahremix em 15/08/2013 - 14:24h
Obrigado!

Vou testar no meu computador, apesar da situação ser um pouco diferente pode ser que me ajude!
#2 Comentário enviado por julio_hoffimann em 15/08/2013 - 17:58h
Ótima dica Fábio.

Abs.
#3 Comentário enviado por danniel-lara em 15/08/2013 - 22:38h
Parabens pela dica
#4 Comentário enviado por kito.eag em 02/09/2017 - 20:47h
Não estava conseguindo compilar o primeiro código.
Só consegui deste jeito:
#include <stdio.h>
#include <usb.h>

int main(void)
{
struct usb_bus *busses;
usb_init();
usb_find_busses();
usb_find_devices();
busses = usb_get_busses();
struct usb_bus *bus;
int c, i, a;
/* ... */
for (bus = busses; bus; bus = bus->next) {
struct usb_device *dev;
int val;
usb_dev_handle *junk;
for (dev = bus->devices; dev; dev = dev->next) {
char buf[1024];
junk = usb_open ( dev );
usb_get_string_simple(junk,2,buf,1023);
if ( junk == NULL ){
printf("Can't open %p (%s)\n", dev, buf );
} else {
val = usb_reset(junk);
printf( "reset %p %d (%s)\n", dev, val, buf );
}
usb_close(junk);
}
}
}


E pra compilar usei o comando:
gcc -o reset_all_usb reset_all_usb.c -lusb



#5 Comentário enviado por jbtozetti em 22/07/2020 - 10:59h
Bom dia

Eu precisaria reiniciar a USB pelo vendor e o ID do dispositivo, tem como?
#7 Comentário enviado por jbtozetti em 22/07/2020 - 13:34h


oPA!

Eu tinha visto esta dica, porém preciso colocar num script q faça isso em várias maquinas diferentes e à medida q o dispositivo é espetado numa porta USB diferente as informações se alteram e o script não funcioaria

Já o vendor e o product são fixos em todas as máquinas independente de qual porta estão espetados

[ ]'s

Contribuir com comentário

Entre na sua conta para comentar.