UART를 통해 Open WRT에서 USB HID 신호 미러링 [닫기]

UART를 통해 Open WRT에서 USB HID 신호 미러링 [닫기]

설정: OpenWRT를 실행하는 Linkit 보드(Smart 7688 Duo) 및 USB 호스트에 연결된 범용 키보드.

목표: /dev/input/event0에서 얻은 신호를 덤프하고 보드의 기본 UART를 통해 Atmega32u4로 보냅니다. 따라서 이 Atmega는 연결된 기계에 대한 키보드처럼 작동합니다.

지금까지 내가 얻은 것은 키보드에서 신호를 받아 OpenWRT의 atmega에 직렬로 보내는 것이 어렵지 않다는 것입니다. 그러나 진짜 문제는 Atmega가 실제 키보드처럼 작동하도록 하는 것입니다.

나는 이것을 기반으로 Python 스크립트를 사용합니다.답변데이터 시각화를 단순화하기 위해 직렬을 통해 Arduino IDE 콘솔로 쉽게 보낼 수 있습니다. 그래서 간단한 것을 사용하십시오키보드를 누르세요()Arduino 스케치에 대한 설명 기계의 키를 재현했으며 ATmega는 HID처럼 작동합니다.

그것은 매우 간단해 보이며 여러분이 해야 할 일은 간단한 키 입력을 흉내내는 것뿐입니다. 그러나 동시 키 누르기, 수정자 키, Caps Lock 등 실제 키보드의 모든 기능을 재현하는 것은 까다로웠습니다.

비슷한 것을 시도한 사람이 있습니까?

추신: 내 생각은 Arduino 키보드 클래스를 수정하여 보낼 수 있도록 하는 것입니다.주요 보고서OpenWRT에서 받은 원시 데이터를 처리하려는 방식이지만, 앞서 말했듯이 결과가 매우 복잡합니다. 난 그냥 허락하고 싶지 않아만약에성명수신된 각 데이터 유형에 대해 Atmega에게 일치하는 키를 수행하도록 지시합니다. 단순히 신호를 미러링하는 방법이 있다고 생각합니다.

편집하다:

많은 노력과 시간을 내어 도움을 주신 @dirkt에게 큰 감사를 드립니다. 매우 생산적인 토론이었고 많은 것을 배웠습니다. /dev/hidraw0에서 얻은 보고서가 반대편의 모든 특수 키를 구현한다는 말을 들었을 때 필요한 답변에 가깝습니다.

따라서 수집한 정보로 질문을 바꿔보세요. 키보드에서 [수정자,예약,키,키,키,키,키,키] 형식으로 보고서를 가져오는 방법

/dev/hidraw0은 키와 이벤트(1: 누름 0: 놓음 2: 보류)를 반환하지만 수정자 바이트를 얻는 방법을 모르겠습니다. (지금은 보관하는 것을 잊어버렸습니다)

답변1

부분 답변:

먼저 몇 가지 사항을 정리하겠습니다.

내가 올바르게 이해했다면 OpenWRT는 MPU(MT7688)에서 실행되고 있습니다. MPU는 UART 뒤에 MCU(ATmega)가 있고, MPU에는 범용 USB HID 키보드가 연결되는 USB 컨트롤러가 있다.

커널에서 키 입력은 다음 계층을 통과합니다.

keyboard -> USB -> HID -> input

따라서 키보드는 USB 패킷을 HID 보고 데이터가 포함된 "인터럽트"로 보냅니다. HID 데이터는 HID 설명자에 설명되어 있으며 키보드의 경우 일반적으로 수정자 바이트와 최대 6개의 동시 키 누름이 있습니다. 그러나 다른 형식도 가능합니다. 에서 원시 hid 보고서를 읽을 수 있습니다 /dev/hidrawX. HID 보고서는 개별 키 누름/해제를 포함하는 커널 입력 레이어 이벤트로 변환됩니다 /dev/input/event0.

이는 UART나 그 뒤에 있는 ATmega와는 아무런 관련이 없습니다.

이제 USB가 아닌 다른 버스를 통해 HID 장치를 커널 계층에 연결하는 방법이 여러 가지 있습니다. 예를 들어 I2C 또는 UART를 통해.

너가 원하는게 그거야? 이는 USB 키보드 이벤트의 존재와는 아무 관련이 없습니다 /dev/input/event0.

또 다른 옵션은 ATmega 측에서 원하는 대로 자신만의 개인 프로토콜을 개발하고 다음을 통해 새 입력 계층 장치를 등록하는 작은 C 프로그램을 실행하는 것입니다.입력, UART를 읽은 다음 입력 레이어 이벤트를 보냅니다.

너가 원하는게 그거야? 마찬가지로 USB 키보드 이벤트의 존재 /dev/input/event0나 이러한 이벤트를 UART로 전달하는 것과는 아무런 관련이 없습니다 .

아니면 MPU에서 키보드 이벤트를 가져와 ATmega로 보내고 거기서 처리한 다음 다시 보내고 실제 입력 이벤트로 작동하도록 하시겠습니까? 이는 확실히 가능하지만 MPU에서 이 작업을 수행하지 않는 이유는 무엇인지 스스로에게 물어봐야 합니다.

그럼 제발실제 목표를 설명하세요.. 현재로서는 조금 불분명합니다. Linux 입력 계층을 조작할 수 있고, Linux HID 계층을 조작할 수 있으며, 두 레이어 모두에 이벤트를 삽입하고 원하는 작업을 수행할 수 있습니다. 형식은 특별히 어렵지 않습니다. 당신은 구체적이어야합니다무엇당신이 원하는.

OpenWRT에서 받은 원시 데이터를 사용하여 원하는 방식으로 KeyReports를 보낼 수 있도록 Arduino 키보드 클래스를 수정하세요.

별 의미가 없습니다. 커널 수준에는 "Arduino 키보드 클래스"가 없습니다. 개발 시스템의 일부로 "Arduino 키보드 클래스"를 사용하는 경우협회그것에. 아마도 별로 도움이 되지 않을 것입니다. 다른 형식(HID 보고서, 입력 레이어 이벤트)에 대해서도 알아야 합니다.

편집하다

따라서 요약하자면(다음에 질문할 때 비슷한 방식으로 설명하세요. 질문도 참조하세요.XY 문제):

USB 키보드와 다른 컴퓨터 사이에 중간 장치가 있어야 합니다. 여기서 다른 컴퓨터는 일반 키보드만 볼 수 있고 키로그를 실행하고 다른 이벤트를 트리거할 수 있습니다. (중개 장치가 실제 하드웨어여야 하는지 또는 작업에 도움이 되거나 키보드 이벤트를 추가로 처리하는 장치가 PC에 설치되어 있는지 여부를 지정하지 않았습니다.)

이렇게 하려면 Linkit 보드를 사용하고 싶습니다. Linkit 보드의 MPU는 키보드의 USB 호스트 역할을 합니다. UART를 통해 MCU(ATmega)와 연결되며, MCU 자체가 USB HID 장치 역할을 할 수 있으며, 이를 다시 다른 PC에 연결할 수 있다.

USB HID 장치로 작동하려면 MCU는 세 가지 작업을 수행해야 합니다. 즉, 보고서를 설명하는 HID 설명자가 있어야 하고, HID 키보드 누르기 보고서를 보내야 하며, 다음을 설정하여 PC의 HID 보고서에 반응해야 합니다. 키보드 LED 등 나는 당신이 이 모든 것을 처리하는 ATmega 라이브러리를 가지고 있다고 가정합니다.

가장 쉬운 방법은 실제 USB 키보드에서 HID 설명자를 복사하는 것입니다. /sys/kernel/debug/hid/DEVICE_ID/rdescDEVICE_ID가 키보드를 식별하는 HID 설명자의 사람이 읽을 수 있는 형식을 찾을 수 있습니다 . 시작하는 16진수를 구문 분석하거나 이 정보를 직접 얻을 수 있는 ioctl이 있는지 알아보세요.

그런 다음 ATmega와 통신하기 위해 임시 프로토콜을 사용하는 MPU의 작은 프로그램이 필요합니다. 다음 작업을 수행해야 합니다. (1) USB hid 장치가 연결된 경우 HID 설명자를 읽고 구문 분석한 후 HID 설명자를 ATmega에 보냅니다. (2) 이제 루프에 들어가서 UART를 통해 키보드 번호인 에서 HID 보고서를 전달하고 UART에서 받은 HID 보고서를 작성 /dev/hidrawN합니다 . (3) USB 키보드 연결이 끊어지면 "exit" 메시지를 보냅니다.N/dev/hidrawN

ATmega에서는 사용 가능한 HID 라이브러리를 사용하여 다른 쪽을 구현하려면 작은 프로그램이 필요합니다.

키로깅 등을 구현할 쪽을 선택할 수 있습니다.

동시 키 입력, Caps Lock 등은 모두 HID 보고서를 전달하여 자동으로 처리됩니다.

관련 정보