基本上来说,STM32 在CubeMX生成的不同class的设备,都是支持windows免驱的,唯独在DFU模式的情况下,需要手动安装st的驱动才能实现功能,那么有什么办法能够在DFU模式下免驱呢,答案就是WinUSB。
废话不多说,我们用最简单明了的方式来实现此功能,上代码!
目前我们选用的都是Microsoft OS 2.0 描述符规范,因为1.0的描述符规范已经逐渐被微软抛弃了,在这里都没有什么存在的意义,1.0是通过请求0xEE的描述符来进行识别,到2.0是通过BOS的请求来获取完整的内容。
通过CubeMX生成基础程序
我这边选择的芯片是STM32F103,当然,其他有USB功能的STM芯片都是适用于这个功能的,我想既然打算开发WinUSB,这部分的内容读者都应该轻车熟路,所以我在这里省略,直接进入正题
修改代码
1.修改设备描述符
一般来说F4的设备需要使能USBD_LPM_ENABLED这个功能,最重要的一点,需要把bcdUSB的版本改为0x0210,这样windows才会试图请求BOS描述符,如下所示:
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
0x10, /*bcdUSB */ 修改此值
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/
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*/
};
2.修改二进制描述符
将程序自动生成的二进制描述符改为如下所示,其中USB_REQ_GET_OS_FEATURE_DESCRIPTOR为请求的VendorCode,我们在下面会有提及
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[33] __ALIGN_END =
{
///
/// WCID20 BOS descriptor
///
0x05, /* bLength */
USB_DESC_TYPE_BOS, /* bDescriptorType */
0x21, 0x00, /* wTotalLength */
0x01, /* bNumDeviceCaps */
///
/// WCID20 device capability descriptor
///
0x1c, /* bLength */
0x10, /* bDescriptorType */
0x05, /* bDevCapabilityType */
0x00, /* bReserved */
0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c, /* bPlatformCapabilityUUID_16 */
0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, 0x9f, /* bPlatformCapabilityUUID_16 */
0x00, 0x00, 0x03, 0x06, /* dwWindowsVersion */
LOBYTE(WINUSB20_WCID_DESC_SET_SIZE), HIBYTE(WINUSB20_WCID_DESC_SET_SIZE),/* wDescriptorSetT