>_ DevTrendses

Idioma

Inicio

Lenguajes

Secciones

Frontend Backend Móvil DevOps AI / ML GameDev Blockchain Embebidos Seguridad
C

Cómo cortar programáticamente la alimentación de un dispositivo USB atascado usando uhubctl

Imagina una situación común: un módem 4G se ha congelado en un servidor remoto, un router de dacha o un banco de pruebas. O una placa Raspberry Pi ha cambiado a un modo anormal, y un controlador de impresora 3D ha dejado de responder a los comandos. Un reinicio normal del SO no ayuda porque la energía sigue llegando a los puertos USB. La única opción es conducir al sitio y desenchufar manualmente el cable.

Si no quieres trabajar como "administrador ambulante", la utilidad uhubctl te será de gran ayuda. Vadim Mikhaylov escribió esta herramienta en C en 2015, y el proyecto sigue activo. El propósito principal del programa es enviar comandos USB de bajo nivel al controlador del hub para que elimine físicamente el voltaje VBUS de un puerto específico.

Cómo funciona y el truco del hardware

uhubctl no realiza milagros de la nada. Solo funciona con hubs donde el fabricante ha implementado soporte de hardware para la conmutación de alimentación por puerto (PPPS). Según los estándares USB 2.0 y USB 3.0, esta especificación existe desde hace mucho tiempo, pero los recortes de costos en los componentes de energía hacen que muchos hubs económicos combinen la energía de todos los puertos en una sola línea.

Sin embargo, hay suficientes dispositivos compatibles en el mercado. El repositorio mantiene una tabla detallada con docenas de modelos verificados:

  • Hubs integrados en monitores Dell, LG, BenQ y Acer.
  • Computadoras de placa única Raspberry Pi (en los modelos 3B+ y 4B, puedes desactivar la alimentación, aunque con algunos matices).
  • Hubs externos de Anker, D-Link, Rosonway y Plugable.
  • Placas base Asus y controladores industriales KUNBUS RevPi.

Bajo el capó

uhubctl se comunica con el hub a través de la biblioteca libusb o directamente a través de las interfaces del kernel de Linux. El kernel de Linux 6.0 introdujo un mecanismo estándar para deshabilitar puertos a través de sysfs. La utilidad prueba esto primero, y si estás ejecutando un sistema más antiguo o macOS, cambia a libusb.

Hay un matiz con USB 3.0. Cuando conectas un hub moderno a un puerto USB 3.0, el sistema lo ve como dos dispositivos lógicos separados: un hub virtual USB 2.0 y un hub virtual USB 3.0. Si cortas la alimentación del puerto en solo una rama, el dispositivo conectado puede simplemente cambiar a la otra velocidad y continuar funcionando. uhubctl maneja esta rutina por ti y realiza una desconexión síncrona en ambos hubs virtuales.

Instalación e inicio rápido

En la mayoría de las distribuciones Linux, la utilidad ya está disponible en los repositorios estándar:

sudo apt install uhubctl

Para macOS, la instalación se hace a través de Homebrew:

brew install uhubctl

Si tu distribución tiene una versión desactualizada, compilar desde las fuentes de Git es sencillo. Necesitarás libusb-1.0 y make:

git clone https://github.com/mvp/uhubctl
cd uhubctl
make
sudo make install

Primero, debes ejecutar la utilidad sin parámetros para ver una lista de hubs disponibles y dispositivos conectados a ellos:

sudo uhubctl

El comando mostrará la topología del bus, las direcciones del hub en formato 1-1 o 2-3.1, y el estado de cada puerto.

Ejemplos de comandos

Para cortar la alimentación del segundo puerto en el hub predeterminado, ejecuta:

sudo uhubctl -a off -p 2

En lugar de off y on, puedes pasar la acción cycle. Deshabilita la alimentación, espera una breve pausa y la vuelve a encender. Esto es adecuado para un reinicio duro de equipos congelados:

sudo uhubctl -a cycle -p 2 -d 3

El parámetro -d 3 establece un retraso de 3 segundos antes de restaurar la alimentación. Si necesitas reiniciar varios puertos a la vez, especifícalos separados por comas o un guión: -p 1,3,4 o -p 1-4.

Configuración de permisos de acceso en Linux

Por defecto, trabajar directamente con dispositivos USB requiere privilegios de root. Para evitar ejecutar scripts a través de sudo, añade reglas udev al archivo /etc/udev/rules.d/52-usb.rules:

SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666" SUBSYSTEM=="usb", DRIVER=="hub|usb", RUN="/bin/sh -c \"chmod -f 666 $sys$devpath/*port*/disable || true\""

Después de eso, ejecuta sudo udevadm trigger --attr-match=subsystem=usb, y los permisos se actualizarán.

Casos de uso prácticos

Los desarrolladores y administradores de sistemas usan uhubctl en una amplia variedad de tareas:

  • Reinicio automático de módems LTE y routers congelados en granjas de monitoreo.
  • Control de indicadores LED externos, ventiladores o cámaras web.
  • Desconexión segura de discos duros externos para eliminar la carga fantasma y ahorrar energía.
  • Integración con OctoPrint para encender y apagar remotamente una impresora 3D.
  • Pruebas de hardware en pipelines de CI/CD cuando necesitas reconectar físicamente una placa de depuración al banco de pruebas.

Limitaciones y características del hardware

Antes de integrar la utilidad en tus scripts, debes verificar las características específicas del hardware de tu sistema. Por ejemplo, en algunos modelos de Raspberry Pi, las líneas de alimentación de los cuatro puertos están conectadas en paralelo. Al intentar apagar un puerto, el sistema cortará la alimentación de los cuatro a la vez.

Además, algunos dispositivos alimentados por USB continúan consumiendo corriente de carga incluso si las líneas de señal de datos están desconectadas. En este caso, solo probar el hub específico con un multímetro o resistor de carga ayudará.

Si estás construyendo un banco de pruebas autónomo, un hogar inteligente o administrando servidores con periféricos conectados, uhubctl es una de esas herramientas compactas que te ahorran viajes largos a hardware varado. El programa se distribuye bajo la licencia GPLv2 y resuelve su tarea sin complejidad innecesaria. Lo principal antes de comenzar es asegurarte de que tu hub USB sea compatible con la gestión de energía.

Proyectos relacionados