안경잡이개발자

728x90
반응형

  Teensy BoardUSB 디바이스 개발을 위한 소형 보드(Board)이다. 사실 Teensy에 올라갈 펌웨어 개발 자체를 아두이노(Arduino) IDE를 이용해서 진행하므로, 아두이노 보드랑 사실상 유사하다. Teensy는 USB 디바이스 개발과 관련한 것에 초점이 더 맞추어져 있긴 한데, 아무튼 아두이노랑 기능적으로 비슷한 일을 할 수 있다.

 

  Teensy 3.5나 3.6 버전의 경우 SD 카드 슬롯(Slot)이 있기 때문에 SD 카드를 꽂을 수 있다. 그래서 SD 카드에 있는 파일을 읽거나, 혹은 SD 카드에 파일을 쓰는 것이 가능하다.

 

 

  그렇다면 Teensy Board 자체를 USB Storage처럼 사용할 수 있을까? Teensy Board를 우리의 호스트(PC)에 꽂으면, 호스트 PC가 이를 USB Storage로 인식하여 파일을 주고 받도록 하고 싶다고 가정해보자. 이 때 사용할 수 있는 라이브러리 중에서 MTP (Media Transfer Protocol)이 있다.

 

  MTP란 일종의 USB 클래스 중 하나이다. 하는 역할 자체는 MSC (Mass Storage Class)와 유사한데, 호스트 PC와 많은 양의 데이터를 주고 받기 위해 사용한다. 다만, 기본적으로 Mass Storage는 호스트 PC가 마운트를 하고 나면, 해당 USB 저장 장치에 대해서 절대적인 제어권을 가지게 된다. MSC는 블록 인터페이스 수준에서 동작하기 때문이다. 반면에 MTP는 논리적인 파일 수준의 송수신이 가능하다. 심지어 특정한 파일에 접근할 때는 암호를 입력하도록 설정할 수도 있다. 그래서 호스트 PC에서 특정한 파일만 가져가도록 할 수도 있는 것이다.

 

  아무튼 기본적으로 MTP는 미디어 파일 같은 것을 옮기기 위한 목적으로 설계되었다. Teensy의 경우에는 MTP 라이브러리가 있어서, 이를 이용할 수 있다. 한 번 Teensy Board를 USB 저장 장치처럼 사용해보자.

 

※ Teensyduino에서 MTP Disk 타입 설정 ※

 

  아두이노에서 보드(Board)를 Teensy로 설정하자. 이후에 이러한 Teensyduino에서는 USB Type으로 MTP Disk를 선택할 수 있다. 아래 그림을 확인해보자. 하지만 정작 이렇다할 MTP 라이브러리 사용 예제는 보이지 않는다.

 

 

  애초에 MTP 기능을 이용하기 위해서는 관련 라이브러리가 존재해야 한다. 아두이노 설치 경로인 C:\Program Files (x86)\Arduino에 MTP 라이브러리가 있는지 확인을 해보면, 존재하지 않는다. 그러면 MTP 기능은 어떻게 사용하라는 건지 궁금해진다. 바로 MTP 라이브러리를 '사용자 라이브러리'로 추가해주어야 한다.

 

  기본적으로 다음의 두 라이브러리가 필요하다.

 

  * SDFat 라이브러리: 아두이노 SDFat 라이브러리는 아두이노 기기에 꽂혀 있는 SD 카드의 FAT16/FAT32 파일 시스템에 접근하도록 해주는 기능을 제공하는 라이브러리다.
  * MTP 라이브러리: 아두이노 MTP 라이브러리는 아두이노 기기에 꽂혀 있는 SD 카드에 호스트(Host) PC가 접근할 수 있도록 해주는 인터페이스 기능을 제공하는 라이브러리다.

 

  따라서 두 작업을 해주자.

 

  1) 아두이노 사용자 라이브러리에 SDFat 라이브러리 추가

  2) 아두이노 사용자 라이브러리에 MTP 라이브러리 추가 

 

  일단 두 라이브러리는 별도로 GitHub에 올려 놓았으니, 이를 받아줄 수 있도록 한다.

 

  https://github.com/ndb796/Teensy-MTP-Library

 

  이제 이 두 라이브러리 폴더를 아두이노 스케치북 위치에 저장해주면 된다. 여기에서 스케치(Sketch)란, 아두이노 IDE를 이용해 작성된 프로그램을 의미한다. 사용자 라이브러리 경로(스케치북 경로)는 어디일까? 바로 아두이노에서 [파일] - [환경설정]에 들어가면 된다.

 

  필자의 경우에는 C:\Users\dongbin\Documents\Arduino\libraries에 라이브러리를 넣어주면 된다.

 

 

  이제 해당 경로에 다음과 같이 MTP 라이브러리, SdFat 라이브러리 폴더를 놓아 두었다. 각 라이브러리 폴더에는 규격에 맞게 라이브러리의 내용이 구현되어 있다.

 

 

  이제 다음의 예제 소스코드를 아두이노 IDE에 넣고 실행할 수 있다.

 

