2012-10-31 4 views
10

그래서 안드로이드 USB 액세서리 API를 구현하여 내 휴대폰을 리눅스를 실행하는 노트북에 연결할 수 있으며 전화를 USB 액세서리 모드로 전환합니다. 그런 다음 액세서리에 액세스하여 열어서 글쓰기를 시작할 수 있습니다. 내 코드는 the documentation의 예와 거의 같습니다. 주요 차이점은 별도의 읽기 및 쓰기 메소드를 사용하고 있으며 JNI를 통해 원시 코드에서 액세스하는 것입니다.안드로이드 USB 액세서리에서 읽기 ENODEV IOException을 던졌습니다

다음은 흥미로운 부분입니다. 2 초 또는 2 초 동안 성공적으로 읽기/쓰기가 완료되면 내 랩톱에서 대량 전송 쓰기가 시작되어 시간 초과 오류가 발생하고 Android 액세서리의 USB 액세서리에 대한 읽기 호출은 ENODEV 오류 코드로 IOException을 발생시킵니다. 이것은 케이블이 여전히 연결되어 있고 UsbManager가 여전히 목록에 액세서리를 나열하고 있으며 여전히 권한이 있습니다.

이상한 점을 추가하기 위해 읽기 루프에 100ms의 잠자기를 넣으면 문제가 근본적으로 사라진다는 것을 발견했습니다. 거기에 수면을하는 것은 단지 끔찍한 진흙 투성이가 아니라 내 앱에 참을 수없는 대기 시간을 가져옵니다. 수면 시간이 낮을수록 해킹의 효과가 적고 잠자기 시간이 10ms 인 곳에서는 효과가 없습니다.

대량 전송을 사용하여 약 20-30kbps의 실시간 데이터를 전송하지만 대량 전송으로는 충분하지 않은 실시간 데이터는 전송하지 않으며 전송 크기의 범위는 약 20에서 50-800 바이트입니다 -30Hz. 그것은 USB의 한계가 될 수 있습니까? 나는 그것에 대한 많은 경험이 없으므로 기본적으로 네트워크 소켓과 거의 같은 것으로 취급하고 있습니다. 더 작은 메시지를 큐에 넣고 덜 자주하지만 더 큰 전송으로 함께 보내야합니까? 작은, 높은 주파수의 대량 전송에 문제가 있습니까? 나는 이것을 살펴볼 것이다. 그러나 나는 기본적으로 여기에서 빨대를 쥐고있다.

하드웨어 :

  • 노트북 우분투 10.04를 실행하고 libusb를 1.0.0을 사용하고 있습니다.
  • 전화는 Galaxy Nexus S 실행중인 Android입니다. 4.1.2.

답변

6

그래도 계속 진행되는 모든 작업을 이해할 수는 없지만 이중 버퍼링을 구현하면 문제가 해결됩니다.

최고 속도로 읽는 자바 안드로이드 앱이 ENODEV 문제에 아무런 문제가 없다는 것을 발견했습니다. 자바 네이티브 인터페이스가 내 문제의 근원이라는 결론을 이끌어 냈습니다.

이전에는 JNI에서 폴링 방식으로 호출 한 메서드에서 직접 UsbAccessory를 읽었습니다. 네이티브 코드에서 자바로, 그리고 자바에서 원래의 안드로이드 커널로의 전환에 관한 모든 것이 분명히 모든 것을 심하게 만들었습니다.

내 수정은 Java 전용 스레드 (JNI 호출 없음)에서 UsbAccessory를 읽고 쓰고 그 데이터를 JNI가 호출하는 메소드에서 읽고 쓸 버퍼링하는 것이 었습니다.

매력처럼 작동하는 것 같습니다. 앞서 간략히 설명했듯이 액세서리 측에서 매우 일관되게 타임 아웃을 보내고, 결국 Android 측에서 IOExeception을 보내고 이제는 IOException도 발생하지 않습니다. 나는 그 행동을 정확히 일으키는 것이 조금 궁금 해서요. 그러나 JNI Kung-fu는 강한 이해가 필요합니다.

관련 문제