模拟物理USB设备的Linux操作

16

我有一个Linux应用程序,希望能够自动化一些测试。该程序的状态应根据某些设备(例如USB设备、WLAN设备、WAN设备)的状态而改变。然而,我们不再拥有物理USB、WLAN、WAN等设备,因此我需要找出一种在不实际插入物理设备、打开/关闭等操作的情况下测试此程序的方法。

我开始尝试创建一个虚拟USB设备,可以从用户空间控制它,但是基本缺乏知识使我无法将这些论坛上类似的主题应用于我的项目。我觉得我需要创建某种虚拟USB驱动程序,然后让它与某个用户级程序通信,而不是usbfs。但是,即使我创建了这个虚拟驱动程序,如何从用户空间“插入”这个设备并让我的程序注册到这个特定的驱动程序呢?我正在尝试做的事情是否可行?


可能让计算机充当其他设备的虚拟USB设备会有所帮助。 - dma_k
2个回答

13
最好的方法是使用Linux Gadget Drivers和硬件,让您成为USB设备。Gadget驱动程序允许计算机“假装”成为任何类型的设备。然后,在测试系统下,您的系统只需连接一个USB OTG电缆到gadget盒子。如果您的gadget盒子具有正确的硬件,甚至不需要拔掉电缆。 "gadget盒子" 可以是运行Linux(如果支持USB OTG),甚至可以是Android手机或树莓派的桌面/笔记本电脑。 (请注意,USB电缆很糟糕。仅因为电缆适合并不意味着它正确地连接了USB OTG。)
一旦您拥有正确的USB OTG硬件,您的gadget盒子就全部由软件组成:
1)如果您测试的设备支持OTG,请确保您的gadget盒子不会尝试成为USB主机。(然后您的测试设备将成为USB客户端。)即确保不自动加载像usb_storage这样的内容。
2)内核开箱即用,支持USB集线器、USB以太网、USB串口和USB存储器的gadgets。只需在gadget盒子上加载正确的模块,它就可以“立即工作”。例如,要创建USB存储器,请执行以下操作:“insmod g_file_storage.ko file=/dev/ram0”。远端将认为您插入了USB存储器。
对于串行设备,您的gadget可以运行用户空间代码,在/dev/USBx上“接电话”并与测试设备通信。(假设模拟4G调制解调器或其他设备。)
许多设备在底层实际上是“USB串行”的,因为制造商太懒以至于不理解USB。
3)通过一点重新编译或配置,您可以让那些通用的Gadget设备假装成各种USB IDs或返回各种供应商字符串等。这虽然不同于“针对真实硬件进行测试”,但至少您正在使用这些设备的通用版本进行测试。

4) 对于内核中不存在的设备类型(例如WiFi或其他设备),你需要自己解决。通过付出足够的心血和汗水,你可以编写自己的设备类型。(最好尽可能保留在用户空间处理,并仅将性能关键部分处理在内核中...)

注意:同时理解和欣赏USB是不可能的。


1
如果我能够物理访问测试系统,那就太完美了;不幸的是,我无法这样做。然而,Linux小工具驱动程序可能会派上用场...我计划编写一个USB驱动程序,在初始化时自动注册一个虚拟USB设备,该设备镜像了在Linux小工具源中找到的设备、配置和接口描述符。这个方案可行吗? - Matt Dorsett
1
看起来内核模块已经被重命名为 usb_f_mass_storage.ko。请参见链接 - netvope
如何通过 usb_f_mass_storage 模块将本地文件系统(部分)暴露出来?这种方式类似于可以在运行 g_file_storage 模块的 Linux 上挂载的“实时” /dev/ram0,因此如果 USB 主机创建文件,则 Linux 可以看到它。 - dma_k

0
你能否在使用VMware的虚拟环境中测试您的应用程序?然后,您可以将任何虚拟设备“连接”到您的宿主机器上的客户VM中,并以此方式测试您的应用程序。

不好意思,我没有那种对代码的访问权限,我只能添加内核模块并运行测试应用程序。这些测试是在远程服务器上运行的。 - Matt Dorsett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接