1 이벤트를 발생시키는 USB HID 장치 만


11

ASUS PSR 2000 Web Surfing Remote Control과 함께 제공되는 eDIO USB Multi Remote Controller (적외선 리시버)가 있습니다.

Remote COntroller를 내 pi에 연결하여 리모콘에서 보낸 키 입력을 수신하려고합니다.

컨트롤러가 HID 장치로 감지되었습니다. lsusb -v 명령의 세부 사항은 다음과 같습니다.

    Bus 001 Device 007: ID 147a:e001 Formosa Industrial Computing, Inc.
    Couldn't open device, some information will be missing
    Device Descriptor:
    bLength                18
    bDescriptorType         1
    bcdUSB               1.10
    bDeviceClass            0 (Defined at Interface level)
   bDeviceSubClass         0
   bDeviceProtocol         0
   bMaxPacketSize0         8
   idVendor           0x147a Formosa Industrial Computing, Inc.
   idProduct          0xe001
   bcdDevice            1.22
   iManufacturer           1
   iProduct                2
   iSerial                 0
   bNumConfigurations      1
  Configuration Descriptor:
  bLength                 9
  bDescriptorType         2
wTotalLength           34
bNumInterfaces          1
bConfigurationValue     1
iConfiguration          4
bmAttributes         0xa0
  (Bus Powered)
  Remote Wakeup
MaxPower              300mA
Interface Descriptor:
  bLength                 9
  bDescriptorType         4
  bInterfaceNumber        0
  bAlternateSetting       0
  bNumEndpoints           1
  bInterfaceClass         3 Human Interface Device
  bInterfaceSubClass      1 Boot Interface Subclass
  bInterfaceProtocol      2 Mouse
  iInterface              0
    HID Device Descriptor:
      bLength                 9
      bDescriptorType        33
      bcdHID               1.10
      bCountryCode            0 Not supported
      bNumDescriptors         1
      bDescriptorType        34 Report
      wDescriptorLength      20
     Report Descriptors:
       ** UNAVAILABLE **
  Endpoint Descriptor:
    bLength                 7
    bDescriptorType         5
    bEndpointAddress     0x81  EP 1 IN
    bmAttributes            3
      Transfer Type            Interrupt
      Synch Type               None
      Usage Type               Data
    wMaxPacketSize     0x0004  1x 4 bytes
    bInterval              10

또한 이벤트가 생성 된 dev 폴더에서 대상 장치를 볼 수 있습니다

    pi@raspberrypi /dev/input/by-id $ dir
    usb-Cypress_Semiconductor_eDio_USB_Multi_Remote_Controlle-event-if00

이와 연관된 이벤트 핸들러는 다음 명령에서 볼 수 있듯이 다음과 같습니다.

pi@raspberrypi /proc/bus/input $ cat devices
I: Bus=0003 Vendor=147a Product=e001 Version=0110
N: Name="Cypress Semiconductor eDio USB Multi Remote Controlle"
P: Phys=usb-bcm2708_usb-1.2/input0
S: Sysfs=/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/input/input2
U: Uniq=
H: Handlers=event0
B: PROP=0
B: EV=1

문제는 장치에 대해 작성된 이벤트 핸들러에서 출력을 읽으려고 할 때입니다. 첫 번째 키 입력은 등록되었지만 후속 키 입력은 CAT 명령으로 표시되지 않습니다.

 pi@raspberrypi /dev/input $ cat event0 | xxd
 0000000: e007 9450 9476 0900 0000 0000 0000 0000  ...P.v..........

장치를 작동 시키려면 어떻게해야하는지 제안하십시오. 첫 번째 키 입력 후 아무 키나 눌러도 장치를 다시 연결하지 않으면 아무 것도 반환되지 않습니다.

문제를 해결하기 위해 수행해야 할 작업을 제안하십시오.


누구든지 ??? 나는 장치에 무슨 일이 일어나고 있는지 단서가 없습니다. 아마도 중재자가 문제가있는 경우 질문을 더 잘 짜는 데 도움이 될 수 있습니까?
SteveIrwin 15

질문이 좋습니다. 그러나 현지화되어있어 많은 사람들이 같은 문제를 겪지 않았을 것이라고 확신합니다. Chris Wallace의 대화 보트에서 사용되는 것과 매우 유사한 것을 보았 으므로이를 살펴볼 수 있습니다. 문제를 진단하기 위해 가장 먼저 물어볼 것은 자체 전원 공급 허브를 사용하고 있습니까? 전원 문제 일 수 있습니다.
Jivings

당신은없이 시도 했습니까 |xxd? 출력을 버퍼링합니다. 내가 사용하는 irw패키지에서 lirc내 원격으로 전송되는 키 코드를 얻을 수 있습니다.
macrojames

커스텀 드라이버는 리눅스 커널 패치를 의미합니다. libusb가 USB 엔드 포인트에 직접 액세스 할 수 있으므로 더 쉬운 옵션은 libusb를 사용하는 것입니다.
Lars Pötter

답변:


5

문제는 불완전한 USB 디스크립터 인 것 같습니다 :

  Couldn't open device, some information will be missing
  Report Descriptors:
  ** UNAVAILABLE **

읽을 수있는 설명자는 이것이 마우스라고 말합니다.

  bInterfaceProtocol      2 Mouse

그리고 데이터 형식을 설명하는 20 바이트의 설명자가 있습니다.

  bDescriptorType        34 Report
  wDescriptorLength      20

그러나 그 중 하나가 없습니다.

하드웨어와 소프트웨어의 특정 조합에 이상한 문제가 있거나 프로그래머가 게으르고 보고서 디스크립터를 구현하지 않았기 때문에 자체 드라이버에 필요하지 않을 수 있습니다. 그러나 아마도 입력 장치를 만드는 드라이버가 혼란 스럽습니다.

libusb를 사용하여 엔드 포인트에서 4 바이트를 읽을 수 있습니다. 아마도 폴링이 작동합니다. 또는 원래 드라이버와 함께 장치를 사용할 때 USB 통신을 살펴보십시오. 고가의 USB 로거 중 하나를 가지고 있지 않으면 매우 까다 롭습니다. 그러나 Linux Kernel은 소프트웨어 USB 로깅을 지원하며 Windows 용 소프트웨어 로거도 있습니다.


4

마지막으로 Libusb의 래퍼 인 PyUSB 라이브러리를 사용하여 자체 구현을 작성할 시간이 있습니다.

여기에 코드를 게시하고 있습니다. 누군가를 도울 수 있습니다.

여기에 사용되는 구성 파일을 만드는 또 다른 코드가 있습니다. 모든 원격 키가 필요하지 않기 때문에 모든 원격 키를 매핑하지 않았습니다.

import usb.core
import usb.util
import ConfigParser 
import shlex
import subprocess
import logging

# find our device
diction={
  6402315641282315:'1',
  6402415641282415:'2',
  6402515641282515:'3',
  6402615641282615:'4',
  6402715641282715:'5',
  6402815641282815:'6',
  6402915641282915:'7',
  6403015641283015:'8',
  6403115641283115:'9',
  }



def load_config():
    dict={}
    config = ConfigParser.RawConfigParser()
    config.read('/codes/remote/remote.cfg')

    dict['vendor']=config.getint('Settings','idVendor')

    dict['product']=config.getint('Settings','idProduct')

    dict['interface']=config.getint('Settings', 'interface')

    r=config.options('Key Mappings')

    for item in r:
        if config.get('Key Mappings',item)!='': 
            dict[item]=config.get('Key Mappings',item)
            #print config.get('Key Mappings',item)
    return dict

def pyus():

    try:
        load_log()
        dict=load_config()
        join_int = lambda nums: int(''.join(str(i) for i in nums))
        #print dict

        dev = usb.core.find(idVendor=dict['vendor'], idProduct=dict['product'])
        interface=dict['interface']

        if dev is None:
            raise ValueError('Device not found')

        if dev.is_kernel_driver_active(interface) is True:
                #print "but we need to detach kernel driver"
                dev.detach_kernel_driver(interface)
        #dev.detatch_kernel_driver(interface) 
        # set the active configuration. With no arguments, the first
        # configuration will be the active one
        dev.set_configuration()

        # get an endpoint instance
        cfg = dev.get_active_configuration()
        interface_number = cfg[(0,0)].bInterfaceNumber
        alternate_setting = usb.control.get_interface(dev,interface_number)
        intf = usb.util.find_descriptor(
            cfg, bInterfaceNumber = interface_number,
            bAlternateSetting = alternate_setting
        )

        ep = usb.util.find_descriptor(
            intf,
            # match the first IN endpoint
            custom_match = \
            lambda e: \
                usb.util.endpoint_direction(e.bEndpointAddress) == \
                usb.util.ENDPOINT_IN
        )

        assert ep is not None
        #print 'packet details',ep.bEndpointAddress , ep.wMaxPacketSize

        while 1:
            try:
                data = dev.read(ep.bEndpointAddress, ep.wMaxPacketSize*2,interface,1000)
                data=data.tolist()
                key=join_int(data)
                #print "Key is " , key
                if  key in diction:

                    try:
                        args=shlex.split(dict[diction[key]])
                        #print args
                        p=subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
                        #print "Pressed key is ",diction[key]
                    except:
                        pass


            except usb.core.USBError as e:
                pass
    except:
        pass

pyus()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.