/*
  This example demonstrates MTP with blinky using systick interrupt.

  This example tests MTP and SdFat
*/

#include <MTP.h>

MTPStorage_SD storage;
MTPD          mtpd(&storage);


volatile int  status = 0;
volatile bool sdfound = 0;
volatile int  count = 1;

void rtc_seconds_isr() {
    if (count-- == 0) {
        digitalWrite(LED_BUILTIN, status);
        Serial.println("I should be commented out");
        status = !status;
        if (sdfound)
            count = 2;
        else
            count = 1;
    }
}

void setup() {
    Serial.begin(19200);
    pinMode(LED_BUILTIN, OUTPUT);

    RTC_IER |= 0x10;  // Enable seconds IRQ from RTC peripheral
    NVIC_ENABLE_IRQ(IRQ_RTC_SECOND); // Enable seconds IRS function in NVIC
}

void loop() {
    if (SD.begin()) {
        sdfound = true;
        mtpd.loop();
    }
    else {
        sdfound = false;
    }
}

 

  다음과 같이 [스케치] - [업로드]를 눌러서 업로드를 진행할 수 있다. 업로드를 진행하면 경고 메시지가 나올 수 있지만, 다음과 같이 정상적으로 Teensy 프로그램이 업로드된다.

 

 

  이제 이 Teensy Board를 PC에 꽂으면 다음과 같이 MTP 디바이스로 인식하게 된다.

 

 

  만약 컴파일(Compile) 단계에서 다음과 같은 경고 메시지가 나온다면, 경고 메시지를 지우기 위해서는 어떻게 해야 되는지 알아보자.

 

 

  우리가 추가한 MTP.h 라이브러리 파일에서 OpenFileByIndex 함수 부분의 uint8_t mode = O_RDONLY를 oflag_t mode = O_RDONLY로 변경하면 경고 메시지가 사라진다.

 

 

  위와 같이 MTP.h 내용을 수정한 뒤에 다시 컴파일을 하면 다음과 같이 깔끔하게 컴파일이 진행된다.

 

 

※ Teensy에서 MTP 라이브러리가 동작하는 원리 ※

 

  이제 간단히 MTP 라이브러리의 동작 원리를 알아보자. MTP 라이브러리는 동작 과정에서 SDFat 라이브러리를 이용하며, 호스트 PC에서 Teensy Device에 접근하도록 했을 때 호스트 PC 입장에서는 마치 USB Mass Storage와 유사한 기능을 이용하는 것처럼 느끼게 해준다. (실제로는 Teensy의 MTP Interface를 거치는 것이므로, Teensy 입장에서는 공개하고 싶은 파일만 호스트 PC가 접근할 수 있도록 처리할 수 있는 것이다.)

  실제로 MTP 라이브러리의 코드 (MTP.h)를 뜯어 보면, USB 관련 헤더 (이 라이브러리는 아두이노 설치 폴더의 hardware/avr/cores 폴더에 구현되어 있다.)에서 USB 주요 기능을 가져와서 USB 패킷을 주고 받는 방식으로 동작하도록 구현되어 있다. (정확히는 usb_dev.h 파일을 참조한다.)

 

 

  아무튼 이렇게 다른 사람이 만들어 놓은 MTP.h 라이브러리가 있어서, 내 Teensy Board를 손쉽게 MTP 디바이스처럼 만들어 사용할 수 있었다. 이 밖에도 다양한 외부 라이브러리가 있으므로 필요한 것들은 찾아서 붙이면 된다. (만약 없다면, 직접 코어 라이브러리를 작성하면 될 것이다.)

728x90
반응형