View
113
Download
0
Category
Preview:
DESCRIPTION
Windows CE .NET Device Driver. 경희대학교 컴퓨터 공학과 조 진 성. 목차. Overview of device driver GPIO_LED device driver 제작 KEYPAD device driver 제작 KEYPAD, GPIO_LED 를 이용한 application 제작. Overview of Device Driver. Device driver. OS 와 application 에게 적절한 인터페이스를 제공한다 . - PowerPoint PPT Presentation
Citation preview
Embedded System Lab. II
Windows CE .NETWindows CE .NETDevice DriverDevice Driver
경희대학교 컴퓨터 공학과조 진 성
Embedded System Lab. II 2
목차
Overview of device driver
GPIO_LED device driver 제작
KEYPAD device driver 제작
KEYPAD, GPIO_LED 를 이용한 application 제작
Embedded System Lab. II
Overview of Device DriverOverview of Device Driver
Embedded System Lab. II 4
Device driver
OS 와 application 에게 적절한 인터페이스를 제공한다 .
Application programmer 는 device driver 를 사용하여 하드웨어에 관한 지식 없이 하드웨어를 사용할 수 있다 .
Embedded System Lab. II 5
WINCE device driver
Application 에서 직접 H/W 제어 불가 제어를 하기 위해서는 device driver 나 커널을 통해서 제어
Device driver 개발 MS “Platform Builder”
네 가지 프로세서를 지원하는 컴파일러 각종 라이브러리 , 소스코드 등을 포함 커널 포팅 및 device driver, Application 같은 모듈 개발
MS “eMbedded Visual C++” : WinCE 용 Native Application 개발 Visual Studio.net 2003 : Managed Application 개발
다른 OS device driver 와 달리 User Mode 에서 동작한다 . dynamic 또는 static 하게 OS 에 링크된다 . 인터럽트를 받는 부분은 커널 소스를 수정하여야 한다 . 커널은 device driver 에게 인터럽트 발생 메시지를 전송한다 .
Embedded System Lab. II 6
WINCE device driver
일반적인 디바이스 드라이버는 디바이스 매니저가 로드 / 관리의 작업수행 용도에 따라 FileSys, GWES 에서 관리 디바이스 매니저가 관리
HKEY_LOCAL_MACHINE\Drivers 레지스트리에 저장 GWES 가 관리
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP 위치
Embedded System Lab. II 7
WINCE device driver 의 종류
Built-in driver Native device driver 전용 디바이스 드라이버 다른 드라이버의 구조에 맞춰서 구현하기가 힘들고 , 정해진 방식대로 ,
정해진 함수들을 구현해야 함 파이프 라인 (Pipeline)
Application 이 WINCE 에서 지원하는 API 를 통해서 device driver 에 접근 정적으로 GWES 에 링크되거나 DLL 로 동작한다 . 이 드라이버는 하드웨어에 완전히 종속적이어서 정해진 인터페이스를
제공하지 않는 경우가 많다 .
Embedded System Lab. II 8
WINCE device driver 의 종류
DrawTextBitBlt
CoreDLL.dll
GWES
DDI.DLLDisplay Driver
DISPLAY(LCD, CRT, …)
Application
DeviceDriver
H/W
OEM,3rd Party
Microsoft
OEM
Built-in driver 구조
Embedded System Lab. II 9
WINCE device driver 의 종류
Installable driver Stream device driver Application 과 device driver 가 데이터를 주고 받는 경우 H/W 를 제어하는 방식이 특정 API 를 통하는 방식
Stream 관련 API : CreateFile, ReadFile, WriteFile 등 User Mode DLL 파일 . 디바이스 매니저 (device.exe) 에 의해 로딩되어 동작한다 . 기본적으로 일관된 인터페이스를 가진다 .
Embedded System Lab. II 10
WINCE device driver 의 종류
Embedded System Lab. II 11
WINCE device driver 의 종류
Layered Driver 일반적인 윈도우 CE 디바이스 드라이버 상위 계층 (upper Layer : MDD)
Module Dependent Driver 각 드라이버들의 공통된 부분의 라이브러리나 소스 공통 모듈
하위 계층 (Lower Layer : PDD) 특정 하드웨어에 맞춰진 코드
Monolithic driver MDD 모듈이 제공되지 않거나 비교적 간단한 드라이버에 적용
Embedded System Lab. II 12
WINCE device driver 의 종류
Embedded System Lab. II 13
Stream device driver
Device 에 상관없이 일관된 인터페이스를 제공한다 .
논리적으로 데이터를 주고받는 device 에 적합하다 .
File system API 와 매치되어 진다 . CreateFile, ReadFile, WriteFile …
디바이스 드라이버 이름은 ‘ COM1’ 같은 형태로 만들어진다 . COM : prefix. 영어 3 문자 . device 종류 구분 1 : index. 한자리 숫자 . device 의 index 레지스트리에 저장되어 있는 값이어야 한다 . 사용시 , ‘COM1:’ 형태로 사용한다 . ‘:’ 를 항상 붙여야 한다 .
Embedded System Lab. II 14
Stream device driver
Embedded System Lab. II 15
드라이버 로드 순서
Device manager(device.exe) 가 시스템에 로드 된다 .
장치열거자 (regenum.dll) 을 이용하여 레지스트리 내 드라이버들을 조사한다 . [HKEY_LOCAL_MACHINE\Drivers\Builtin] 을 검사한다 .
드라이버들의 목록과 초기화할 순서를 만든다 .
레지스트리를 읽어 각각의 드라이버 (DLL 파일 ) 을 로드한다 .
각 드라이버의 Active 키를 생성하고 레지스트리에 저장한다 . [HKEY_LOCAL_MACHINE\Drivers\Active] 에 저장한다 .
xxx_Init 을 통해 드라이버를 초기화 시킨다 .
이후 CreateFile 을 통해 드라이버를 사용한다 .
Embedded System Lab. II
Device Driver Device Driver 제작방법제작방법
Embedded System Lab. II 17
Device driver 제작
기본적으로 필요한 파일 *.c – source file *.def – definition file makefile sources – target name, source files 등을 설정한다 .
Embedded System Lab. II
GPIO_LED device driverGPIO_LED device driver
Embedded System Lab. II 19
작업개요
GPIO 를 이용한 LED device driver 의 제작
PXA255PRO3 board 에 2 개의 led 가 있다 .
2 개의 led 는 GPIO82 와 83 에 연결되어 있다 .
LED 가 10 회 깜박거리는 application 을 만들어 2 개의 led 를 test 한다 .
Embedded System Lab. II 20
[\wince40\platform\PXA255PRO3\drivers\gpio_led]
필요한 모든 파일은 위 디렉토리에 저장한다 .
Embedded System Lab. II 21
gpio_led.c(1)// gpio_led.c#include <windows.h>#include <nkintr.h>#include <drv_glob.h>#include <oalintr.h>
#include "xsc1.h"#include "gpio.h"
#define GPIO_82 0x00040000#define GPIO_83 0x00080000
#define GPIO_LED1 0x01#define GPIO_LED2 0x02
#define LED_ON 1#define LED_OFF 0
Embedded System Lab. II 22
gpio_led.c(2)volatile GPIO_REGS *v_pGPIOReg;
BOOL WINAPIDllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved){
switch ( dwReason ){
case DLL_PROCESS_ATTACH:DEBUGMSG(1, (TEXT("GPIO_LED : DLL_PROCESS_ATTACH\r\n")));DisableThreadLibraryCalls((HMODULE) hInstDll);break;
}
return (TRUE);}
Embedded System Lab. II 23
gpio_led.c(3)//------------------------------------------------------------------------------// Returns context data for this Init instance//// Arguments:// dwContext - registry path for this device's active key////------------------------------------------------------------------------------DWORDLED_Init(DWORD dwContext){
DEBUGMSG(1, (TEXT("GPIO_LED : LED_Init\r\n")));
v_pGPIOReg = (GPIO_REGS *)VirtualAlloc(0, 0x80, MEM_RESERVE, PAGE_NOACCESS);if ( v_pGPIOReg == NULL )
{ ERRORMSG(1, (TEXT("LED_Init: GPIO VirtualAlloc failed!\r\n"))); goto error_return; }
Embedded System Lab. II 24
gpio_led.c(4)if ( !VirtualCopy((PVOID)v_pGPIOReg, (PVOID)GPIO_BASE_U_VIRTUAL, 0x80,
PAGE_READWRITE|PAGE_NOCACHE) ) { ERRORMSG(1, (TEXT("LED_Init: GPIO VirtualCopy failed!\r\n"))); goto error_return; }
DEBUGMSG (1, (TEXT("LED_Init - Success\r\n") ));
v_pGPIOReg->GPDR_z |= GPIO_82 | GPIO_83;v_pGPIOReg->GPSR_z |= GPIO_82 | GPIO_83;
return (TRUE);
error_return:
DEBUGMSG (1, (TEXT("LED_Init - Fail!!\r\n") ));
Embedded System Lab. II 25
gpio_led.c(5)if (v_pGPIOReg)
VirtualFree((PVOID) v_pGPIOReg, 0, MEM_RELEASE);
v_pGPIOReg = NULL;
return (FALSE);
} // LED_Init
//------------------------------------------------------------------------------//------------------------------------------------------------------------------BOOLLED_Close( DWORD Handle ){
return FALSE;} // LED_Close
Embedded System Lab. II 26
gpio_led.c(6)//------------------------------------------------------------------------------//// Device deinit - devices are expected to close down.// The device manager does not check the return code.////------------------------------------------------------------------------------BOOLLED_Deinit( DWORD dwContext // future: pointer to the per disk structure ){
return FALSE;} // LED_Deinit
Embedded System Lab. II 27
gpio_led.c(7)//------------------------------------------------------------------------------//// Returns handle value for the open instance.////------------------------------------------------------------------------------DWORDLED_Open( DWORD dwData, DWORD dwAccess, DWORD dwShareMode ){
DEBUGMSG(1, (TEXT("GPIO_LED : LED_Open\r\n")));
return (TRUE);} // LED_Open
Embedded System Lab. II 28
gpio_led.c(8)DWORD LED_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes){
WORD i;BYTE *pTmp;
pTmp = (BYTE *) pBuffer;
DEBUGMSG(1, (TEXT("GPIO_LED : LED_Write\r\n")));
for(i=0; i<dwNumBytes; i++)DEBUGMSG(1, (TEXT("Write Data[%d] = 0x%x \r\n"), i, pTmp[i] ));
if ( (pTmp[0] & GPIO_LED1) == LED_ON )v_pGPIOReg->GPCR_z |= GPIO_82;
elsev_pGPIOReg->GPSR_z |= GPIO_82;
Embedded System Lab. II 29
gpio_led.c(9)if ( ((pTmp[0] & GPIO_LED2)>>1) == LED_ON )
v_pGPIOReg->GPCR_z |= GPIO_83;else
v_pGPIOReg->GPSR_z |= GPIO_83;
return dwNumBytes;}
Embedded System Lab. II 30
gpio_led.c(10)//------------------------------------------------------------------------------//// I/O Control function - responds to info, read and write control codes.// The read and write take a scatter/gather list in pInBuf////------------------------------------------------------------------------------BOOLLED_IOControl( DWORD Handle, DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned ){
return FALSE;} // LED_IOControl
Embedded System Lab. II 31
gpio_led.c(11)//------------------------------------------------------------------------------//------------------------------------------------------------------------------DWORD LED_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes){return 0;}DWORD LED_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod){return 0;}void LED_PowerUp(void){}void LED_PowerDown(void){}
Embedded System Lab. II 32
gpio_led.defLIBRARY GPIO_LED
EXPORTS LED_InitLED_DeinitLED_OpenLED_CloseLED_ReadLED_WriteLED_SeekLED_IOControlLED_PowerDownLED_PowerUp
Embedded System Lab. II 33
makefile!if 0Copyright (c) Microsoft Corporation. All rights reserved.!endif!if 0Use of this source code is subject to the terms of the Microsoft end-userlicense agreement (EULA) under which you licensed this SOFTWARE PRODUCT.If you did not accept the terms of the EULA, you are not authorized to usethis source code. For a copy of the EULA, please see the LICENSE.RTF on yourinstall media.!endif## DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source# file to this component. This file merely indirects to the real make file# that is shared by all the components of Windows CE.#!INCLUDE $(_MAKEENVROOT)\makefile.def
Embedded System Lab. II 34
sources(1)!if 0Copyright (c) Microsoft Corporation. All rights reserved.!endif!if 0Use of this source code is subject to the terms of the Microsoft end-userlicense agreement (EULA) under which you licensed this SOFTWARE PRODUCT.If you did not accept the terms of the EULA, you are not authorized to usethis source code. For a copy of the EULA, please see the LICENSE.RTF on yourinstall media.!endif
TARGETNAME=gpio_ledRELEASETYPE=PLATFORMTARGETTYPE=DYNLINK
TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.libSOURCELIBS=$(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\drvlib.lib
Embedded System Lab. II 35
sources(2)DEFFILE=gpio_led.def
PREPROCESSDEFFILE=1
DLLENTRY=DllEntry
INCLUDES=..\..\inc
SOURCES=gpio_led.c
Embedded System Lab. II 36
Compile device driver
Platform builder 에서 [Build]->[Open build release directory] 를 선택한다 .
Embedded System Lab. II 37
현재 device driver 를 구현한 directory 로 이동한다 . [SET WINCEREL=1] 을 입력한다 .
위 환경변수를 설정하면 , 자동으로 release directory 에 복사된다 .
[build –cfs] 를 입력한다 .
Embedded System Lab. II 38
Build 가 에러없이 완료되었다 .
Embedded System Lab. II
GPIO LED Test Application GPIO LED Test Application 제작제작
Embedded System Lab. II 40
gpio_led test application
Platform builder 에서 [File]->[New Project or File…] 을 선택한다 .
Embedded System Lab. II 41
[WCE Application] 을 선택한다 . Project Name 에는 적절한 이름을 적은 후 , [OK] 를 선택한다 .
Embedded System Lab. II 42
[A simple Windows CE application] 을 선택한다 . [Finish] 를 선택한다 .
Embedded System Lab. II 43
위와 같이 새로운 project 가 생성된 것을 볼 수 있다 . [Source Files]->[gpio_led_test.cpp] 의 내용을 수정해야 한다 .
Embedded System Lab. II 44
gpio_led_test.cpp(1)// gpio_led_test.cpp : Defines the entry point for the application.//
#include "stdafx.h"
HANDLE g_hLed = INVALID_HANDLE_VALUE;
BOOL BlinkLED(){
BYTE i;BYTE bTmp;DWORD dwWrittenNum;BOOL bIsWritten;
if( g_hLed == INVALID_HANDLE_VALUE )return FALSE;
Embedded System Lab. II 45
gpio_led_test.cpp(2)for( i = 0; i < 4; ++i ){
bTmp = i;
// Write to GPIO_LEDbIsWritten = WriteFile( g_hLed, (LPCVOID)&bTmp, 1, &dwWrittenNum, NULL );
Sleep(100);}
return bIsWritten;}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){
Embedded System Lab. II 46
gpio_led_test.cpp(3)RETAILMSG( 1, (TEXT("gpio_led_test ------\r\n")) );
BYTE bTmp[10];int i;
// open GPIO_LED deviceg_hLed = CreateFile( L"LED1:",
(DWORD)GENERIC_READ | GENERIC_WRITE, 0,(LPSECURITY_ATTRIBUTES) NULL,(DWORD)OPEN_EXISTING, // OPEN_ALWAYS(DWORD)0, // FILE_FLAG_OVERLAPPE
D(HANDLE)NULL );
if( g_hLed == INVALID_HANDLE_VALUE ){
RETAILMSG( 1, (TEXT("CreateFile Error : 0x%x\r\n"), GetLastError() ) );return 0;
}
Embedded System Lab. II 47
gpio_led_test.cpp(4)else
RETAILMSG( 1, (TEXT("CreateFile Sucesss : HANDLE(0x%x)\r\n"), g_hLed ) );
bTmp[0] = 0x00;
// repeat 10 times.for( i = 0; i < 10; ++i ){
// Blink GPIO_LEDif( BlinkLED() == FALSE )
return -1;
Sleep(100);}
return 0;}
Embedded System Lab. II 48
Build gpio_led_test app
Platform builder 에서 [Build]->[Build gpio_led_test.exe] 를 선택한다 .
Embedded System Lab. II 49
에러없이 컴파일이 완료되었다 .
Embedded System Lab. II
Making OS ImageMaking OS Image
Embedded System Lab. II 51
Making OS image
GPIO_LED 를 build 한 다음 , 이 device driver 를 OS image 에 포함 시켜야 한다 .
OS image 에 포함시키기 위해 platform.bib, platform.reg 파일을 변경하여야 한다 .
Embedded System Lab. II 52
platform.reg, platform.bib
[wince40\platform\PXA255Pro3\files\] 밑에 있다 .
Platform.bib (gpio_sw_drvr.dll 아래에 삽입 )
Platform.reg(IF BSP_FPGABOARD 전에 삽입 )
gpio_sw_drvr.dll $(_FLATRELEASEDIR)\gpio_sw_drvr.dll NK SH
gpio_led.dll $(_FLATRELEASEDIR)\gpio_led.dll NK SH
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\GPIO_LED]
“Dll”=“gpio_led.dll”
“Prefix”=“LED”
“Index”=dword:1
“Order”=dword:0
IF BSP_FPGABOARD
Embedded System Lab. II 53
dirs
[WINCE420\PLATFORM\PXA255PRO3\DRIVERS] 에 있다 .
이 파일을 수정함으로써 자동으로 gpio_led.dll 을 생성할 수 있다 .
gpio_sw_drvr \gpio_led \ 추가
Embedded System Lab. II 54
이전 설정을 적용하기 위해 커널 이미지를 다시 빌드해야 한다 .
[Build]->[Rebuild platform] 을 선택한다 .
Embedded System Lab. II 55
OS Image 생성이 완료되었다 .
Embedded System Lab. II
BoardBoard 에 에 DownloadDownload 하기하기
Embedded System Lab. II 57
Board 에 download 하기
먼저 , OS Image 를 board 에 download 한다 .
과정은 이전과 동일하다 .
Embedded System Lab. II 58
Platform builder 가 debugging 모드로 바뀌었다 . [Target]->[Run Programs…] 을 선택한다 .
Embedded System Lab. II 59
Run programs 대화상자가 뜬다 . [gpio_led_test.exe] 파일을 선택하고 , [Run] 을 선택한다 .
Board 와 debugging 메시지를 보며 device driver 가 잘 동작하는지 확인한다 .
Embedded System Lab. II
KEYPAD Device Driver KEYPAD Device Driver 제작제작
Embedded System Lab. II 61
작업개요
GPIO 와 interrupt 를 이용한 key device driver 의 제작
PXA255-PRO board 에 12 개의 key button 이 있다 .
Key 를 눌렀을 때 , interrupt 를 걸어 그에 해당하는 service routine 이 실행되게 한다 .
debugging 창에 key 값을 출력한다 .
작업시 유의사항 Keypad 는 interrupt 를 이용해야 한다 . Interrupt 를 사용하기 위해서는 kernel 을 수정해야 한다 . Application 을 실행할 때 , blocking 방식을 사용하여야 한다 .
Embedded System Lab. II 62
Driver start Application Start
KPD_Init()
KPD_Open()
KPD_Read()
WaitForSingleObject()
Waiting key interrupt
Copy datapBufer = (key value)
InterruptDone()
CreateFile()
ReadFile()
Waiting...
Call KPD_Open()
Call KPD_Read()
ReadFile() blocking
ReadFile() waking
Embedded System Lab. II 63
WINCE 커널에서의 인터럽트 설정
Interrupt ID 등록 WINCE 커널에서는 interrupt 확인을 위해 interrupt ID 를 사용한다 . 최대 32 개 까지 interrupt ID 를 사용할 수 있다 .( 주요한 ID 는 미리 정의됨 ) 다음을 추가한다 .
<\WINCE420\PLATFORM\PXA255PRO3\INC\oalintr.h>
<\WINCE420\PLATFORM\PXA255PRO3\INC\oalintr.inc>
Embedded System Lab. II 64
Interrupt 초기화 및 Enable, Done, Disable 을 구현한다 . WINCE 에서 interrupt handling 은 ISR(interrupt service routine) 에서
이루어지지 않고 , IST(interrupt service thread) 에서 이루어진다 . 따라서 , 디바이스 드라이버에서 인터럽트 초기화가 요구된다 . [\wince420\platform\pxa255pro3\kernel\hal\cfwxsc1.c] 에 다음을 추가한다 .
OEMInterruptEnable() 함수
Embedded System Lab. II 65
OEMInterruptDisable() 함수
OEMInterruptDone() 함수
Embedded System Lab. II 66
Interrupt Service Routine 구현 WinCE 에서 ISR 은 Physical Interrupt number 을 Logical Interrupt(Interru
pt ID) 로 맵을 해준다 . ARM 의경우 Interrupt 를 여러 장치 들이 공유한다 . 따라서 interrupt 요구한 디바이스를 확인해야 한다 . WinCE 의 커널은 device 의 interrupt 요구 시 OEMInterruptHandler()
호출
kernelOEMInterruptHandler()
•Interrupt Pending Reigster 체크•Interrupt 발생지 확인•해당 interrupt ID 리턴
device driverISTdevice driver
ISTdevice driverISTdevice driver
IST
커널은 리턴된 interrupt ID에 따라 event 를 발생
eventInterrupt request
Embedded System Lab. II 67
[\wince420\platform\pxa255pro3\kernel\hal\arm\intxsc1.c] 에 다음을 추가한다 . OEMInterruptHandler() 함수
Embedded System Lab. II 68
[wince40\platform\PXA255PRO3\drivers\keypad\]
필요한 모든 파일은 위 디렉토리에 저장한다 .
드라이버 구동 절차 IST 생성 – CreateThread() 각 레지스터 address 설정 – Keypad_InitializeAddresses() Interrupt 활성화 – Keypad_EnableInterrupt() Interrupt 를 받을 event 생성 – CreateEvent() Interrupt 와 event 를 연결 – InterruptInitialize() ReadFile() 시 event 가 trigger 되면 값 전달 - KPD_Read()
Embedded System Lab. II 69
keypad_drvr.c(1)// keypad.c#include <windows.h>#include <nkintr.h>#include "XSC1.h"#include "XSC1bd.h"#include <drv_glob.h>#include <oalintr.h>#include "bcr.h"
extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
#define PRIVATE static#define PUBLIC
PRIVATE HANDLE gPwrButtonIntrEvent;PRIVATE HANDLE gPwrButtonIntrThread;
PRIVATE volatile GPIO_REGS *v_pGPIOReg = NULL;PRIVATE volatile INTC_REGS *v_pICReg = NULL;
Embedded System Lab. II 70
keypad_drvr.c(2)PRIVATE volatile unsigned char *v_pKeypad = NULL;
PRIVATE VOIDKeypad_EnableInterrupt(VOID){
v_pGPIOReg->GPDR_x &= ~GPIO_0;v_pGPIOReg->GEDR_x = GPIO_0;v_pGPIOReg->GRER_x |= GPIO_0;
INTC_GPIO0_INT_EN (v_pICReg->icmr);
RETAILMSG(1,(TEXT("::: Enable Interrupt of GPIO 0 --- ")));}
PRIVATE BOOLKeypad_IsPushed(VOID){
return ((v_pGPIOReg->GPLR_x & GPIO_0) ? TRUE : FALSE);}
Embedded System Lab. II 71
keypad_drvr.c(3)PRIVATE voidKeypadDeallocateVm(VOID){
if (v_pICReg) {
VirtualFree((void *)v_pICReg,0x400,MEM_RELEASE);v_pICReg = NULL;
}
if (v_pGPIOReg) {
VirtualFree((void *)v_pGPIOReg,0x400,MEM_RELEASE);v_pGPIOReg = NULL;
}
if (v_pKeypad) {
VirtualFree((void *)v_pKeypad,1,MEM_RELEASE);
Embedded System Lab. II 72
keypad_drvr.c(4)v_pKeypad = NULL;
}}
PRIVATE BOOLKeypad_InitializeAddresses(VOID){
BOOL RetValue = TRUE;
if (v_pICReg == NULL) {
v_pICReg = (volatile INTC_REGS *)VirtualAllocCopy(0x400,(char *)TEXT("KeypadEnable: INTC_BASE_U_VIR
TUAL"),(PVOID)INTC_BASE_U_VIRTUAL);
if (v_pICReg) {
if (v_pGPIOReg == NULL) {
Embedded System Lab. II 73
keypad_drvr.c(5)v_pGPIOReg = (volatile GPIO_REGS *)
VirtualAllocCopy(0x400,(char *)TEXT("KeypadEnable: GPIO_BASE_U_VIRTUAL"),
(PVOID)GPIO_BASE_U_VIRTUAL);}
}}
if (v_pKeypad == NULL) {
v_pKeypad = (volatile unsigned char *)VirtualAllocCopy(1,(char *)TEXT("KeypadEnable: IO_BASE_U_VIRTUAL"),(PVOID)IO_BASE_U_VIRTUAL);
}
if ( !v_pGPIOReg|| !v_pICReg || !v_pKeypad ){
KeypadDeallocateVm();DEBUGMSG(1,(TEXT("KeypadEnable(): Error %u\r\n"),GetLastError()));
Embedded System Lab. II 74
keypad_drvr.c(6)return (FALSE);
}
return(TRUE);
}
DWORDKeypad_IntrThread(PVOID pArg){
if (!Keypad_InitializeAddresses()){
RETAILMSG(1, (TEXT("::: Keypad_InitializeAddresses Fail\r\n")));return 0;
}
Keypad_EnableInterrupt();
Embedded System Lab. II 75
keypad_drvr.c(7)gPwrButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!(InterruptInitialize(SYSINTR_KEYPAD, gPwrButtonIntrEvent, 0, 0))) {
RETAILMSG(1, (TEXT("::: SYSINTR_KEYPAD Init Fail\r\n")));}
RETAILMSG(1, (TEXT("::: Interrupt Initialize succeedd on SYSINTR_KEYPAD \r\n")));
while (1) {
// just loop not to exit the program.Sleep(100);
}
return 0; }
Embedded System Lab. II 76
keypad_drvr.c(8)PUBLIC DWORDKPD_Init(DWORD dwContext){
DWORD IDThread;gPwrButtonIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) Keypad_IntrThread,
0, 0, &IDThread);
if ( gPwrButtonIntrThread == NULL ){
RETAILMSG(1, (TEXT("Fatal Error! Failed to create Keypad one Intterupt thread.\r\n")));
return (FALSE);} else {
RETAILMSG(1, (TEXT(" Keypad one Intterupt Init\r\n")));return TRUE;
}return 0;
}
Embedded System Lab. II 77
keypad_drvr.c(9)PUBLIC BOOL WINAPIDllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved){
switch ( dwReason ){case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls((HMODULE) hInstDll);break;
}
return (TRUE);}
BOOLKPD_Close( DWORD Handle ){
return TRUE;} // KPD_Close
Embedded System Lab. II 78
keypad_drvr.c(10)//// Device deinit - devices are expected to close down.// The device manager does not check the return code.//BOOLKPD_Deinit( DWORD dwContext ) // future: pointer to the per disk structure{
return TRUE;} // KPD_Deinit//// Returns handle value for the open instance.//DWORDKPD_Open( DWORD dwData, DWORD dwAccess, DWORD dwShareMode){
return TRUE;} // KPD_Open
Embedded System Lab. II 79
keypad_drvr.c(11)//// I/O Control function - responds to info, read and write control codes.// The read and write take a scatter/gather list in pInBuf//BOOLKPD_IOControl(DWORD Handle, DWORD dwIoControlCode, PBYTE pInBuf,
DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned )
{return FALSE;
} // KPD_IOControl
//-----------------------------------------------------------------------------// Read function.DWORD KPD_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes){
if( dwNumBytes < 1 )return FALSE;
Embedded System Lab. II 80
keypad_drvr.c(12)WaitForSingleObject(gPwrButtonIntrEvent, INFINITE);
if (Keypad_IsPushed()) // To Filter Noise{
Sleep(100);
if (Keypad_IsPushed()){
((BYTE*)pBuffer)[0] = (*v_pKeypad)&0x0f;
RETAILMSG(1,(TEXT(" SYSINTR_KEYPAD !!! ")));}
}InterruptDone(SYSINTR_KEYPAD);
return TRUE;}
Embedded System Lab. II 81
keypad_drvr.c(13)DWORD KPD_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes){
return 0;}DWORD KPD_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod){
return 0;}
void KPD_PowerUp(void){
return;}
void KPD_PowerDown(void){
return;}
Embedded System Lab. II 82
Keypad_drvr.defLIBRARY KEYPAD_DRVR
EXPORTS KPD_InitKPD_DeinitKPD_OpenKPD_CloseKPD_ReadKPD_WriteKPD_SeekKPD_IOControlKPD_PowerDownKPD_PowerUp
Embedded System Lab. II 83
makefile!if 0Copyright (c) Microsoft Corporation. All rights reserved.!endif!if 0Use of this source code is subject to the terms of the Microsoft end-userlicense agreement (EULA) under which you licensed this SOFTWARE PRODUCT.If you did not accept the terms of the EULA, you are not authorized to usethis source code. For a copy of the EULA, please see the LICENSE.RTF on yourinstall media.!endif## DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source# file to this component. This file merely indirects to the real make file# that is shared by all the components of Windows CE.#!INCLUDE $(_MAKEENVROOT)\makefile.def
Embedded System Lab. II 84
sources(1)!if 0Copyright (c) Microsoft Corporation. All rights reserved.!endif!if 0Use of this source code is subject to the terms of the Microsoft end-userlicense agreement (EULA) under which you licensed this SOFTWARE PRODUCT.If you did not accept the terms of the EULA, you are not authorized to usethis source code. For a copy of the EULA, please see the LICENSE.RTF on yourinstall media.!endif
TARGETNAME=keypad_drvrRELEASETYPE=PLATFORMTARGETTYPE=DYNLINK
TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.libSOURCELIBS=$(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\drvlib.lib
Embedded System Lab. II 85
sources(2)DEFFILE=keypad_drvr.def
PREPROCESSDEFFILE=1
DLLENTRY=DllEntry
INCLUDES=..\..\inc
SOURCES=keypad_drvr.c
Embedded System Lab. II 86
Compile device driver
Platform builder 에서 [Build]->[Open build release directory] 를 선택한다 .
Embedded System Lab. II 87
현재 device driver 를 구현한 directory 로 이동한다 . [SET WINCEREL=1] 을 입력한다 .
위 환경변수를 설정하면 , 자동으로 release directory 에 복사된다 .
[build –cfs] 를 입력한다 .
Embedded System Lab. II 88
Build 가 에러없이 완료되었다 .
Embedded System Lab. II
KEYPAD Test ApplicationKEYPAD Test Application
Embedded System Lab. II 90
KEYPAD test application
Platform builder 에서 [File]->[New Project or File…] 을 선택한다 .
Embedded System Lab. II 91
[WCE Application] 을 선택한다 . Project Name 에는 적절한 이름을 적은 후 , [OK] 를 선택한다 .
Embedded System Lab. II 92
[A simple Windows CE application] 을 선택한다 . [Finish] 를 선택한다 .
Embedded System Lab. II 93
위와 같이 새로운 project 가 생성된 것을 볼 수 있다 . [Source Files]->[keypad_test.cpp] 의 내용을 수정해야 한다 .
Embedded System Lab. II 94
keypad_test.cpp(1)// keypad_test.cpp : Defines the entry point for the application.//
#include "stdafx.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ // TODO: Place code here.
HANDLE hKey = INVALID_HANDLE_VALUE;BOOL bIsRead;BYTE bBuf = 0x0;DWORD dwReadBytes;
Embedded System Lab. II 95
keypad_test.cpp(2)// open keypad devicehKey = CreateFile( L"KPD1:",
(DWORD)GENERIC_READ | GENERIC_WRITE, 0,(LPSECURITY_ATTRIBUTES) NULL,(DWORD)OPEN_EXISTING, // OP
EN_ALWAYS(DWORD)0,
// FILE_FLAG_OVERLAPPED(HANDLE)NULL );
if( hKey == INVALID_HANDLE_VALUE ){
RETAILMSG( 1, (TEXT("CreateFile Error : 0x%x\r\n"), GetLastError() ) );return 0;
}else
RETAILMSG( 1, (TEXT("CreateFile Sucesss : HANDLE(0x%x)\r\n"), hKey ) );
Embedded System Lab. II 96
keypad_test.cpp(3)while( bBuf != 0x4 ){
bIsRead = ReadFile( hKey, &bBuf, 1, &dwReadBytes, NULL );
RETAILMSG( 1, (TEXT("Key(0x%x) pressed!!\r\n"),bBuf) );}
return 0;}
Embedded System Lab. II 97
Build keypad_test app
Platform builder 에서 [Build]->[Build keypad_test.exe] 를 선택한다 .
Embedded System Lab. II 98
에러없이 컴파일이 완료되었다 .
Embedded System Lab. II
Making OS ImageMaking OS Image
Embedded System Lab. II 100
Making OS image
Keypad_drvr 를 build 한 다음 , 이 device driver 를 OS image 에 포함 시켜야 한다 .
OS image 에 포함시키기 위해 platform.bib, platform.reg 파일을 변경하여야 한다 .
Embedded System Lab. II 101
platform.reg, platform.bib
[Wince40\platform\PXA255PRO3\files\] 밑에 있다 . 아래의 내용들은 이전 GPIO_LED 에서 설정한 부분에 삽입한다 . Platform.bib
Platform.reg
keypad_drvr.dll $(_FLATRELEASEDIR)\keypad_drvr.dll NK SH
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\KEYPAD]
“Dll”=“keypad_drvr.dll”
“Prefix”=“KPD”
“Index”=dword:1
“Order”=dword:0
Embedded System Lab. II 102
dirs
[WINCE420\PLATFORM\PXA255PRO3\DRIVERS] 에 있다 .
이 파일을 수정함으로써 자동으로 gpio_led.dll 을 생성할 수 있다 .
gpio_sw_drvr \gpio_led \keypad \ 추가
Embedded System Lab. II 103
이전 설정을 적용하기 위해 커널 이미지를 다시 빌드해야 한다 .
[Build]->[Rebuild platform] 을 선택한다 .
Embedded System Lab. II 104
OS Image 생성이 완료되었다 .
Embedded System Lab. II
BoardBoard 에 에 DownloadDownload 하기하기
Embedded System Lab. II 106
Board 에 download 하기
먼저 , OS Image 를 board 에 download 한다 .
과정은 이전과 동일하다 .
Embedded System Lab. II 107
Platform builder 가 debugging 모드로 바뀌었다 . [Target]->[Run Programs…] 을 선택한다 .
Embedded System Lab. II 108
Run programs 대화상자가 뜬다 . [keypad_test.exe] 파일을 선택하고 , [Run] 을 선택한다 .
Board 와 debugging 메시지를 보며 device driver 가 잘 동작하는지 확인한다 .
Embedded System Lab. II
KEYPAD, GPIO_LEDKEYPAD, GPIO_LED 를 이용한 를 이용한 applicationapplication제작제작
Embedded System Lab. II 110
GPIO_LED, KEYPAD test app
Platform builder 에서 [File]->[New Project or File…] 을 선택한다 .
Embedded System Lab. II 111
[WCE Application] 을 선택한다 . Project Name 에는 적절한 이름을 적은 후 , [OK] 를 선택한다 .
Embedded System Lab. II 112
[A simple Windows CE application] 을 선택한다 . [Finish] 를 선택한다 .
Embedded System Lab. II 113
위와 같이 새로운 project 가 생성된 것을 볼 수 있다 . [Source Files]->[gpio_led_key.cpp] 의 내용을 수정해야 한다 .
Embedded System Lab. II 114
gpio_led_key.cpp(1)// gpio_led_key.cpp : Defines the entry point for the application.//
#include "stdafx.h"
HANDLE g_hLed = INVALID_HANDLE_VALUE;
BOOL BlinkLED(){
BYTE i;BYTE bTmp;DWORD dwWrittenNum;BOOL bIsWritten;
if( g_hLed == INVALID_HANDLE_VALUE )return FALSE;
Embedded System Lab. II 115
gpio_led_key.cpp(2)for( i = 0; i < 4; ++i ){
bTmp = i;
// write to GPIO_LEDbIsWritten = WriteFile( g_hLed, (LPCVOID)&bTmp, 1, &dwWrittenNum, NULL );
Sleep(100);}
return bIsWritten;}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){
Embedded System Lab. II 116
gpio_led_key.cpp(3) // TODO: Place code here.
HANDLE hKey = INVALID_HANDLE_VALUE;BOOL bIsRead;BYTE bBuf = 0x0;DWORD dwReadBytes;int i;
// open GPIO_LED deviceg_hLed = CreateFile( L"LED1:",
(DWORD)GENERIC_READ | GENERIC_WRITE, 0,(LPSECURITY_ATTRIBUTES) NULL,(DWORD)OPEN_EXISTING, // OPEN_ALWAYS(DWORD)0, // FILE_FLAG_OVERLAPPED(HANDLE)NULL );
if( g_hLed == INVALID_HANDLE_VALUE ){
RETAILMSG( 1, (TEXT("CreateFile(gpio_led) Error : 0x%x\r\n"), GetLastError() ) );return 0;
Embedded System Lab. II 117
gpio_led_key.cpp(4)}else RETAILMSG( 1, (TEXT("CreateFile(gpio_led) Sucesss : HANDLE(0x%x)\r\n"), g_hLed ) );
// open keypad devicehKey = CreateFile( L"KPD1:",
(DWORD)GENERIC_READ | GENERIC_WRITE, 0,(LPSECURITY_ATTRIBUTES) NULL,(DWORD)OPEN_EXISTING, // OPEN_ALWAYS(DWORD)0, // FILE_FLAG_OVERLAPPED(HANDLE)NULL );
if( hKey == INVALID_HANDLE_VALUE ){
RETAILMSG( 1, (TEXT("CreateFile(keypad) Error : 0x%x\r\n"), GetLastError() ) );return 0;
}else
RETAILMSG( 1, (TEXT("CreateFile(keypad) Sucesss : HANDLE(0x%x)\r\n"), hKey ) );
Embedded System Lab. II 118
gpio_led_key.cpp(5)// read keypad and repeat writing to GPIO_LEDwhile( bBuf != 0xB ){
bIsRead = ReadFile( hKey, &bBuf, 1, &dwReadBytes, NULL );
//RETAILMSG( 1, (TEXT("Key(0x%x) pressed!!\r\n"),bBuf) );for( i = bBuf; i >= 0; --i ){
RETAILMSG( 1, (TEXT("remaining count : %d\r\n"), i) );
if( BlinkLED() == FALSE )return -1;
}}return 0;
}
Embedded System Lab. II 119
Build gpio_led_key app
Platform builder 에서 [Build]->[Build gpio_led_key.exe] 를 선택한다 .
Embedded System Lab. II 120
에러없이 컴파일이 완료되었다 .
Embedded System Lab. II
BoardBoard 에 에 DownloadDownload 하기하기
Embedded System Lab. II 122
Board 에 download 하기
먼저 , OS Image 를 board 에 download 한다 .
과정은 이전과 동일하다 .
Embedded System Lab. II 123
Platform builder 가 debugging 모드로 바뀌었다 . [Target]->[Run Programs…] 을 선택한다 .
Embedded System Lab. II 124
Run programs 대화상자가 뜬다 . [gpio_led_key.exe] 파일을 선택하고 , [Run] 을 선택한다 .
Board 와 debugging 메시지를 보며 application 이 잘 동작하는지 확인한다 .
Embedded System Lab. II 125
Debug message 로 application 이 잘 동작하는 것을 확인할 수 있다 .
Recommended