Conexão de dispositivo USB-serial com PID personalizado para ttyUSB0 no dispositivo incorporado

19

Estou tentando obter um dispositivo USB Serial FTDI com um PID personalizado para conectar-se automaticamente (ou mesmo manualmente) a ttyUSB% n, sem muito sucesso. O VID / PID normal do dispositivo é 0403/6001. Quando programado dessa maneira, ele funciona perfeitamente e automaticamente se conecta ao ttyUSB0 quando conectado. Mesmo com o driver recompilado para respeitar nosso novo PID, quando programado com o personalizado, o ttyUSB0 não aparece, mas o reconhece como um dispositivo ftdi_sio e carrega o driver.

Eu adicionei nosso PID ao cabeçalho e fonte:

// in ftdi_sio_ids.h
#define FTDI_CUSTOM_PID 0xABCD // not the actual pid
// then in ftdi_sio.c
static struct usb_device_id id_table_combined [] = {
    // devices....
    { USB_DEVICE(FTDI_VID, FTDI_CUSTOM_PID) },
    // ....

Recompilou o kernel inteiro e atualizou o dispositivo novamente. Quando conecto o dispositivo, recebo:

usb 1-1: new full-speed USB device number 2 using at91_ohci
usbcore: registered new interface driver usbserial
usbserial: USB Serial Driver core
USB Serial support registered for FTDI USB Serial Device
usbcore: registered new interface driver ftdi_sio
ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver

lsusb mostra o VID / PID personalizado correto. O driver parece reconhecer que deveria usar o ftdi_sio com ele, mas não o anexa ao ttyUSB0 como faria com o PID não modificado. Alguma sugestão sobre o que estou fazendo de errado aqui?

trycatch
fonte
11
Que tipo incorporado é esse? Possui UDEV? Nesse caso, UDEV é sua melhor aposta (e eu posso ajudar ainda mais com isso).
quer

Respostas:

17

Você não precisa modificar o kernel apenas uma vez; você pode substituí-lo.

  1. Desconecte o dispositivo
  2. modprobe ftdi_sio
  3. echo 0403 6001 >/sys/bus/usb-serial/drivers/ftdi_sio/new_id
  4. Conecte o dispositivo

E seu dispositivo deve funcionar.

Sua outra alternativa é usar a bindinterface sysfs; Eu sugiro usar lsusb -tpara descobrir o caminho correto + interface nesse caso.

Usando um exemplo parcial do meu sistema, de um dispositivo de armazenamento USB (seria muito semelhante para USB-serial).

$ lsusb -t
...
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
    |__ Port 1: Dev 5, If 0, Class=Hub, Driver=hub/3p, 5000M
        |__ Port 3: Dev 6, If 0, Class=Hub, Driver=hub/3p, 5000M
            |__ Port 3: Dev 7, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
 ...
 $ echo '4-1.3.3:1.0' >/sys/bus/usb/drivers/usb-storage/bind

O formato do número é: BUS-PORT(.PORT)+:1.INTERFACE. O único número que não é visível na saída lsusb é o primeiro dígito após os dois pontos; e sempre foi um 1na minha experiência. Alguém com conhecimento mais profundo do kernel provavelmente pode me dizer o que é e fornecer um contra-exemplo.

robbat2
fonte
Funcionou perfeitamente, obrigado. Deve ser a resposta aceita.
Amr Bekhit
11
Apenas me perguntando: se eu mudar de idéia, e eu não quero que este vid / pid use o driver ftdi_sio, mas outro, como reverto essa etapa?
Bram
Escreva o vid / pid em remove_id para desfazer o eco em new_id.
robbat2
@trycatch, você pode aceitar a resposta?
robbat2
11
@kay new_id / remove_id é apenas para remover IDs adicionados dinamicamente. Se eu entendo o que você quer fazer: você deseja impedir que um driver específico seja carregado para algum dispositivo.
robbat2
12

Você não precisa modificar o kernel, pode automatizar o processo assim:

  1. Adicione a seguinte linha única ao /etc/udev/rules.d/99-ftdi.rules

    ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", RUN+="/sbin/modprobe ftdi_sio" RUN+="/bin/sh -c 'echo 0403 6001 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id'"

  2. Reinicie ou execute sudo udevadm control --reload para pegar a nova regra.

  3. Desconecte o dispositivo.

  4. Conecte o dispositivo.

Stephen
fonte
1

situação absolutamente semelhante aconteceu com a placa eval da SiLabs - o chip USB-UART CP2102 está sendo fornecido com VID / PID irregular:

lsusb

Bus 001 Device 002: ID 10c4:804c Cygnal Integrated Products, Inc.

problema resolvido carregando o módulo cp210x e enviando VID / PID conforme mencionado anteriormente:

sudo modprobe cp210x

sudo -s

echo 10c4 804c > /sys/bus/usb-serial/drivers/cp210x/new_id

O arquivo 99-cp210.rules correspondente para o udev é o seguinte:

ACTION=="add", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="804c", RUN+="/sbin/modprobe cp210x" RUN+="/bin/sh -c 'echo 10c4 804c > /sys/bus/usb-serial/drivers/cp210x/new_id'"

Oleg Kokorin
fonte
Para futuros viajantes que tentam fazer com que um stick HUSBZB-1 funcione, aqui está um arquivo udev que vincula o driver cp210x conforme mencionado acima e vincula os dispositivos tty a / dev / zigbee e / dev / z-wave ACTION=="add", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8a2a", RUN+="/sbin/modprobe cp210x" RUN+="/bin/sh -c 'echo 10c4 8a2a > /sys/bus/usb-serial/drivers/cp210x/new_id'" SUBSYSTEM=="tty", ATTRS{interface}=="HubZ Z-Wave Com Port", SYMLINK+="zwave" SUBSYSTEM=="tty", ATTRS{interface}=="HubZ ZigBee Com Port", SYMLINK+="zigbee"
nebulous