WebUSB API 与串行 API

WebUSB API vs Serial API

两者 WebUSB and Web Serial API 都可用于通过 Web 浏览器与使用 USB 插头连接到计算机的设备进行通信。

我对使用 hardware/microcontrollers 进行编程完全陌生(之前只进行过 web 开发),但我已经广泛尝试找出决定设备是否可以被两个 API 中的哪一个读取的因素-s。 Universial Serial 总线毕竟是串行的,不是吗?!所以我的问题如下:

如果能启发前面的问题,下面是我的USB探索故事:

我有两种来自同一制造商的不同类型的设备(都用于读取在 运行 比赛中用于计时的电子标签),其中在 Chrome 浏览器中,一个出现在 Serial 的弹出窗口中API 和另一个在为两个 API 实现基本功能时出现在 WebUSB 的弹出窗口中。 Serial API 中的一个我可以通过 Streams API 发送和接收字节进行通信,但我需要通过批量传输进行通信的 WebUSB。在串行 API 传输中,我似乎从未丢失过数据,但是在 WebUSB 中的批量传输中,如果我拉得不够快,我似乎会丢失数据(即在再次拉出之前对已经拉出的数据进行大量处理) .所以它们对我来说看起来都很“连续”,而且我不能对两者都使用 SerialAPI(而且我不明白为什么),这似乎更可靠并且使用方便流 API.

我在 OSX (10.14.6)。

当我对两个设备执行 ioreg -l -p IOUSB 时,结果是这样的:

    +-o USB <-> Serial@14200000  <class AppleUSBDevice, id 0x10000d0b3, registered, matched, active, busy 0 (10 ms), retain 28>
        {
          "sessionID" = 210143274448224
          "iManufacturer" = 1
          "bNumConfigurations" = 1
          "idProduct" = 24577
          "bcdDevice" = 1024
          "Bus Power Available" = 250
          "USB Address" = 30
          "bMaxPacketSize0" = 8
          "iProduct" = 2
          "iSerialNumber" = 0
          "bDeviceClass" = 0
          "Built-In" = No
          "locationID" = 337641472
          "bDeviceSubClass" = 0
          "bcdUSB" = 272
          "USB Product Name" = "USB <-> Serial"
          "PortNum" = 1
          "non-removable" = "no"
          "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
          "bDeviceProtocol" = 0
          "IOUserClientClass" = "IOUSBDeviceUserClientV2"
          "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=4,"CapabilityFlags"=32768,"MaxPowerState"=4,"DriverPowerState"=4}
          "IOBusyInterest" = "IOCommand is not serializable"
          "Device Speed" = 1
          "USB Vendor Name" = "FTDI"
          "idVendor" = 1027
          "kUSBCurrentConfiguration" = 1
          "IOGeneralInterest" = "IOCommand is not serializable"
          "IOClassNameOverride" = "IOUSBDevice"
        }
    +-o Emit eScan@14200000  <class AppleUSBDevice, id 0x10000d0d8, registered, matched, active, busy 0 (10 ms), retain 23>
        {
          "sessionID" = 210198267509902
          "iManufacturer" = 1
          "bNumConfigurations" = 1
          "idProduct" = 768
          "bcdDevice" = 274
          "Bus Power Available" = 250
          "USB Address" = 31
          "bMaxPacketSize0" = 8
          "iProduct" = 2
          "iSerialNumber" = 3
          "bDeviceClass" = 2
          "Built-In" = No
          "locationID" = 337641472
          "bDeviceSubClass" = 0
          "bcdUSB" = 512
          "USB Product Name" = "Emit eScan"
          "PortNum" = 2
          "non-removable" = "no"
          "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
          "bDeviceProtocol" = 0
          "IOUserClientClass" = "IOUSBDeviceUserClientV2"
          "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=4,"CapabilityFlags"=32768,"MaxPowerState"=4,"DriverPowerState"=4}
          "IOBusyInterest" = "IOCommand is not serializable"
          "Device Speed" = 1
          "USB Vendor Name" = "EMIT AS"
          "idVendor" = 8263
          "kUSBCurrentConfiguration" = 1
          "IOGeneralInterest" = "IOCommand is not serializable"
          "USB Serial Number" = "0969395112001500"
          "IOClassNameOverride" = "IOUSBDevice"
        }

What determines if a device that is connected with a USB plug is compatible with the Serial API or WebUSB API?

这取决于所使用的驱动程序和设备。一些设备通过 USB 进行通信,而其他设备则在 USB 之上使用串行协议。

在 MacOS 上,如果没有为设备安装驱动程序(即 kernel/driver 扩展),将使用默认的 USB 驱动程序,您可以使用 WebUSB(但不是 Web系列)。如果设备在 USB 之上使用串行协议,您可以编写自己的 user-space 串行驱动程序。

在Windows上,如果设备没有指定特殊的微软OS描述符,默认的USB驱动程序将不会加载,所以在大多数情况下你必须安装一个驱动程序来与设备。

Can this depend on which drivers I have on my computer? E.g. can this have something to do with USB CDC (which I frequently seem to stumble upon in my research) and a driver for this?

是的,CDC-ACM是一种驱动程序。还有各种其他 USB-serial 芯片(例如 FTDI、Prolific、SiLabs、TI),每个芯片都有自己的 USB 串行驱动程序。

您还有一些设备通过 USB 使用 HID,您需要使用 WebHID API 与它们通信。

Can the same device be compatible with WebUSB on one computer, but Serial API on another? E.g. depending on available drivers or the host OS?

是的,没错。如果你知道你的目标设备有一个特定的芯片,例如Prolific PL2303,您可以先尝试通过 Web Serial 连接到它。如果失败,您可以回退到 WebUSB 并使用运行在 WebUSB 之上的 user-space 串行驱动程序连接到它。

If I had used another programming environment, e.g. used C to write a native program, could I then choose freely to communicate with a particular device with either the "serial way" to do it or the USB protocol?

不是真的。您的本机程序还取决于安装的驱动程序。不同之处在于,用于安装本机程序的安装程序还可以安装必要的驱动程序。