로그인 | 회원가입
   이용안내    장바구니    주문조회    마이쇼핑    게시판
상품검색 검색 
아이디  
비밀번호
보안접속 보안접속
회원가입
  아이디찾기
  비밀번호찾기
상품목록
  ARM
  PIC
  AVR
  DSP
  MAXQ
  MSP430
  OTHER
게시판
공지사항
자유게시판
강좌-USB기타
자료실
샘플 기획전
전화: 031-429-0845
팩스: 031-477-1407
운영시간
  09:00 ~ 18:00
 
현재위치: > 게시판 > 강좌-USB기타
강좌-USB기타
USB및 기타자료입니다.


찾기
제목 Setup Data 활용하기 0  추천하기
작성자 글쓴이 작성일 2014-10-29 16:22:33 조회수 357
   
   

오늘도 계속해서 Endpoint 0를 통해 디바이스로 명령을 내려 보내는 일을 해 보자.

저번의 UniFull Firmware v1.1은 Setup Data중에 앞 2byte만을 사용해서 LED를 On/Off했었다.

( 사실상 그 2byte 중에서도 4bit만 쓸 수 있었다. )

 

다들 기억하겠지만 Setup Data는 총 8byte이다.

오늘은 앞부분 2byte를 제외한 나머지 6btye를 디바이스로 명령을 내려 보내는데 활용하는 방법을 배워 보자.

그 예로서 LED를 일정 시간 간격( Delay )으로 켰다 껏다를 일정횟수( Repeat )만큼 반복하는 예제를 만들어 보자.

 

우선 UniFull 보드를 컨트롤 할 어플리케이션을 만들어 보자.

( UniFull Application v1.0에 살을 붙인다. )

( 그리고 버전을 펌웨어와 일치시키기 위해 이 어플리케이션을 UniFull Application v1.2 라고 하겠다. )

 

1. 먼저 UniFull Application v1.0 프로젝트 폴더를 다른 이름으로 복사한다.

 

2. Visual Studio에서 새로 복사한 프로젝트를 연다.

 

2. 다음엔 리소스 에디터에서 메인 Dialog ( IDD_UNIFULL_DIALOG )에 우리의 목적에 맞도록 버튼과 에디트박스를 추가한다.

 

 

 

3. 추가한 리소스들의 Title과 ID를 적절히 바꾸어 준다.

( 오른 버튼 클릭 → Properties )

 

 

 

4. Class Wizard를 사용해서 에디트박스들에 멤버변수를 생성하고, 연결시켜준다.

  ( 메뉴의  View → Class Wizard 클릭 )

 

 

 

5. “Send SETUP Data” 버튼을 더블 클릭해서 이 버튼이 눌리면 실행될 멤버함수를 추가해 준다.

 

 

6. 추가한 OnButtonSendSetup() 멤버함수에 버튼이 눌렸을 때 실행될 코드를 써 넣는다.

 

 

보시다시피 CONTROL_REQUST란 구조체의 usValue, usIndex 멤버에

LED를 키고 끌 간격과 횟수를 넣어 DeviceIoControl을 호출하고 있다.

CONTROL_REQUST란 구조체는 어플리케이션에서 드라이버로 이런 명령 ( IOCTL_UNIFULL_LED_FLICKER )을 내릴 때,

이 목적에 맞도록 데이터를 전송하기 위해

어플리케이션 프로그래머와 드라이버 프로그래머가 합의한 데이터 구조이다.

( 사실 이 회의 강좌만을 위한 구조체라면 더 간단해야 하겠지만, 이 구조체에는 이후의 강의에도 쓸려고 다른 멤버들이 더 들어 있다. )

 

이렇게 어플리케이션에서 시작된 명령은 다음과 같은 패킷들이 되어 USB 케이블을 통해 디바이스로 전송된다.

 

 

그럼 이제 위에서 받은 패킷들을 처리할 펌웨어를 짜 보자.

이전에도 말 했다시피 EP0를 통해 들어오는 명령들은 control_handler()에서 처리해 주면 된다.

 

 

그리고 unifulldev.c를 보면 아래와 같이 define 문이 하나 더 늘어난 것을 볼 수 있다.

#define LED_ON      0x00    

#define LED_OFF 0x01

#define LED_FLICKER 0x02

 

어플리케이션에서 드라이버로 IOCTL_UNIFULL_LED_FLICKER를 내려 보내면,

드라이버에서는 펌웨어로 LED_FLICKER를 내려 보낸다.

이건 프로그래머들 간에 미리 약속된 것이다.

 

 

led_flicker()를 보면 DEVICE_REQUEST란 구조체에서 wValue와 wIndex를 뽑아 쓰고 있는데,

이 또한 어플리케이션에서 IOCTL_UNIFULL_LED_FLICKER라는 명령을 내릴 때

CONTROL_REQUST 구조체에 usValue, usIndex, usLength에 값을 담아 드라이버로 보내면

