[方案相关] 【华大测评】+ HC32F460 WINUSB移植、遇到的问题与解决方法

[复制链接]
11798|9
 楼主| 纪国圣 发表于 2021-10-2 10:19 | 显示全部楼层 |阅读模式
最近有空测试了一下官方的VCP例程,使用感觉不错,将其稍微改动做了一个CDC回环测试,速率也不错,就是安装驱动有些麻烦,于是想直接将CDC改写成WINUSB不就不需要驱动了吗?于是抽空从之前写的STM32 WINUSB移植到HC32F460。一、移植的方法
修改的话主要是在CDC的基础上添加有关描述符的发送等函数。修改方法如下:

1.修改头文件usb_core_driver.h中的结构体usb_dev_class_func,添加如下成员:
1.PNG
2.修改usb_dev_stdreq.c中的void hd_usb_getdesc(usb_core_instance *pdev, const USB_SETUP_REQ *req),添加如下语句:
2.PNG

3.添加宏定义USBD_SUPPORT_USER_STRING_DESC:
3.PNG
4.修改usb_dev_cdc_class.c中的usb_dev_class_func  class_cdc_cbk,添加成员变量:

4.PNG
5.添加extern __USB_ALIGN_BEGIN uint8_t usb_dev_strdesc[USB_MAX_STR_DESC_SIZ] __USB_ALIGN_END、__USB_ALIGN_BEGIN uint8_t USBD_WINUSB_OSFeatureDesc[USB_LEN_OS_FEATURE_DESC] __USB_ALIGN_END、uint8_t *USBD_WinUSBOSFeatureDescriptor(uint16_t *length):
5.PNG
6.PNG
6.修改配置描述符:
7.PNG
8.PNG
7.修改usb_dev_core.c中的void hd_usb_setup_process(usb_core_instance *pdev),添加如下语句:
9.PNG
8.继续在usb_dev_cdc_class.c中添加有关描述符的函数:
10.PNG
11.PNG
12.PNG
13.PNG
14.PNG
9.至此WINUSB修改完毕。为了测试发送速度,在做一些修改:
15.PNG
15_1.PNG
16.PNG
29.PNG
30.PNG
由于之前做STM32 WINUSB+CDC时将系统的驱动弄崩了,于是需要安装驱动。驱动安装完毕,电脑识别了USB设备:
17.PNG
测试USB上传速度HC32F460->PC:
18.PNG
速度相当不错。
二、遇到的问题
1.相比于STM32的uint8_t USBD_WinUSB_TransmitPacket(USBD_HandleTypeDef *pdev),由于HC32F460的USB发送函数void hd_usb_deveptx( usb_core_instance *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
是没有提供是否成功发送的状态值,因此不能保证数据因为USB总线繁忙而丢失。
19.PNG
可以看出很多数据并没有成功发送。
2.每次系统复位后,都会出现掉驱动的情况:
20.PNG
查看设备信息,发现有CM_PROB_FAILED_START问题,String Descriptors读不到:
21.PNG
22.PNG

  1.     =========================== USB Port2 ===========================

  2. Connection Status        : 0x01 (Device is connected)
  3. Port Chain               : 1-5-2
  4. Properties               : 0x01
  5. IsUserConnectable       : yes
  6. PortIsDebugCapable      : no
  7. PortHasMultiCompanions  : no
  8. PortConnectorIsTypeC    : no

  9.       ======================== USB Device ========================

  10.         +++++++++++++++++ Device Information ++++++++++++++++++
  11. Device Description       : WinUSB 设备
  12. Device ID                : USB\VID_07E9&PID_07E9\00000000050C
  13. Hardware IDs             : USB\VID_07E9&PID_07E9&REV_0200 USB\VID_07E9&PID_07E9
  14. Driver KeyName           : {88bae032-5a81-49f0-bc3d-a4ff138216d6}\0008 ({88BAE032-5A81-49F0-BC3D-A4FF138216D6})
  15. Driver                   : \SystemRoot\System32\drivers\WinUsb.sys (Version: 6.3.9600.18088  Date: 2015-10-11)
  16. Driver Inf               : C:\Windows\inf\winusb.inf
  17. Legacy BusType           : PNPBus
  18. Class                    : USBDevice
  19. Class GUID               : {88bae032-5a81-49f0-bc3d-a4ff138216d6}
  20. Service                  : WINUSB
  21. Enumerator               : USB
  22. Location Info            : Port_#0002.Hub_#0003
  23. Location IDs             : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(5)#USB(2), ACPI(_SB_)#ACPI(PCI0)#ACPI(XHC_)#ACPI(RHUB)#ACPI(HS05)#USB(2)
  24. Container ID             : {73a183c8-3781-5e8a-93bc-38be9dd6928c}
  25. Manufacturer Info        : WinUSB 设备
  26. Capabilities             : 0x14 (Removable, UniqueID)
  27. Status                   : 0x01806400 (DN_HAS_PROBLEM, DN_DISABLEABLE, DN_REMOVABLE, DN_NT_ENUMERATOR, DN_NT_DRIVER)
  28. Problem Code             : 10 (CM_PROB_FAILED_START)
  29. Power State              : D3 (supported: D0, D2, D3, wake from D0, wake from D2)

  30.         +++++++++++++++++ Registry USB Flags +++++++++++++++++
  31. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UsbFlags\07E907E90200
  32. osvc                    : REG_BINARY 01 A0
  33. SkipContainerIdQuery    : REG_BINARY 01 00

  34.         ---------------- Connection Information ---------------
  35. Connection Index         : 0x02 (2)
  36. Connection Status        : 0x01 (DeviceConnected)
  37. Current Config Value     : 0x00
  38. Device Address           : 0x3E (62)
  39. Is Hub                   : 0x00 (no)
  40. Number Of Open Pipes     : 0x00 (0)
  41. Device Bus Speed         : 0x01 (Full-Speed)
  42. Data (HexDump)           : 02 00 00 00 12 01 00 02 00 00 00 40 E9 07 E9 07   ...........@....
  43.                            00 02 01 02 03 01 00 01 00 3E 00 00 00 00 00 01   .........>......
  44.                            00 00 00                                          ...

  45.         --------------- Connection Information V2 -------------
  46. Connection Index         : 0x02 (2)
  47. Length                   : 0x10 (16 bytes)
  48. SupportedUsbProtocols    : 0x03
  49. Usb110                  : 1 (yes)
  50. Usb200                  : 1 (yes)
  51. Usb300                  : 0 (no)
  52. ReservedMBZ             : 0x00
  53. Flags                    : 0x00
  54. DevIsOpAtSsOrHigher     : 0 (Is not operating at SuperSpeed or higher)
  55. DevIsSsCapOrHigher      : 0 (Is not SuperSpeed capable or higher)
  56. DevIsOpAtSsPlusOrHigher : 0 (Is not operating at SuperSpeedPlus or higher)
  57. DevIsSsPlusCapOrHigher  : 0 (Is not SuperSpeedPlus capable or higher)
  58. ReservedMBZ             : 0x00
  59. Data (HexDump)           : 02 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00   ................

  60.     ---------------------- Device Descriptor ----------------------
  61. bLength                  : 0x12 (18 bytes)
  62. bDescriptorType          : 0x01 (Device Descriptor)
  63. bcdUSB                   : 0x200 (USB Version 2.00)
  64. bDeviceClass             : 0x00 (defined by the interface descriptors)
  65. bDeviceSubClass          : 0x00
  66. bDeviceProtocol          : 0x00
  67. bMaxPacketSize0          : 0x40 (64 bytes)
  68. idVendor                 : 0x07E9
  69. idProduct                : 0x07E9
  70. bcdDevice                : 0x0200
  71. iManufacturer            : 0x01 (String Descriptor 1)
  72. iProduct                 : 0x02 (String Descriptor 2)
  73. iSerialNumber            : 0x03 (String Descriptor 3)
  74. bNumConfigurations       : 0x01 (1 Configuration)
  75. Data (HexDump)           : 12 01 00 02 00 00 00 40 E9 07 E9 07 00 02 01 02   .......@........
  76.                            03 01                                             ..

  77.     ------------------ Configuration Descriptor -------------------
  78. bLength                  : 0x09 (9 bytes)
  79. bDescriptorType          : 0x02 (Configuration Descriptor)
  80. wTotalLength             : 0x0020 (32 bytes)
  81. bNumInterfaces           : 0x01 (1 Interface)
  82. bConfigurationValue      : 0x01 (Configuration 1)
  83. iConfiguration           : 0x00 (No String Descriptor)
  84. bmAttributes             : 0xC0
  85. D7: Reserved, set 1     : 0x01
  86. D6: Self Powered        : 0x01 (yes)
  87. D5: Remote Wakeup       : 0x00 (no)
  88. D4..0: Reserved, set 0  : 0x00
  89. MaxPower                 : 0x32 (100 mA)
  90. Data (HexDump)           : 09 02 20 00 01 01 00 C0 32 09 04 00 00 02 FF 00   .. .....2.......
  91.                            00 00 07 05 01 02 40 00 00 07 05 81 02 40 00 00   ......@......@..

  92.         ---------------- Interface Descriptor -----------------
  93. bLength                  : 0x09 (9 bytes)
  94. bDescriptorType          : 0x04 (Interface Descriptor)
  95. bInterfaceNumber         : 0x00
  96. bAlternateSetting        : 0x00
  97. bNumEndpoints            : 0x02 (2 Endpoints)
  98. bInterfaceClass          : 0xFF (Vendor Specific)
  99. bInterfaceSubClass       : 0x00
  100. bInterfaceProtocol       : 0x00
  101. iInterface               : 0x00 (No String Descriptor)
  102. Data (HexDump)           : 09 04 00 00 02 FF 00 00 00                        .........

  103.         ----------------- Endpoint Descriptor -----------------
  104. bLength                  : 0x07 (7 bytes)
  105. bDescriptorType          : 0x05 (Endpoint Descriptor)
  106. bEndpointAddress         : 0x01 (Direction=OUT EndpointID=1)
  107. bmAttributes             : 0x02 (TransferType=Bulk)
  108. wMaxPacketSize           : 0x0040 (64 bytes)
  109. bInterval                : 0x00 (ignored)
  110. Data (HexDump)           : 07 05 01 02 40 00 00                              ....@..

  111.         ----------------- Endpoint Descriptor -----------------
  112. bLength                  : 0x07 (7 bytes)
  113. bDescriptorType          : 0x05 (Endpoint Descriptor)
  114. bEndpointAddress         : 0x81 (Direction=IN EndpointID=1)
  115. bmAttributes             : 0x02 (TransferType=Bulk)
  116. wMaxPacketSize           : 0x0040 (64 bytes)
  117. bInterval                : 0x00 (ignored)
  118. Data (HexDump)           : 07 05 81 02 40 00 00                              ....@..

  119.     ----------------- Device Qualifier Descriptor -----------------
  120. Error                    : ERROR_GEN_FAILURE

  121.       -------------------- String Descriptors -------------------
  122. String descriptors are not available  (because the device has problem code CM_PROB_FAILED_START)
重新安装驱动设备工作正常。
三、解决方法
对于第一个问题,暂且希望官方能做一个修改。下面重点讲解一下解决的方法。
首先对比一下STM32与HC32F460关于USB的Setup阶段的处理方法:
STM32:
  1. USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
  2. {
  3.   USBD_StatusTypeDef ret;

  4.   USBD_ParseSetupRequest(&pdev->request, psetup);

  5.   pdev->ep0_state = USBD_EP0_SETUP;

  6.   pdev->ep0_data_len = pdev->request.wLength;

  7.   switch (pdev->request.bmRequest & 0x1FU)
  8.   {
  9.     case USB_REQ_RECIPIENT_DEVICE:
  10.       ret = USBD_StdDevReq(pdev, &pdev->request);
  11.       break;

  12.     case USB_REQ_RECIPIENT_INTERFACE:
  13.       ret = USBD_StdItfReq(pdev, &pdev->request);
  14.       break;

  15.     case USB_REQ_RECIPIENT_ENDPOINT:
  16.       ret = USBD_StdEPReq(pdev, &pdev->request);
  17.       break;

  18.     default:
  19.       ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
  20.       break;
  21.   }

  22.   return ret;
  23. }
  1. USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  2. {
  3.   USBD_StatusTypeDef ret = USBD_OK;

  4.   switch (req->bmRequest & USB_REQ_TYPE_MASK)
  5.   {
  6.     case USB_REQ_TYPE_CLASS:
  7.     case USB_REQ_TYPE_VENDOR:
  8.       ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
  9.       break;

  10.     case USB_REQ_TYPE_STANDARD:
  11.       switch (req->bRequest)
  12.       {
  13.         case USB_REQ_GET_DESCRIPTOR:
  14.           USBD_GetDescriptor(pdev, req);
  15.           break;

  16.         case USB_REQ_SET_ADDRESS:
  17.           USBD_SetAddress(pdev, req);
  18.           break;

  19.         case USB_REQ_SET_CONFIGURATION:
  20.           ret = USBD_SetConfig(pdev, req);
  21.           break;

  22.         case USB_REQ_GET_CONFIGURATION:
  23.           USBD_GetConfig(pdev, req);
  24.           break;

  25.         case USB_REQ_GET_STATUS:
  26.           USBD_GetStatus(pdev, req);
  27.           break;

  28.         case USB_REQ_SET_FEATURE:
  29.           USBD_SetFeature(pdev, req);
  30.           break;

  31.         case USB_REQ_CLEAR_FEATURE:
  32.           USBD_ClrFeature(pdev, req);
  33.           break;

  34.         default:
  35.           USBD_CtlError(pdev, req);
  36.           break;
  37.       }
  38.       break;

  39.     default:
  40.       USBD_CtlError(pdev, req);
  41.       break;
  42.   }

  43.   return ret;
  44. }

HC32F460:
  1. void hd_usb_setup_process(usb_core_instance *pdev)
  2. {
  3.     USB_SETUP_REQ req;

  4.     hd_usb_parsesetupreq(pdev , &req);

  5.     switch (req.bmRequest & 0x1Fu)
  6.     {
  7.         case USB_REQ_RECIPIENT_DEVICE:
  8.             hd_usb_standarddevreq (pdev, &req);
  9.             break;

  10.         case USB_REQ_RECIPIENT_INTERFACE:
  11.             hd_usb_standarditfreq(pdev, &req);
  12.             break;

  13.         case USB_REQ_RECIPIENT_ENDPOINT:
  14.             hd_usb_standardepreq(pdev, &req);
  15.             break;

  16.         default:
  17.             hd_usb_stalldevep(pdev, req.bmRequest & 0x80u);
  18.             break;
  19.     }
  20. }
  1. void hd_usb_standarddevreq(usb_core_instance *pdev, USB_SETUP_REQ *req)
  2. {
  3.     if(req->bRequest == USB_REQ_GET_DESCRIPTOR)
  4.     {
  5.         hd_usb_getdesc (pdev, req) ;
  6.     }
  7.     else if(req->bRequest == USB_REQ_SET_ADDRESS)
  8.     {
  9.         hd_usb_setaddr(pdev, req);
  10.     }
  11.     else if(req->bRequest == USB_REQ_SET_CONFIGURATION)
  12.     {
  13.         hd_usb_setconfig (pdev , req);
  14.     }
  15.     else if(req->bRequest == USB_REQ_GET_CONFIGURATION)
  16.     {
  17.         hd_usb_getconfig (pdev , req);
  18.     }
  19.     else if(req->bRequest == USB_REQ_GET_STATUS)
  20.     {
  21.         hd_usb_getstatus (pdev , req);
  22.     }
  23.     else if(req->bRequest == USB_REQ_SET_FEATURE)
  24.     {
  25.         hd_usb_setfeature (pdev , req);
  26.     }
  27.     else if(req->bRequest == USB_REQ_CLEAR_FEATURE)
  28.     {
  29.         hd_usb_clrfeature (pdev , req);
  30.     }
  31.     else
  32.     {
  33.         if (pdev->dev.class_callback->ep0_setup (pdev, req))
  34.         {
  35.             hd_usb_ctrlerr(pdev);
  36.         }
  37.     }
  38. }
可以看出STM32在USBD_StdDevReq中遍历常见情况后会直接抛出USBD_CtlError(pdev, req);,而HC32F460则是判断pdev->dev.class_callback->ep0_setup (pdev, req)才抛出hd_usb_ctrlerr(pdev)。就是这个差异导致掉驱动。实际调试可以定位到这个问题:
23.PNG
修改void hd_usb_setup_process(usb_core_instance *pdev)中的hd_usb_standarddevreq (pdev, &req)和hd_usb_standarditfreq(pdev, &req):
24.PNG
25.PNG
26.PNG
27.PNG
从新安装驱动之后,不再掉驱动了:
28.PNG
设备工作正常。
WINUSB代码:
HC32F460_WINUSB.zip (1.06 MB, 下载次数: 86)
CDC代码:
HC32F460_CDC.zip (1.06 MB, 下载次数: 75)
INF文件:
Driver Package1.zip (11.77 KB, 下载次数: 64)
上位机测速软件:
WINUSB.zip (9.79 MB, 下载次数: 95)









精灵魔仙 发表于 2021-10-3 14:43 | 显示全部楼层
看了下好像是OS 1.0的,何不同时移植BOS Descriptor OS 2.0的版本?
duo点 发表于 2021-10-4 14:34 来自手机 | 显示全部楼层
讲解超详细的
 楼主| 纪国圣 发表于 2021-10-30 09:29 | 显示全部楼层
上传一份Microsoft_OS_2.0_Descriptors版本:
1.PNG
2.PNG
3.PNG
Microsoft_OS_2.0_Descriptors_Specification.pdf (593.95 KB, 下载次数: 69)
HC32F460_WINUSB MS_OS_20.zip (6.66 MB, 下载次数: 88)
kiwis66 发表于 2021-11-1 10:07 | 显示全部楼层
学习了,比较详细,
感谢
vip3 发表于 2023-12-6 14:21 | 显示全部楼层
实现不了,安装驱动失败
h32446975 发表于 2024-1-24 10:25 | 显示全部楼层
楼主描述的很详细,非常好的分享。
biscuit2 发表于 2024-2-28 09:25 | 显示全部楼层
楼主你好,我下载你的 《【华大测评】+ HC32F460 WINUSB移植、遇到的问题与解决方法》里面的WINUSB源码到HC32F460PETB芯片里,电脑USB显示HDSC WINUSB有感叹号,请教一下原因,万分感谢。
biscuit2 发表于 2024-3-13 09:09 | 显示全部楼层
例程里有一处BUG,修改后解决问题。
小夏天的大西瓜 发表于 2024-3-27 08:30 | 显示全部楼层
讲解的很详细,按照这个过程能够正常配置
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

407

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部