Trabalhando com USB Gadgets no Linux
- por Sergio Prado
Atualmente a maioria das plataformas embarcadas possuem uma ou mais portas USB Host, que permitem conectar dispositivos USB como teclados e pendrives. Neste caso, a plataforma embarcada atua como um host USB.
Algumas destas plataformas embarcadas possuem também uma porta USB OTG (On-The-Go), permitindo-a não só atuar como host, mas também como um device USB. Desta forma, é possível transformar a plataforma embarcada em um dispositivo USB como um pendrive, teclado, conversor USB/serial ou interface de rede.
No Linux, a camada de software capaz de fazer o sistema se comportar como um device USB é chamada de USB Gadgets.
Os gadgets USB são habilitados na configuração do kernel, acessando o menu Device Drivers -> USB support -> USB Gadget Support:
Existem gadgets USB para fazer o hardware se comportar como diferentes tipos de dispositivo, incluindo áudio, ethernet, armazenamento, serial, impressora, modem e webcam.
Normalmente os gadgets são habilitados como módulo, já que somente um gadget pode estar em funcionamento ao mesmo tempo. Desta forma, quando você quiser usar determinado gadget, basta carregar o módulo correspondente.
Vamos então fazer alguns testes, transformando uma plataforma de hardware qualquer nos tipos mais comuns de gadgets USB.
Utilizei a Beaglebone Black nos testes, usando uma distribuição customizada criada com o Buildroot. Mas os mesmos testes podem ser realizados em qualquer plataforma de hardware (ou mesmo um PC) rodando um sistema Linux.
Por convenção, chamarei de target o hardware (Beaglebone Black) e de host a máquina de desenvolvimento.
SERIAL GADGET
O gadget serial é habilitado no kernel através da opção CONFIG_USB_G_SERIAL, e permite transformar o target em uma porta serial.
Para usá-lo, basta carregar o módulo g_serial:
# modprobe g_serial |
Deverá aparecer uma nova porta serial no target:
# ls -l /dev/ttyGS0 crw------- 1 root root 242, 0 Jan 1 00:00 /dev/ttyGS0 |
No host, conectando-se ao target com um cabo USB, deverá aparecer também uma porta serial (é como se você tivesse conectado no host um cabo conversor USB/serial):
$ ls -l /dev/ttyACM0 crw-rw---- 1 root dialout 166, 0 Jan 22 22:27 /dev/ttyACM0 |
Desta forma, a partir de uma interface USB, é possível se comunicar serialmente com o target, possibilitando por exemplo iniciar uma aplicação de terminal nesta conexão serial.
NETWORK GADGET
O gadget de rede é habilitado no kernel através da opção CONFIG_USB_ETH, e permite transformar o target em uma interface de rede.
Para utilizá-lo, basta carregar o módulo g_ether:
# modprobe g_ether |
Com o módulo carregado, deverá aparecer uma nova interface de rede (normalmente usb0), que pode ser configurada normalmente:
# ifconfig usb0 10.0.0.1 up |
No host, conectando-se ao target com um cabo USB, uma nova interface de rede também deverá estar disponível e poderá ser configurada:
$ sudo ifconfig usb0 10.0.0.2 up |
A partir deste momento, através de uma interface USB, você conseguirá se comunicar via rede com o target.
USB STORAGE GADGET
Este gadget é habilitado no kernel através da opção CONFIG_USB_MASS_STORAGE, e permite transformar o target em um dispositivo de armazenamento.
Para utilizá-lo, basta carregar o módulo g_mass_storage, passando como parâmetro um arquivo ou uma partição que será utilizada para salvar os arquivos do dispositivo de armazenamento:
# modprobe g_mass_storage file=/dev/mmcblk0p2 stall=0 |
No host, conectando-se ao target com um cabo USB, automaticamente será aberto o programa padrão de gerenciamento de arquivos, como se o target fosse um pendrive.
OUTROS GADGETS
Existem diversos outros gadgets, incluindo dispositivos HID como teclado e mouse, som, impressora, etc. Você pode até criar seu próprio USB gadget em espaço de usuário com o gadgetfs.
E o mais legal é que está tudo pronto! Basta ter uma interface USB OTG disponível e habilitar alguns módulos do kernel.
Bom divertimento!
Sergio Prado