Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346686
  • 博文数量: 88
  • 博客积分: 907
  • 博客等级: 准尉
  • 技术积分: 1230
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-26 13:27
文章分类

全部博文(88)

文章存档

2017年(1)

2014年(3)

2013年(29)

2012年(21)

2011年(26)

2010年(8)

分类: LINUX

2011-05-12 22:35:45

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

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

 

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

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

 

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

 

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

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

模式了。

 

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

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

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

 

中断传输:interrupt in ,在这里只需要interrupt inok了,既只要一个端点,至于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

       },

 

};

 

 

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

阅读(1873) | 评论(0) | 转发(0) |
0

上一篇:usb旅途之SCSI

下一篇:开发板上nfs

给主人留下些什么吧!~~