| 这一节,准备基于usb_cdc 例程修改成自定义的大数据传输,我只是抛砖引玉,如果说的有什么不对的地方还请大家指教。 在很多时候通用的usb协议是不能满足我们的使用的,比如我们要传我们自定义的数据和上位机通信(bootloader等),很多人可能会说可以用cdc虚拟串口啊还是现成的,但是这样就面临3个问题1.虚拟串口的速度根本达不到usb的最大速度,2.就是它的上位机驱动是st公司自己的,在成功驱动后显示的是st的名字,这对于很多公司来说是不可接受的。3.就是你不能按照自己的格式发送,只能按照它的要求发送数据。 不废话直接上代码: 1.      用stm32cubemx生成1个usb_cdc 例程,这里就不贴教程了,应该很简单。 2.      修改usbd_desc.c中的报告描述符,原因在与在上位机获取设备描述符时,不让上位机讲我们的设备识别成任何一种设备。 将:bDeviceClass,bDeviceSubClass,bDeviceProtocol,全部改成0x00 /* USB Standard Device Descriptor */ __ALIGN_BEGIN uint8_tUSBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =   {    0x12,                      /*bLength */    USB_DESC_TYPE_DEVICE,      /*bDescriptorType*/    0x00,                       /*bcdUSB */    0x00,         0x00,                       /*bDeviceClass*/    0x00,                      /*bDeviceSubClass*/    0x00,                      /*bDeviceProtocol*/    USB_MAX_EP0_SIZE,         /*bMaxPacketSize*/    LOBYTE(USBD_VID),          /*idVendor*/    HIBYTE(USBD_VID),          /*idVendor*/    LOBYTE(USBD_PID_FS),          /*idVendor*/    HIBYTE(USBD_PID_FS),          /*idVendor*/    0x00,                      /*bcdDevice rel. 2.00*/    0x02,    USBD_IDX_MFC_STR,          /*Index of manufacturer  string*/    USBD_IDX_PRODUCT_STR,      /*Index of product string*/    USBD_IDX_SERIAL_STR,       /*Index of serial number string*/    USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/   } ;   3.      修改报告描述符 将接口描述数量改成1个,因为cdc通信默认使用两个接口 /*Configuration Descriptor*/  0x09,   /* bLength: ConfigurationDescriptor size */  USB_DESC_TYPE_CONFIGURATION,     /* bDescriptorType: Configuration */  USB_CDC_CONFIG_DESC_SIZ,               /* wTotalLength:no of returned bytes */  0x00,   0x01,// 0x02,   /* bNumInterfaces: 2interface */  0x01,   /* bConfigurationValue:Configuration value */  0x00,   /* iConfiguration: Indexof string descriptor describing the configuration */  0xC0,   /* bmAttributes: selfpowered */  0x32,   /* MaxPower 0 mA */ /*********************************************************/ 然后修改接口描述符,修改接口类,接口子类等,注释掉Header Functional Descriptor,Call ManagementFunctional Descriptor,ACM Functional Descriptor,Union FunctionalDescriptor 修改端点描述符 整个配置描述符为:   /* USB CDC deviceConfiguration Descriptor */ __ALIGN_BEGINuint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = {   /*Configuration Descriptor*/   0x09,  /* bLength: Configuration Descriptor size */   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returnedbytes */   0x00,   0x01,// 0x02,   /* bNumInterfaces: 2interface */   0x01,  /* bConfigurationValue: Configuration value */   0x00,  /* iConfiguration: Index of string descriptor describing theconfiguration */   0xC0,  /* bmAttributes: self powered */   0x32,  /* MaxPower 0 mA */     /*---------------------------------------------------------------------------*/      /*Interface Descriptor */   0x09,  /* bLength: Interface Descriptor size */   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */   /*Interface descriptor type */   0x00,  /* bInterfaceNumber: Number of Interface */   0x00,  /* bAlternateSetting: Alternate setting */   0x02,//0x01,  /* bNumEndpoints: One endpoints used */      0xDC,//0x02,  /* bInterfaceClass: Communication Interface Class */   0xA0,//0x02,  /* bInterfaceSubClass: Abstract Control Model */   0xB0,//0x01,  /* bInterfaceProtocol: Common AT commands */   0x00,  /* iInterface: */    //  /*Header Functional Descriptor*/ //  0x05,  /* bLength: Endpoint Descriptor size */ //  0x24,  /* bDescriptorType: CS_INTERFACE */ //  0x00,  /* bDescriptorSubtype: Header Func Desc */ //  0x10,  /* bcdCDC: spec release number */ //  0x01, //   //  /*Call Management Functional Descriptor*/ //  0x05,  /* bFunctionLength */ //  0x24,  /* bDescriptorType: CS_INTERFACE */ //  0x01,  /* bDescriptorSubtype: Call Management Func Desc */ //  0x00,  /* bmCapabilities: D0+D1 */ //  0x01,  /* bDataInterface: 1 */ //   //  /*ACM Functional Descriptor*/ //  0x04,  /* bFunctionLength */ //  0x24,  /* bDescriptorType: CS_INTERFACE */ //  0x02,  /* bDescriptorSubtype: Abstract Control Management desc */ //  0x02,  /* bmCapabilities */ //   //  /*Union Functional Descriptor*/ //  0x05,  /* bFunctionLength */ //  0x24,  /* bDescriptorType: CS_INTERFACE */ //  0x06,  /* bDescriptorSubtype: Union func desc */ //  0x00,  /* bMasterInterface: Communication class interface */ //  0x01,  /* bSlaveInterface0: Data Class Interface */ //   //  /*Endpoint 2 Descriptor*/ //  0x07,                           /* bLength: EndpointDescriptor size */ //  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */ //  CDC_CMD_EP,                     /* bEndpointAddress */ //  0x03,                           /* bmAttributes: Interrupt */ //  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */ //  HIBYTE(CDC_CMD_PACKET_SIZE), //  0x10,                           /* bInterval: */   /*---------------------------------------------------------------------------*/    //  /*Data class interface descriptor*/ //  0x09,  /* bLength: Endpoint Descriptor size */ //  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */ //  0x01,  /* bInterfaceNumber: Number of Interface */ //  0x00,  /* bAlternateSetting: Alternate setting */ //  0x02,  /* bNumEndpoints: Two endpoints used */ //  0x0A,  /* bInterfaceClass: CDC */ //  0x00,  /* bInterfaceSubClass: */ //  0x00,  /* bInterfaceProtocol: */ //  0x00,  /* iInterface: */      /*Endpoint OUT Descriptor*/   0x07,  /* bLength: Endpoint Descriptor size */   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */   CDC_OUT_EP,                        /* bEndpointAddress */   0x02,                              /* bmAttributes:Bulk */   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),   0x00,                              /* bInterval:ignore for Bulk transfer */      /*Endpoint IN Descriptor*/   0x07,  /* bLength: Endpoint Descriptor size */   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */   CDC_IN_EP,                         /* bEndpointAddress */   0x02,                              /* bmAttributes:Bulk */   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),   0x00                               /* bInterval:ignore for Bulk transfer */ } ; 最好将下面的USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] 和uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 也改了因为以备不时之需。 4.      修改发送函数 由于我们还是使用cdc的端点收发,所以不用重新初始化。我们只需要增加我们自己的bulk传输的收发函数就可以了   uint8_tBulkRxBuffer[512]; uint8_t  USBD_BULK_ReceivePacket(USBD_HandleTypeDef*pdev) {         USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*)pdev->pClassData;      /* Suspend or Resume USB Out process */   if(pdev->pClassData != NULL)   {     if(pdev->dev_speed == USBD_SPEED_HIGH  )      {            /* Prepare Out endpoint to receive nextpacket */       USBD_LL_PrepareReceive(pdev,                              CDC_OUT_EP,                              BulkRxBuffer,                              512);     }     else     {       /* Prepare Out endpoint to receive nextpacket */       USBD_LL_PrepareReceive(pdev,                              CDC_OUT_EP,                              BulkRxBuffer,                              512);     }     return USBD_OK;   }   else   {     return USBD_FAIL;   } }     uint8_tBulkTxBuffer[512]; uint8_t  USBD_BULK_TransmitPacket(USBD_HandleTypeDef*pdev) {         USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*)pdev->pClassData;      if(pdev->pClassData != NULL)   {     if(hcdc->TxState == 0)     {       /* Tx Transfer in progress */       hcdc->TxState = 1;              /* Transmit next packet */       USBD_LL_Transmit(pdev,                        CDC_IN_EP,                        BulkTxBuffer,                        512);              return USBD_OK;     }     else     {       return USBD_BUSY;     }   }   else   {     return USBD_FAIL;   } } 已经就完成了自定义大数据传输的修改。 调用以上两个函数就可以完成和pc机的通信。 将我们的设备插到上位机上,使用libusb-win32 自动生成这个设备的驱动之后就能正常通信。 是不是很简单。。。 
 |