четверг, 10 сентября 2015 г.

Работа с модулями (драйверами) ядра usb-тачскрина eGalax на BBB

В нашем случае необходимо посмотреть конфиги сборки ядра Debian 8, полученные через menuconfig, запущенного на одноплатнике BeagleBone Black element14. Интересующие нас конфиги показывают, как были собраны определенные драйверы для touchscreen'а eGalax, подключенного к BBB через интерфейс USB. Меня интересуют два драйвера, которые могут быть собраны в виде подключаемых (.ko-файлов) и встроенных модулей:

1) файл bb-kernel/KERNEL/drivers/input/touchscreen/usbtouchscreen.c соответствует модулю usbtouchscreen.ko; нас интересует конфиг CONFIG_TOUCHSCREEN_USB_EGALAX, который включает функциональность взаимодействия с устройством eGalax Touchkit;

2) файл bb-kernel/KERNEL/drivers/usb/musb/musb_core.c и другие соответствуют модулю musb-hdrc.ko; нас интересует конфиг CONFIG_USB_MUSB_HDRC, который отвечает за подключение и способ подключения модуля.

Я собираю версию ядра 4.1.1-bone10 по мануалу https://eewiki.net/display/linuxonarm/BeagleBone+Black с дефолтными настройками. 

При запуске на устройстве приложения с GUI, собранном на Qt 4.8.3, touchscreen через некоторое время перестает работать. В консоль при этом выводятся ошибки вида: 

[  117.033004] musb-hdrc: 28/31 max ep, 16384/16384 memory
[  117.394023] musb-hdrc musb-hdrc.1.auto: Babble
[  117.398559] musb-hdrc musb-hdrc.1.auto: Babble
[  117.403037] musb-hdrc: setup fifo_mode 4 

