USB复合设备(mass storage&hid)

usb真是很强很大,强是现在很多产品都用她来做,为了方便,不用开发驱动。大是因为usb协议太多了,就光hid都有好多种。还是扯回正题,这次总

结复合型设备,前面总结了hid和mass storage设备,如果在正常情况下两个设备都正常了的,那么现在就可以来做做复合型设备了。

 

百度和google都没找到她的定义,那么我来定义一下(见笑),复合型设备:具有两种usb设备功能的一种设备,无论是相同的设备功能,还是不同的

设备功能,只要同时具有两种以上的功能就是复合型设备。其实很直白,大家都看的出来。

 

现在就把hid keyboard and usb mass storage复合起来,组成一个设备。

 

首先要说的是既然是复合型设备,那么就有多个interface,这里有两个设备,那么就需要两个interface,需要几个设备描述符呢,一个就够了,那配

置描述符呢,也只需要一个就好了,那需要几个端点描述符呢,这个嘛,我就不知道了(开玩笑,你在总结你不知道),这个就得讲讲usb的几种传输

模式了。

 

在usb里面一共有四种传输:控制传输、中断传输、批量传输、等时传输。控制和批量端点用于异步的数据传输,驱动需要他们就立马工作。中断和等

时端点是周期性的,即在固定时间段连续的传输数据。是不是有点熟悉,的确,前面总结过的,在这里再提提。所以有几个端点,还是得看你在用哪种

传输模式,hid keyboard和usb mass storage他们使用的传输方式是中断传输和批量传输。

 

中断传输:interrupt in ,在这里只需要interrupt in就ok了,既只要一个端点,至于interrupt out就不用管了。

批量传输:bulk in和bulk out,由于u盘是双向的,当然需要有两个端点哦,毕竟他们通信要有来回才行啊。

 

所以要复合hid keyboard和usb mass storage就需要三个端点。好了,前面说来复合型设备的描述符分别是:设备描述符*1+配置描述符*1+端点描

述符*3,那么到这里就完了吗,如果只是usb mass storage,在加一个端点就完了,但是这里是Hid,还需要一个子类,在hid里面还有很多子类,那么

就需要区分他们,不然host不知道你是哪家的,好比有很多人叫张三,但是这个世界那么多是张三,你知道他应该是哪家的呢,还是只有slave主动说

自己是谁方便。现在配置是设备描述符*1+配置描述符*1+端点描述符*3+子类描述符,但是描述符排列是有顺序的,写完一个在写另外一个。


// Descriptors for the GET_DESCRIPTOR and SET_DESCRIPTOR requests.

typedef struct usb_device_descriptor {

   unsigned char      length;                // USB_DEVICE_DESCRIPTOR_LENGTH == 18

   unsigned char      type;                  // USB_DEVREQ_DESCRIPTOR_TYPE

   unsigned char      usb_spec_lo;

   unsigned char      usb_spec_hi;

   unsigned char      device_class;

   unsigned char      device_subclass;

   unsigned char      device_protocol;

   unsigned char      max_packet_size;

   unsigned char      vendor_lo;

   unsigned char      vendor_hi;

   unsigned char      product_lo;

   unsigned char      product_hi;

   unsigned char      device_lo;

   unsigned char      device_hi;

   unsigned char      manufacturer_str;

   unsigned char      product_str;

   unsigned char      serial_number_str;

   unsigned char      number_configurations;

} __attribute__((packed)) usb_device_descriptor;

 

/*设备描述符*/

      const usb_device_descriptor  device_desc = {

                    .length = USB_DEVICE_DESC_SIZE, //0x12

                    .type = USB_DEVICE_DESCRIPTOR_TYPE, // 1

                    .usb_spec_lo =0x00,

                    .usb_spec_hi =0x02,

                    .device_class = 0x00,

                    .device_subclass = 0x00,

                    .device_protocol = 0x00,

                    .max_packet_size = USB_MAX_PACKET0,

                    .vendor_lo = 0x51,

                    .vendor_hi = 0xC2,

                    .product_lo = 0x03,

                    .product_hi = 0x20,

                    .device_lo =0x00,

                    .device_hi = 0x01,

                    .manufacturer_str = 0x01,

                    .product_str= 0x02,

                    .serial_number_str = 0x03,

                .number_configurations = 0x01, //

       

      };

 

 

typedef struct usb_configuration_descriptor {

   unsigned char      length;

   unsigned char      type;

      

   unsigned char      total_length_lo;

   unsigned char      total_length_hi; //totallength

      

   unsigned char      number_interfaces;  

   unsigned char      configuration_id;

   unsigned char      configuration_str;

   unsigned char      attributes;

   unsigned char      max_power;

} __attribute__((packed)) usb_configuration_descriptor;

 

typedef struct usb_interface_descriptor {

   unsigned char      length;

   unsigned char      type;

   unsigned char      interface_id;

   unsigned char      alternate_setting;

   unsigned char      number_endpoints;

   unsigned char      interface_class;

   unsigned char      interface_subclass;

   unsigned char      interface_protocol;

   unsigned char      interface_str;

} __attribute__((packed)) usb_interface_descriptor;

 

 

typedef struct usb_endpoint_descriptor {

   unsigned char      length;

   unsigned char      type;

   unsigned char      endpoint;

   unsigned char      attributes;

   unsigned char      max_packet_lo;

   unsigned char      max_packet_hi;

   unsigned char      interval;

} __attribute__((packed)) usb_endpoint_descriptor;

 

typedef struct usb_hid_descriptor

