Aynı USB-seri bağdaştırıcılar arasında nasıl ayrım yapılır?


26

Dizüstü bilgisayarımda aynı seri USB adaptörünü kullanıyorum (Ubuntu 9.10). Adaptörler Sabrent tarafından üretilmiştir ve aşağıdaki gibi gösterildiği gibi bir Prolific PL2303 IC etrafında üretilmiştir lsusb:

Bus 001 Device 008: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port  
Bus 001 Device 007: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port  
Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port  

Tarafından görüntülenen özniteliklerin hiçbiri udevadmbelirli bir adaptöre özgü görünmüyor:

foo@bar:~$ udevadm info --attribute-walk --path=/sys/bus/usb-serial/devices/ttyUSB0

   looking at device
 '/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.1/1-4.1:1.0/ttyUSB0':  
     KERNEL=="ttyUSB0"  
     SUBSYSTEM=="usb-serial"  
     DRIVER=="pl2303"   
     ATTR{port_number}=="0"  

   looking at parent device
 '/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.1/1-4.1:1.0':
     KERNELS=="1-4.1:1.0"  
     SUBSYSTEMS=="usb"  
     DRIVERS=="pl2303"  
     ATTRS{bInterfaceNumber}=="00"  
     ATTRS{bAlternateSetting}==" 0"  
     ATTRS{bNumEndpoints}=="03"  
     ATTRS{bInterfaceClass}=="ff"  
     ATTRS{bInterfaceSubClass}=="00"  
     ATTRS{bInterfaceProtocol}=="00"  
     ATTRS{modalias}=="usb:v067Bp2303d0300dc00dsc00dp00icFFisc00ip00"  
     ATTRS{supports_autosuspend}=="1"  

   looking at parent device
 '/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.1':
     KERNELS=="1-4.1"   
     SUBSYSTEMS=="usb"  
     DRIVERS=="usb"   
     ATTRS{configuration}==""  
     ATTRS{bNumInterfaces}==" 1"  
     ATTRS{bConfigurationValue}=="1"  
     ATTRS{bmAttributes}=="80"  
     ATTRS{bMaxPower}=="100mA"  
     ATTRS{urbnum}=="538"  
     ATTRS{idVendor}=="067b"  
     ATTRS{idProduct}=="2303"  
     ATTRS{bcdDevice}=="0300"  
     ATTRS{bDeviceClass}=="00"  
     ATTRS{bDeviceSubClass}=="00"  
     ATTRS{bDeviceProtocol}=="00"  
     ATTRS{bNumConfigurations}=="1"  
     ATTRS{bMaxPacketSize0}=="64"  
     ATTRS{speed}=="12"  
     ATTRS{busnum}=="1"  
     ATTRS{devnum}=="6"  
     ATTRS{version}==" 1.10"  
     ATTRS{maxchild}=="0"  
     ATTRS{quirks}=="0x0"  
     ATTRS{authorized}=="1"  
     ATTRS{manufacturer}=="Prolific Technology Inc."  
     ATTRS{product}=="USB-Serial Controller"  

     <snip>

 foo@bar:~$ udevadm info --attribute-walk --path=/sys/bus/usb-serial/devices/ttyUSB1

   looking at device
 '/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.5/1-4.5:1.0/ttyUSB1':
     KERNEL=="ttyUSB1"  
     SUBSYSTEM=="usb-serial"  
     DRIVER=="pl2303"  
     ATTR{port_number}=="0"  

   looking at parent device
 '/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.5/1-4.5:1.0':
     KERNELS=="1-4.5:1.0"  
     SUBSYSTEMS=="usb"  
     DRIVERS=="pl2303"  
     ATTRS{bInterfaceNumber}=="00"  
     ATTRS{bAlternateSetting}==" 0"  
     ATTRS{bNumEndpoints}=="03"  
     ATTRS{bInterfaceClass}=="ff"  
     ATTRS{bInterfaceSubClass}=="00"  
     ATTRS{bInterfaceProtocol}=="00"  
     ATTRS{modalias}=="usb:v067Bp2303d0300dc00dsc00dp00icFFisc00ip00"  
     ATTRS{supports_autosuspend}=="1"  

   looking at parent device
 '/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.5':
     KERNELS=="1-4.5"  
     SUBSYSTEMS=="usb"  
     DRIVERS=="usb"  
     ATTRS{configuration}==""  
     ATTRS{bNumInterfaces}==" 1"  
     ATTRS{bConfigurationValue}=="1"  
     ATTRS{bmAttributes}=="80"  
     ATTRS{bMaxPower}=="100mA"  
     ATTRS{urbnum}=="69"  
     ATTRS{idVendor}=="067b"  
     ATTRS{idProduct}=="2303"  
     ATTRS{bcdDevice}=="0300"  
     ATTRS{bDeviceClass}=="00"  
     ATTRS{bDeviceSubClass}=="00"  
     ATTRS{bDeviceProtocol}=="00"  
     ATTRS{bNumConfigurations}=="1"  
     ATTRS{bMaxPacketSize0}=="64"  
     ATTRS{speed}=="12"  
     ATTRS{busnum}=="1"  
     ATTRS{devnum}=="7"  
     ATTRS{version}==" 1.10"  
     ATTRS{maxchild}=="0"  
     ATTRS{quirks}=="0x0"  
     ATTRS{authorized}=="1"  
     ATTRS{manufacturer}=="Prolific Technology Inc."  
     ATTRS{product}=="USB-Serial Controller"  

     <snip>

Adaptörlerin tümü tek bir USB hub'ına takılı. Bağdaştırıcılar arasında ayrım yapamadığım için, bağdaştırıcının göbeğindeki hangi fiziksel bağlantı noktasına takılı olduğuna bağlı olarak her bağdaştırıcının adını düzelten bir udev kuralı yazmam mümkün mü?

Yanıtlar:


24

Bağdaştırıcının göbeğindeki hangi fiziksel bağlantı noktasına bağlı olduğunu belirleyerek her bağdaştırıcının adını düzelten bir udev kuralı yazabilir miyim?

Evet, olduğu gibi, var. Yukarıdaki ikinci örnekte gösterilen cihaz hiyerarşisinin son bölümünü göz önünde bulundurun:

'/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.5' ana cihaza bakıyor: KERNELS == "1-4.5" SUBSYSTEMS
== "usb"
SÜRÜCÜLER == "usb "
ATTRS {configuration} ==" "
ATTRS {bNumInterfaces} ==" 1 "
ATTRS {bConfigurationValue} ==" 1 "
ATTRS {bmAttributes} ==" 80 "
ATTRS {bMaxPower} ==" 100mA "
ATTRS {urbnum} = = "69"
ATTRS {idVendor} == "067b"
ATTRS {idProduct} == "2303"
ATTRS {bcdDevice} == "0300"
ATTRS {bDeviceClass} == "00"
ATTRS {bDeviceSubClass} == "00"
ATTRS {bDeviceProtocol} == "00"
ATTRS {bNumConfigurations} == "1"
ATTRS {bMaxPacketSize0} == "64"
ATTRS {hız} == "12"
ATTRS {busnum} == "1"
ATTRS {devnum} == "7" ATTRS {sürüm} == "1.10" ATTRS {maxchild} == "0" ATTRS {quirks} == "0x0"
ATTRS {yetkili} == "1"
ATTRS {üretici} = = "Üretken Teknoloji Şirketi"
ATTRS {ürün} == "USB-Seri Denetleyici"

Çekirdek tarafından bu aygıta verilen ad (KERNELS == "1-4.5"), bu cihazın veri yolu 1'deki dördüncü bağlantı noktasına bağlı bir göbeğin beşinci bağlantı noktasına takıldığını gösterir ( kod çözme hakkında daha fazla bilgi için bu SSS'ye bakın) sysfs usb aygıtı hiyerarşisi). Bu kılavuzdan udev kurallarını yazmak için biraz yardımla, USB-seri-port dönüştürücülerim için aşağıdaki udev kurallarını belirledim:

KERNEL == "ttyUSB *", KERNELS == "1-8.1.5", NAME = "ttyUSB0"
KERNEL == "ttyUSB *", KERNELS == "1-8.1.6", NAME = "ttyUSB1"
KERNEL = = "ttyUSB *", KERNELS == "1-8.1.1", NAME = "ttyUSB2"
KERNEL == "ttyUSB *", KERNELS == "1-8.1.2", NAME = "ttyUSB3"

