1 概述

1.1 WCID 简介

WCID全称为“WINDOWS Compatible ID”,是一种可提供额外的信息,在Windows系统中,为了便于驱动程序自动安装,并在某些情况下,允许即时访问的USB设备。

WCID允许Windows应用程序几乎在插入后立即使用设备,这既不是HID也不是大容量存储的USB设备需要最终用户执行手动驱动程序安装。因此,WCID可以做到像HID和大容量存储USB设备那样“即插即用”。WCID是WinUSB设备功能的扩展,由Microsoft在Windows8开发人员预览版期间提出,WinUSB自Windows XP SP2以来一直是Windows一部分的功能。

WinUSB设备是一种通用串行总线(USB)设备,其固件定义了某些Microsoft操作系统(OS)特征描述符,这些描述符将兼容ID报告为"WINUSB"。WinUSB设备的用途是让Windows将Winusb.sys作为设备的功能驱动程序载入,而无需自定义INF文件。对于WinUSB设备,你无须为设备分发INF文件,这大大简化了驱动程序安装过程。截至2012年5月,从Windows Vista开始的所有平台上都提供了自动 WinUSB WCID 驱动程序。在 Windows 8 或更高版本地系统上已经集成了该驱动程序,这意味着Windows 8 或更高版本地系统上不需要安装驱动程序,系统自动会匹配WinUSB驱动,而对于Vista、Windows7、XP系统,可以通过一些第三方软件(如Zadig)来安装或生成WCID版本的驱动程序,同样只需要安装一次WCID版本的驱动软件,以后所有WCID设备都可以使用该驱动,间接实现了免驱。

在WCID之前,只有标准类别的USB设备,如HID(USB键盘、鼠标、游戏杆等)或大容量存储(U盘、基于闪存的存储、媒体播放器等)不需要安装驱动程序,因为Windows会在设备第一次插入时自动处理。而其他设备通常需要自己手动提供和安装驱动程序,在WIN8以后厂家自己提供的驱动程序还可能受到微软的驱动程序签名限制,造成不必要的麻烦。

原文参考:https://github.com/pbatard/libwdi/wiki/WCID-Devices

1.2 WinUSB限制条件

WinUSB有许多限制条件,一般来说注意以下几点即可:

1) WinUSB不支持Windows 2003 ( 32bit/64bit );

2)WinUSB不支持Windows XP 64位(可以通过第三方驱动支持);

3) USB设备版本必需是2.0或2.0以上,WinUSB不支持USB1.0和1.1。

原文参考:https://www.cnblogs.com/shangdawei/archive/2013/04/17/3026394.html

2 WinUSB设备枚举关键信息

设备枚举为WinUSB的三个关键信息:

1)OS字符串描述符;

2)扩展兼容ID OS功能描述符;

3)扩展属性OS功能描述符;

2.1 支持OS字符串描述

当有USB设备插入,系统会向设备索取设备描述符,根据设备描述符中的bcdUSB版本号判断是否检索0xEE位置的OS设备字串描述符,如果bcdUSB版本号大于等于2.0,则系统会检索0xEE位置的OS设备字串描述符,支持WinUSB的OS描述如下:

如果0xEE处的OS描述符不存在或者描述格式不正确,系统将设置osvc值为0x0000,表示该USB设备不是WCID设备。如果OS描述正确,系统将osvc设置为0x01##。

2.2 设置兼容ID特征描述符

在获取到osvc为有效值的前提下,系统将进一步获取兼容ID特征描述符,索引号为0x04,兼容ID特征描述符包含紧跟一个或多个功能部分的标题部分,具体取决于是否是复合设备。标题部分指定整个描述符的长度、功能部分的数量以及版本号。对于非复合设备,标题后紧跟一个仅与设备的接口关联的功能部分。该部分的compatibleID字段必须指定"WINUSB"作为字段值。复合设备有多个功能部分。每个功能部分的compatibleID字段必须指定"WINUSB"。兼容ID特征描述符格式如下:

2.3 扩展属性描述符

最后是添加扩展属性描述符,注册设备接口GUID,包含紧跟一个或多个自定义属性部分的标题部分,索引号为0x05。标题部分描述整个扩展属性描述符,包含其总长度、版本号以及自定义属性部分的数量。WinUSB应用程序正是通过GUID来检索对应的USB设备,并进行访问,详细定义如下表所示:

3 USB枚举过程

通过Keil调试可以获取到USB枚举的全部信息,如下图所示。枚举过程中共有40条交互信息:

在Excel中统计如表格所示,第一列表示方向:1为Windows往设备发,0为设备回复信息。

  1. 当Windows检测到有USB设备插入,首先会向设备索取设备描述符长度,设备正确回复后Windows分配USB设备地址,并以之前收到的实际长度去获取完整的设备描述符;
  2. 获取USB设备信息,包含基本配置、设备接口、端点等信息;
  3. Windows判断第一步获取的bcdUSB版本号如果大于等2.0,则还会索引0xEE处的OS字符串描述符,确认设备是否支持WCID,若回复内容为MSFT100则说明该设备支持WCID,后续才会继续获取兼容ID特征描述等;
  4. 获取兼容ID特征描述符,回复兼容信息为WinUSB设备;
  5. 获取兼容ID后,系统会根据兼容ID的情况请求属性描述符,对于WinUSB设备需要注册设备接口GUID;
  6. 后续其他信息获取…

4 实例应用

4.1 生成USB 工程

本实例采用STM32F405RGT6 + USBS3300 实现USB HS 高速WinUSB设备,使用STM32CubeMX生成基础工程,CubeMX版本号为6.3,STM32F4 package版本为1.26.2,电脑系统为WIN10。

备注:USB FS同样按如下使用方法,需要注意的是USB FS只能用外部时钟,且配置时需要注意外部时钟频率!!

//---------------------我是广告-----------------------

详细配置及参考工程请移步淘宝店:https://item.taobao.com/item.htm?spm=a230r.1.14.11.18cc4864SdV6xL&id=660992604144&ns=1&abbucket=20#detail

//---------------------我是广告-----------------------

1)打开CubeMX选择MCU型号STM32F405RGT6:

2)按如下顺序在Connectivity中选中USB_TG_HS,然后设置External Phy为Device_Only,并且将NVIC的三个中断都勾选上:

3)按如下步骤在Middleware选项中选择USB_DEVICE,右侧HS IP选择Communication Device Class(Virtual Port Com),然后在Device Descriptor中设置相关属性:此处VID PID分别设置为0x1234、0xABCD(可自行更改,点击输框右侧小齿轮将格式改为16进制显示);设置PRODUCT_STRING,些处以GUOXUAN为例(可自行更改),这个字符串就是最终显示在设备管理器中的名字;设置CONFIGURATION_STRING 和 INTERFACE_STRING,固定为WINUSB_Config 和 WINUSB Interface。

4)点击下一页Clock Configuration 直接点确定会自动配置好时钟:

5)点击下一页配置工程信息,适当将堆栈容量改大,避免一些意外问题,设置好后点击右上角生成工程:

6)生成好后直接编译工程,可以编译成功:

将程序烧入单片机后连接电脑,该USB设备被识别成了串口,并且没有显示出产品字符串,因为设备描述符没有修改,设备被枚举成了CDC串行通信类:

4.2 修改工程文件

(1) 增加兼容ID描述符和扩展属性描述符定义,其中扩展描述符中的GUID定义可根据实际需求更改,本文以{12345678-ABCD-1234-ABCD-FEDCBA987654}为例:

//-----------ADD GUOXUAN----------------#define USB_LEN_OS_FEATURE_DESC 0x28__ALIGN_BEGIN uint8_t USBD_WINUSB_OSFeatureDesc[USB_LEN_OS_FEATURE_DESC] __ALIGN_END ={0x28, 0, 0, 0, // length0, 1,          // bcd version 1.04, 0,          // windex: extended compat ID descritor1,             // no of function0, 0, 0, 0, 0, 0, 0, // reserve 7 bytes// function0,             // interface no0,             // reserved'W', 'I', 'N', 'U', 'S', 'B', 0, 0, //  first ID0,   0,   0,   0,   0,   0, 0, 0,  // second ID0,   0,   0,   0,   0,   0 // reserved 6 bytes     };#define USB_LEN_OS_PROPERTY_DESC 0x8E__ALIGN_BEGIN uint8_t USBD_WINUSB_OSPropertyDesc[USB_LEN_OS_PROPERTY_DESC] __ALIGN_END ={0x8E, 0, 0, 0,  // length 246 byte0x00, 0x01,   // BCD version 1.00x05, 0x00,   // Extended Property Descriptor Index(5)0x01, 0x00,   // number of section (1)//; property section       0x84, 0x00, 0x00, 0x00,   // size of property section0x1, 0, 0, 0,   //; property data type (1)0x28, 0,        //; property name length (42)'D', 0,'e', 0,'v', 0,'i', 0,'c', 0,'e', 0,'I', 0,'n', 0,'t', 0,'e', 0,'r', 0,'f', 0,'a', 0,'c', 0,'e', 0,'G', 0,'U', 0,'I', 0,'D', 0,0, 0,// change by yourself0x4E, 0, 0, 0,  // ; property data length'{', 0,'1', 0,'2', 0,'3', 0,'4', 0,'5', 0,'6', 0,'7', 0,'8', 0,'-', 0,'A', 0,'B', 0,'C', 0,'D', 0,'-', 0,'1', 0,'2', 0,'3', 0,'4', 0,'-', 0,'A', 0,'B', 0,'C', 0,'D', 0,'-', 0,'F', 0,'E', 0,'D', 0,'C', 0,'B', 0,'A', 0,'9', 0,'8', 0,'7', 0,'6', 0,'5', 0,'4', 0,'}', 0,0, 0,};//------------------------------

(2)增加OS字符串描述,固定为“MSFT100”,VENDOR_CODE可自行更改;增加这三个描述的接口指针函数:

//-----------ADD GUOXUAN----------------const uint8_t USBD_OS_STRING[8] = {'M','S','F','T','1','0','0',0xA0, //USB_REQ_MS_VENDOR_CODE,};uint8_t *USBD_WinUSBOSStrDescriptor(uint16_t *length){USBD_GetString((uint8_t *)USBD_OS_STRING, USBD_StrDesc, length);return USBD_StrDesc;}uint8_t *USBD_WinUSBOSFeatureDescriptor(uint16_t *length){*length = USB_LEN_OS_FEATURE_DESC;return USBD_WINUSB_OSFeatureDesc;}uint8_t *USBD_WinUSBOSPropertyDescriptor(uint16_t *length){*length = USB_LEN_OS_PROPERTY_DESC;return USBD_WINUSB_OSPropertyDesc;}//------------------------------------

(3) 响应设备描述请求中的的的的USB_REQ_TYPE_VENDOR请求:

 case USB_REQ_TYPE_VENDOR:USBD_WinUSBGetDescriptor( pdev, req ); //-----CHANGE GUOXUAN-------break;

(4) 响应接口请求USBD_StdItfReq中的case USBD_STATE_CONFIGURED:

if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES){ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);if ((req->wLength == 0U) && (ret == USBD_OK)){(void)USBD_CtlSendStatus(pdev);}}//-----------------ADD GUOXUAN-------------if ( req->bmRequest == 0xC1 ){USBD_WinUSBGetDescriptor( pdev, req );break;}//----------------------------------------else{USBD_CtlError(pdev, req);}break;

(5) 响应0xEE请求:

//---------------ADD GUOXUAN----------case 0xEE: // OS Stringpbuf = (uint8_t *) pdev->pClass->GetWinUSBOSDescriptor(&len);break;//------------------------------------

(6) 修改CDC配置描述信息:

//---------------CHANGE GUOXUAN---------------/* USB CDC device Configuration Descriptor */#define WINUSB_CONFIG_DESC_SIZE 32__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[WINUSB_CONFIG_DESC_SIZE] __ALIGN_END ={/*Configuration Descriptor*/0x09,   /* bLength: Configuration Descriptor size */USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */WINUSB_CONFIG_DESC_SIZE,                /* wTotalLength:no of returned bytes */0x00,0x01,   /* bNumInterfaces: 1 interface for WINUSB */0x01,   /* bConfigurationValue: Configuration value */USBD_IDX_CONFIG_STR,   /* iConfiguration: Index of string descriptor describing the configuration */0xC0,   /* bmAttributes: self powered */0x32,   /* MaxPower 0 mA *//*---------------------------------------------------------------------------*//*Data class interface descriptor*/0x09,   /* bLength: Endpoint Descriptor size */USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */0x00,   /* bInterfaceNumber: Number of Interface, zero based index of this interface */0x00,   /* bAlternateSetting: Alternate setting */0x02,   /* bNumEndpoints: Two endpoints used */0xff,   /* bInterfaceClass: vendor */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 */};/* USB CDC device Configuration Descriptor */__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[WINUSB_CONFIG_DESC_SIZE] __ALIGN_END ={/*Configuration Descriptor*/0x09,   /* bLength: Configuration Descriptor size */USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */WINUSB_CONFIG_DESC_SIZE,                /* wTotalLength:no of returned bytes */0x00,0x01,   /* bNumInterfaces: 1 interface for Game IO */0x01,   /* bConfigurationValue: Configuration value */USBD_IDX_CONFIG_STR,   /* iConfiguration: Index of string descriptor describing the configuration */0xC0,   /* bmAttributes: self powered */0x32,   /* MaxPower 0 mA *//*---------------------------------------------------------------------------*//*Data class interface descriptor*/0x09,   /* bLength: Endpoint Descriptor size */USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */0x00,   /* bInterfaceNumber: Number of Interface, zero based index of this interface */0x00,   /* bAlternateSetting: Alternate setting */0x02,   /* bNumEndpoints: Two endpoints used */0xff,   /* bInterfaceClass: vendor */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_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */HIBYTE(CDC_DATA_FS_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_FS_MAX_PACKET_SIZE),        /* wMaxPacketSize: */HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),0x00                                        /* bInterval: ignore for Bulk transfer */};//------------------------------------------

//---------------------我是广告-----------------------

详细配置及参考工程请移步淘宝店:https://item.taobao.com/item.htm?spm=a230r.1.14.11.18cc4864SdV6xL&id=660992604144&ns=1&abbucket=20#detail

//---------------------我是广告-----------------------

编译下载及问题处理

修改完上述4个文件后,编译工程并下载,下载完后设备最好断一次电,重新插入USB后,在设备管理器中可以看到已经成功枚举出了设备名为GUOXUAN的通用串行总线设备:

但凡事都有意外,当下载好后重新插入USB也可能出现以下情况(不限于以下这两种!!),只要设备名上有叹号,说明明枚举不成功,此时除了检查代码有无错误以外还可以尝试删除注册表中已有的VID PID信息,因为CubeMX生成好工程时测试连接过一次,枚举为了串口,注测表中已记录这个设备的信息,但现在设备描述符又指定为了WinUSB设备,所以造成了枚举失败。

删除注册表中USB设备信息的方法:

1、下载PStools工具包 https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx,解压到C:\pstools

2、以管理员身份运行CMD,输入命令:cd C:\pstools ,切换到pstools目录,再输入命令:psexec.exe -i -d -s regedit.exe

3、进入HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\删除相关设备(以本文为例,VID PID分别为 1234 ABCD)

进入HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UsbFlags\删除相关设备(以本文为例,VID PID分别为 1234 ABCD)

4、OK,此时再插入该Device,即被当做全新设备插入,装载驱动。

原文参考:

https://www.codenong.com/41644081/

https://blog.csdn.net/lxc1014/article/details/45170107?utm_source=app&app_version=4.17.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

4.3 与上位机通信

在本测试中上位机发送一个数据包到USB设备,数据包的前两个字节设置为数据长度,设备接收到该数据包后根据数据长度返回一包数据。

4.3.1 修改数据接收和发送函数

修改usbd_cdc_if.c文件中数据接收函数,首先添加定义:

//-----------------ADD GUOXUAN-----------------------extern volatile int8_t usb_rxne;extern uint8_t usb_rx[2048];//---------------------------------------------------

然后修改数据接收处理:

//-------------ADD GUOXUAN--------------------memcpy(usb_rx, Buf, *Len);usb_rxne = SET;//--------------------------------------------

在main.c中添加数据发送函数:

首先引用头文件:

//---------------ADD GUOXUAN--------------------------#include "usbd_cdc_if.h"//----------------------------------------------------

添加定义:

//--------------ADD GUOXUAN-----------------------uint8_t usb_rx[2048];uint8_t usb_tx[81920];volatile int8_t usb_rxne = RESET;extern USBD_HandleTypeDef hUsbDeviceHS;//-----------------------------------------------

添加接收函数:

//------------ADD GUOXUAN-------------------void WinUSB_Receive_HS(){uint16_t i = 0;if (usb_rxne != SET) return;i = usb_rx[0] + (usb_rx[1]<<8);CDC_Transmit_HS(usb_tx, i);usb_rxne = RESET;}//------------------------------------------

最后在main里面的while(1)里调用:

while (1){/* USER CODE END WHILE */WinUSB_Receive_HS();/* USER CODE BEGIN 3 */}

4.3.2 与上位机通信测试

上位机采用C#编写,使用开源库WinUSBNet(XP使用LibUsbDotNet)进行访问,上位机发送一个包,设备回复一个包;上行和下行的包大小自由设置(本测试主要测上行速率,下发的包大小置固定为64,若下发包大小超过512,设备USB接收函数需要做相应处理,因为单次传输最大包长为512,大于512将会被分包接收);上行包的大小可改变,以测试不同包长时的速率;点击一次send发送1000个包,并统计速率(本次测试没有对接收和发送的数据作任何处理,实际应用情况下,加上数据处理后通信速率稍低于测试值)。WIN8、WIN7、XP均是在虚拟机运行测试的,通信速率可能会受到一些影响。

WIN10上测试结果如下:

WIN8上测试结果如下:

WIN7和XP上默认不带WinUSB驱动,设备插到电脑后,设备管理器可以看到设备枚举失败,但用zadig软件可以识别到该设备为WICD设备,可以安装WinUSB驱动程序,省去了手动写inf文件,也可以用zadig软件将驱动程序导出,通过右键更新驱动程序的方式安装。

WIN7上测试结果如下:

XP上测试结果如下(XP使用LibUsbDotNet,默认情况下接收buffer只能到4095):

5 常见问题

1)没有USB测试仪无法抓包分析

用Keil进行抓包,全新的USB枚举过程数据通信大概有40条左右,最大长度不超过150字节,所以定义一个数组usbLog[50][200],在USB设备请求通信入口 USBD_StdDevReq()函数处记录上位机下发的信息,在USB设备回复数据USBD_CtlSendData()函数处记录回复给上位机的信息,即可抓取到全部通信内容。第3章节USB枚举过程中信息正是用此方法获取的。

2)抓包分析抓不到0xEE命令

调试过程中,可能第一次并未完全修改正确,插入电脑后枚举失败,但是电脑已经记录下了该设备PID VID,当下次枚举的时候,该PID VID已经存在并且记录了该设备不是WinUSB设备,所示不会发送0xEE命令,解决办法是更换PID VID 或者4.2.5所述的方法删除注册表中相应的PID VID即可。

3)完全按上述流程修改后还是无法枚举成功

同第2条。

4)下载正确程序后不枚举或枚举失败

因为USB HS使用的是外部PHY,重新烧写单片机程序可能不会让USB重新枚举,通常断电一次即可枚举成功。

5)传输过程中有丢包现象

检查包长设置是否合理,缓冲区buffer是否足够。

STM32 WinUSB(WCID)免驱高速通信 20M/s(附详细测试)相关推荐

  1. ROS下UVC免驱高速摄像头图像读取以及利用image_transport进行图像传递

    网上可以买到很多高速摄像头模块,常见的就是这个ov2710模组,采用uvc免驱,号称在1080p 30fps,720p 60fps以及VGA 120fps. 值得是注意的是,这些高速模式都是在MJPG ...

  2. WinUsb实现USB免驱通讯技术总结

    随着电脑更新换代.USB接口逐渐替代传统接口(串口等),为了更加方便与PC机进行通讯,引入USB通讯. 如何才能实现产品与PC又快又稳定通讯 如何解决串口通讯中接受不定时帧间隔问题 如何实现即插即用的 ...

  3. WinUsb实现USB免驱通讯介绍

    背景 以往项目使用串口通讯,通过空闲超时区分不同数据帧,但Window系统响应非实时,超时间隔不确定导致无法判断是否是完整的一帧数据,同时串口通讯还需要安装对应的驱动包,英文系统.繁体系统等可能安装失 ...

  4. ROS下获取USB免驱动高速摄像头图像数据

    开发环境 使用uvc_camera package 1. 安装uvc_camera package 2. 测试和查看安装结果 3. 配置自己的.launch文件 深入研究库文件 开发环境 PC系统 u ...

  5. 可以真正实现免驱的WinUSB设备

    可以真正实现免驱的WinUSB设备 为什么要使用WinUSB设备? USB设备的枚举过程 如何让一个USB设备被识别为WinUSB设备? WinUSB设备枚举成功后如何挂载驱动 如何确定WinUSB设 ...

  6. Realtek 2.5G PCIE网卡 RTL8125B-CG支持PXE免驱简介

    RTL8125B-CG/RTL8125BS-CG热点为:PXE免驱,适用于多个细分市场和新兴应用,如桌面.移动.工作站.服务器.通信平台和嵌入式应用程序. PCI Express是一种高带宽.低针数. ...

  7. usb hid 调试软件_开源USB免驱固件升级软件分享

    跳兔科技开源软件分享,免驱的USB固件升级软件,给您的产品提供无限的活力.加快产品上市速度. 相信做MCU开发的人都免不了要做boot升级功能,产品投入使用中,如果再使用link进行固件更新的话就比较 ...

  8. 如何使用 WinUSB 与 USB 设备 (USBDevice) 通信

    选择 USB 设备的驱动程序模型 https://github.com/libusbx/libusbx/wiki/Windows-Backend WinUSB does not support Win ...

  9. 在人脸识别、机器视觉中USB免驱摄像头拍照颜色不对怎么办?大影30~1600万像素多种摄像头方案通过一次白平衡解决偏色问题。

    应用参考: ■工业自动化控制设备:自动生产线上的产品缺陷检测/产品质检/分捡/计数/控制零件装配;电路板焊接检测/自动贴片机高速取料对位/3D立体成像 ■政企工程人脸及静脉指纹识别设备:ATM机/社保 ...

最新文章

  1. sed替换每行最后一个字符
  2. Problem A: 平面上的点——Point类 (I)
  3. MATLAB控制运算精度
  4. springboot集成shiro无法加载样式status302
  5. Java生成CSV文件
  6. LeetCode 206. 反转链表
  7. [渝粤教育] 盐城工学院 无机及分析化学C 参考 资料
  8. pcl从一个点云里面导出下标
  9. 解决visual studio换行(回车键)不能代码补全问题
  10. 开源数据库:何为NoSQL生态系统?
  11. 玩转华为数据中心交换机系列 | 配置基于VLAN的MAC地址学习限制示例
  12. javaweb项目遇到错误
  13. c语言 dirent,DIR和dirent结构体
  14. 以Maya为引擎的小游戏:是男Yin就坚持2K帧
  15. 计算机网络OSI模型的各层及主要功能
  16. 什么样的岗位会最先被人工智能 (AI) 取代?
  17. python实现pdf文件合并,多个pdf文件合并,pdf文件叠加
  18. php每日任务,炉石传说新版本增加35个日常任务 每日任务奖励汇总
  19. pl0语言的扩充之repeat-until语句
  20. pytorch做seq2seq注意力模型的翻译

热门文章

  1. MySQL数据库——锁机制
  2. 【软件工程】敏捷宣言
  3. 雷神黑武士5代shark评测
  4. 如何让微信号开通检测软件替你顶起一片天?
  5. 大恒相机开发实践(2)——触发采图
  6. 2022年下半年软件设计师考试上午真题(专业解析+参考答案)
  7. 实现一个直播视频app源码的邀请码功能
  8. 移植python到小米路由器记录。
  9. 威纶通触摸屏232脚位_威纶通各系列触摸屏引脚排列.pdf
  10. win10照片查看器_win10系统,图片查看器不见了咋办?教你调出传统图片查看器。...