По умолчанию работу с устройством выполняет модуль musb_hdrc.ko, который иногда сразу корректно определяется (с родным проводом touchscreen'а microUSB-USB), иногда не сразу, но после определения всё равно корректно не работает:

[  122.553033] usb 1-1: new low-speed USB device number 112 using musb-hdrc
[  122.783949] input: eGalax Inc. Touch as /devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/0003:0EEF:0001.0002/input/input2
[  122.849162] input: eGalax Inc. Touch as /devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/0003:0EEF:0001.0002/input/input3
[  122.898208] hid-generic 0003:0EEF:0001.0002: input,hidraw0: USB HID v1.12 Pointer [eGalax Inc. Touch] on usb-musb-hdrc.1.auto-1/input0

Если не изменять при сборке конфигурацию ядра, модуль musb_hdrc.ko подключен как buildin, его нельзя выгрузить (modprobe -r musb_hdrc.ko). Для того, чтобы он собрался, как loadble, надо изменить значение конфига CONFIG_USB_MUSB_HDRC с y (CONFIG_USB_MUSB_HDRC=y) на m (CONFIG_USB_MUSB_HDRC=m). Я хочу попробовать использовать драйвер usbtouchscreen.ko взамен дефолтного. Надо проверить, чтобы CONFIG_TOUCHSCREEN_USB_EGALAX принимал значение y (CONFIG_TOUCHSCREEN_USB_EGALAX=y).

В запущенном ядре это можно сделать через виртуальную файловую систему /proc. C помощью команды zgrep посмотреть текущие конфиги ядра можно следующим образом:

zgrep CONFIG_TOUCHSCREEN_USB_EGALAX /proc/config.gz

Вывод:
CONFIG_TOUCHSCREEN_USB_EGALAX=y

При помощи команды zcat:

zcat /proc/config.gz | grep CONFIG_USB_MUSB_HDRC

Вывод:

CONFIG_USB_MUSB_HDRC=m

Список загруженных драйверов (lsmod) после полного включения устройства (одновременно присутствуют модули musb_hdrc и usbtouchscreen, которые работаю с одним и тем же touchscreen'ом)

root@arm:~# lsmod
Module                  Size  Used by
evdev                  10539  0 
joydev                  9151  0 
usbtouchscreen         17751  0 
rtc_ds1307             14464  0 
musb_dsps              10968  0 
musb_hdrc              88733  1 musb_dsps
omap_aes               15339  0 
omap_sham              23075  0 
tda998x                14551  1 
tilcdc                 33295  0 
omap_rng                5246  0 
drm_kms_helper        127409  4 tda998x,tilcdc
rng_core                8697  1 omap_rng
musb_am335x             1505  0 
leds_gpio               3709  0 
uio_pdrv_genirq         3681  0 
uio                    10132  1 uio_pdrv_genirq

Сокращенный вывод определения usb-устройств при загрузке (dmesg | grep usb | pager):

[    2.720396] usbcore: registered new interface driver usbfs
[    2.720462] usbcore: registered new interface driver hub
[    2.720542] usbcore: registered new device driver usb
[    3.970142] usbcore: registered new interface driver dln2
[    4.160221] usbcore: registered new interface driver usbhid
[    4.166124] usbhid: USB HID core driver
[    8.873011] 47401300.usb-phy supply vcc not found, using dummy regulator
[    8.936929] 47401b00.usb-phy supply vcc not found, using dummy regulator
[    9.708516] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[    9.708541] musb-hdrc: MHDRC RTL version 2.0 
[    9.708549] musb-hdrc: setup fifo_mode 4
[    9.708568] musb-hdrc: 28/31 max ep, 16384/16384 memory
[    9.718096] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[    9.718120] musb-hdrc: MHDRC RTL version 2.0 
[    9.718128] musb-hdrc: setup fifo_mode 4
[    9.718144] musb-hdrc: 28/31 max ep, 16384/16384 memory
[    9.718273] musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
[    9.767551] musb-hdrc musb-hdrc.1.auto: new USB bus registered, assigned bus number 1
[    9.811958] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    9.819184] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    9.826788] usb usb1: Product: MUSB HDRC host driver
[    9.831992] usb usb1: Manufacturer: Linux 4.1.1-bone10 musb-hcd
[    9.838210] usb usb1: SerialNumber: musb-hdrc.1.auto
[   10.204805] musb-hdrc musb-hdrc.1.auto: Babble
[   10.218782] musb-hdrc musb-hdrc.1.auto: Babble
[   10.232673] musb-hdrc: setup fifo_mode 4
[   10.232692] musb-hdrc: 28/31 max ep, 16384/16384 memory
...
[  147.199617] musb-hdrc: 28/31 max ep, 16384/16384 memory
[  147.554737] musb-hdrc musb-hdrc.1.auto: Babble
[  147.582661] musb-hdrc: setup fifo_mode 4
[  148.011454] usb 1-1: new low-speed USB device number 104 using musb-hdrc
[  148.178764] usb 1-1: New USB device found, idVendor=0eef, idProduct=0001
[  148.185915] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  148.193432] usb 1-1: Product: Touch
[  148.197086] usb 1-1: Manufacturer: eGalax Inc.
[  148.261444] input: eGalax Inc. Touch as /devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/0003:0EEF:0001.0001/input/input0
[  148.322628] input: eGalax Inc. Touch as /devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/0003:0EEF:0001.0001/input/input1
[  148.365571] hid-generic 0003:0EEF:0001.0001: input,hidraw0: USB HID v1.12 Pointer [eGalax Inc. Touch] on usb-musb-hdrc.1.auto-1/input0
[  148.407404] usbcore: registered new interface driver usbtouchscreen

Отключим автоматическую загрузку драйвера musb_hdrc.ko, сформировав файл /etc/modprobe.d/blacklist.conf со следующим содержанием:

blacklist musb_hdrc
install musb_hdrc /bin/true

Включим автоматическую загрузку модуля usbtouchscreen.ko, добавив в файл /etc/modules следующую строчку:

usbtouchscreen

Для применения настроек выполним:

update-initramfs -u

За взаимодействие с нашим тачскрином eGalax по USB отвечает два устройства: /dev/input/event0 и /dev/input/event1. Посмотреть физическое получение информации с тачскрина можно, выполнив команду:

cat /dev/input/event1 | hexdump

Проблема с возникающей ошибкой "babble" была решена на аппаратном уровне добавлением обычного usb-хаба, на уровне приложения Qt я делаю переоткрытие устройства /dev/input/event1.

Использованный материал: