web-dev-qa-db-ja.com

同一のUSB-シリアルアダプターを区別する方法

私はラップトップ(Ubuntu 9.10)で多数の同一のUSB-シリアルアダプターを使用しています。アダプターはSabrentによって製造され、lsusbで示されるように、Prolific PL2303 ICを中心に構築されています。

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  

udevadmで表示される属性は、特定のアダプターに固有のものではないようです。

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>

すべてのアダプターは、単一のUSBハブに接続されます。アダプター自体を区別できないので、アダプターが接続されているハブの物理ポートに基づいて各アダプターの名前を修正するudevルールを作成する方法はありますか?

25
Chris OBrien

アダプタが接続されているハブの物理ポートに基づいて各アダプタの名前を修正するudevルールを作成する方法はありますか?

はい、あります。上記の2番目の例に示されているデバイス階層の最後の部分を検討してください。

親デバイスを見る '/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"

カーネルによってこのデバイスに付けられた名前(KERNELS == "1-4.5")は、このデバイスがバス1のポート4に接続されたハブの5番目のポートに接続されていることを示します( このFAQ sysfs usbデバイス階層をデコードする方法の詳細については)。 このガイド からいくつかの助けを借りてudevルールを書くことで、USBからシリアルポートへのコンバーター用に次のudevルールセットを思いつきました。

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"

これらのルールには1つの明らかな欠点があります。すべてのUSBシリアルコンバーターが同じハブ(「1-8.1。*」)に接続されることを前提としています。 USBからシリアルへのコンバーターが別のUSBポートに接続されている場合、上記の名前付けスキームと競合する「ttyUSB0」という名前を割り当てることができます。ただし、すべてのコンバーターをハブに接続したままにしておくため、この制約に耐えることができます。

23
Chris OBrien

この特定のケースでは役に立ちませんが、一部のアダプターには一意のシリアルIDが割り当てられます。

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

アダプターのシリアルIDの例:

  ATTRS{serial}=="A6008isP"`

そして、udevルールには次が含まれます。

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

ソース

15
Cas

/dev/serial/by-id/の内容を見ましたか?同様の状況で、各デバイスには一意の永続IDが割り当てられました(実際に何を表しているのかわかりません)。

7
Rob Tirrell

元の質問は3年前に尋ねられたので、これは質問者を苦しめることはないかもしれませんが、今後の参考のために投稿します。

Silicon labsは、FTDI-ChipのEEPROMにアクセスしてシリアル番号を再プログラムする方法がありますが、Windowsのみです:

製品ページ ->ツール->固定機能カスタマイズユーティリティ

直接リンク

命令はremotehqにあります。

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

SourceforgeにはUnixライブラリもあります。 CP2101/CP2102/CP2103でのみテストされており、私は個人的に試してみませんでした。

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

3
Smundo

書式設定が必要なため、コメントではなく回答を使用します。

これらのルールには1つの明らかな欠点があります。すべてのUSBシリアルコンバーターが同じハブ(「1-8.1。*」)に接続されることを前提としています。 USBからシリアルへのコンバーターが別のUSBポートに接続されている場合、上記の名前付けスキームと競合する「ttyUSB0」という名前を割り当てることができます。ただし、すべてのコンバーターをハブに接続したままにしておくので、この制約に耐えることができます。

私はこの問題を抱えていましたが、小さなCプログラムを使用して%devpathのテキストまたは選択した他のUSB属性を操作することで簡単に修正できます。

次に、このプログラムを次のように呼び出します。

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"

ここで、multiusbserial-idはコンパイルされたCプログラムです。

プログラムは特定のポイントの後にテキストを印刷する必要があるだけなので、複雑ではありません

/* 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;
}

ブログ記事 に詳細を書いた。これは、組み込みシステムチームのプログラミング環境をセットアップするシリーズの1つです。

1
vk5tu

このようなUSBシリアルデバイスをリストできます。

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

2行は次で終わる

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

これはRaspberry Piにあります。デバイスttyUSB1を接続したままにし、アダプターttyUSB0を引き出して別のポートに接続し、次に別のポートに接続してから、最初のポートに戻します。

enter image description here

# 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.0がクリーンアップされない理由はわかりませんが、USBポート間でアダプタを変更することはめったにないので、それでも問題ありません。


私の問題は、USBケーブルを介して接続されたArduinoを介してシャッターリレーを制御し、別のArduino(同じメーカー、同じモデル)を介して環境センサーデータを読み取るRaspberry Piで、シャッターがアクティブになったときにArduinoが蹴られることでしたボードから離れて、ttyUSB0からttyUSB2に再割り当てされます(ttyUSB1はシャッターです)。センサーデータが現在どのデバイスに存在していたかを試行錯誤する必要がないように、このPythonスクリプトで終わりました。

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

次の出力が得られます

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

接続エラーによるタイムアウトが発生している場合にのみ、このチェックを実行します。

0
Daniel F