동일한 USB- 직렬 어댑터를 구별하는 방법은 무엇입니까?


26

필자는 랩탑 (Ubuntu 9.10)과 동일한 여러 USB- 직렬 어댑터를 사용합니다. 어댑터는 Sabrent에서 제조되며 다음과 같이 Prolific PL2303 IC 주위에 구축됩니다 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  

로 표시된 속성 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 규칙을 작성할 수있는 방법이 있습니까?

답변:


24

허브에 어댑터가 연결된 실제 포트를 기반으로 각 어댑터의 이름을 수정하는 udev 규칙을 작성할 수있는 방법이 있습니까?

그렇습니다. 위의 두 번째 예에 표시된 장치 계층 구조의 마지막 부분을 고려하십시오.

상위 장치 '/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"
공격자 {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 직렬 컨트롤러"

커널 (KERNELS == "1-4.5")이이 장치에 지정한 이름은이 장치가 버스 1의 포트 4에 연결된 허브의 다섯 번째 포트에 연결되어 있음을 나타냅니다 ( 디코딩 방법에 대한 자세한 내용 은 이 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"

이러한 규칙에는 한 가지 명백한 단점이 있습니다. 모든 USB- 직렬 변환기가 동일한 허브 ( "1-8.1. *")에 연결되어 있다고 가정합니다. USB- 직렬 변환기를 다른 USB 포트에 꽂은 경우 "ttyUSB0"이라는 이름이 지정 될 수 있으며 이는 위에서 설명한 이름 지정 체계와 충돌합니다. 그러나 모든 변환기를 허브에 꽂아 두고이 제약 조건을 충족시킬 수 있습니다.


1
그 출처를 인용 해 주셔서 감사합니다. 자주 묻는 질문 리눅스 USB는 내가 필요 정확히이었다.
Lucas

16

이 특정한 경우에는 도움이되지 않지만 일부 어댑터에는 고유 한 일련 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"

출처


7
안타깝게도, 대부분의 저렴한 직렬 어댑터에는 고유 한 직렬이 없습니다. (
portforwardpodcast

7

의 내용을 보셨습니까 /dev/serial/by-id/? 비슷한 상황에서 각 장치에는 고유 한 영구 ID가 할당되었습니다 (실제로 무엇을 나타내는 지 모릅니다).


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

3

원래의 질문은 3 년 전에 제기 된 이후로, 이것은 질문을 다루지 않을 수도 있지만 나중에 참조 할 수 있도록 게시 할 것입니다.

FTDI- 칩의 EEPROM에 액세스하여 일련 번호를 다시 프로그래밍하는 방법이 있지만 Silicon labs는 도구를 제공하지만 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/


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

더 자세한 내용 으로 블로그 기사 를 썼습니다 . 임베디드 시스템 팀 프로그래밍 환경을 설정하는 시리즈 중 하나입니다.


0

이와 같은 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

두 줄은

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

이것은 라즈베리 파이에 있습니다. 이제 장치를 ttyUSB1연결 한 상태로두고 어댑터 ttyUSB0를 빼서 다른 포트에 꽂은 다음 초기 포트에 다시 연결합니다.

여기에 이미지 설명을 입력하십시오

# 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

연결 오류로 인해 시간 초과가 발생하는 경우에만이 확인을 수행합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.