USB 프로토콜의 전송 형태(Transfer Type)에 대해서 알아보자!
USB 전송 형태(Transfer Type)
USB 프로토콜을 제대로 이해하기 위해서 공부할 것들이 몇 가지 있다.
그 중에서 꼭 알아야 하는 것은 바로 USB의 전송 형태(Transfer Type)이다. 기본적으로 USB 프로토콜은 호스트(PC)와 디바이스(USB 장치)와의 통신에 관한 것이다.
구체적으로 그림과 함께 설명할 예정인데, 참고해야 할 점은 '회색(Gray)' 부분은 호스트(PC)가 보내는 패킷이고, '하얀색(White)' 부분은 디바이스(Device)가 보내는 패킷이다.
1. 등시성 전송(Isochronous Transfer)
첫 번째로 알아 볼 USB 전송 타입은 등시성 전송 타입이다. 이는 데이터의 전송 시간을 보증할 때 사용하는 타입이다. 데이터에 오류가 있어도 재전송을 하지 않으며, 호스트(PC)에서는 등시성 전송을 위해 시간을 스케줄링한다.
일반적으로 이어폰과 같이 실시간으로 데이터를 받아서 송출해야 하는 디바이스에서 사용된다. 생각해 보면, 이어폰처럼 실시간으로 데이터를 주고 받아야 하는 경우에서 데이터에 약간의 오류가 있다고 재전송을 시킬 수는 없을 것이다.
아무튼 등시성 전송은 다음과 같이 토큰 패킷과 데이터 패킷으로 처리된다. 흔히 이어폰의 경우에는 호스트가 OUT 패킷을 보냄으로써 "나 지금 음악 스트림 보낼거야."라고 말한 뒤에, 이어폰 디바이스한테 DATA 패킷을 연달아 보내는 것이다. 여기에서 토큰(Token) 패킷이란, 데이터의 방향을 알려주기 위해 호스트가 디바이스에게 보내는 패킷이다.
참고: OUT 패킷은 말 그대로 호스트 PC가 디바이스에게 보낼 데이터가 있다는 의미이다. 호스트 입장에서 받아야 할 데이터가 있다면 호스트가 먼저 IN 패킷을 보낸 뒤에, 디바이스로부터 데이터를 받게 된다.
2. 인터럽트 전송(Interrupt Transfer)
작은 크기의 데이터를 전달할 때 사용하는 타입이다. 일반적으로 마우스와 같이 클릭할 때만, 일시적으로 호스트(PC)가 데이터를 읽어들이는 경우에서 사용된다. 예시로는 키보드, 마우스 등이 있다.
인터럽트 전송은 말 그대로 비주기적인 형태의 전송이다. 인터럽트 요청은 디바이스에 의해서 차례대로 큐에 담기게 되고, 호스트가 USB 디바이스한테, "너 보내 줄 데이터 있니?"라고 물어보면, 그 때 큐에 담겨진 인터럽트 요청들이 디바이스에서 호스트로 보내진다.
예를 들어 우리가 키보드를 PC에 꽂은 뒤에, 타자를 친다고 가정해보자. 우리가 키보드에 입력한 데이터들은 일시적으로 키보드 디바이스의 내부 메모리 큐에 담기게 되고, 호스트가 폴링(Polling)을 하게 되면 그제서야 호스트에서 우리가 입력했던 문자들을 받아들이게 된다. (여기에서 알 수 있듯이, 호스트 입장에서는 주기적으로 폴링을 해야 한다.) 어느 정도의 주기로 폴링을 할 지는 디바이스의 엔드포인트 디스크립터(Endpoint Descriptor)에 명시되어 있다.
구체적인 과정은 다음과 같다.
▶ IN 토큰 패킷: 호스트가 데이터를 받는 경우이다. 호스트가 IN 패킷을 보내면, 디바이스의 큐에 데이터가 저장된 경우 데이터를 보내주게 된다. 데이터를 잘 받았으면 ACK를 보낸다. 디바이스의 큐가 비어있으면 (인터럽트 메시지가 없으면) 디바이스에서는 NAK를 보낸다. 그리고 오류가 발생한 상황에서는 디바이스가 STALL을 보내는데, 이러면 호스트가 IN 패킷을 다시 보낸다. 군더더기 없이 깔끔하다.
▶ OUT 토큰 패킷: 호스트가 데이터를 보내는 경우이다. 호스트가 디바이스로 데이터를 보내는 경우에는, OUT 패킷을 발행한 뒤에 데이터를 보낸다. 디바이스 입장에서는 데이터를 차례대로 받는데, 이는 엔드포인트 버퍼에 담기게 된다. 아직 이전 패킷을 다 처리하지 못해서 엔드포인트 버퍼가 비어 있지 않다면, 디바이스는 NAK를 보낸다. 마찬가지로 오류 상황일 때는 STALL을 보낸다.
3. 벌크 전송(Bulk Transfer)
대량의 데이터를 신뢰성 있게 전달할 때 사용하는 타입이다. 데이터 패킷 전송 과정에서 오류가 발생하면 재전송을 요구하며, 등시성 전송과는 다르게 전송 속도는 보증하지 않는다. 대표적인 예시로는 USB 저장 장치(Mass Storage)가 있다.
기본적으로 Bulk Transfer와 Interrupt Transfer는 사실상 같은 트랜잭션 형태를 보인다. 그림 자체도 비슷한 걸 확인할 수 있는데, 벌크와 인터럽트의 차이점은 인터럽트에서는 전송요구에 대한 시간의 주기를 설정할 수 있다는 것이다. 즉, 호스트가 주기적으로 폴링을 수행하도록 요구할 수 있다.
예를 들어 우리가 마우스를 클릭했는데 0.2초 뒤에 클릭이 된 것처럼 처리가 된다면 매우 불편할 것이다. 반면에 대용량 파일을 보내는 과정에서 0.2초 정도의 딜레이는 큰 문제가 없을 것이다. 더불어 Bulk Transfer에서는 1번의 트랜잭션으로 데이터가 전부 전송되지 않을 수 있기 때문에, 데이터를 분할해서 트랜잭션을 반복한다.
4. 제어 전송(Control Transfer)
USB 기기에게 명령을 내리거나 상태 관련 연산을 수행하기 위해 사용하는 타입이다. 모든 USB 기기는 제어 전송을 위해 엔드포인트(Endpoint) 0번을 사용하며, 어떤 데이터를 보낼지 또한 USB 규격으로 정해져 있다. 제어 전송의 경우 모든 USB 기기가 사용하는 전송 타입이다. 기본적으로 처음에 USB 디바이스를 PC에 꽂았을 때부터, 제어 전송을 통해 디스크립터(Descriptor) 정보를 받게 되기 때문이다. 이러한 작업들을 수행하는 것이 바로 제어 전송(Control Transfer)이다.
기본적으로 제어 전송은 3가지 단계로 구성된다. 차례대로 설정 단계(Setup Stage), 데이터 단계(Data Stage), 상태 단계(Status Stage)이다.
1) 설정 단계(Setup Stage): 제어 전송에서 가장 기본적인 단계이다. 이 단계는 초기 설정을 수행하며 세 개의 패킷(Token, Data, Handshake)으로 구성된다. 먼저 토큰 패킷으로는 설정을 진행할 Address 정보와 Endpoit 번호가 담기게 된다. 이후에 정확히 어떤 내용을 설정할 것인지 데이터 패킷에 담아서 보낸다. 예를 들어, 처음에 USB 디바이스에 연결된 상태라면 Descriptor 정보를 보내달라는 내용을 데이터 패킷에 담아서 보낼 것이다.
2) 데이터 단계(Data Stage): 데이터 단계는 필요하다면 존재할 수 있다. 만약 데이터 단계가 있다면, 설정 단계에서 '데이터 단계에서 얼마나 많은 패킷이 전달될 지' 미리 설정이 된다. 데이터 단계는 다수의 IN 토큰 (호스트가 데이터를 받는 경우)과 OUT 토큰 (호스트가 데이터를 보내는 경우)으로 구성되는 경우가 많다.
예를 들어 '설정 단계'에서 디바이스에게 Descriptor 정보를 달라는 패킷을 보냈다면, 이 데이터 단계에서는 IN 토큰을 발행해서 디바이스로부터 Descriptor 정보를 받게 된다.
3) 상태 단계(Status Stage): 제어 요청의 처리 상태를 보고하기 위해 사용되는 단계이다. 즉, 정상적으로 제어 전송이 완료되었는지를 확인하는 마지막 단계라고 할 수 있다.
데이터 단계에서 호스트가 IN 토큰을 보냈다면, 호스트 입장에서는 데이터를 모두 다 정상적으로 받았는지 궁금하다. 그래서 OUT 토큰과 길이가 0인 데이터 패킷을 하나 보내서, 디바이스한테 "너 데이터 다 보낸 거야?"라고 물어본다. 그래서 디바이스에서 데이터를 다 보냈다면 호스트에게 ACK를 보냄으로써 현재의 COMMAND가 종료되었음을 알린다. 혹은 NAK를 보내서 아직 더 처리할 게 남았다는 것을 알리게 된다.
반면에 데이터 단계에서 호스트가 OUT 토큰을 보냈다면, 정상적으로 데이터가 다 보내졌는지 확인하기 위해서 IN 토큰을 하나 보내서 디바이스에게 정상적으로 통신이 완료된 건지 물어보는 것이다.
* 상태 단계에서 OUT 토큰을 보내는 경우는 다음과 같다. (데이터 단계에서 호스트가 IN 토큰을 보낸 경우)
* 상태 단계에서 IN 토큰을 보내는 경우는 다음과 같다. (데이터 단계에서 호스트가 OUT 토큰을 보낸 경우)
USB 기기 클래스(Device Class)
USB 기기 클래스에 따라서 사용하는 전송 형태(Transfer Type)에도 차이점이 있다. 앞서 언급했듯이, 마우스나 키보드와 같은 디바이스들은 인터럽트 전송 타입을 많이 사용할 것이다. USB 기기 클래스를 간략히 소개하면 다음과 같은 것들이 있다.
* MSC (Mass Storage Class): USB 외부 저장장치에 대한 클래스로, Bulk Transfer를 사용한다.
* ADC (Audio Device Class): 오디오 장치에 대한 클래스로, Isochronous Transfer를 사용한다.
* HID (Human Interface Device): I/O 장치(키보드, 마우스) 같은 것에 대한 클래스로, Interrupt Transfer를 사용한다.
이외에도 MTP (Media Transfer Protocol)과 같은 클래스도 있다. 이 클래스는 MSC (Mass Storage Class)의 대용으로 사용될 수 있다. 기본적으로 USB 시스템에서는 Host가 주도권을 가지게 되는데, MSC의 경우 호스트가 마운트를 하고 나면, 해당 USB 저장 장치에 대해서 절대적인 제어권을 가진다. MSC는 블록 인터페이스 수준에서 동작하기 때문이다.
반면에 MTP는 논리적인 파일 수준의 송수신이 가능하다. 예를 들어 USB를 MTP로 제공할 때는, 특정 파일에 접근할 때는 암호를 입력하도록 하거나 할 수도 있다. 즉, MTP나 MSC나 모두 내부적으로 Bulk Transfer와 비슷한 기능을 이용하지만 목적 자체가 다르다는 점이 특징이다.
'기타' 카테고리의 다른 글
MTP(Media Transfer Protocol) 라이브러리를 이용하여 Teensy를 USB Storage처럼 사용해보자! (0) | 2020.05.12 |
---|---|
USB(Universal Serial Bus) 프로토콜의 기초 지식 (0) | 2020.05.11 |
SD 카드의 파일(이미지, 동영상)이 삭제되어 있고 정체 불명의 파일(깨진 파일)이 존재할 때, 복구 방법 (5) | 2020.05.06 |
가상 번호 만들어서 카카오톡 계정 2개 사용하기 (+ 카카오톡 계정 전화번호 교체 방법) (2) | 2020.05.05 |
크롬(Chrome) 브라우저가 느리게 동작하거나 인터넷 접속이 안 될 때 해결 방법 모음 (ERR_TIMED_OUT) (3) | 2020.05.05 |