基于 Arduino Leonardo/Micro 的定制 HID 兼容 UPS 无法在 Ubuntu 18.04 LTS 上运行

基于 Arduino Leonardo/Micro 的定制 HID 兼容 UPS 无法在 Ubuntu 18.04 LTS 上运行

我正在开发基于 Arduino Micro 的自定义 HID 兼容 UPS。当我将其连接到 Apple OSX(我使用 Macbook 作为主机)或 Windows 10 VM 计算机时,操作系统会正确确定我的“UPS”,并且我还可以将剩余电池容量和其他参数报告回主机。

但是,当我将其插入 Ubuntu 18.04 LTS 时,它无法工作(电源设置中未显示)。同时,商用 APC UPS 在 Ubuntu 下工作正常。lsusb 的发布如下:

abratchik@ubuntu-parallels-vm:~$ lsusb
Bus 001 Device 003: ID 203a:fffa  
Bus 001 Device 002: ID 203a:fffa  
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 002: ID 203a:fff9  
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 004: ID 2341:8036 Arduino SA Leonardo (CDC ACM, HID)
Bus 002 Device 006: ID 051d:0003 American Power Conversion UPS
Bus 002 Device 003: ID 203a:fffe  
Bus 002 Device 002: ID 203a:fffc  
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub


abratchik@ubuntu-parallels-vm:~$ lsusb -t
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 5000M
    |__ Port 1: Dev 2, If 0, Class=Video, Driver=uvcvideo, 5000M
    |__ Port 1: Dev 2, If 1, Class=Video, Driver=uvcvideo, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 1: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/15p, 12M
        |__ Port 5: Dev 4, If 2, Class=Human Interface Device, Driver=usbhid, 12M
        |__ Port 5: Dev 4, If 0, Class=Communications, Driver=cdc_acm, 12M
        |__ Port 5: Dev 4, If 1, Class=CDC Data, Driver=cdc_acm, 12M
        |__ Port 4: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 12M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/15p, 480M
    |__ Port 1: Dev 2, If 0, Class=Printer, Driver=usblp, 480M
    |__ Port 2: Dev 3, If 0, Class=Printer, Driver=usblp, 480M

在第一张打印输出中,我的定制 UPS 的 ID 为 2341:8036,而 APC UPS 的 ID 为 051d:0003。第二张打印输出也显示它们都被正确识别为 HID 设备(我的 UPS 为总线 02 端口 5 接口 2,APC 为端口 4 接口 0),并且两者都使用连接USB驱动程序,这也是正确的并且符合预期。

但是,Ubuntu 正确地将 APC 检测为 UPS,而我的 UPS 根本没有显示:

abratchik@ubuntu-parallels-vm:~$ upower -e
/org/freedesktop/UPower/devices/line_power_ADP0
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/ups_hiddev3
/org/freedesktop/UPower/devices/DisplayDevice

abratchik@ubuntu-parallels-vm:~$ upower -i /org/freedesktop/UPower/devices/ups_hiddev3
  native-path:          /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2.4/2-2.4:1.0/usbmisc/hiddev3
  vendor:               American Power Conversion 
  model:                Smart-UPS C 1500 FW:UPS 10.0 / ID=1005
  serial:               3S1838X02676  
  power supply:         yes
  updated:              Thu 03 Dec 2020 10:00:04 AM +04 (-11 seconds ago)
  has history:          yes
  has statistics:       yes
  ups
    present:             yes
    state:               fully-charged
    warning-level:       none
    time to empty:       2.0 hours
    percentage:          100%
    icon-name:          'battery-full-charged-symbolic'

此外,Arduino 板上的 RX/TX LED 不闪烁,因此看起来板子和 VM 之间没有交换。正如我上面提到的,同一块板子在 OSX 和 Windows 10 下运行良好。

我搜索了一下,发现关于这个主题的许多文章都提到了 usbhid-ups 驱动程序,据我所知,默认情况下不会安装该驱动程序,需要进行一些配置。我真的想避免这种情况,让我的 UPS 完全“即插即用”,类似于 APC UPS。已经不知道我的 UPS 可能有什么不同,除了供应商 ID/产品 ID,但这将是我尝试更改这些的最后选择。任何提示我遗漏了什么都将不胜感激。

答案1

最后我明白了它是如何工作的。Linux 中的 usbhid 驱动程序没有问题,它只是 HID 协议的低级解析器,除了解密设备响应并将其传递给管理层之外,并没有真正做任何智能工作,管理层是udev(Linux 内核设备管理器)和优力管理器,位于 udev 之上。

UPower 实际上定义了所有支持的供应商 ID/产品 ID 的列表,并以以下形式将其提供给 udevudev 规则。所以我是对的 - 在这种情况下,供应商 ID/产品 ID 确实很重要 - 如果您是 APC,那么您的 UPS 将被自动检测到,否则即使该设备符合 HID 标准,UPower 也会忽略它。

幸运的是,有一个解决方法。udev 规则以文本格式存储在 /etc/udev/rules.d/ 文件夹中,因此可以轻松定义其他规则。必须创建文件98-upower-hid.规则(我认为确切的文件名并不那么重要)在此文件夹中并添加以下行:

ATTRS{idVendor}=="2341", ENV{UPOWER_VENDOR}="Arduino"
ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", ENV{UPOWER_BATTERY_TYPE}="ups"

重启。之后,Ubuntu 就可以正常识别带有 UPS 草图的 Arduino 板了。

相关内容