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+子类描述符,但是描述符排列是有顺序的,写完一个在写另外一个。
-
- typedef struct usb_device_descriptor {
- unsigned char length;
- unsigned char 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,
- .type = USB_DEVICE_DESCRIPTOR_TYPE,
- .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;
-
- 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 = {
-
-
- {
- .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,
- .configuration_id = 0x01,
- .configuration_str = 0x00,
- .attributes = USB_CONFIG_BUS_POWERED,
- .max_power = USB_CONFIG_POWER_MA(300)
- },
-
-
-
-
- {
- .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,
- .interface_subclass = 0x06,
- .interface_protocol = 0x50,
- .interface_str = 0x04
- },
-
-
-
-
- {
-
- .length = USB_ENDPOINT_DESC_SIZE,
- .type = USB_ENDPOINT_DESCRIPTOR_TYPE,
- .endpoint = USB_ENDPOINT_IN(2),
- .attributes = USB_ENDPOINT_TYPE_BULK,
- .max_packet_lo = 0x40,
- .max_packet_hi =0x00,
- .interval = 0x00, },
-
-
-
- {
-
- .length = USB_ENDPOINT_DESC_SIZE,
- .type = USB_ENDPOINT_DESCRIPTOR_TYPE,
- .endpoint = USB_ENDPOINT_OUT(3),
- .attributes = USB_ENDPOINT_TYPE_BULK,
- .max_packet_lo = 0x40,
- .max_packet_hi =0x00,
- .interval = 0x00,
- },
-
-
-
-
-
-
- {
- .length = USB_INTERFACE_DESC_SIZE,
- .type = USB_INTERFACE_DESCRIPTOR_TYPE,
- .interface_id = 0x01,
- .alternate_setting = 0x00,
- .number_endpoints = 0x01,
- .interface_class = USB_DEVICE_CLASS_HUMAN_INTERFACE,
- .interface_subclass = HID_SUBCLASS_BOOT,
- .interface_protocol = HID_PROTOCOL_NONE,
- .interface_str = 0x00
- },
-
-
- {
- .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
- },
-
-
-
- {
- .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
- },
-
- };
到这里基本就完成了复合设备,只要你的代码两部分都整合在一起,就好了。 |