펌웨어에서는 이 값을 DEVICE_REQUEST 구조체의 wValue, wIndex, wLength에서 넘겨받기로 약속된 것이다.

( 이번 예제에서는 wLength를 사용하지는 않지만, 사용할 수 도 있다. )

 

요약하자면 이 번 예제를 이용하면 어플리케이션에서 어떤 명령을 내릴 때,

UniFull보드로 6byte의 데이터를 추가로 더 넘길 수 있다는 말쌈이닷.

각각의 명령을 나타내는 define문 ( ex. IOCTL_UNIFULL_LED_FLICKER, LED_FLICKER )에서 중요한 건 그 뒤의 숫자이지 이름이 아니므로

이름은 꼴린 대로 바꾸어도 된다.

 

 

이번 예제에서는 명령을 받은 디바이스가 자기 할 일( LED를 지정한 시간간격으로 횟수만큼 깜빡이기 )을 다 끝낸 다음에

single_transmit(0, 0);을 호출하고 있다.

 

우선 single_transmit(0, 0);을 호출하는 것이 무슨 의미인지를 알아보려면 윗 그림을 다시 참조해야 한다.

이번처럼 Data Stage가 없는 Control Transfer는 다음과 같은 순서대로 패킷이 날라 다닌다.

 

 

1. Token Packet : 호스트가 특정 디바이스를 호출한다. 디바이스에게 명령을 내리기 위해서 이다.

( 이 패킷에 디바이스에 할당된 주소가 들어 있고,

디바이스는 항상 토큰 패킷을 주시하고 있다가 자기에게 할당된 번호가 호출되면 반응해야 한다.

물론 이 같은 과정은 D12 칩에서 자동으로 이루어 지므로 우리가 관여하지 않아도 된다. )

 

2. Data Packet : 이어서 호스트는 8byte의 setup data를 날린다.

(그럼 D12의 펌웨어는 이 setup data를 DEVICE_REQUEST 구조체에 담아 control_handler()를 호출해 준다. )

 

3. Handshake Packet : 디바이스는 데이터를 잘 수신했는지 호스트에게 알려야 한다,

( 데이터를 잘 받았다 오바! : ACK,

지금 바쁘니깐 쫌 있다 다시 보내라 오바! NAK

지금 뭔소리 하노? 통 모리겠다. : STALL

중에 하나를 골라 날리면 된다. )

 

4. Token Packet : 호스트가 디바이스를 호출한다. 이번엔 아까 내린 명령을 디바이스가 다 처리했는지 묻기 위함이다.

( 디바이스가 다 처리해서 대답할 때까지 계속 물어본다. 얼렁얼렁 처리해서 대답해야 한다. )

 

5. Data Packet : 디바이스에서 일 다 끝났다고 호스트에게 보고한다.

( 이게 single_transmit(0, 0);을 호출하면 날라가는 패킷이다. 데이터가 없는 데이터 패킷. )

 

6. Handshake Packet : 호스트에서 아까 보낸 Data Packet 잘 받았다고 디바이스에게 알린다.

 

 

이제 single_transmit(0, 0);의 의미를 아셨남?

그렇다면 우리가 single_transmit(0, 0);을 호출하기 전까지는 호스트가 UniFull에게 다른 명령을 보낼 수 없다는 것도 대충 눈치 까셨으리라 믿는다.

우리의 예제에서처럼 LED를 다 깜빡 거릴 동안의 긴 시간 동안 EP0로 날라오는 명령에 응답할 수 없는 이런 상황은 별로 바람직하지 않다.

어떤 경우에도 EP0는 즉각 응답할 수 있어야 한다. 여러 가지 이유들 때문에….

따라서 이 예제는 약간 고쳐져야 한다.

숙제다. 함 해보시라.

( 힌트. Flag를 사용해 메인 루프에서 돌린다. )

( 더 좋은 방법은 타이머를 이용하는 것이다. )

 


댓글달기 회원에게만 댓글 작성 권한이 있습니다. 회원가입하여 정보공유를 하면 좋겠습니다.
첨부파일
답변
  스팸신고 스팸해제
글쓰기
 
이전글 [부록] STALL & USB BUS RESET
다음글 UniFull 펌웨어 소스 정정 및 드라이버 업데이트
 
 
| 회사소개 | 이용약관 | 개인정보취급방침 | 이용안내
Copyright ⓒ 2010 KitKorea All rights reserved.
전화 : 031-429-0845 FAX : 031-477-1407
Contact open@kitkorea.com for more information.
법인명(상호):인터전자 주식회사 주소:14120 경기도 안양시 동안구 흥안대로 112-1 (호계동)
사업자 등록번호 안내 [138-81-28277] / 통신판매업 신고 제 안양 1753호 [사업자정보확인]
개인정보보호책임자 :홍성호(open@kitkorea.com) / 대표자(성명):홍성호
cafe24