Linux驱动(3)- LInux USB驱动层次

在Linux系统中,提供了主机侧和设备侧USB驱动框架。

从主机侧,需要编写USB驱动包括主机控制器驱动,设备驱动两类,USB

主机控制驱动程序控制插入其中的USB设备。

USB设备驱动程序控制该设备如何作为从设备与主机进行通信。

1.主机侧与设备侧USB驱动

USB采用树状拓扑结构,主机侧和设备侧的USB控制器分别为主机控制器和USB

设备控制器,每条总线上只有一个主机控制器,负责协调主机与设备间的通讯,而设备不能主动向主机发送任何数据。

从主机侧看,要实现的USB驱动包括两类:USB主机控制器驱动和USB设备驱动。

USB设备驱动MASS storage/CDC/HID控制USB设备如何与主机通信
USB核心

负责USB驱动管理和协议处理的主要工作。

1.通过定义一些数据结构,宏和函数功能,向上为设备驱动提供编程接口,向下为USB主机控制器驱动提供编程接口。

2.维护整个系统的USB设备信息。

3.完成设备热插拔控制,总线数据传输控制

USB主机控制器驱动OHCI/EHCI/UHCI控制插入其中的USB设备
主机控制器只有一个主机控制器,负责协调主机与设备间的通讯

从设备上看,

Gardget Function 驱动(Mass storage/serial...)具体控制USB功能的实现,使设备表现出“网络连接”,“打印机”或者“USB Mass Storage”
Gadet Function APIUDC驱动函数的简单包装
UDC驱动(omap/pxa2xx)直接访问硬件,控设备和主机间的地层通信
USB设备控制器
2.设备,配置,接口,端点

 在USB设备逻辑中,包含设备,配置,接口和端点4个层次。

 

接口       

1.代表一个节本功能,是USB设备驱动程序控制对象,一个复杂的USB设备可以有多个接口。

2.每个配置有多个接口,而设备接口是端点的汇集。

一个配置中所有接口都可以同时有效,并且被不同的驱动程序连接。

端点

是USB通信的最基本形式,每个USB设备接口在主机看来就是一个端点的集合。

主机只能通过端点与设备进行通信,以使用设备功能。

每个端点都有一定的属性,包括传述方向,总线访问频率,贷款,端点好,数据包的最大容量等。

一个端点只能一个方向上成在数据,从主机到设备(输入端点),或者从设备到主机(输出端点),因此端点可看作一个单向的管道。

 设备通常有一个或者多个配置

配置通常有一个或者多个接口

接口通常有一个或者多个配置

接口有0个或者多个端点。


这种层次花配置信息在设备中通过一组标准的描述符来描述。

设备描述符

1.关于设备的通用信息,例如供应商 ID,产品ID,修订ID,支持设备类,自类和适合协议以及默认端点的最大包大小。

2.在LInux内核中,USB设备用usb_device结构体来描述,USB

设备描述符定义为usb_device_descriptor结构体。

配置描述符

此配置中的接口,支持的刮起和恢复的能力以及功率的要求。USB配置在内核中使用usb_host_config接口体描述,USB配置描述定义为结构体usb_config_descriptor

接口描述符

接口类,子类和使用的协议,接口备用配置的数目和端点数目。

USB接口在内核中使用usb_interface结构体描述。

端点描述符端点地址,方向和类型,支持的最大报打包大小,如果是中断类型的端点侧包括轮询频率。使用usb_host)endpoint接口体来描述。

 

设备描述符定义为usb_device_descriptor结构体

/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor { //usb设备描述符
    __u8  bLength;//长度
    __u8  bDescriptorType;//描述符类型

    __le16 bcdUSB;//usb SPEC的版本
    __u8  bDeviceClass;//设别类型
    __u8  bDeviceSubClass;//设备子类型
    __u8  bDeviceProtocol;//协议
    __u8  bMaxPacketSize0;//最大传输大小
    __le16 idVendor;//厂商ID
    __le16 idProduct;//设备ID
    __le16 bcdDevice;//设备版本号
    __u8  iManufacturer;//描述厂商字符串的索引
    __u8  iProduct;//描述产品字符串的索引
    __u8  iSerialNumber;//序列号
    __u8  bNumConfigurations;//设备当前速度模式下支持的配置数量。有的设备可以在多个速度模式下操作,这里包括的只是当前速度模式下的配置数目,不是总的配置数目
} __attribute__ ((packed));

 配置描述符:用结构体usb_config_descriptor描述。

struct usb_config_descriptor { //配置描述符
    __u8  bLength;//描述符长度
    __u8  bDescriptorType;//配置描述符的类型

    __le16 wTotalLength;//使用GET_DESCRIPTOR请求从设备里获得配置描述符信息时,返回的数据长度
    __u8  bNumInterfaces;//这个配置包含的接口数量
    __u8  bConfigurationValue;//对于拥有多个配置的设备来说,可以拿这个值为参数,使用SET_CONFIGURATION请求来改变正在被使用的 USB配置,
	                          bConfigurationValue就指明了将要激活哪个配置。咱们的设备虽然可以有多个配置,但同一时间却也只能有一个配置被激活。捎带着提一下,
	                          SET_CONFIGURATION请求也是标准的设备请求之一,专门用来设置设备的配置。
    __u8  iConfiguration;//描述配置信息的字符串描述符的索引值
    __u8  bmAttributes;//这个字段表征了配置的一些特点,比如bit 6为1表示self-powered,bit 5为1表示这个配置支持远程唤醒。
	                    另外,它的bit 7必须为1
    __u8  bMaxPower;//设备正常运转时,从总线那里分得的最大电流值,以2mA为单位。
	                 设备可以使用这个字段向hub表明自己需要的的电流,但如果设备需求过于旺盛,
	                 请求的超出了hub所能给予的,hub就会直接拒绝还记得struct usb_device结构里的bus_mA吗?它就表示hub所能够给予的。计算机的usb端口可以提供最多500mA的电流
} __attribute__ ((packed));

接口描述符:用usb_interface_descriptor结构体描述

/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
    __u8  bLength;//接口描述符长度
    __u8  bDescriptorType;//接口描述符类型

    __u8  bInterfaceNumber;//接口号。每个配置可以包含多个接口,这个值就是它们的索引值。
    __u8  bAlternateSetting;//接口使用的是哪个可选设置。协议里规定,接口默认使用的设置总为0号设置。
    __u8  bNumEndpoints;//接口拥有的端点数量。这里并不包括端点0,因为端点0是控制传输,是所有的设备都必须提供的,
	                    所以这里就没必要多此一举的包括它了。对于hub,因为它的传输是中断传输,所以此值为1(不包括端点0)
    __u8  bInterfaceClass;//接口类型
    __u8  bInterfaceSubClass;//接口子类型
    __u8  bInterfaceProtocol;//接口所遵循的协议
    __u8  iInterface;//描述该接口的字符串索引值
} __attribute__ ((packed));

端点描述符:定义为usb_endpoint_descriptor结构体 

/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {//USB 端点描述符(每个USB设备最多有16个端点)
    __u8  bLength;//描述符的字节长度
    __u8  bDescriptorType;//描述符类型,对于端点就是USB_DT_ENDPOIN

    __u8  bEndpointAddress;//bit0~3表示端点地址,bit8 表示方向,输入还是输出
    __u8  bmAttributes;//属性(bit0、bit1构成传输类型,00--控制,01--等时,10--批量,11--中断)
    __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;//对于同步传送的端点,此域必须为1
} __attribute__ ((packed));

可以通过lsusb -v查看usb节电信息

Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               3.10
  bDeviceClass            9 Hub
  bDeviceSubClass         0 
  bDeviceProtocol         3 
  bMaxPacketSize0         9
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0003 3.0 root hub
  bcdDevice            6.05
  iManufacturer           3 Linux 6.5.0-35-generic xhci-hcd
  iProduct                2 xHCI Host Controller
  iSerial                 1 0000:03:00.4
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x001f
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval              12
        bMaxBurst               0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值