USB驱动的概念介绍

相关概念

1、USB是主从结构

所有的USB传输都是从USB主机发起,USB设备没有能力“主动”通知USB主机。

例子:USB鼠标滑动一下立刻产生数据,但是它没有能力通知PC机来取数据,只能被动等待PC机来读。

2、USB的传输类型

(1)控制传输:可靠的、时间有保证,比如:USB设备的识别过程

(2)批量传输:可靠、时间没有保证。比如:U盘

(3)中断传输:可靠、实时。比如:USB鼠标

(4)实时传输:不可靠、实时,比如:USB摄像头

3、USB的传输对象:端点(endpoint)

读U盘或写U盘,可以细化为:把数据写到U盘的端点1,从U盘的端点2里读出数据。

除了端点0外,每个端点只支持一个方向的数据传输。

端点0用于控制传输,既能输出也能输入。

4、每个端点都有传输类型,传输方向

5、术语里,程序里说的输入(in)、输出(out)都是基于USB主机的立场来说的。比如鼠标的数据是从鼠标传到PC机,对应的端点称为“输入端点”

6、USB总线驱动程序的作用

(1)识别USB设备

(2)查找并安装对应的的设备驱动程序

(3)只提供USB读写函数,并不了解数据的含义,只有对应的设备驱动程序了解

USB驱动程序框架

                                    应用层

-----------------------------------------------------------------------

                   USB设备驱动程序(可以有很多个)

内核层     ------------------------------------------------

                            USB总线驱动程序

-----------------------------------------------------------------------

 硬件层                 USB主机控制器

               USB设备(和USB设备驱动程序一一对应)

 

其中,USB主机控制器有3种规范:

UHCI: Intel公司规范,低速(1.5Mbps)/高速(12Mbps)

OHCI:微软公司规范,低速/高速

EHCI:高速(480Mbps)

 

USB总线驱动程序

下面重点分析一下识别USB设备的流程:

1.1 分配地址

1.2 告诉USB设备(set address)

1.3 发出命令获取描述符

描述符的信息可以在include/linux/usb/Ch9.h看到,另外各种描述符的关系如下所示:

一个硬件设备都有一个对应的设备描述符

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

一个硬件可能有多个配置,上面结构体中也有显示了配置的个数,所以也有配置描述符

struct usb_config_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__le16 wTotalLength;
	__u8  bNumInterfaces; //接口个数
	__u8  bConfigurationValue;
	__u8  iConfiguration;
	__u8  bmAttributes;
	__u8  bMaxPower;
} __attribute__ ((packed));

       每个配置可能有一个或者多个接口,接口是用来描述逻辑上的设备,比如一个USB声卡,硬件上只有一个,但是逻辑上可以分为录音和播放,所以就要有两个接口来描述

struct usb_interface_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bInterfaceNumber;
	__u8  bAlternateSetting;
	__u8  bNumEndpoints; //端点个数
	__u8  bInterfaceClass;
	__u8  bInterfaceSubClass;
	__u8  bInterfaceProtocol;
	__u8  iInterface;
} __attribute__ ((packed));

前面我们说过,USB实际使用端点来传输数据的,所以也应该有端点描述符

struct usb_endpoint_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bEndpointAddress; //端点地址
	__u8  bmAttributes;
	__le16 wMaxPacketSize;
	__u8  bInterval;

	/* NOTE:  these two are _only_ in audio endpoints. */
	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
	__u8  bRefresh;
	__u8  bSynchAddress;
} __attribute__ ((packed));

下面的图可以清晰的表述上面几种描述符的关系:

下面给出大概的USB设备识别的代码流程:

这里涉及到另外一个重要的总线,USB设备总线,和我们之前讲过的另外一个总线(设备、驱动、总线模型简介)类似:

                                                                USB_BUS_TYPE

                                  usb_new_device /                          \usb_register

                                                            /                               \

                                          usb_interface                            usb_driver

Linux系统已经为我们搭好了usb_interface的框架,我们只要编写好usb_driver的代码就好了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值