嵌入式Linux USB设备检测端口和地址

3
我正在为我的板子开发一个USB应用程序。它有两个USB端口。当我在每个端口插入一个USB驱动器时,我在控制台上会得到以下消息:
在1号端口:
usb 1-1: new high speed USB device using atmel-ehci and address 4
usb 1-1: New USB device found, idVendor=0781, idProduct=5567
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: Cruzer Blade
usb 1-1: Manufacturer: SanDisk
usb 1-1: SerialNumber: 3515430A2EE2729D
scsi2 : usb-storage 1-1:1.0
scsi 2:0:0:0: Direct-Access     SanDisk  Cruzer Blade     8.02 PQ: 0 ANSI: 0 CCS
sd 2:0:0:0: [sdb] 7856127 512-byte logical blocks: (4.02 GB/3.74 GiB)
sd 2:0:0:0: [sdb] Write Protect is off
sd 2:0:0:0: [sdb] Assuming drive cache: write through
sd 2:0:0:0: [sdb] Assuming drive cache: write through
 sdb:
 sdb1
sd 2:0:0:0: [sdb] Assuming drive cache: write through
sd 2:0:0:0: [sdb] Attached SCSI removable disk

在2号端口:
usb 1-2: USB disconnect, address 3
usb 1-2: new high speed USB device using atmel-ehci and address 5
usb 1-2: New USB device found, idVendor=0781, idProduct=5567
usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-2: Product: Cruzer Blade
usb 1-2: Manufacturer: SanDisk
usb 1-2: SerialNumber: 3515430A2EE2729D
scsi3 : usb-storage 1-2:1.0
scsi 3:0:0:0: Direct-Access     SanDisk  Cruzer Blade     8.02 PQ: 0 ANSI: 0 CCS
sd 3:0:0:0: [sda] 7856127 512-byte logical blocks: (4.02 GB/3.74 GiB)
sd 3:0:0:0: [sda] Write Protect is off
sd 3:0:0:0: [sda] Assuming drive cache: write through
sd 3:0:0:0: [sda] Assuming drive cache: write through
 sda:
 sda1
sd 3:0:0:0: [sda] Assuming drive cache: write through
sd 3:0:0:0: [sda] Attached SCSI removable disk

但是这些消息都在控制台上。
我想检测哪个设备已连接到哪个端口并具有地址(如sda,sdb等)。
我在谷歌上搜索了一下,并找到了两个独立提供此信息的系统路径: 1)/sys/bus/usb/devices/1-x 2)/sys/class/scsi_disk/x:0:0:0/device 第一个提供以下信息:
1-2:1.0               bus                   maxchild                            
authorized            busnum                product                             
bConfigurationValue   configuration         quirks                              
bDeviceClass          descriptors           remove                              
bDeviceProtocol       dev                   serial                            
bDeviceSubClass       devnum                speed                               
bMaxPacketSize0       devpath               subsystem                           
bMaxPower             driver                uevent                              
bNumConfigurations    ep_00                 urbnum                              
bNumInterfaces        idProduct             usb_device:usbdev1.4                
bcdDevice             idVendor              version                             
bmAttributes          manufacturer 

第二个提供了这些信息:
block:sdb            iorequest_cnt        scsi_disk:2:0:0:0                     
bus                  max_sectors          scsi_level                            
delete               modalias             state                                 
device_blocked       model                subsystem                             
driver               queue_depth          timeout                               
evt_media_change     queue_type           type                                  
iocounterbits        rescan               uevent                                
iodone_cnt           rev                  vendor                                
ioerr_cnt            scsi_device:2:0:0:0 

因此,这两个数据结构之间没有共同的信息。我可以从第一个路径获取USB设备的端口号和序列号。我可以从第二个路径中获取地址(sda、sdb等)。但它们之间没有共同的信息。我怎么能知道特定的USB设备在端口1上是否安装在sda上?或者一个连接到端口2的设备是否安装在sdc上?
3个回答

4

正如其他人建议的那样,使用udev可能是一种清洁的方法。但是直接回答你的问题,如果你枚举/sys/block并读取所有块设备的符号链接(即readlink),你会看到类似于以下内容:

sde -> ../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4:1.0/host12/target12:0:0/12:0:0:1/block/sde

符号链接提供了您所需的信息,即块设备和USB拓扑结构中节点之间的关系。
另外,请注意您问题中最后引用的文本中的“block:”。

3

我认为你应该学习更多关于udev(或者在旧系统上使用hal)的内容。


1
好的,我搜索了关于udev的信息并了解到它可以提供有关设备的信息。你能指导我更深入地了解udev吗? - androidFan
1
udev 可以配置在USB设备插入时执行操作,但是我忘记了具体详情。 - Basile Starynkevitch

0

您可以使用udev子系统在系统启动期间映射设备。

  1. 使用命令[lsusb]和[lsusb -v]来识别您想要控制的每个设备的VendorID、ProductID和SerialID。

  2. 在[/etc/udev/rules.d/]中创建一个新文件,比如说名为[77-my.rules]的文件,其内容基于以下模板:

    SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0781", ATTRS{idProduct}=="5567", ATTRS{serial}=="3515430A2EE2729D", SYMLINK+="mydisk00"

    SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0781", ATTRS{idProduct}=="5567", ATTRS{serial}=="3515430A2EE2ABA", SYMLINK+="mydisk11"

  3. 重新启动udev子系统[/etc/init.d/udev restart]或重新启动Linux机器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接