USB设备仿真框架设计指南——7.USB设备模拟器示例

本节描述DSF中包含的USB设备模拟器示例。
本节包括以下内容:

DSF USB HID通用样本

DSF USB Loopback设备仿真

DSF USB音频设备示例

USB键盘样本


英文原文连接:https://docs.microsoft.com/zh-cn/previous-versions/windows/hardware/dsf/ff542300(v%3dvs.85)


DSF USB HID通用样本

描述

DSF USB HID通用代码示例演示如何构建符合设备仿真框架(DSF)的基本USB HID设备。代码显示了如何将模拟设备设置成一个HID设备。您还可以使用hclient示例来检测模拟硬件生成的HID报告。然后,用户可以验证模拟的硬件生成响应。有关hclient示例的更多信息,请参见HClient。有关HIDClass设备的设备堆栈的信息,请参阅 Device Stacks for Generic HIDClass Devices

工作原理

仿真器综述

通用USB HID模拟器样本的结构类似于DSF USB Loopback Device Simulation 示例。通用USB HID模拟器具有以下结构:

  • 一个实现USB 1.1 HID设备仿真器的InProc COM对象。该对象与DSF COM对象交互以实现设备模拟器和控制器模拟器之间的交互。
  • 创建一个InProc COM对象实例的测试脚本。InProc COM对象表示模拟设备。当控制器运行时,测试脚本将模拟设备插入控制器。

通用HID模拟器创建USB HID专用设备报告描述符,并将它们返回到主机,如USB HID设备类规范中所述。这些设备和报表描述符每台设备各不相同。因此,必须更新特定设备的示例代码中的设备和报表描述符。通用HID示例仅实现通用设备来承载请求。因此,必须实现符合设备类规范的设备类特定请求。HID通用示例不包括任何主机到设备请求。然而,在实践中,可以实现由设备类规范所确定的主机到设备请求。为了定制HID通用示例以模拟特定的HID设备类,您可能必须根据规范更新CHIDDevice::OnDeviceRequest方法。

初始化模拟器

默认情况下,模拟器分别由类构造函数(CHIDDevice::CHIDDevice)和FinalConstruct方法(CHIDDevice::FinalConstruct)初始化。构造函数初始化全局变量,FinalConstruct初始化通用USB设备的属性。若要初始化通用HID设备的属性,FinalConstruct调用CHIDDevice::BuildHIDDescriptors。然后,示例代码在CHIDDevice::CreateReportDescriptor中填充示例报告描述符,在CHIDDevice::CreateHIDDescriptor.中填充示例设备描述符。或者,您的代码可以使用CHIDDevice::CreateCustomHIDDescriptor 和CHIDDevice::CreateCustomReportDescriptor ,并且可以传入包含自定义描述符的SAFEARRAY,以创建自定义HID设备。最后,示例代码调用CHIDDevice::ConfigureDevice来创建和初始化USB设备端点、接口和配置。作为设备配置过程的一部分,示例代码为CHIDDevice::SetupControlConnectionPoint配置事件接收器。对于您的模拟,代码可以为IN端点和任何其他端点添加事件接收器。

端点数据传输

HID通用示例只实现在CHIDDevice::ConfigureINEndpoint中自定义的IN端点中断,例如,可以修改m_piINEndpoint->put_Attributes以实现批量传输端点,而不是中断传输端点。您的HID模拟设备应该使用事件驱动的处理来进行中断传输。为了在这个模拟中使用IN端点,在向CHIDDevice::QueueInputReport 输入的SAFEARRAY输入中的队列中包含设备的HID input reports。根据实现的HID设备来构造输入报告。使用CHIDDevice::StartProcessing和CHIDDevice::StopProcessing开始和停止处理排队到IN端点的数据。使用CHIDDevice::StartProcessingCHIDDevice::StopProcessing开始和停止处理排队到IN端点的数据。CHIDDevice::get_IdleTimeout 和CHIDDevice::put_IdleTimeout 方法允许用户获取或设置设备端点处理每个输入报告的速率。

其他模拟器的方法和性能

模拟器需要一个属性,该属性公开由SoftUSBDevice.DSFDevice方法返回的对象。SoftUSBDevice.DSFDeviceCHIDDevice::get_DSFDevice中实现。CHIDDevice::CreateStrings方法提供了用于添加设备模拟器所使用的字符串的实用工具。

终止模拟器

SoftUSBDevice.Destroy方法移除事件接收器并释放所有对象。模拟器在CHIDDevice::Destroy中实现了这个方法。此外,您应该在CHIDDevice::Destroy中执行资源清理。

错误处理

所有操作阶段可能发生的无数错误情况,在前面没有处理时,您必须考虑这些错误条件,并根据USB和UBHID规范实现它们。在HID通用示例COM对象中,为调试目的提供Logging属性和SetEndpointDiagnostics方法。CHIDDevice::SetEndpointDiagnostics方法设置可以从内核调试器查看的端点上的调试输出级别。CHIDDevice::put_Logging记录方法打开或关闭模拟器生成的调试输出。

统计与诊断

如果测试应用程序必须监视关于模拟设备的诊断信息,则可以通过在CHIDDevice中收集信息并通过在CHIDDevice对象上设置的属性公开信息来实现此监视。例如,为了跟踪读取和写入的字节总数,CHIDDevice可以为这些运行总数中的每一个保留成员变量。为了提供对测试应用程序的访问,模拟设备可以在COM对象上公开TotalReadTotalWritten 属性,这些属性仅返回成员变量的当前值。请注意,对这些变量的访问必须同步。

建立样例

您可以在src\test\dsf\usb\GenericHID目录中找到HID通用设备的示例代码。要构建设备模拟器的自定义版本,请使用WDK构建环境并运行build -cZP。此命令生成一个COM库,称为SoftHIDReceiver.dll。或者,当安装DSF运行时,提供并准备使用此资源。

还可以使用微软的Visual Studio 2005或Visual Studio更高版本来创建此示例。

通用HID设备仿真演练

下面的步骤显示了一个示例测试场景的流程:

  • 使用DSFx86Runtime.msi 或DSFx64Runtime.msi安装DSF运行时。
  • 运行%programfiles%\dsf\softehcicfg.exe /install以创建模拟USB 2.0EHCI控制器并模拟将控制器插入主机系统。
  • 运行 cscript.exe TestGenericHID.wsf.
  1. 创建一个DSF.DSF COM 对象,以提供对DSF公开的辅助方法的访问。

  2. 创建一个SOFTUSB.SoftUSBHub COM对象来创建一个USB集线器仿真。这种仿真需要插入USB 1.1设备。

  3. 为了暴露控制器的根集线器端口,从DSF设备的集合中查找模拟控制器。使用根集线器端口定位端口以插入模拟的集线器并等待设备枚举。

  4. 创建SoftHIDReceiver.HIDDevice.1 COM对象,表示通用HID设备仿真。然后测试将开启日志记录。

  5. 按顺序调用CHIDDevice::CreateCustomReportDescriptorCHIDDevice::CreateCustomHIDDescriptor, 和CHIDDevice::ConfigureDevice 来执行设备初始化。

  6. 在USB集线器上找到可用的端口,并在控制器运行时将集线器插入控制器。等待设备枚举。

  7. 接下来,创建输入报告,将它们排队到端点,并开始处理报表。当I/O测试完成后,停止处理。

  8. 测试完成后,调用集线器上的unplug方法来删除通用HID设备。

  9. 调用根集线器上的拔出方法以从控制器中删除集线器。

  10. 调用CHIDDevice::Destroy 清空任何剩余资源的方法。

  • 运行softehcicfg /remove以从主机上拔出控制器。

向微软发送有关此主题的评论

创建日期:2010/9/21

英文原文连接:https://docs.microsoft.com/zh-cn/previous-versions/windows/hardware/dsf/ff538334(v%3dvs.85)


DSF USB Loopback设备仿真

描述

DSF USB Loopback设备仿真代码示例展示了如何基于设备仿真框架(DSF)构建USB仿真。代码显示了如何将模拟设备设置为类似于USB设备,以及DSF支持用于处理USB数据的两种方法。测试脚本还演示了如何测试设备。

工作原理

运行样例

当从微软Windows驱动程序包(WDK)安装DSF时,包含环回仿真代码的预编译版本。要运行代码,可以使用这个提供的版本,也可以使用通过使用WDK构建环境编译的版本。要使用您编译的版本,只需用您自己的版本替换所提供的版本,并运行regsvr32 SoftUSBLoopback.dll来注册您定制的模拟版本。所提供的DLL已经注册,因此不需要注册该文件。

为了执行代码,可以使用名为RunLoopbackSample.wsf 的VBScript文件,该文件与DSF一起安装在Program Files\dsf目录中。在运行脚本之前,必须在目标系统上添加模拟USB控制器。要安装模拟USB控制器,需要运行softehcicfg.exe /install

要执行loopback设备,请运行cscript RunLoopbackSample.wsf。该脚本会创建一个新的设备。新设备然后插入到刚刚安装的模拟USB控制器中。主机系统表现为好像已经插入了一个新设备并加载适当的驱动程序。在这种情况下,Usbsamp.sys 是枚举设备所需的驱动程序,因为loopback设备模拟Intel批量USB测试板。在USB总线上枚举设备之后,您可以选择以轮询模式或事件模式运行该设备。有关如何创建和安装一个Usbsamp.sys驱动程序的更多信息,请参见UsbSamp。有关轮询和事件操作模式的更多信息,请参阅本主题中的轮询模式和事件驱动模式部分。

当设备没有数据要处理时,它会向脚本发送一个事件,该脚本询问您是否要继续。如果不提供任何输入,则假定选择继续。如果您选择不继续,则设备被拔出,并要求您按Enter来结束脚本。

若要与loopback设备交换数据,必须运行Usbsamp.exe测试应用程序。您可以在WDK安装的src\usb\usbsamp目录中找到这个测试应用程序。通过运行usbsamp.exe /u,您可以看到设备和端点是如何配置的。

若要从设备发送和接收512字节,请运行以下命令。

usbsamp.exe -r 512 -w 512 -i 0 -o 1

可以将数据量调整到所需的任何值。IN端点为0,OUT端点为1。这些值需要保持恒定,因为端点只在一个方向上工作。

注意:Usbsamp.sys驱动程序和Usbsamp.exe测试应用程序替换了早期版本的WDK的BulkUSB.sys驱动程序和RwBulk.exe测试程序。有关Usbsamp的更多信息,请参见 UsbSamp

处理设备请求

SoftUSBLoopback设备是USB模拟设备的一个简单例子。该设备不处理任何设备请求。该设备只接收发送给它的标准USB设备请求,因此DSF基础架构将处理这些请求。一个设备只需要处理供应商特定的和类特定的请求。

事件驱动模式

该设备可以在轮询或事件驱动模式下运行。

在事件驱动模型中,每当有待处理的数据时,loopback设备通过调用 OnWriteTransfer函数从主机控制器接收数据。当从主机接收到OUT事务时,调用OnWriteTransfer作为OUT端点。此调用发生在任意线程上,因为事件是从内核模式发送的。然后,该设备简单地通过调用函数QueueINData.将数据传递到IN端点。此调用将数据添加到IN端点队列中。当IN端点接收来自主机控制器的数据请求时,从队列中简单地读取数据。

轮询模式

在轮询模式模型中,设备周期性地查询OUT端点,以确定是否有需要处理的数据。设备调用 DrainOUTQueue和maxTransfers设置为0,这表示设备想知道队列中有多少项。如果存在数据,则设备通过使用DrainOUTQueue函数从端点读取数据,一次读取一个请求。然后,该设备通过调用函数 QueueINData将数据传递到IN端点。此调用将数据添加到IN端点队列中。当IN端点接收来自主机控制器的数据请求时,从队列读取数据。

建立样本

您可以在src\test\dsf\usb\softusbloopback目录中找到USB Loopback 设备的示例代码。若要使用WDK生成环境构建可执行文件,请运行build -cZP。这个命令产生一个称为SoftUSBLoopback.dll的DLL文件。

还可以使用微软的Visual Studio 2005或Visual Studio更高版本来创建此示例。

向微软发送有关此主题的评论

创建日期:2010/9/21

英文原文连接:https://docs.microsoft.com/zh-cn/previous-versions/windows/hardware/dsf/ff538337(v%3dvs.85)

 


DSF USB音频设备示例

USB音频设备模拟器样本是微软DSS-80数字声音系统的部分模拟。此示例模拟所有音频输出功能,但不模拟音频输入和HID控制功能。样本包括左、右扬声器、低音扬声器、音量、低音、高音、图形均衡器和静音控制。

你可以在你的WDK安装目录\src\Test\DSF\USB\SoftUSBAudio中找到音频设备示例代码。可以在\Program Files\dsf\USBAudio文件夹中与DSF运行时一起安装该音频示例设备和脚本。该脚本将引导您完成设备创建和热插拔到控制器中,然后暂停以等待击键结束模拟。当暂停脚本时,您可以播放来自任何源的声音,例如Microsoft Windows Media Player或控制面板中的Sound项,并且脚本将显示关于所处理的同步OUT事务的统计数据。

音频设备具有包括音频控制接口和音频流接口的单一配置。音频控制接口不定义端点,它专门用作特定设备请求的目标。音频流接口具有六个备选方案,这些备选方案仅在其最大分组大小上变化,并且它定义了单个同步OUT端点。

音频设备对象公开单个双接口,IAudioDevice和事件接口,IAudioDeviceEvents,它们包含以下属性、方法和事件:

  1. 在控件端点上安装事件接收器。
  2. 循环休眠250毫秒(ms),触发IAudioDeviceEvents::ContinueSimulating 以确定是否结束循环,并调用同步OUT端点上的 ISoftUSBEndpoint::DrainOUTQueue以删除接收的任何事务。控制端点事务事件在SoftUSBEndpoint运行期间创建的单独的任意线程上接收。
  • IAudioDevice::AreKeystrokesWaiting方法调用了_kbhit C运行时例程并返回结果。此方法允许脚本检查键是否已被按下,而不会阻塞键盘读取,例如,通过调用WScript.StdIn.ReadLine

该设备模拟器是用C++引用ATL类库编写的一个IPROC COM对象实现的。该对象定义了一个名为CAudioDevice的C++类(它位于src\Test\DSF\USB\SoftUSBAudio\文件夹中AudioDevice.h 和 AudioDevice.cpp文件中。该类实现 IAudioDeviceISoftUSBEndpointEvents,和IAudioDeviceEvents的事件源。CAudioDevice::FinalConstruct方法创建SoftUSBDevice对象,并使用包含音频描述符数据的大量静态结构对其进行配置。

CAudioDevice::OnDeviceRequest方法实现了控制端点的 ISoftUSBEndpointEvents::OnDeviceRequest事件。此方法向控制台(通过使用printf)显示每个设备请求的细节,并根据设备请求的目标是音频控制接口还是同步端点,分支到CSoftUSBEndpoint::ProcessAudioControlInterfaceRequestCSoftUSBEndpoint::ProcessEndpointRequest 。成员变量维护每个音频控件的当前值。

当测试应用程序调用IAudioDevice::StartSimulation 时运行的主仿真循环由CAudioDevice::StartSimulation实现。在每次迭代期间,StartSimulation 调用CAudioDevice::DrainIsochEndpoints,然后StartSimulation (此处是StartSimulation还是CAudioDevice::DrainIsochEndpoints有点不确定,希望朋友们指导一下)为每个音频流接口备用程序处理同步OUT端点(它之前存储在m_piIsochEndpoints数组中)。DrainIsochEndpoints调用 ISoftUSBEndpoint::DrainOUTQueue来移除最多16个事务,当控制器接收到这些事务时,端点会排队。DrainIsochEndpoints将在队列中保留的事务数写入控制台窗口。

如前所述,模拟器对同步OUT端点的SoftUSBEndpoint对象使用轮询,并周期性地丢弃事务数据。对这个模拟器的一个可能的增强(除了完成丢失的音频输入和HID控件之外)是检查事务数据并确保其正确形成和排序。还有许多故障注入机会,例如返回音频控制请求的无效值和损坏音频输入数据。

向微软发送有关此主题的评论

创建日期:2010/9/21

英文原文连接:https://docs.microsoft.com/zh-cn/previous-versions/windows/hardware/dsf/ff538330(v%3dvs.85)


USB键盘样本

描述

DSF USB键盘样本分为两个部分:通用HID设备和键盘。这两个部分展示了HID设备如何与设备仿真框架(DSF)交互。通用设备展示设备如何与DSF交互,键盘设备展示如何在通用设备上构建HID模拟器。

工作原理

键盘样本被分割成两个不同的可执行文件--InputKbd.dll 和SoftHIDDevice.dll。这种组织为代码提供了更大的灵活性,因为任何HID类设备都可以使用SoftHIDDevice.dll 作为基础,并在自己的可执行文件中实现特定于设备的代码。例如,您可以在HIDDevice上编写鼠标模拟器,它负责所有HID类特定的USB协议消息。模拟器只需要实现设备和供应商特定的消息。例如,键盘必须为CAPS LOCK实现LED指示,并且还必须处理设备的按键。

实施与设计

使用此示例开发DSF HID模拟器。

建立样本

可以从微软Windows驱动程序工具包(WDK)生成环境编译示例代码。

要使用WDK生成环境编译,请导航到src\Test\DSF\USB\InputKbd目录并运行build -cZP。然后,导航到src\Test\DSF\USB\SoftHidDevice目录并运行build -cZP

安装

通用

在运行测试脚本之前,必须在目标系统上安装模拟USB控制器。要安装模拟的EHCI控制器,请运行softehcicfg.exe /install

模拟ECHI控制器将出现在DSFRoot下的设备管理器中。在将模拟设备插入根集线器之前,应等待此枚举完成。

要运行脚本,请打开命令提示符窗口,导航到Program Files\dsf\usbhid目录,并运行 cscript Create1.1Kbd.wsf。然后你应该按照命令行的指令。这些指令告诉您打开一个新的命令提示符窗口以运行cscript Use1.1Kbd.wsf (也在Program Files\dsf\usbhid目录中)。

Create1.1Kbd脚本创建并插入一个新的模拟USB集线器到根集线器。Create1.1Kbd脚本然后创建一个新的键盘设备,插入到刚刚创建的仿真集线器中。所有用DSF模拟的USB 1.0设备都必须通过模拟USB集线器插入。只有USB 2.0设备可以直接插入到根集线器中。该系统通知用户发现一个新的HID类设备,并且该设备是一个微软的自然键盘。然后系统为设备加载合适的驱动程序。Create1.1Kbd脚本提示用户在每个步骤中继续。当完全枚举集线器和键盘设备时,Create1.1Kbd脚本提示用户运行Use1.1Kbd.wsf脚本。Use1.1Kbd.wsf脚本生成键盘发送的按键的HID报告。如果你有命令提示符窗口的焦点,你会看到文本“hello World”出现。

终端用户

要使用已编译的代码的版本,只需替换在目标系统上安装DSF时加载的DLL。文件位于Program Files\dsf\usbhid中。替换InputKbd.dll 和SoftHIDDevice.dll。您不需要注册这些文件,因为在安装DSF时执行该操作。

代码之旅

文件清单

文件                                                                                   描述

softhidevice.dll Inputkbd.dll                                           DSF HID Device simulators

向微软发送有关此主题的评论

创建日期:2010/9/21

英文原文连接:https://docs.microsoft.com/zh-cn/previous-versions/windows/hardware/dsf/ff538336(v%3dvs.85)#installation

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值