{

   unsigned char      length;

   unsigned char      type;

   unsigned char      bcdhid_lo;

   unsigned char      bcdhid_hi;

   unsigned char      countrycode;

   unsigned char       numdescriptor;

   unsigned char      descriptortype;

   unsigned char      descriptorlength_lo;

   unsigned char      descriptorlength_hi;

      

}__attribute__((packed)) usb_hid_descriptor;

 

 

typedef struct usb_scsi_hid_config

{

      const usb_configuration_descriptor config;

 

      const usb_interface_descriptor    scsi_inter;                  

      const usb_endpoint_descriptor     scsi_endpoint_in;

      const usb_endpoint_descriptor     scsi_endpoint_out;

 

      const usb_interface_descriptor    hid_inter;

      const usb_hid_descriptor            hid_desc;      

      const usb_endpoint_descriptor     hid_endpoint_in;

 

}__attribute__((packed)) USB_CON_INT_ENDP_DESCRIPTOR_STRUCT;

 

#define USB_CON_INT_ENDP_DESCRIPTOR_STRUCT_LENGTH                (sizeof(USB_CON_INT_ENDP_DESCRIPTOR_STRUCT))

 

const USB_CON_INT_ENDP_DESCRIPTOR_STRUCT usb_scsi_hid_con_int_endp = {

 

      /*config*/

      {

      .length= USB_CONFIGUARTION_DESC_SIZE,

      .type = USB_CONFIGURATION_DESCRIPTOR_TYPE,

      .total_length_lo =  USB_CON_INT_ENDP_DESCRIPTOR_STRUCT_LENGTH&0xff,

      .total_length_hi = (USB_CON_INT_ENDP_DESCRIPTOR_STRUCT_LENGTH>>8)&0xff,

      .number_interfaces = 0x02, /*两个interface*/

      .configuration_id = 0x01, /*一个configuration*/

      .configuration_str = 0x00,

      .attributes = USB_CONFIG_BUS_POWERED,

      .max_power = USB_CONFIG_POWER_MA(300)

      },

 

 

 

      /*usb mass storage interface descriptor*/    

      {

      .length = USB_INTERFACE_DESC_SIZE,

      .type   = USB_INTERFACE_DESCRIPTOR_TYPE,

      .interface_id = 0x00,

      .alternate_setting = 0x00,

      .number_endpoints = 0x02,

      .interface_class = USB_DEVICE_CLASS_STORAGE, /*0x08表示mass storage*/

      .interface_subclass = 0x06, /*表示支持SCSI Primary command-2*/

      .interface_protocol = 0x50, /*仅使用批量传输*/

      .interface_str = 0x04

      },

 

 

 

      /*usb mass storage Bulk in 2*/

      {

      /* Endpoint, EP2 Bulk IN */

      .length = USB_ENDPOINT_DESC_SIZE,           /* bLength */

      .type = USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType */

      .endpoint = USB_ENDPOINT_IN(2),               /* bEndpointAddress */

      .attributes = USB_ENDPOINT_TYPE_BULK,           /* bmAttributes */

      .max_packet_lo = 0x40,                    /* wMaxPacketSize */

      .max_packet_hi =0x00,                             

      .interval = 0x00,    /* bInterval: ignore for Bulk transfer */                     },

 

 

      /*usb mass storage Bulk out 3*/

      {

      /* Endpoint, EP3 Bulk OUT */

      .length = USB_ENDPOINT_DESC_SIZE,           /* bLength */

      .type =   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType */

      .endpoint = USB_ENDPOINT_OUT(3),              /* bEndpointAddress */

      .attributes = USB_ENDPOINT_TYPE_BULK,           /* bmAttributes */

      .max_packet_lo = 0x40,                    /* wMaxPacketSize */

      .max_packet_hi =0x00,                             

      .interval = 0x00,    /* bInterval: ignore for Bulk transfer */                                                 

      },

 

 

 

 

 

             /*hid interface descriptor */

      {

      .length = USB_INTERFACE_DESC_SIZE,

      .type   = USB_INTERFACE_DESCRIPTOR_TYPE, // 4

      .interface_id = 0x01,

      .alternate_setting = 0x00,

      .number_endpoints = 0x01,

      .interface_class = USB_DEVICE_CLASS_HUMAN_INTERFACE, //03

      .interface_subclass = HID_SUBCLASS_BOOT, /*0x01*/

      .interface_protocol = HID_PROTOCOL_NONE, /*0x00,没有协议,也可以写你需要的协议具体的看hid协议*/

      .interface_str = 0x00

      },

 

      /*hid subclass descriptor*/

      {

      .length = HID_DESC_SIZE,

      .type = HID_HID_DESCRIPTOR_TYPE,

      .bcdhid_lo = 0x00,

      .bcdhid_hi =0x01,

      .countrycode = 0x00,

      .numdescriptor = 0x01,

      .descriptortype = HID_REPORT_DESCRIPTOR_TYPE,

      .descriptorlength_lo = HID_REPORT_DESC_SIZE&0xff,

      .descriptorlength_hi = (HID_REPORT_DESC_SIZE>>8)&0xff

      },

 

 

      /*hid endpoint interrupt in 1*/

      {

      .length = USB_ENDPOINT_DESC_SIZE,

      .type = USB_ENDPOINT_DESCRIPTOR_TYPE,

      .endpoint = USB_ENDPOINT_IN(1),

      .attributes = USB_ENDPOINT_TYPE_INTERRUPT,

      .max_packet_lo =0x08,

      .max_packet_hi =0x00,

      .interval = 0x20

      },

 

};

 

 

到这里基本就完成了复合设备,只要你的代码两部分都整合在一起,就好了,

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值