USB 장치가 포트에 끼워지면 어떤일이 일어날까

출처 : http://muosys.egloos.com/52055

 

오늘은 USB 디바이스를 USB 포트에 꽂았을 때 어떤 일이 일어나는가에 대해 까발겨 보자.

USB 디바이스를 포트에 끼우면, 우리의 컴퓨터는 새로운 USB 디바이스가 포트에 삽입되었음을 알아차린다.
어떻게 알아차릴까?

알 필요 없다. ㅋㅋㅋ
그딴건 USB Host 컨트롤러, Hub, Function 컨트롤러의 하드웨어와 시스템 소프트웨어를 설계하는 사람들만 알면 된다.
우리는 몰라도 펌웨어 짜는데 아무 애로사항이 없겠다.
그래도 궁금한 행자들은 USB Specification의 xxx Signaling Environment 섹션을 읽어보기 바란다.

컴퓨터가 새로운 USB 장치를 인지하면 젤 먼저 하는 일이 USB 장치에 리셋을 거는 일이다.
여기서 리셋은 행자들이 상상하는 그 리셋이 아니다.
행자들이 알고 있는 그 하드웨어 리셋과 구분하기 위해 이제부터는 “USB 리셋” 이라고 부르겠다.
USB 리셋이 뭐냐하면 USB에 관련된 기능들만 초기화 하는 것을 일컷는다.

구체적으로 FX2에서는 USB 리셋이 걸리면
• Toggle bits are cleared to 0.
• The device address is reset to zero.
• If the Default USB Device is active, the USB configuration and alternate settings are reset to zero.
• The FX2 will renegotiate with the host for high-speed (480 Mbps) mode.

이 딴 일을 한다고 Technical Reference Manual(T.R.M.)에 나와있다.
벌써 눈이 @.@ 되시는가?

걱정마시라.
토글 비트가 뭐고, 디바이스 어드레스는 뭐고, USB configuration과 alternate 세팅은 뭔지 차차 알게 될 것이다.
우쨋든. USB 리셋을 걸고나서 컴퓨터는.
(이제부터 무식하게 컴퓨터라 하지 않고, 쫌 있어 보이도록 “USB 호스트”라 하겠당.)
호스트는 디바이스에게 묻는다.

호스트 : 넌 누구냐?
clip_image001
디바이스 : 전 아무갠뎁쇼.
(자기 이력서를 내민다.)
(* 이 이력서를 device descriptor라고 부른다.)
호스트 : (이력서를 흘낏 보더니 휙 던져버리고)
그래? 그럼 앞으로 니 번호는 3번이다.
앞으로 3번이라고 부르면 째깍째깍 대답해야 헌다. 알긋냐?
디바이스 : 아 네~.
호스트 : 3번! 이력서 함 줘봐라.
디바이스 : (이기~ 이기~ 미칫나?)
아 네~ 여기 있슴돠.
(* 두 번째로 device descriptor를 제출한다.)

-To be Continue-
여기까지가 오늘 설명할 시나리오다.
디바이스의 이력서인 디바이스 디스크립터(device descriptor)에는 다음과 같은 항목들이 들어 있다.

0x18 Descriptor length : 이력서의 총 길이는 18바이트야.
0x01 Decriptor type : 이력서 제목은 “디바이스 디스크립터”
0200 Specification Version (십진수): 난 USB 2.0 장치야.
0x00 Device class
0x00 Device sub-class
0x00 Device sub-sub-class
0x40 Maximum packet size : 난 한번에 64바이트를 보낼 수 있지
0x0547 Vendor ID : 난 0x0547번 회사가 만들었써
0x2131 Product ID : 제품번호 0x2131번이지
0x0000 Product version ID : 펌웨어 버전은 0x0000이고 말이야.
0x01 Manufacturer string index : 회사의 이름을 알고 싶으면 스트링 디스크립터(String Descriptor)의 첫번째 항목을 봐봐봐~
0x02 Product string index : 제품명을 알려면 두번째 껄 보고
0x00 Serial number string index : 글고 내 시리얼 번호에 해당하는 문자열은 없어.
0x01 Number of configurations : 다음장이 있어.

이게 디바이스 디스크립터의 내용이다.
디바이스가 호스트에게 이 디스크립터를 보낼 때는 본좌처럼 친절하게 설명하지 않고,
기냥
18 01 00 02 00 00 00 64… (본좌 16진수로 표기 했다.)
요렇게 보내면 호스트가 알아서 첫번째 바이트 18은 디스크립터의 길이고, 두번째 바이트 01은 이 디스크립터의 타입이 디바이스 디스크립터고, 등등 알아서 해석하게 된다.

왜 호스트가 또라이처럼 두번이나 디바이스 디스크립터를 요구하느냐 하면 첫 번째로 디바이스 디스크립터를 요구했을 때는 딴 것은 안보고 여덟 번째 바이트 즉 0x40만 보고 이 디바이스는 64바이트 단위로 통신을 하는구나 라고 캐치를 하고 담부터는 64바이트에 맞추어 통신을 하게된다.(Control Pipe의 Packet Size)
뭐 행자들이 굳이 알 필요는 없지만… 궁금해 할 꺼 같아서
안 궁금했는가? 쩝.

위의 시나리오를 보면 호스트가 디바이스에게 주소(3번)를 할당하는 씬이 있다.
주소할당이 된 다음부터는 이때 할당된 주소로 디바이스를 호출하게 된다.
디바이스는 자신에게 할당된 주소 외의 명령은 기냥 생까면 된다.

사실 이것도 알 필요 없다.
왜냐면 주소를 할당 받고, 그 주소 말고 다른 주소로 오는 명령을 쌩까는 이 일련의 과정들을 FX2가 자동으로 해 주기 때문이다.
근데 왜 설명을 했느냐?
잘난 척 한번 해보고 싶었다. ㅋㅋㅋ

그럼 주소가 할당되기 전까지는 어떻게 디바이스랑 통신했을까?
0번 주소로 디바이스랑 통신했다.
디바이스가 처음 USB 포트에 끼워지면 무조건 0번지로 오는 명령을 들어야 한다.
부연하자면 처음에는 0번지에 “Endpoint 0”를 통해 통신한다.
떱. 오늘은 뜬구름 잡는 얘기를 너무 많이 한 것 같다.
행자들 머리 아프기 전에 그만 할란다.
USB Initial Enumeration에 관한 자세한 사항은 여기를 참조하시라.
낼은 막판에 또 새로 튀어 나온 이 Endpoint란게 뭔지를 함 뒤벼바야겠다.
지금은 이 첨보는 용어들하며 뭐가 몬지 잘 모르겠지만 몇 번 듣고 나면 윤곽이 서서히 잡힐게다.
걱정마라.

디바이스 디스크립터의 맨 마지막 항목이
0x01 Number of configurations
였다.
이 말은 컨피규레이션 디스크립터(Configuration Descriptor)가 하나 있다는 말이다.
이 컨피규레이션 디스크립터가 모냐 하면(아 한글로 쓰니 댑따 이상하당. 담부턴 기냥 영어로 써야쥐.)
비유를 하자면 디바이스 디스크립터가 사람이라고 하면 Configuration descriptor는 옷 이라고 비유 할 수 있다.
행자들이 날마다 옷을 바꿔 입듯이 디바이스도 배트맨 옷을 입을 수도 있고, 슈퍼맨 옷을 입을 수도 있고 투명 망토도 입을 수 있다.
그런 옷을 갈아 입을 때마다 배트맨도 되고, 슈퍼맨도 되고, 해리포터도 된다는 말쌈이다.

근데 보통은 배트맨은 배트맨 옷만 입고, 슈퍼맨은 슈퍼맨 옷만 입듯이 이 Configuration Descriptor도 보통 디바이스들은 하나씩만 가진다.

이 Configuration 디스크립터도 디바이스 디스크립터처럼 여러 개의 항목을 가지지만, 다 쓸데 없고 주 용도는 파워는 어떻게 공급받으며, 얼마를 소모하는가를 호스트에게 알려주기 위함이다.

보통의 USB 장치는 포트를 통해 전원을 공급받지만, USB 하드디스크처럼 500mA(앞에서 언급했다.)만 가지고는 배가 고픈 식충이들은 외부에서 전원을 공급해주어야 한다.
또, USB 포트를 통해 전원을 공급받는 경우는 자신이 얼마만큼의 전원을 소비하는지를 알려주어야 호스트가 적절하게 대응할 수 있다.

어떤 때는 포트전원만 쓰다가, 어떤 때는 외부전원을 쓰는 디바이스는 당삼 Configuration 디스크립터를 두 개 가진다.
근데, 그런 장치가 있나?
얼렁 생각이 안 나는걸 보니 흔치는 않은 모냥이닷.

이제 우리는 Device Desscriptor와 Configuration Descriptor를 알았다.
그게 다인 것 같은가?
ㅋㅋㅋ
더 있다.
(그림을 클릭해서 휜색 바탕에서 보시라. 배경색땜에 깜장선이 잘 안보인닷.)

clip_image001

보라
두개 외에
Interface Descriptors
Endpoint Descriptors
(String Descriptors)
가 더 있다.

인터페이스 디스크립터(Interface Descriptor)를 설렁 설명하고 오늘의 하이라이뚜 엔드포인트 디스크립터(Endpoint Descriptor)로 넘어가자

인터페이스 디스크립터도 여러 개의 항목을 가지지만 뺄껀 빼고 요점만 설명하면 자기의 직업은 뭔지, 또 자기가 가진 연장은 몇 개인지를 호스트에게 알린다.

디바이스가 Mass Storage Class(저장장치)인지, Human Input Device(입력장치인지) 등등등이 디바이스의 직업이 되겠꼬 연장이라 함은 그 직업을 수행하기 위해 필요한 Endpoint가 되겠따.

쪼기 위의 그림에서 알 수 있듯이 하나의 Configuration Descriptor아래에는 여러 개의 Interface Descriptor가 딸려 있을 수 있다.
이 말은 슈퍼맨이 어떤 때는 신문기자 클라크일 수도 있꼬, 어떤때는 슈퍼맨이 되었다가 크립토나이트 광선을 맞으면 비실이가 되는 것과 같은 이치이다.

USB 디바이스를 하나 만들었는데 이넘이 어떤 때는 이동식 저장장치로, 어떤 때는 USB 카메라로 동작하게끔 하려면 Interface Descriptor를 두 개 써넣어야 하것따.

쫌 더 자세하고 덜 친절한 설명을 보려면 http://www.beyondlogic.org/usbnutshell/usb5.htm#InterfaceDescriptors를 참조하시라.

엔드포인트 디스크립터(Endpoint Descriptor)
이거를 설명할라고 봄부터 소쩍새가 졸라 울었떤 거시다.

엔드포인트 이것은 호스트와 디바이스간의 통신이 이루어지는 실제 통로이다.
당삼 엔드포인트 디스크립터는 이 엔드포인트를 설명한 설명서가 되겠꼬.

벌써 눈치 챘겟지만 이 엔드포인트도 여러 개가 있을 수 있다.
또, USB 장치라면 최소한 하나는 있어야 한다. 이름하야 엔드뽀인뚜 0번

이 0번 엔드포인트(Endpoint)는 디폴트 컨트롤 엔드포인트라고 불리기도 한다.
바로 전 강좌에서 언급했듯이 디바이스가 포트에 끼워지면 호스트가 맨 처음 이 0번 엔드포인트를 통해 디바이스에게 말을 건다.

넌 누구냐?
clip_image002
두번 우려먹으니 썰렁한가? 흠.

이 0번(디폴트 컨트롤) 엔드포인트는 호스트가 디바이스에게 이래라 저래라 명령을 내리는 통로다.
따라서 호스트 말을 듣기 싫으면 이 0번 엔드포인트에서 오는 명령을 생까버리면 된다.
그럼 행자도 짐싸서 회사를 떠나야 할 것이다. ㅋㅋㅋ
짐싸기 싫으면 0번 엔드포인트에서 오는 명령을 재깍재깍 수행하도록 펌웨어를 작성하자. 알~겠느냐~?

엔드포인트의 종류가 네개가 있는데, 하나는 이미 설명한 컨트롤 엔드포인트이고, 나머지는 인터럽트(Interrupt), 벌크(Bulk), 아이소크로너스(Isochronous) 엔드포인트이다.

간단히 설명하자면 컨트롤 엔드포인트는 다른 엔드포인트와는 달리 양방향 통신을 한다.

인터럽트(Interrupt) 엔드포인트는 통신이 도착하면 인터럽트가 걸려서 알려주는 그 인터럽트랑 상관없는 기냥 일정시간 마다 비교적 적은 데이터 량의 통신이 이루어지는 엔드포인트 이다.
USB 키보드, 마우스 이딴거 만들 때 쓰인다.

벌크(Bulk) 엔드포인트는 허벌나게 많은 양의 데이터를 시간구애 받지 않고 정확히 전달하고자 할 때 쓰이는 엔드포인트이다.
대표적으로 USB 저장장치에 활용한다.

아이소크로너스(Isochronous) 엔드포인트는 많은 양의 데이터를 정해진 시간 안에 전달하기 위한 엔드포인트이다.
대신 데이터의 무결성은 보장하지 않는다.
USB 캠, USB 스피커 이딴데 쓴다.
생각해 봐라 USB 캠에서 호스트로 동영상 이미지 전송하는데 한 두 픽셀 깨졌다고 표시나 나겠는가?

더 자세한 것은 필요할 때, 그때 그때 배우도록 하자

사족을 붙이자면 Enpoint를 파이프(Pipe)라 부르기도 한다.

오늘도 역시나 뜬구름 잡는 소리였따만 다음엔 펌웨어 코드로 들어가 보도록 하자.
다들 미리 요걸 따운 받아 설치해 놓자.
링크가 안열리는 행자는 여기로 직접가서 “SETUP_FX2LP_DVK_1004.exe”를 다운받으시라.

그리고, 다운받아서 설치할 때, Keil Complier가 안 설치되 있는 행자들은 그것도 같이 설치하시라.

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: