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


찾기
제목 USB 디바이스와 통신하기 위한 어플리케이션 작성 1/2 0  추천하기
작성자 글쓴이 작성일 2014-10-29 16:22:33 조회수 654
   
   

이번엔 어플리케이션에서 어떻게 드라이버를 통해 디바이스와 통신하는지를 살펴보자.

 

이 강좌를 따라올 정도의 행자들이라면

당근빠따 컴퓨터의 COM 포트를 통해 RS232포트를 가진 디바이스와 통신한 경험이 있을 게다.

그 때 어찌 하셨나?

하이퍼터미널 같은 터미널 프로그램을 이용해서 했지요. 라고 대답 하면 본좌 대략 난감하다.

그런 하이퍼터미널 같은 어플리케이션이 어떻게 디바이스와 통신하는지를 물어본 거시기 때문이다.

 

뭐 별거 있나?

CreateFile로 디바이스의 Handle을 얻어온 후,

그 핸들을 함수인자로 주어 ReadFile, WriteFile, DeviceIoCtl로 디바이스에 접근하면 된다.

작업이 끝났다면 당빠 CloseFile을 호출 해 Handle을 반환하면 되고 말이다.

 

Application <-> Device Driver <-> Device 로 이어지는 명령전달 라인을 아주 간략히 설명해 보자.

먼저 어플리케이션에서 위의 함수들을 호출하면

그럼 운영체제의 I/O Manager란 것이

운영체제의 일부인 디바이스 드라이버 모듈을 호출해서 일을 처리하게 하고,

최종적으로 디바이스 드라이버는 디바이스에게 일을 시킨다.

 

그럼 어플리케이션에서 USB 디바이스에게

데이터를 주고 받는 등의 작업을 시키려면 필요한 게 뭘까?

 

우선 CreateFile로 디바이스의 Handle을 얻어오기 위해서는

그 디바이스를 직접 컨트롤 할 드라이버의 "이름"이 필요하다.

 

그리고, ReadFile, WriteFile, DeviceIoCtl을 써서

USB 디바이스에게 구체적인 작업지시를 하려면

디바이스가 알아먹고 처리할 수 있는 명령의 "목록"이 필요하다.

 

 

첫 번째 "이름"이 뭐냐를 자세히 디벼주마.

 

시리얼 통신을 하는 프로그램을 한번이라도 작성해 본 행자들은

CreateFile의 맨 처음 인자에 “\\\\\.\\COM1” 이라고 준 것을 기억할 것이다.

이게 바로 COM포트 1번을 이용해 통신할 때 필요한 드라이버의 "이름"이다.

 

"이름"을 주는 방식은 두 가지가 있는데,

 

하나는 그 이름을 “\\\\\.\\COM1”, “\\\\.\\ezusb-0” 처럼 주는 것이다.

이 방식을 Symbolic Link를 사용한다고 한다.

 

다른 하나는

GUID(Globally Unique Identifier)를 이용하는 방법이다.

위의 Symbolic Link를 사용하는 방법의 문제 점은 이름이 중복될 가능성이 상존한다는 점이다.

생각해 봐라. COM1, ezusb 같은 소위 보기 좋은 이름들은 나 말고 누군가도 생각할 수 있다.

혹시 그대가 어쩌다가~

중복된 이름을 가진 두 장치를 컴퓨터에 설치하고 그 중 하나를 제어하기 위해 CreateFile을 호출하면

운영체제는 어찌해야 될 지 몰라 파랗게 질린 모습을 보여줄지도 모른다.

이와 같은 문제를 극복하기 위해

절대로 리바이벌은 안 한다는 GUID Generator(GUIDGEN.exe)를 사용해

말 그대로 지구상에서(Globally) 유일무이한(Unique) 이름(Identifier)을 맹글어 쓰는 방법이다.

 

 

말이 쫌 길어 졌지만 두 가지 방법 다

어플리케이션에서 운영체제에다가

“야! 나는 이 이름을 가진 디바이스랑 통신 할 거니까 그 디바이스의 Handle을 나한테 넘겨.”

