USB子系统一(USB协议简介)

1 总线简介

1.1 背景

  • 发展背景

       外部设备的接口五花八门,USB的远大志愿就是取代这些五花八门的接口,无需安装驱动,无需螺丝加固,即插即用,所以取名为Universal.也就是USB的首个字母~U,就是通过,最好所有的设备都能使用的意思。于是UBS开启了它漫长的奋斗之路.

  • 发展历程

       低速usb1.0: 1995年,第一代USB问世,取名为Low Speed USB,传输速度约为1.5 Mbps,因为自身问题太多,基本没什么人用,也没能引多大的重视.

       全速sub1.0: 1998年,三年磨一剑,USB1.1版本问世,取名为Full Speed USB,它是最早被采用的修订版,传输速度约为12 Mbps.

       高速usb2.0: 2000年,推出的Hi-Speed,也就是USB 2.0,理论传输速度翻了40倍,达到了480Mbps。

       高速usb3.0: 2008年推出的USB 3.0理论传输速度再翻十倍,达到了惊人的5Gbps。

1.2 特点

  1. 它是串行总线,usb2.0及之前是半双工的,usb3.0是全双工的。
  2. usb总线属于外部总线,CPU无法直接访问,需要通过"USB控制器"来访问usb设备。
  3. USB的设计为非对称式的,它由一个主机控制器和若干通过集线器设备以树形连接的设备组成。一个控制器下最多可以有5级Hub,包括Hub在内,最多可以连接128个设备。
  4.  在任何时候,信息在usb上的传输,只能由usb控制器发起,usb设备只能被动接受。
  5. 凡是支持usb的外部设备,即usb设备。都带有usb通信控制器,里面实际包含一个微处理器. hub是一种特殊的usb设备。

 1.3 信息传输方式

  1. 控制型:主要用于设备的"配置"和控制。比如usb控制器与usb设备建立连接的过程。
  2. 等时型:主要用于事实音频和视频信号。比如usb相机,网络电话等。
  3. 中断型:名曰"中断"型,实际上是用于对USB设备的周期性查询。比如键盘,操纵杆和鼠标等,这类传输一般都是单向的。
  4. 成块型:用于信息量较大,没有很强的时间要求,但是要求信息的可靠性。比如USB打印机、扫描仪、大容量存储设备。

2 usb描述符

分为四种:设备描述符、配置描述符、接口描述符、端点描述符。

       USB协议规定每个usb接口的设备必须支持这四种描述符, 这些描述符存放在usb设备的EEPROM中,在usb设备枚举时,主机控制器会获取设备上的这些描述符,以给这个设备安装对应的驱动。

2.1 接口描述符

内核中使用usb_interface_descriptor结构表示接口描述符:

struct usb_interface_descriptor {
	__u8  bLength;           // 表示接口描述符的字节长度。规定为9
	__u8  bDescriptorType;   // 表示描述符类型。接口描述符为0x04
	__u8  bInterfaceNumber;  // 接口号。每个配置包含多个接口,这个值是它们的索引值
	__u8  bAlternateSetting; // 接口使用哪个可选设置,协议规定,默认使用设置为0的设置
	__u8  bNumEndpoints;    // 接口拥有的端点数量。这里不包含端点0,端点0是所有USB设备必须提供的
	__u8  bInterfaceClass;  // 接口协议相关
	__u8  bInterfaceSubClass; // 接口协议相关
	__u8  bInterfaceProtocol; // 接口协议相关
	__u8  iInterface;         // 字符串描述符的索引,字符串描述符一般记录厂商,序列号等字符串
} __attribute__ ((packed));

2.2 端点描述符

内核中使用usb_endpoint_descriptor结构表示端点描述符:

struct usb_endpoint_descriptor {
	__u8  bLength;           // 端点描述符的字节长度
	__u8  bDescriptorType;   // 描述符类型,端点描述符类型为0x05
	__u8  bEndpointAddress;  // 含有端点的地址,端点的端口号,端点为输入/输出
	__u8  bmAttributes;      // 属性:表示传输类型
	__le16 wMaxPacketSize;   // 端点一次可以处理的最大字节数
	__u8  bInterval;         // 设备希望主机控制器轮训自己的时间间隔
	__u8  bRefresh;
	__u8  bSynchAddress;
} __attribute__ ((packed));

2.3 设备描述符

struct usb_device_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__le16 bcdUSB;
	__u8  bDeviceClass;
	__u8  bDeviceSubClass;
	__u8  bDeviceProtocol;
	__u8  bMaxPacketSize0;
	__le16 idVendor;
	__le16 idProduct;
	__le16 bcdDevice;
	__u8  iManufacturer;
	__u8  iProduct;
	__u8  iSerialNumber;
	__u8  bNumConfigurations;
} __attribute__ ((packed));

2.4 配置描述符

struct usb_config_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;
	__le16 wTotalLength;
	__u8  bNumInterfaces;
	__u8  bConfigurationValue;
	__u8  iConfiguration;
	__u8  bmAttributes;
	__u8  bMaxPower;
} __attribute__ ((packed));

3 USB驱动模型

  • USB总线

usb子系统初始化时,会向内核注册usb总线:

bus_register(&usb_bus_type);

总线类型用usb_bus_type表示,总线用usb_bus表示,内核中只有一种usb总线类型,但是可以有多条总线。一般一个usb控制器代表一条usb总线,对应一个struct usb_bus xxx变量,是在主机控制驱动加载时注册到内核的。

  • USB驱动

内核中有两种USB驱动:usb设备驱动,usb接口驱动。

usb设备驱动用结构体usb_device_driver表示,注册用usb_register_device_driver函数。特别注意的是linux中只有一个usb设备驱动,是在usb子系统初始化时注册的。

问1:那这个usb设备驱动仅有一个,它是用来做什么的?为什么一个就可以支持这么多设备?

usb接口驱动用结构体usb_driver表示,注册用usb_register函数。比如鼠标、键盘等都需要注册一个单独的接口驱动。

问2:这两种驱动如何区分呢?为什么需要这两种驱动?在匹配驱动时如何知道是匹配哪种驱动呢?

  • USB设备

内核有两种USB设备:usb设备,usb接口设备。

我们常用的一般都是usb接口设备,比如键盘,鼠标等。

usb设备用结构体usb_device表示,注册用usb_alloc_dev函数。

usb接口用结构体usb_interface表示,注册用usb_register_dev函数。

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值