STM32 USB HID 组合设备(配置多个接口)

USB Compound Device,USB复合设备
USB Composite Device,USB组合设备

 

USB Composite Device,不内嵌Hub,几个设备的PID和VID都是相同

 

此文均在STM32F767IGTx已实现普通custom HID工程上做解释。

//usb配置描述符
/* USB CUSTOM_HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
  0x09, /* bLength: 长度,设备字符串的长度为9字节 */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: 类型,配置描述符的类型 */
  USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: 配置描述符的总长度 */
  0x00,
  0x01,         /*bNumInterfaces: 配置所支持的接口数量1个*/
  0x01,         /*bConfigurationValue: 该配置的值*/
  0x00,         /*iConfiguration: 该配置的字符串的索引值,该值为0表示没有字符串*/
  0xC0,         /*bmAttributes: bus powered */
  0x32,         /*MaxPower 100 mA: 从总线上获得的最大电流为100mA*/

  /************** 接口描述符 ****************/
  /* 09 */
  0x09,         /*bLength: 长度,接口描述符的长度为9字节 */
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: 接口描述符的类型*/
  0x00,         /*bInterfaceNumber: 该接口的编号*/
  0x00,         /*bAlternateSetting: 该接口的备用编号*/
  0x02,         /*bNumEndpoints: 该接口所使用的端点数*/
  0x03,         /*bInterfaceClass: 该接口所使用的类为HID*/
  0x00,         /*bInterfaceSubClass : 该接口所用的子类 1=BOOT, 0=no boot*/
  0x00,         /*nInterfaceProtocol : 该接口使用的协议 0=none, 1=keyboard, 2=mouse*/
  0,            /*iInterface: 该接口字符串的索引*/
  /******************** HID描述符 *************************/
  /* 18 */
  0x09,         /*bLength: HID描述符的长度为9字节*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID的描述符类型*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: HID协议的版本*/
  0x01,
  0x00,         /*bCountryCode: 国家代号*/
  0x01,         /*bNumDescriptors: 下级描述符的数量*/
  0x22,         /*bDescriptorType: 下级描述符的类型*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: 下一集描述符的长度*/
  0x00,
  /******************** 输入端点描述符 ********************/
  /* 27 */
  0x07,          /*bLength: 端点描述符的长度为7字节*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: 端点描述符的类型*/
  CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03, /*bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),
			1(等时传输),2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点: 
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 该端点支持的最大包长度 */
  0x00,
  0x01,//0x20,          /*bInterval: 轮询间隔*/
  /* 34 */
  /******************** 输出端点描述符 ********************/
  0x07,	         /* bLength: 端点描述符的长度为7字节 */
  USB_DESC_TYPE_ENDPOINT,	/* bDescriptorType: 端点描述符的类型 */
  CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03,	/* bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),1(等时传输),
			2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点: 
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留 */
  CUSTOM_HID_EPOUT_SIZE,	/* wMaxPacketSize: 该端点支持的最大包长度  */
  0x00,
  0x01,//0x20,	/* bInterval: 轮询间隔 */
  /* 41 */
} ;

在这个配置描述符里可以注意到bNumInterfaces,详细查询可以查到这个意思是该配置包含的接口数,一般配置均配置的1,如果配置大于1,则为复合设备,即多个接口。

可以看到最开始的9个字节是整个USB的描述,而后面都和接口相关,所以尝试直接复制后面的接口描述符、HID描述符、输入端点描述符、输出端点描述符,并修改相关的接口地址和描述符总长度。但测试发现枚举失败,PC未能识别。

查了网上的资料后发现第二个接口的HID描述符并不需要再添加,于是删除。修改第二个接口的编号bInterfaceNumber,并将报告描述符的数据也安全复制一份放入报告描述符内,继续测试,依然枚举失败,确实不可能就这么简单。

再查资料发现网上说标准设备描述符和报告描述符都不需要修改,只需要修改配置描述符即可,于是将报告描述符复原。另外发现网上成功例子中的第二个接口没有添加HID描述符,也将HID描述符删除,修改好相应的大小。配置描述符中第3个字节wTotalLength为配置描述符的总长度,也需要修改为正确的大小。配置描述符中bAlternateSetting为接口的编号,两个接口的编号不应相同。

