Android usb 设备管理器lsusb 分析

在android 平台,我们再调试所有usb 设备时,硬件焊接好后,在内核usb 核心驱动正常情况下(当然只要USB外设遵循标准协议基本没有问题),我们都会通过lsusb 指令在确认usb 设置是否正常接入且被识别到,并且得到usb 设备的vid,pid,及bus id,device id。

lsub 命令

在这里插入图片描述
通过命令,我们可以查询到当前系统中,在usb 的三条总线分别插入的6个USB设备。

lsusb 源码分析

toyboy工具箱中的lsusb 工具源码在 external\toybox\toys\other\lsusb.c中

/* lsusb.c - list available USB devices
 *
 * Copyright 2013 Andre Renaud <[email protected]>

USE_LSUSB(NEWTOY(lsusb, NULL, TOYFLAG_USR|TOYFLAG_BIN))

config LSUSB
  bool "lsusb"
  default y
  help
    usage: lsusb

    List USB hosts/devices.
*/

#include "toys.h"

static int list_device(struct dirtree *new)
{
  FILE *file;
  char *name;
  int busnum = 0, devnum = 0, pid = 0, vid = 0;

  if (!new->parent) return DIRTREE_RECURSE;
  if (new->name[0] == '.') return 0;
  name = dirtree_path(new, 0);
  snprintf(toybuf, sizeof(toybuf), "%s/%s", name, "/uevent"); 
  file = fopen(toybuf, "r");   // 打开uevent 设备文件
  if (file) {
    int count = 0;
     //  循环读取/sys/bus/usb/devices/xxx/uevent  设备节点下的文件信息,一行一行读取
    while (fgets(toybuf, sizeof(toybuf), file))
      if (sscanf(toybuf, "BUSNUM=%u\n", &busnum)    // 解析bus num
          || sscanf(toybuf, "DEVNUM=%u\n", &devnum)  // 解析device num
          || sscanf(toybuf, "PRODUCT=%x/%x/", &pid, &vid)) count++;    // 解析pid,vid

    if (count == 3)  // 解析完成后打印
      printf("Bus %03d Device %03d: ID %04x:%04x\n", busnum, devnum, pid, vid);
    fclose(file);
  }
  free(name);

  return 0;
}

void lsusb_main(void)
{
   // dirtree_read 在/sys/bus/usb/devices目录下树状遍历uevent ,并传入回调函数list_device
  dirtree_read("/sys/bus/usb/devices/", list_device);   
}

整个过程就是树状解析/sys/bus/usb/device/ 目录下(包括子目录)的uevent 文件节点,解析到bus num,device num,pid,vid 成功后,就打印出来。如上面的lsusb 执行指令结果。
http://linux-usb.sourceforge.net/FAQ.html#gs3在这里插入图片描述

uevent 节点信息分析

shell@cv6a648_base:/ $ cat /sys/bus/usb/devices/usb1/uevent                    
MAJOR=189
MINOR=0
DEVNAME=bus/usb/001/001
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=1d6b/2/310
TYPE=9/0/1
BUSNUM=001
DEVNUM=001
shell@cv6a648_base:/ $ cat /sys/bus/usb/devices/usb2/uevent                    
MAJOR=189
MINOR=128
DEVNAME=bus/usb/002/001
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=1d6b/2/310
TYPE=9/0/1
BUSNUM=002
DEVNUM=001
shell@cv6a648_base:/ $ cat /sys/bus/usb/devices/usb3/uevent                    
MAJOR=189
MINOR=256
DEVNAME=bus/usb/003/001
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=1d6b/2/310
TYPE=9/0/1
BUSNUM=003
DEVNUM=001

shell@cv6a648_base:/sys/bus/usb/devices $ cat 1-1.3/uevent                     
MAJOR=189
MINOR=2
DEVNAME=bus/usb/001/003
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=90c/1000/1100
TYPE=0/0/0
BUSNUM=001
DEVNUM=003

通过上面节点我们可以分析BUSNUM,DEVNUM,PRODUCT 得到四个id,其中PRODUCT 得到pid,vid。其中还有一个DEVNAME 属性可以得到usb 总线和device 的树形关系。DEVNAME=bus/usb/001/003 表示第1条总线上面的第3个设备

