Tenho um dispositivo USB-para-UART multiporta baseado no chip CH348 executando um driver fora do kernel obtido de https://github.com/WCHSoftGroup/ch9344ser_linux
O driver cria nós de dispositivo de 8 caracteres ( /dev/ttyCH9344USB0
... /dev/ttyCH9344USB7
). O dispositivo não fornece um número de série no descritor de dispositivo USB, mas há uma EEPROM que desejo ler do dispositivo, extrair o número de série de lá e usá-lo para criar um link simbólico como /dev/ttyUSB.CH348.<serial_number>.<instance>
.
Criei uma udev
regra simples e a coloquei em /etc/udev/rules.d/99-usb-serial.rules
:
ACTION=="add", KERNEL=="*ttyCH9344USB*", OPTIONS="log_level=debug", PROGRAM="/usr/local/bin/ch34x_serial %E{DEVNAME}", SYMLINK+="ttyUSB.CH348.$result"
A regra funciona como esperado, mas apenas para UM único nó ALEATÓRIO de 8. Na verdade, tentei várias regras de correspondência e, independentemente do método que uso (nome do kernel, atributos usb, etc.), se corresponder, isso acontece apenas para UMA única instância ALEATÓRIA da série. Pode criar um link simbólico para a instância 3, ou 6, ou 7, ou qualquer outra, mas apenas para uma única.
Eu verifiquei journalctl
e udevadm monitor -p
, e descobri que há exatamente 8 add
eventos diferentes chegando udev
quando eu carrego o módulo do driver. Todos os eventos são idênticos, exceto pelas propriedades KERNEL, DEVPATH, SEQNUM e MINOR, e se parecem com isso:
KERNEL[706136.962119] add /devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2/1-1.1.3.2.1/1-1.1.3.2.1:1.0/tty/ttyCH9344USB0 (tty)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2/1-1.1.3.2.1/1-1.1.3.2.1:1.0/tty/ttyCH9344USB0
SUBSYSTEM=tty
DEVNAME=/dev/ttyCH9344USB0
SEQNUM=26571
MAJOR=168
MINOR=0
Não entendo por que apenas um desses eventos reais aciona a regra, enquanto que se eu executar udevadm test
para qualquer um dos 8 nós de dispositivo, a regra funciona perfeitamente para todos eles.
Parece que ele udev
está armazenando a ação em cache de alguma forma e descartando as "duplicatas", embora eu não entenda como ele chega a essa conclusão.
Estou executando o Ubuntu 24.04 Server com udev
versão 255.4-1ubuntu8.4
.
Qualquer ajuda seria apreciada. Obrigado.
Como se viu,
udev
estava executando meuch34x_serial
programa 8 vezes em paralelo, como apontado por @meuh em seu comentário. Aparentemente, o driver não tolera isso para operações de acesso à EEPROM.Para superar isso, adicionei uma sincronização simples baseada em um semáforo compartilhado para serializar a comunicação com a EEPROM subjacente. Suponho que eu poderia, em vez disso, corrigir o driver ch9344_linux, mas modificar o programa do espaço do usuário pareceu mais fácil.
Qualquer pessoa que precise resolver o mesmo problema de conectar vários dispositivos CH348 a uma máquina pode experimentar a ferramenta modificada disponível em https://codeberg.org/AlexanderAmelkin/ch34x_serial
A versão modificada, juntamente com uma regra udev simples (também disponível no repositório acima), funciona bem para mim e produz 8 aliases de dispositivo separados.