Пользовательский HID-совместимый ИБП на базе Arduino Leonardo/Micro не работает на Ubuntu 18.04 LTS

Я разрабатываю пользовательский HID-совместимый ИБП на базе Arduino Micro. Когда я подключаю его к Apple OSX (я использую Macbook в качестве хост-машины) или Windows 10 VM machine, мой "UPS" правильно определяется операционной системой, и я также могу сообщать об оставшейся емкости батареи и других параметрах обратно на хост.

Однако, когда я подключаю его к Ubuntu 18.04 LTS, он не работает (не отображается в настройках питания). В то же время коммерческий ИБП APC прекрасно работает под 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

В первой распечатке мой пользовательский ИБП идет с ID 2341:8036, а ИБП APC - 051d:0003. Вторая распечатка также показывает, что оба они правильно идентифицированы как HID-устройства (Bus 02 порт 5 интерфейс 2 для моего ИБП и порт 4 интерфейс 0 для APC) и оба используют usbhid драйвер, что также правильно и как ожидалось.

Однако APC правильно определяется Ubuntu как ИБП, в то время как мой ИБП вообще не отображается:

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'

Также светодиоды RX/TX не мигают на плате Arduino, так что похоже, что нет обмена между платой и виртуальной машиной. Эта же плата прекрасно работает под OSX и Windows 10, как я уже говорил выше.

Я немного погуглил и обнаружил, что многие статьи на эту тему ссылаются на драйвер usbhid-ups, который не установлен по умолчанию и требует некоторой настройки, как я понял. Я бы очень хотел избежать этого и сделать свой ИБП полностью "plug-and-play", подобно ИБП APC. Уже потерял идеи, что может быть другим для моего ИБП, кроме, может быть, ID поставщика/ID продукта, но это был бы мой последний вариант, чтобы попытаться изменить их. Любая подсказка, что я упускаю, будет очень признательна.

0
задан 3 December 2020 в 09:16

1 ответ

Наконец-то я понял, как это работает. Драйвер usbhid в Linux не виноват, это просто низкоуровневый синтаксический анализатор протокола HID, который на самом деле не выполняет никакой интеллектуальной работы, кроме расшифровки ответов устройства и передачи их на уровень управления, который udev (диспетчер устройств ядра Linux) и UPower manager, который находится поверх udev.

UPower фактически определяет список всех поддерживаемых Vendor ID/Product ID и передает его udev в виде правил udev. Так что я был прав - в этом случае идентификатор поставщика / идентификатор продукта имеет значение - если вы являетесь APC, ваш ИБП будет обнаружен автоматически, в противном случае устройство просто игнорируется UPower, даже если оно совместимо с HID.

К счастью, есть обходной путь. Правила udev хранятся в папке /etc/udev/rules.d/ в текстовом формате, поэтому можно легко определить дополнительные правила. Нужно создать файл 98-upower-hid.rules (думаю, точное имя файла не так важно) в этой папке и добавить следующие строки:

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

Reboot. После этого плата Arduino со скетчем ИБП прекрасно распознается Ubuntu.

0
ответ дан 28 December 2020 в 14:49

Другие вопросы по тегам:

Похожие вопросы: