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

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值