配置好后测试枚举成功,接口1正常,但接口2不正常,如下图所示。

以下为修改好的配置描述符

__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[64] __ALIGN_END =
{
  0x09, /* bLength: 长度,设备字符串的长度为9字节 */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: 类型,配置描述符的类型 */
  0x40,//USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: 配置描述符的总长度 */
  0x00,
  0x02,//0x01,         /*bNumInterfaces: 配置所支持的接口数量1个*/
  0x01,         /*bConfigurationValue: 该配置的值*/
  0x00,         /*iConfiguration: 该配置的字符串的索引值,该值为0表示没有字符串*/
  0xC0,         /*bmAttributes: bus powered */
  0x32,         /*MaxPower 100 mA: 从总线上获得的最大电流为100mA*/

  /************** 接口描述符 ****************/
  /* 09 */
  0x09,         /*bLength: 长度,接口描述符的长度为9字节 */
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: 接口描述符的类型*/
  0x00,         /*bInterfaceNumber: 该接口的编号*/
  0x00,         /*bAlternateSetting: 该接口的备用编号*/
  0x02,         /*bNumEndpoints: 该接口所使用的端点数*/
  0x03,         /*bInterfaceClass: 该接口所使用的类为HID*/
  0x00,         /*bInterfaceSubClass : 该接口所用的子类 1=BOOT, 0=no boot*/
  0x00,         /*nInterfaceProtocol : 该接口使用的协议 0=none, 1=keyboard, 2=mouse*/
  0,            /*iInterface: 该接口字符串的索引*/
  /******************** HID描述符 *************************/
  /* 18 */
  0x09,         /*bLength: HID描述符的长度为9字节*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID的描述符类型*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: HID协议的版本*/
  0x01,
  0x00,         /*bCountryCode: 国家代号*/
  0x01,         /*bNumDescriptors: 下级描述符的数量*/
  0x22,         /*bDescriptorType: 下级描述符的类型*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: 下一集描述符的长度*/
  0x00,
  /******************** 输入端点描述符 ********************/
  /* 27 */
  0x07,          /*bLength: 端点描述符的长度为7字节*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: 端点描述符的类型*/
  CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03, /*bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),
			1(等时传输),2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点: 
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 该端点支持的最大包长度 */
  0x00,
  0x01,//0x20,          /*bInterval: 轮询间隔*/
  /* 34 */
  /******************** 输出端点描述符 ********************/
  0x07,	         /* bLength: 端点描述符的长度为7字节 */
  USB_DESC_TYPE_ENDPOINT,	/* bDescriptorType: 端点描述符的类型 */
  CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03,	/* bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),1(等时传输),
			2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点: 
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留 */
  CUSTOM_HID_EPOUT_SIZE,	/* wMaxPacketSize: 该端点支持的最大包长度  */
  0x00,
  0x01,//0x20,	/* bInterval: 轮询间隔 */
  /* 41 */
  
  /************** 接口描述符 ****************/
  /* 41 */
  0x09,         /*bLength: 长度,接口描述符的长度为9字节 */
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: 接口描述符的类型*/
  0x01,//0x00,         /*bInterfaceNumber: 该接口的编号*/
  0x00,         /*bAlternateSetting: 该接口的备用编号*/
  0x02,         /*bNumEndpoints: 该接口所使用的端点数*/
  0x03,         /*bInterfaceClass: 该接口所使用的类为HID*/
  0x00,         /*bInterfaceSubClass : 该接口所用的子类 1=BOOT, 0=no boot*/
  0x00,         /*nInterfaceProtocol : 该接口使用的协议 0=none, 1=keyboard, 2=mouse*/
  1,//0,            /*iInterface: 该接口字符串的索引*/
#if 0
  /******************** HID描述符 *************************/
  /* 50 */
  0x09,         /*bLength: HID描述符的长度为9字节*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID的描述符类型*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: HID协议的版本*/
  0x01,
  0x00,         /*bCountryCode: 国家代号*/
  0x01,         /*bNumDescriptors: 下级描述符的数量*/
  0x22,         /*bDescriptorType: 下级描述符的类型*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: 下一集描述符的长度*/
  0x00,
#endif
  /******************** 输入端点描述符 ********************/
  /* 59 */
  0x07,          /*bLength: 端点描述符的长度为7字节*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: 端点描述符的类型*/
  0x82,//CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03, /*bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),
			1(等时传输),2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点: 
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 该端点支持的最大包长度 */
  0x00,
  0x01,//0x20,          /*bInterval: 轮询间隔*/
  /* 66 */
  /******************** 输出端点描述符 ********************/
  0x07,	         /* bLength: 端点描述符的长度为7字节 */
  USB_DESC_TYPE_ENDPOINT,	/* bDescriptorType: 端点描述符的类型 */
  0x02,//CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03,	/* bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),1(等时传输),
			2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点: 
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留 */
  CUSTOM_HID_EPOUT_SIZE,	/* wMaxPacketSize: 该端点支持的最大包长度  */
  0x00,
  0x01,//0x20,	/* bInterval: 轮询间隔 */
  /* 73 */
};

 

接口2调试好后再添加后续修改内容。

 

接口2显示不正常原因为配置描述符不正确,多个interface中每个interface都应该包含接口描述符、HID描述符、端点描述符,上面看的配置描述符的第二个interface中没有包含HID描述符,所以正确的配置描述符应为如下所示。

__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[73] __ALIGN_END =
{
  0x09, /* bLength: 长度,设备字符串的长度为9字节 */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: 类型,配置描述符的类型 */
  0x49,//0x40,//USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: 配置描述符的总长度 */
  0x00,
  0x02,//0x01,         /*bNumInterfaces: 配置所支持的接口数量1个*/
  0x01,         /*bConfigurationValue: 该配置的值*/
  0x00,         /*iConfiguration: 该配置的字符串的索引值,该值为0表示没有字符串*/
  0xC0,         /*bmAttributes: bus powered */
  0x32,         /*MaxPower 100 mA: 从总线上获得的最大电流为100mA*/

  /************** 接口描述符 ****************/
  /* 09 */
  0x09,         /*bLength: 长度,接口描述符的长度为9字节 */
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: 接口描述符的类型*/
  0x00,         /*bInterfaceNumber: 该接口的编号*/
  0x00,         /*bAlternateSetting: 该接口的备用编号*/
  0x02,         /*bNumEndpoints: 该接口所使用的端点数*/
  0x03,         /*bInterfaceClass: 该接口所使用的类为HID*/
  0x00,         /*bInterfaceSubClass : 该接口所用的子类 1=BOOT, 0=no boot*/
  0x00,         /*nInterfaceProtocol : 该接口使用的协议 0=none, 1=keyboard, 2=mouse*/
  0,            /*iInterface: 该接口字符串的索引*/
  /******************** HID描述符 *************************/
  /* 18 */
  0x09,         /*bLength: HID描述符的长度为9字节*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID的描述符类型*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: HID协议的版本*/
  0x01,
  0x00,         /*bCountryCode: 国家代号*/
  0x01,         /*bNumDescriptors: 下级描述符的数量*/
  0x22,         /*bDescriptorType: 下级描述符的类型*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: 下一集描述符的长度*/
  0x00,
  /******************** 输入端点描述符 ********************/
  /* 27 */
  0x07,          /*bLength: 端点描述符的长度为7字节*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: 端点描述符的类型*/
  CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03, /*bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),
			1(等时传输),2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点:
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 该端点支持的最大包长度 */
  0x00,
  0x01,//0x20,          /*bInterval: 轮询间隔*/
  /* 34 */
  /******************** 输出端点描述符 ********************/
  0x07,	         /* bLength: 端点描述符的长度为7字节 */
  USB_DESC_TYPE_ENDPOINT,	/* bDescriptorType: 端点描述符的类型 */
  CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03,	/* bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),1(等时传输),
			2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点:
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留 */
  CUSTOM_HID_EPOUT_SIZE,	/* wMaxPacketSize: 该端点支持的最大包长度  */
  0x00,
  0x01,//0x20,	/* bInterval: 轮询间隔 */
  /* 41 */

  /************** 接口描述符 ****************/
  /* 41 */
  0x09,         /*bLength: 长度,接口描述符的长度为9字节 */
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: 接口描述符的类型*/
  0x01,//0x00,         /*bInterfaceNumber: 该接口的编号*/
  0x00,         /*bAlternateSetting: 该接口的备用编号*/
  0x02,         /*bNumEndpoints: 该接口所使用的端点数*/
  0x03,         /*bInterfaceClass: 该接口所使用的类为HID*/
  0x00,         /*bInterfaceSubClass : 该接口所用的子类 1=BOOT, 0=no boot*/
  0x00,         /*nInterfaceProtocol : 该接口使用的协议 0=none, 1=keyboard, 2=mouse*/
  1,//0,            /*iInterface: 该接口字符串的索引*/
#if 1
  /******************** HID描述符 *************************/
  /* 50 */
  0x09,         /*bLength: HID描述符的长度为9字节*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID的描述符类型*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: HID协议的版本*/
  0x01,
  0x00,         /*bCountryCode: 国家代号*/
  0x01,         /*bNumDescriptors: 下级描述符的数量*/
  0x22,         /*bDescriptorType: 下级描述符的类型*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: 下一集描述符的长度*/
  0x00,
#endif
  /******************** 输入端点描述符 ********************/
  /* 59 */
  0x07,          /*bLength: 端点描述符的长度为7字节*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: 端点描述符的类型*/
  0x82,//CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03, /*bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),
			1(等时传输),2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点:
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留,*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 该端点支持的最大包长度 */
  0x00,
  0x01,//0x20,          /*bInterval: 轮询间隔*/
  /* 66 */
  /******************** 输出端点描述符 ********************/
  0x07,	         /* bLength: 端点描述符的长度为7字节 */
  USB_DESC_TYPE_ENDPOINT,	/* bDescriptorType: 端点描述符的类型 */
  0x02,//CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: 该端点(输入)的地址,D7:0(OUT),1(IN),D6~D4:保留,D3~D0:端点号*/
  0x03,	/* bmAttributes: 端点的属性为为中断端点. D0~D1表示传输类型:0(控制传输),1(等时传输),
			2(批量传输),3(中断传输) 非等时传输端点:D2~D7:保留为0 等时传输端点:
			D2~D3表示同步的类型:0(无同步),1(异步),2(适配),3(同步) D4~D5表示用途:0(数据端点),
			1(反馈端点),2(暗含反馈的数据端点),3(保留),D6~D7:保留 */
  CUSTOM_HID_EPOUT_SIZE,	/* wMaxPacketSize: 该端点支持的最大包长度  */
  0x00,
  0x01,//0x20,	/* bInterval: 轮询间隔 */
  /* 73 */
};

另附上报告描述符

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
	0x06, 0x99,	0xff,	// Usage Page (HS_HID_DEMO_HID_USAGE_PAGE) 
	0x09, 0x01,			// Usage (HS_HID_DEMO_HID_USAGE_1) 
	0xA1, 0x01,			// Collection (Application) 
                        
	0x75, 0x08,			// Report Size (8) 
	0x95, 0x40,			// Report Count (64) 
	0x15, 0x00,			// Logical Minimum (0) 
	0x25, 0xFF,  		// Logical Maximum (255)
						
	0x19, 0,			// Usage Minimum (HS_HID_DEMO_HID_USAGE_0) 
	0x29, 0x3f,			// Usage Maximum (HS_HID_DEMO_HID_USAGE_63)
	0x81, 0x02,			// Input (Data,Var,Abs) 
						
	0x19, 0,			// Usage Minimum (HS_HID_DEMO_HID_USAGE_0) 
	0x29, 0x3f,			// Usage Maximum (HS_HID_DEMO_HID_USAGE_63)
	0x91, 0x02,			// Output (Data,Var,Abs)
                        
	0xC0				// End Collection 
	//28
}; 

 

参考资料:http://www.stm32cube.com/question/540

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值