130|root@cv6a648_base:/ # lsusb                                                
Bus 001 Device 002: ID 1a40:0101
Bus 001 Device 001: ID 1d6b:0002
Bus 002 Device 001: ID 1d6b:0002
Bus 003 Device 001: ID 1d6b:0002
Bus 001 Device 003: ID 090c:1000
Bus 001 Device 006: ID 0bda:b82c
root@cv6a648_base:/ # ls /dev/bus/usb/001/                          // 总线1下有4个设备           
001
002
003
006
root@cv6a648_base:/ # ls /dev/bus/usb/002/                          // 总线2下有1个设备           
001
root@cv6a648_base:/ # ls /dev/bus/usb/003/                          // 总线1下有1个设备
001

其它属性分析

我们先分析上面bus-1 下面的第4个usb (也即Bus 001 Device 006 )设备属性:
在这里插入图片描述
如下:

root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bMaxPower                 
500mA
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/devpath                   
1.4
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/product                   
802.11ac NIC 
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bNumConfigurations      
1
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bNumInterfaces            
 3
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/quirks                    
0x0
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/removable                 
unknown
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/removable                 
unknown
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/authorized                
1
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bcdDevice                 
0210
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/idProduct                 
b82c
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/remove                    
/system/bin/sh: cat: /sys/bus/usb/devices/1-1.4/remove: Permission denied
root@cv6a648_base:/ # 
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/avoid_reset_quirk       
0
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bmAttributes              
80
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/idVendor                  
0bda
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/serial                    
123456
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bConfigurationValue       
1
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/busnum                    
1
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/ltm_capable               
no
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/speed                     
480
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bDeviceClass              
ef
root@cv6a648_base:/ # 
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/configuration             
root@cv6a648_base:/ # 
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/manufacturer              
Realtek
root@cv6a648_base:/ # cat /sys/bus/usb/devices/1-1.4/bDeviceProtocol           
01
root@cv6a648_base:/ #  cat /sys/bus/usb/devices/1-1.4/version                   
 2.10

其中bDeviceClass 在USB协议中取值范围是:00h ~ FFh 此处为EF 为一个杂项设备,其实就是realtek的一个wifi 模组,起采用的是usb 接口。

USB class CODE 详细说明

上面bDeviceClass 值对应的用途如下:

Class code             用途           详细说明
00h                    Device         表示CLASS的信息在接口的描述符中定义
01h                    Interface      Audio   音频设备
02h                    Both           Communications and CDC Control通信设备
03h                    Interface      HID (Human Interface Device) 人机接口设备
05h                    Interface      Physical 物理设备
06h                    Interface      Image 图像设备
07h                    Interface      Printer 打印机
08h                    Interface      Mass Storage 大容量存储
09h                    Device         Hub
0Ah                    Interface      CDC-Data 通信设备
0Bh                    Interface      Smart Card 智能卡
0Dh                    Interface      Content Security 内容安全设备
0Eh                    Interface      Video 视频设备 
0Fh                    Interface      Personal Healthcare  个人健康设备
10h   Interface      Audio/Video Devices 音频/视频设备
DCh                    Both           Diagnostic Device 诊断设备
E0h                    Interface      Wireless Controller 无线控制器(蓝牙设备等)
EFh                    Both           Miscellaneous 杂项(ActiveSync,PalmSync,各种协会等)
FEh                    Interface      Application Specific 应用专有规范(固件升级,红外,USB测试与测量等)
FFh                    Both           Vendor Specific 供应商自定义规范
注:各类设备的class subclass protocol的详细定义可以参考http://www.usb.org/developers/defined_class

又如,总线2 上面的1号设备是hub设备,对应的USB Class code 是09h,并且制定驱动类型
在这里插入图片描述
又如U盘设备,驱动是标注的usb-storage驱动,USB class code 是08h
在这里插入图片描述
wifi,bluetooth设备,驱动分别是厂商的驱动,对应的USB class code 是0xE0,0xFF
在这里插入图片描述
2.4 G HID 空鼠输入设备,USB Class code 为0x03 为HID 人机接口设备,使用的驱动是usbhid 驱动
在这里插入图片描述
麦克风输入设备,USB Class code 为0x01, 对应的驱动是snd-usb-audio
在这里插入图片描述

后续继续学习usb 协议规范及libusb 开源库中 USB API 接口的使用。

发布了101 篇原创文章 · 获赞 19 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/kehyuanyu/article/details/100532383