라고 말할 때 그 "이름"을 만드는 방법이다.

 

어느 방법을 사용하느냐 하는 것은 어플리케이션 프로그래머와 디바이스 프로그래머가 상의하기 나름이다.

하지만, Symbolic Link를 사용하는 것은 될수록 피하는 게 좋다.

 

씨바. 난 열라 독창적인 이름을 만들어내고 말테야!

라고 우기는 행자들은 말리지 않겠다. 지금 시간 햇빛도 안 나니 말릴 수 가 없다. -.-;;

다만 본좌는 GUID를 쓸꺼다. :P

 

 

첫번째 "이름"을 디볐으니,

두번째 "목록"을 후빌 차례다.

 

ReadFile, WriteFile, DeviceIoControl을 써서

디바이스에게 작업지시를 할 때, 디바이스가 알아먹고 처리할 수 있는 명령의 "목록"말이다.

 

디바이스를 만들때는 "LED를 켜라"라는 명령을 처리할 수 있는 장치를 만들어 놓고,

"LED를 꺼라"라는 명령을 내려 보내면 디바이스는 어떻게 반응 할 까?

기냥 KIN~하고 생깔지, 폭주해서 자폭해 버릴지는 메누리도 모른다.

폭주 에바

 

따라서 우리는 디바이스가 알아들을 수 있는 명령만 내려 보내야 한다.

어떻게?

먼저 어플리케이션 프로그래머, 드라이버 프로그래머가 머리를 맞대고 상의해서

"내가 A라고 뻐꾸기 날리면 니가 B를 처리한 후 C를 리턴해 주라"라고 합의본 후,

그 결과를 헤더 파일에 정리한다.

마찬가지로 드라이버 프로그래머와 펌웨어 프로그래머도 같은 짓을 해야 한다.

그리고 나서 (예를 들어서)

 

헤더파일에 이렇게 선언해 놓고

#define LED_ON  1

 

요렇게 호출하면

DeviceIoControl(핸들, LED_ON, ...)

드라이버가 알아 듣고 적절한 동작을 위하게 된다.

 

자 이제 이론은 그만하고 실습에 들어가 보자.

이번 목표는 UniFull 보드에 LED 하나를 연결하고

그 LED On/Off를 어플리케이션에서 제어하는 것이다.

 

먼저 어플리케이션을 만들어야 한다.

DOS 모드에서 동작하는 어플리케이션을 만들면 이해하기는 쉽겠지만

쌍팔년도 아니고 바야흐로 21세기를 5년이나 보낸 이 시점에서

그깐 뽀대 안나는 깜장창 보여주기도 뻘쭘해서 MFC를 이용한 윈도우 프로그램으로 맹근다.

 

아직 MFC를 모르는 행자들 미리부터 너무 쫄지 마시라.

강좌의 목표에서 벗어나므로 본좌가 MFC 프로그래밍을 어떻게 하는지 가르쳐 줄 수는 없지만,

그걸 몰라도 전체적인 흐름을 따라잡고,

나중에 필요한 부분의 코드를 손 댈 수 있을 정도는 설명해 준다. 그까이꺼 뭐 대충~.

 

 

기본적으로

UniFull App v1.0은 MFC로 Dialog Base의 프로젝트를 생성 한 후에

리소스 에디터에서 버튼 하나를 추가하고,

그 버튼의 Handling function을 추가한다.

그 과정은 낼 올려 주마.

 

 

자 이제 위의 어플리케이션 소스를 다운 받아 열어 보자.

소스코드를 담고 있는 폴더를 보면

MFC 위저드가 생성한 파일들 외에 본좌가 따로 추가해준 파일들이 있다.

usb100.h

usbdi.h

usbioctl.h

usbiodef.h

wdm.h

그리고 UniFullusr.h

 

맨 아래 파일은 본좌가 만들어 추가해준 헤더파일이다,

요거이 어플리케이션과 드라이버간의 통신에 필요한

드라이버의 "이름"(GUID)과 명령 "목록"(Interface)을 담고 있는 헤더 파일이다.

그 이외 5개의 헤더파일들은 이 프로젝트 내에서 호출하는 함수들을 위한 헤더파일 들이다.

( DDK(Driver Development Kit)에서 복사해 왔다. )

 

 

 

오늘의 하이라이뚜

UniFullDlg.cpp 파일의 OnButtonLED() 멤버함수를 보시라.

행자들의 이해력을 필요로 하는 부분은 오직 이 OnButtonLED() 함수 하나 뿐이다.

"LED ON/OFF" 버튼을 클릭하면 낼롬 이 함수로 뛰어들어온다.

 

 

그런 다음 아래의 절차를 차례로 수행한다.

OpenFile함수에서 우리가 접근하고자 하는 디바이스의 핸들을 얻고,

DeviceIoControl로 디바이스에게 LED를 켜라 또는 꺼라 라고 시키며,

할 일이 다 끝났다면 CloseHandle로 핸들을 반환한다.

 

이게 줄거리의 전부다.

 

어라? 앞서에는 CreateFile로 핸들을 얻는다메?

아잉~ 구라쟁이~.

하는 행자들에게는 박수를. 짝짝짝.

나머지는 육군 호이짜 부대에 입대를 권한다.

호이짜~ 호이짜~

 

 

 

OpenFile함수를 따라 들어가 보면

거기 CreateFile이 있다.

 

 

h = CreateFile ( szCompleteDeviceName,

        GENERIC_WRITE | GENERIC_READ,

        FILE_SHARE_WRITE | FILE_SHARE_READ,

        NULL,

        OPEN_EXISTING,

        0,

        NULL );

 

 

 

뭐 이래저래 장황한 코드가 나오지만

HANDLE OpenFile(…);

BOOL GetUsbDeviceFileName(…);

HANDLE OpenUsbDevice(…);

HANDLE OpenOneDevice(…);

이 네 함수는 CreateFile의 맨 처음 인자를 얻기 위해 필요한 함수들이고,

우리가 손댈 필요가 없다.

 

 

이제 파일(디바이스) 핸들을 얻었으니,

그 핸들을 가지고 디바이스와 통신할 차례이다.

 

bRet = DeviceIoControl( hFile, lLed, NULL, 0, NULL, 0, &dwBytesReturned, NULL );

가 그 코드이다.

 

이 함수에 대한 설명은 MSDN Library를 참조하시라. 꼭 한번 볼 것을 권한다.

 

다른 인자들은 이 예에서는 사용을 안하고,

두 번째 인자 ( DWORD dwIoControlCode )가 우리가 디바이스에게

이 일을 햐쇼. 라고 명령하는 부분이 되겠다.

 

이 코드는 UniFullUsr.h에 선언되어 있는데,

IOCTL_UNIFULL_xxxxx하는 것들이 다 그것들이다.

 

 

여기까지가 UniFull Application 1.0의 소스에 대한 대략적인 설명이다.

 

 

MFC에 익숙하지 않은 행자들을 위해 첨언 하자면

C 콘솔프로그램에서 프로그램을 시작하면 main()문으로 들어가듯이

버튼을 누르면 OnButtonLED()로 들어온다.

라는 정도만 알고,

버튼이 눌렸을 때 처리해야 하는 일은 OnButtonLED() 함수 내에서 처리해 주면 되겠다.

더 자세한 것들은 책 사서 보시라.

 

프로젝트 생성에 대한 자세한 절차는 낼 업뎃한다.

 

댓글달기 회원에게만 댓글 작성 권한이 있습니다. 회원가입하여 정보공유를 하면 좋겠습니다.
첨부파일
답변
  스팸신고 스팸해제
글쓰기
 
이전글 isr.c 2편
다음글 USB 디바이스와 통신하기 위한 어플리케이션 작성 2/2
 
 
| 회사소개 | 이용약관 | 개인정보취급방침 | 이용안내
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