Bu kuralların belirgin bir dezavantajı vardır: tüm USB-seri dönüştürücülerinin aynı hub'a bağlanacağını varsaymaktadırlar ("1-8.1. *"). USB'den seri dönüştürücüye başka bir USB portuna takılmışsa, yukarıda açıklanan adlandırma düzeniyle çakışacak olan "ttyUSB0" adı verilebilir. Ancak, tüm dönüştürücüleri hub'a bağlı bıraktığım için bu kısıtlama ile yaşayabilirim.


1
Bu kaynakları gösterdiğin için teşekkürler. Sıkça Sorulan Sorular Linux USB tam olarak ne ihtiyaç vardı.
Lucas

16

Bu özel durumda yardımcı olmasa da, bazı adaptörlere benzersiz seri kimlikler atanır:

udevadm info -a -n /dev/ttyUSB1 | grep '{serial}'

Örnek bir adaptör seri kimliği:

  ATTRS{serial}=="A6008isP"`

ve udev kuralları bundan sonra şunları içerecektir:

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A6008isP", SYMLINK+="arduino"

Kaynak


7
Ne yazık ki, ucuz seri adaptörlerin çoğunun benzersiz dizileri yok :(
portforwardpodcast

7

İçeriğine baktın mı /dev/serial/by-id/? Benzer bir durumda, her aygıta benzersiz bir kalıcı kimlik atandı (aslında neyi temsil ettiğini bilmediğini kabul ediyorum).


<VENDOR><delimeter><MODEL><delimeter><SERIAL>
Pithikos

3

Asıl soru 3 yıl önce sorulduğundan, bu soruya soracağınız adresi olmayabilir, ancak daha sonra başvurmak üzere göndereceğim.

FTDI-Chips'in EEPROM'una erişerek Seri Numarasını yeniden programlamanın bir yolu var, Silikon laboratuvarları bir araç sağlıyor, ancak bu yalnızca Windows:

Ürün sayfası -> Araçlar-> Sabit İşlev Özelleştirme Yardımcı Programı

Doğrudan bağlantı

Remotehq adresinde bir talimat bulunabilir:

http://remoteqth.com/wiki/index.php?page=How+to+set+usb+device+SerialNumber

Sourceforge'da bir Unix kütüphanesi de var. Sadece CP2101 / CP2102 / CP2103 ile test edilmiştir ve şahsen denemedim.

http://sourceforge.net/projects/cp210x-program/


1

Biçimlendirmeye ihtiyaç duyduğum bir yorum yerine bir cevap kullanarak.

Bu kuralların belirgin bir dezavantajı vardır: tüm USB-seri dönüştürücülerinin aynı hub'a bağlanacağını varsaymaktadırlar ("1-8.1. *"). USB'den seri dönüştürücüye başka bir USB portuna takılmışsa, yukarıda açıklanan adlandırma düzeniyle çakışacak olan "ttyUSB0" adı verilebilir. Ancak, tüm dönüştürücüleri hub'a bağlı bıraktığım için bu kısıtlama ile yaşayabilirim.

Bu sorunu yaşadım ve% devpath metnini veya seçtiğiniz bir başka USB özniteliğini değiştirmek için küçük bir C programı kullanarak kolayca çözüldü.

Daha sonra şu programı şöyle çağırırsınız:

ACTION!="add|change", GOTO="99-local-end

SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6001", ENV{ID_MM_DEVICE_IGNORE}="1"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GOTO="99-local-tty-ftdi"
GOTO="99-local-end"

LABEL="99-local-tty-ftdi"
IMPORT{program}="/usr/local/lib/udev/multiusbserial-id %s{devpath}"
# Hayes-style Modem
ENV{ID_MULTIUSBSERIAL_DEVNAME_MINOR}=="1", GROUP="dialout", MODE="0660", SYMLINK+="modem"
# Console for network device
ENV{ID_MULTIUSBSERIAL_DEVNAME_MINOR}=="2", GROUP="wheel", MODE="0660", SYMLINK+="ttyswitch"
# Serial port for software development
ENV{ID_MULTIUSBSERIAL_DEVNAME_MINOR}=="3", GROUP="eng", MODE="0660", SYMLINK+="ttyrouter"
# Unused
ENV{ID_MULTIUSBSERIAL_DEVNAME_MINOR}=="4", GROUP="wheel", MODE="0660"

LABEL="99-local-end"

burada multiusbserial-id derlenmiş C programıdır.

Program sadece belirli bir noktadan sonra metin yazdırmak gerekiyor, bu yüzden karmaşık değil

/* multiusbserial.c */
#include <stdio.h>
#include <stdlib.h>

#define PROGRAM_NAME "multiusbserial-id"
#define VARIABLE_PREFIX "ID_MULTIUSBSERIAL_"

int main(int argc, char *argv[])
{
  char *p;
  int found = 0;

  if (argc != 2) {
    fprintf(stderr, "Usage: " PROGRAM_NAME " ATTRS{devpath}\n");
    exit(1);
  }

  for (p = argv[1]; *p != '\0'; p++) {
    if (*p == '.') {
      p++;
      found = (*p != '\0');
      break;
    }
  }

  if (!found) {
    fprintf(stderr, PROGRAM_NAME ": unexpected format\n");
    exit(1);
  }

  printf(VARIABLE_PREFIX "DEVNAME_MINOR=%s\n", p);
  return 0;
}

Daha fazla ayrıntı içeren bir blog yazısı yazdım . Gömülü sistemler ekibi programlama ortamı kurma konusunda bir seridir.


0

Bunun gibi USB seri aygıtlarını listeleyebilirsiniz

ls -l /sys/bus/usb-serial/devices
total 0
lrwxrwxrwx 1 root root 0 Oct  9 09:10 ttyUSB0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3:1.0/ttyUSB0
lrwxrwxrwx 1 root root 0 Oct  9 09:10 ttyUSB1 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5:1.0/ttyUSB1

İki çizgi ile sona eriyor

1-1.3:1.0/ttyUSB0
1-1.5:1.0/ttyUSB1

Bu Ahududu Pi'de. Şimdi aygıtı ttyUSB1bağlı bırakacağım ve adaptörü ttyUSB0çıkarıp başka bir porta, sonra diğerine ve sonra ilk porta geri takacağım

görüntü tanımını buraya girin

# original setup
['1-1.3:1.0', 'ttyUSB0'] --
['1-1.5:1.0', 'ttyUSB1']

# move it to port above 1.3
['1-1.3:1.0', 'ttyUSB0']
['1-1.5:1.0', 'ttyUSB1']
['1-1.2:1.0', 'ttyUSB2'] --

# move it to port above 1.5
['1-1.3:1.0', 'ttyUSB0']
['1-1.5:1.0', 'ttyUSB1']
['1-1.4:1.0', 'ttyUSB2'] --

# move it back to the original port
['1-1.3:1.0', 'ttyUSB0'] --
['1-1.5:1.0', 'ttyUSB1']

1-1.3:1.0Bağlantı kesildikten sonra neden temizlenemediğini bilmiyorum , ancak bağdaştırıcıları nadiren bir USB bağlantı noktasından diğerine değiştirdiğim için bununla yaşayabilirim.


Benim sorunum, panjur rölelerini USB kablosu ile bağlı bir Arduino aracılığıyla kontrol eden ve ortam sensörü verilerini başka bir Arduino (aynı üretici, aynı model) aracılığıyla okuyan bir Raspberry Pi'de, kepenkler devreye girdiğinde Arduino'nun sensör verilerini tekmeledi. tahtadan çıkar ve ttyUSB0'dan ttyUSB2'ye yeniden atandı (ttyUSB1 deklanşördür). Sensör verilerinin şu an hangi cihazda bulunduğunu deneme yanılma yoluyla bulmak zorunda olmadığımı bu Python betiği ile bitirdim.

usb_devices = collections.OrderedDict()
usb_device_list = subprocess.check_output('ls -l /sys/bus/usb-serial/devices', shell=True, universal_newlines=True).split('\n')
for usb_device in usb_device_list:
  match = re.search("([^/]+)/([^/]+)$", usb_device)
  if match:
    usb_devices[match.group(1)] = match.group(2)

for key, value in usb_devices.items():
  print key, value

# I know that 1.3 is the environment sensor device
if '1-1.3:1.0' in usb_devices:
  print '1-1.3:1.0 -->', usb_devices['1-1.3:1.0'] # == ttyUSB0

Bu bana aşağıdaki çıktıyı verir

1-1.3:1.0 ttyUSB0
1-1.5:1.0 ttyUSB1
1-1.3:1.0 --> ttyUSB0

Bu kontrolü yalnızca bağlantı hatası nedeniyle zaman aşımına uğradığında yapıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.