您的位置:首页 > 其它

usb设备的描述符和相应结构体

2013-06-08 11:41 183 查看
usb 设备的一些结构

以前零星记录的一些信息,可能来自于网络,可能来自于自己的spec 阅读。

通常,一个USB设备由三个功能模块组成:USB总线接口、USB逻辑设备和功能单元。

1、设备中USB总线接口指的是USB设备中的串行接口引擎(SIE);

2、USB逻辑设备被USB系统软件看作是一个端点的集合;

3、功能单元被客户软件看作是一个接口的集合。

SIE、端点和接口都是USB设备的组成单元。为了更好地描述USB设备的特征,USB提出了设备架构的概念。从这个角度来看,可以认为USB设备是由一些配置、接口和端点组成的,即一个USB设备可以含有一个或多个配置,在每个配置中可含有一个或多个接口,在每个接口中可含有若干个端点。其中,配置和接口是对USB设备功能的抽象,实际的数据传输由端点来完成。

在使用USB设备前,必须指明其采用的配置和接口。这个步骤一般是在设备接入主机时设备进行 握手协议 时完成的。USB设备使用各种描述符来说明其设备架构,包括设备描述符、配置描述符、接口描述符、端点描述符以及字符串描述符,它们通常被保存在USB设备的固件程序中。

所以,在usb驱动程序中,也需要对应的设置描述符的结构体,以便完成程序数据结构的完整性。一般在usb 2.0的spec中第九章有介绍。或者在linux、uboot中有ch9.h定义这些数据结构。

1、设备描述符结构

/* USB_DT_DEVICE: Device descriptor */

struct usb_device_descriptor { 设备描述符 如USB扬声器

__u8 bLength; 描述符的长度

__u8 bDescriptorType; 描述符类型的编号

__le16 bcdUSB; USB版本号

__u8 bDeviceClass; USB的设备类code

__u8 bDeviceSubClass; USB的子类code

__u8 bDeviceProtocol; USB的协议code

__u8 bMaxPacketSize0; 默认端口端口0的最大包大小

__le16 idVendor; 厂商编号

__le16 idProduct; 产品编号

__le16 bcdDevice; 设备出厂的编号

__u8 iManufacturer; 描述厂商的字符串的索引

__u8 iProduct; 描述产品的字符串的索引

__u8 iSerialNumber; 描述设备序列号的字符串的索引

__u8 bNumConfigurations; 可能的配置数量

} __attribute__ ((packed));

2、配置描述符结构

struct usb_config_descriptor { 多个配置描述符

__u8 bLength; 描述符的长度

__u8 bDescriptorType; 描述符类型的编号

__le16 wTotalLength; 配置 所返回的所有数据的大小

__u8 bNumInterfaces; 配置 所支持的interface数

__u8 bConfigurationValue; Set_Configuration命令需要的参数值

__u8 iConfiguration; 描述该配置的字符串的索引值

__u8 bmAttributes; 供电模式的选择

__u8 bMaxPower; 设备从总线提取的最大电流

} __attribute__ ((packed));

3、接口描述符结构

/* USB_DT_INTERFACE: Interface descriptor */

struct usb_interface_descriptor { 多个接口描述符 如音频接口,旋钮和按钮接口

__u8 bLength; 描述符的长度

__u8 bDescriptorType; 描述符类型的编号

__u8 bInterfaceNumber; 接口的编号

__u8 bAlternateSetting; 备用的接口描述符编号,提供不同质量的服务参数.

__u8 bNumEndpoints; 该接口所使用的端口数,不包括端口0

__u8 bInterfaceClass; 接口类型

__u8 bInterfaceSubClass; 接口子类型

__u8 bInterfaceProtocol; 接口所遵循的协议

__u8 iInterface; 描述该接口的字符串索引值

} __attribute__ ((packed)

4、端点描述符结构

/* USB_DT_ENDPOINT: Endpoint descriptor */

struct usb_endpoint_descriptor { 多个端口描述符

__u8 bLength; 描述符长度

__u8 bDescriptorType; 描述符的类型

__u8 bEndpointAddress; 端点号:0-3是端口点,第7位是方向(0-OUT,1-IN)

__u8 bmAttributes; 端口属性:bit[0:1] 00:控制端点 01:同步传输端点 02:批量传输端点 03:中断端点

__le16 wMaxPacketSize; 数据包的最大容量

__u8 bInterval; 轮询数据传送端点的时间间隔,即中断传送时轮询间隔,此域为1-255

批量和控制传送时,此域忽略

同步传送时,为1

5、字符串描述符结构

/* USB_DT_STRING: String descriptor */

struct usb_string_descriptor { 字符串描述符

__u8 bLength; 描述符长度

__u8 bDescriptorType; 描述符类型

__le16 wData[1]; /* UTF-16LE encoded */

} __attribute__ ((packed))

那么usb驱动中,就会定义usb device 结构体:

struct usb_device {

   int devnum; //设备号,是在USB总线的地址

   char devpath [16]; //用于消息的设备ID字符串

   enum usb_device_state state; //设备状态:已配置、未连接等等

   enum usb_device_speed speed; //设备速度:高速、全速、低速或错误

  

   struct usb_tt *tt; //处理传输者信息;用于低速、全速设备和高速HUB

   int ttport; //位于tt HUB的设备口

  

   unsigned int toggle[2]; //每个端点的占一位,表明端点的方向([0] = IN, [1] = OUT)  

   struct usb_device *parent; //上一级HUB指针

   struct usb_bus *bus; //总线指针

   struct usb_host_endpoint ep0; //端点0数据

   struct device dev; //一般的设备接口数据结构

 

   struct usb_device_descriptor descriptor; //USB设备描述符

   struct usb_host_config *config; //设备的所有配置

   struct usb_host_config *actconfig; //被激活的设备配置

   struct usb_host_endpoint *ep_in[16]; //输入端点数组

   struct usb_host_endpoint *ep_out[16]; //输出端点数组

  

   char **rawdescriptors; //每个配置的raw描述符

  

   unsigned short bus_mA; //可使用的总线电流

   u8 portnum; //父端口号

   u8 level; //USB HUB的层数

  

   unsigned can_submit:1; //URB可被提交标志

   unsigned discon_suspended:1; //暂停时断开标志

   unsigned persist_enabled:1; //USB_PERSIST使能标志

   unsigned have_langid:1; //string_langid存在标志

   unsigned authorized:1;

   unsigned authenticated:1;

   unsigned wusb:1; //无线USB标志

   int string_langid; //字符串语言ID

   /* static strings from the device */ //设备的静态字符串

   char *product; //产品名

   char *manufacturer; //厂商名

   char *serial; //产品串号

  

   struct list_head filelist; //此设备打开的usbfs文件

  #ifdef CONFIG_USB_DEVICE_CLASS

   struct device *usb_classdev; //用户空间访问的为usbfs设备创建的USB类设备

  #endif

  #ifdef CONFIG_USB_DEVICEFS

   struct dentry *usbfs_dentry; //设备的usbfs入口

  #endif

  

   int maxchild; //(若为HUB)接口数

   struct usb_device *children[USB_MAXCHILDREN];//连接在这个HUB上的子设备

   int pm_usage_cnt; //自动挂起的使用计数

   u32 quirks;

   atomic_t urbnum; //这个设备所提交的URB计数

  

   unsigned long active_duration; //激活后使用计时

  #ifdef CONFIG_PM //电源管理相关

   struct delayed_work autosuspend; //自动挂起的延时

   struct work_struct autoresume; //(中断的)自动唤醒需求

   struct mutex pm_mutex; //PM的互斥锁 

 

   unsigned long last_busy; //最后使用的时间

   int autosuspend_delay;

   unsigned long connect_time; //第一次连接的时间

  

   unsigned auto_pm:1; //自动挂起/唤醒

   unsigned do_remote_wakeup:1; //远程唤醒

   unsigned reset_resume:1; //使用复位替代唤醒

   unsigned autosuspend_disabled:1; //挂起关闭

   unsigned autoresume_disabled:1; //唤醒关闭

   unsigned skip_sys_resume:1; //跳过下个系统唤醒

  #endif

   struct wusb_dev *wusb_dev; //(如果为无线USB)连接到WUSB特定的数据结构

};

配置的定义

一个USB设备可以有多个配置,并可在它们之间转换以改变设备的状态。一个时刻只能有一个配置可以被激活。

struct usb_host_config {

struct usb_config_descriptor desc; //配置描述符

char *string; /* 配置的字符串指针(如果存在) */

struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS]; //配置的接口联合描述符链表

struct usb_interface *interface[USB_MAXINTERFACES]; //接口描述符链表

struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];

unsigned char *extra; /* 额外的描述符 */

int extralen;

};

设备usb接口

一个USB接口代表一个基本功能,每个USB驱动控制一个接口。所以一个物理上的硬件设备可能需要 一个以上的驱动程序。有时插入一个USB设备后,系统会识别出多个设备,并安装相应多个的驱动。

USB接口在内核中使用 struct usb_interface 来描述。USB core将其传递给USB驱动,并由USB驱动负责后续的控制。

struct usb_interface {

struct usb_host_interface *altsetting; /* 包含所有可用于该接口的可选设置的接口结构数组。每个 struct usb_host_interface 包含一 套端点配置(即struct usb_host_endpoint结构所定义的端点配置。这些接口结构没有特别的顺序。*/

struct usb_host_interface *cur_altsetting; /* 指向altsetting内部的指针,表示当前激活的接口配置*/

unsigned num_altsetting; /* 可选设置的数量*/

/* If there is an interface association descriptor then it will list the associated interfaces */

struct usb_interface_assoc_descriptor *intf_assoc;

int minor; /* 如果绑定到这个接口的 USB 驱动使用 USB 主设备号, 这个变量包 含由
USB 核心分配给接口的次设备号. 这只在一个成功的调用 usb_register_dev后才有效。*/

/*以下的数据在我们写的驱动中基本不用考虑,系统会自动设置*/

enum usb_interface_condition condition; /* state of binding */

unsigned is_active:1; /* the interface is not suspended */

unsigned sysfs_files_created:1; /* the sysfs attributes exist */

unsigned ep_devs_created:1; /* endpoint "devices" exist */

unsigned unregistering:1; /* unregistration is in progress */

unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */

unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */

unsigned needs_binding:1; /* needs delayed unbind/rebind */

unsigned reset_running:1;

struct device dev; /* 接口特定的设备信息 */

struct device *usb_dev;

int pm_usage_cnt; /* usage counter for autosuspend */

struct work_struct reset_ws; /* for resets in atomic context */

};

struct usb_host_interface {

struct usb_interface_descriptor desc; //接口描述符

struct usb_host_endpoint *endpoint; /* 这个接口的所有端点结构体的联合数组*/

char *string; /* 接口描述字符串 */

unsigned char *extra; /* 额外的描述符 */

int extralen;

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: