这是我上一个问题的后续行动,Need to write driver for USB peripheral device?
背景
我正在使用STM32微控制器(裸机/无操作系统)设计USB外设 . 该设备偶尔会连接到Windows PC,并在每个方向传输几KB数据 . 将有一个定制的PC应用程序,使用专有协议(即USB有效载荷)控制数据传输 .
PC将永远是主设备(发起者) - 它将发送命令,设备将发出响应,在单个命令或响应中,任意方向上最多可传输几百个字节的数据 . 我想我会想要使用USB批量传输模式 .
选项1 - USB CDC
据我所知,一个选项是我可以使用USB通信设备类(CDC) . 在设备方面,我可以使用ST的示例代码用于USB CDC,例如,来自STM32Cube . 在PC端,设备将显示为虚拟COM端口(VCP) . 然后在软件中我必须定义我的消息格式,命令等 .
- 我是否正确解释了这一点?
选项2 - WinUSB
我无法理解这是什么,以及如何使用它 .
-
WinUSB与USB设备类的关系是什么?它似乎起到了“通用”USB类的作用,但我找不到任何解释它的文档 .
-
WinUSB是否提供任何内置的消息分隔符?例如WinUsb_WritePipe将缓冲区的内容作为原子单位发送到设备吗?或者我只是像VCP / UART那样获得原始流?
-
如何在设备上实现WinUSB?有可用的示例代码吗? (最好是STM32 . )
选择
- 为我的申请选择选项1和2有哪些相关注意事项?
3 回答
是的,您正确描述了USC CDC ACM .
WinUSB用于支持没有特定设备类的设备 . 如果您的设备实现了人机接口设备,大容量存储设备或通信设备(CDC)等设备类,则只需使用操作系统附带的驱动程序与该设备通信即可 . 如果你想要一个更加可定制和灵活的USB接口,不推荐它 . 有些人编写的驱动程序是WinUSB的替代品:您可以查找libusbK,libusb0.sys和UsbDK作为示例 . WinUSB的优势在于它带有Windows,所以我不会使用其他驱动程序,除非它具有您真正需要的特定功能 .
我相信
WinUSB_WritePipe
将数据作为单个USB传输发送 . 传输在USB规范中有特定的定义 . 您可以判断传输何时结束,因为您将在传输结束时收到一个短数据包 . 短数据包是一个小于 endpoints 最大数据包大小的数据包,它可能是零长度 . 你应该仔细检查这是否真的是真的;尝试发送一个最大数据包大小的倍数的传输,并确保Windows在结束时发送一个零长度数据包 . 顺便说一句,您应该考虑将数据作为控制传输或 endpoints 0上的一系列控制传输发送 . 控制传输具有内置的请求概念和对请求的响应 . 尽管名称,控制转移可用于传输大量数据;它们通常用于USB引导加载程序(参见DFU类) . 使用控制传输而不是非零 endpoints 的另一个优点是,您不必添加额外的 endpoints 描述符并初始化固件中的 endpoints . 您的USB堆栈应该具有处理自定义控制传输的机制,您应该只需编写一些回调函数就可以进行自定义控制传输 .要在设备端实现WinUSB,您需要编写自己的USB描述符,然后使用低级USB传输命令从 endpoints 读取和写入数据,或者在 endpoints 0上处理特定于供应商的控制传输 . 我不熟悉STM32 USB库,但您应该能够识别实现控制传输和IN和OUT endpoints 的核心组件,而无需对设备类进行任何特定操作 . 这是您学习如何使用的组件 .
默认情况下,您应该使用WinUSB而不是USB CDC ACM . 使用USB CDC ACM的唯一原因是,如果您的设备实际上是串行端口,或者您希望人们更容易在各种编程语言和环境中与您的设备通信 . 大多数编程语言都支持串行端口,但用户仍然必须在生成特定命令格式的代码之上编写代码,因此它实际上并没有给你那么多 . USB CDC ACM的一个问题是,如果设备在打开手柄时断开连接,然后重新连接,各种USB CDC ACM驱动程序可以经常陷入糟糕的状态 . 特别是,Windows 10之前的usbser.sys不能很好地处理这个问题,您通常必须拔出并重新插入设备才能使COM端口再次可用 . USB CDC ACM使用批量 endpoints 进行数据传输,因此没有延迟保证 . 使用WinUSB,您可以选择使用中断 endpoints ,以确保始终为每个USB帧传输一个数据包 .
WinUSB由两部分组成:
WinUsb.sys是一个内核模式驱动程序,可以作为过滤器或功能驱动程序安装在USB设备的内核模式设备堆栈中的协议驱动程序之上 .
WinUsb.dll是一个公开WinUSB API的用户模式DLL . 当应用程序作为设备的功能驱动程序安装时,应用程序可以使用此API与WinUsb.sys进行通信 . WinUSB.dll暴露的WinUSB API . WinUSB以联合安装程序包WinUSBCoInstaller.dll的形式包含在Windows驱动程序工具包(WDK)中,位于WinDDK \ BuildNumber \ Redist \ Winusb中 .
要在应用程序中使用WinUSB API:
包括WinUsb.h
将WinUsb.lib添加到链接到您的应用程序的库列表 .
Usb100.h包含一些有用宏的声明 .
使用设备接口GUID获取设备路径 . 正确的GUID是您在INF中用于安装WinUsb.sys的GUID .
通过将在INF中定义的设备接口GUID传递给SetupDiGetClassDevs来获取设备信息集的句柄 . 该函数返回一个HDEVINFO句柄 .
调用SetupDiEnumDeviceInterfaces枚举系统的设备接口并获取设备接口的信息 .
调用SetupDiGetDeviceInterfaceDetail以获取设备接口的详细数据 .
调用GetDevicePath函数以获取设备路径 .
将设备路径传递给CreateFile以获取设备的文件句柄 . 使用ReadFile和WriteFile与设备通信 .
将文件句柄传递给WinUsb_Initialize以初始化WinUSB并获取WinUSB句柄 . 当您调用WinUSB API函数时,使用设备的WinUSB句柄来识别设备,而不是设备的文件句柄 .
对于更高级的解决方案 - 使用功能:
WinUsb_QueryDeviceInformation获取设备的速度 .
WinUsb_QueryInterfaceSettings获取相应的接口描述符 . WinUSB句柄对应于第一个接口 .
WinUsb_QueryPipe获取有关每个 endpoints 的信息 .
WinUsb_WritePipe将缓冲区写入设备 - 默认行为:零长度写入在堆栈中向下转发 . 如果传输长度大于最大传输长度,WinUSB会将请求分成较小的最大传输长度请求并按顺序提交 .
更多功能和信息:http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/winusb_howto.docx
出于调试目的,您可能需要:winusbtrace_tool https://blogs.msdn.microsoft.com/usbcoreblog/2010/02/05/how-to-generate-and-view-a-winusb-debug-trace-log/; Wireshark https://www.wireshark.org带USBPcap插件 .
其他示例:http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html . 示例模板随Visual Studio一起提供 .
您还需要具备编写.inf文件的知识 .
另一种与USB通信的简便方法 - libusb-win32 https://sourceforge.net/projects/libusb-win32/
我的简单示例控制台应用程序向设备发送小的(用于保持活动状态)数据块:
我还必须做同样的要求:PC <==> STM
Microsoft在WinUSB上有很多文档 . 以下是我看到的回答你问题的内容......
自定义USB设备示例
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CustomUsbDeviceAccess
为USB设备开发Windows应用程序 - C#和VB
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-applications-that-communicate-with-a-usb-device
用于USB设备的Windows桌面应用程序
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/windows-desktop-app-for-a-usb-device
如何使用WinUSB函数访问USB设备
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device
开发USB主控制器的Windows驱动程序
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-drivers-for-usb-host-controllers
Windows.Devices.Usb Windows.Devices.Usb命名空间
https://docs.microsoft.com/en-us/uwp/api/windows.devices.usb