Android USB mode
안드로이드는 USB Accessory 모드와 USB Host 모드를 통하여 USB 주변 기기 및 Android USB Accessory (안드로이드 액세서리 프로토콜로 구현되어있는 하드웨어)를 지원하고 있습니다.
Figure 1. USB Host and Accessory Modes
그림에서 보듯이 Android device는 USB Host 모드와 Accessory 모드(USB Device)를 가질 수 있지만, Android device가 USB Host Mode가 되기 위해서는 몇 가지 제약 조건을 가지게 됩니다.
- H/W에서의 USB host 지원
- Android 3.1 이상에서 USB Host 관련 API 제공
위의 제약 조건 외에도 여러 가지 이유가 있겠지만 Accessory 모드는 USB Device로 동작한다는 것만 알아두시면 되겠습니다.
USB Accessory 모드는 USB Host에서 외부 USB 하드웨어로 역할을 합니다. 그 예로는 도킹 스테이션, 음악장비, 키오스크, 카드 리더기, 로봇 컨트롤러가 될 수 있습니다. USB Accessory 모드는 안드로이드 구동 장치와 함께 작동하도록 설계해야 하며 안드로이드 액세서리 통신 프로토콜(Android accessory communication protocol)을 준수해야 합니다.
USB Host 모드는 안드로이드 장치에서 사용하며 PC와 같이 USB 장치로 연결되어 관리 및 동작하는 USB Host 장치가 있는 상태에서 Accessory USB 디바이스 형태로 연결되게 됩니다. 그 예로는 디지털 카메라, 키보드, 마우스 및 게임 컨트롤러가 되겠습니다.
안드로이드 플랫폼을 탑재한 장치에서 USB Host를 탑재하거나 ADK와 연결되어 동작하는 Accessory 모드일 때 사용하는 프로토콜과 관련 API가 제공됩니다.
Android USB API
우선 USB Accessory 모드 API의 경우, 네임스페이스는 com.android.future.usb와 android.hardware.usb입니다.
|
Class |
Description |
|
UsbManager |
연결된 Accessory에 대한 검사 및 통신을 위해 사용되는 클래스 |
|
UsbAccessory |
USB Accessory 정보를 관리 및 확인하는 클래스 |
사용하는 방법은 추후 실제 ADK를 활용하여 예제를 보여드리도록 하겠습니다. 간단하게 쓰이는 방법은 실제 안드로이드 어플리케이션을 구현 시, 센서 관리자의 초기화 및 설정과 비슷하게 사용됩니다.
Version별 Library 사용 방법
// Android 2.3.4(add-on library) UsbManager획득
UsbManager manager = UsbManager.getInstance(this);
// Android 3.1 UsbAccessory 획득
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Android 2.3.4(add-on library) UsbAccessory 획득
UsbAccessory accessory = UsbManager.getAccessory(intent);
// Android 3.1 UsbAccessory 획득
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
USB Accessory API 사용 시 매니페스트 파일에 추가되어야 할 예입니다. 여기서android.hardware.usb.action.USB_ACCESSORY_ATTACHED를 사용해 원하는 USB 장치가 연결되었을 시, 동작해야 할 메인 Activity를 지정하게 됩니다.
다음은 Res/xml/accessory_filter.xml 파일에 저장되는 내용입니다.
여기에서는 Accessory가 Android Device에 연결되었을 때 Accessory를 구별할 수 있는 ID String을 Android Device에 전송하게 됩니다. 해당 모델 제조 업체 및 버전을 가진 Accessory를 resource에 추가하면 됩니다.
Android Device에 USB accessory가 연결되었을 때, Application이 연결된 Accessory를 지원하는지 확인하고 지원하면 Accessory와의 통신을 설정한다.
1. Accessory attach event를 위한 intent filter를 사용해서 Accessory 연결 확인
2. Accessory와의 통신을 하기 위한 permission 요청
3. Interface endpoint를 통해서 Accessory와 Data를 read, write
USB Host 모드 API의 경우에는 USB Host 장치를 탑재한 안드로이드 장치에서 사용하는 클래스로 PC와 같이USB 장치로 연결되어 관리 및 동작하는 USB Host 장치가 있는 상태에서 Accessory가 USB 디바이스 형태로 연결될 때 이를 관리하기 위해 지원되는 클래스들입니다.
|
Class |
Description |
|
UsbManager |
연결된 Accessory에 대한 검사 및 통신을 위해 사용되는 클래스 |
|
UsbAccessory |
연결된 USB 장치의 정보나 인터페이스 방법, 엔드 포인트 정보에 접근하기 위해 사용되는 클래스 |
|
UsbInterface |
USB 인터페이스 정의 클래스 |
|
UsbEndpoint |
USB 엔드포인트(endpoint)에 관련된 관리 클래스, 엔드포인트는 USB 통신 시 장치 정보 및 각 장치간 데이터를 송수신하는 역할을 담당 |
|
UsbDeviceConnection |
USB 장치와 연결된 정보를 나타낸다. 이 클래스로 동기적/ 비동기적으로 데이터를 송수신할 수 있음 |
|
UsbRequest |
UsbDeviceConnection 클래스를 통해 비동기적으로 통신을 요구할 때 사용 |
|
UsbConstants |
USB 관련 상수와 linux/usb/ch9.h에 정의된 상수를 관리 |
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
...
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
UsbDevice device = deviceList.get("deviceName");
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
...
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next()
// your code
}
위와 같은 형태로 Activity에서 사용됩니다.
우리가 앞으로 보고자 하는 부분은 Accessory 모드에 치중 할 것이기 때문에 Host 모드에 대해서는 간단히 설명하겠습니다.
USB Host 모드에서도 Accessory 모드와 마찬가지로 매니패스트 파일에 추가를 해야하며accessory_filter.xml와 같은 device_filter.xml을 사용하게 됩니다.
<manifest ...>
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
...
<application>
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
</application>
</manifest>
android.hardware.usb.action.USB_DEVICE_ATTACHED를 사용해 원하는 USB 장치가 연결되었을 시, 동작해야 할 메인 액티비티를 지정하게 됩니다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
</resources>
또한 res/xml/device_filter.xml을 통하여 사용하려는 USB의 Accessory의 벤더 및 장치 아이디를 지정하여 원하는 장치가 USB Host로 연결 시 동작하도록 지정하게 됩니다.
USB Host API를 사용한 장치구동은 마치 PC에서 USB 디바이스 드라이버를 설치해 필요한 장치가 연결되면 해당 장치의 장치 아이디를 이용해 제어하는 것과 유사합니다.
Android Open Accessory Development Kit
Android Open Accessory Development Kit(이하 ADK)는 Android의 Accessory를 만들 수 있게 제공되는Target board와 Target board의 동작을 정의하는 command set을 말하게 됩니다.
다시 말해 ADK는 한정된 기능을 실행 할 수 있는 Accessory를 만들고, Accessory기능을 수행 할 수 있는command를 명시해서 Android Device에서 정의된 command로 Accessory를 동작시키는 H/W와command를 말하게 됩니다.
앞으로 사용하게 될 Target board 입니다.
1. Arduino Mega ADK(ATMEL사의 ATmega2560)
http://arduino.cc/en/Main/ArduinoBoardADK
Figure 2. Arduino ADK
2. Hardkernel사의 ODROID-ADK(PIC24F)
http://www.hardkernel.com/renewal_2011/products/prdt_info.php?g_code=G131063014581
Figure 3. ODROID-ADK
다음에는 Target Board를 가지고 Android Application과 H/W의 Firmware 작성법에 대해서 알아보도록 하겠습니다.
다음은 Seeeduino ADK 를 이용하여 직접 테스트해본 결과입니다. 가변저항의 값을 Input, LED를 Output 형태로 구현하여 실제 안드로이드 플랫폼에서 동작해본 것입니다.