125
Embedded System Lab. II Windows CE .NET Windows CE .NET Device Driver Device Driver 경경경경경 경경경 경경경 경 경 경

Windows CE .NET Device Driver

  • Upload
    emmy

  • View
    113

  • Download
    0

Embed Size (px)

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

Page 1: Windows CE .NET Device Driver

Embedded System Lab. II

Windows CE .NETWindows CE .NETDevice DriverDevice Driver

경희대학교 컴퓨터 공학과조 진 성

Page 2: Windows CE .NET Device Driver

Embedded System Lab. II 2

목차

Overview of device driver

GPIO_LED device driver 제작

KEYPAD device driver 제작

KEYPAD, GPIO_LED 를 이용한 application 제작

Page 3: Windows CE .NET Device Driver

Embedded System Lab. II

Overview of Device DriverOverview of Device Driver

Page 4: Windows CE .NET Device Driver

Embedded System Lab. II 4

Device driver

OS 와 application 에게 적절한 인터페이스를 제공한다 .

Application programmer 는 device driver 를 사용하여 하드웨어에 관한 지식 없이 하드웨어를 사용할 수 있다 .

Page 5: Windows CE .NET 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 에게 인터럽트 발생 메시지를 전송한다 .

Page 6: Windows CE .NET Device Driver

Embedded System Lab. II 6

WINCE device driver

일반적인 디바이스 드라이버는 디바이스 매니저가 로드 / 관리의 작업수행 용도에 따라 FileSys, GWES 에서 관리 디바이스 매니저가 관리

HKEY_LOCAL_MACHINE\Drivers 레지스트리에 저장 GWES 가 관리

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP 위치

Page 7: Windows CE .NET Device Driver

Embedded System Lab. II 7

WINCE device driver 의 종류

Built-in driver Native device driver 전용 디바이스 드라이버 다른 드라이버의 구조에 맞춰서 구현하기가 힘들고 , 정해진 방식대로 ,

정해진 함수들을 구현해야 함 파이프 라인 (Pipeline)

Application 이 WINCE 에서 지원하는 API 를 통해서 device driver 에 접근 정적으로 GWES 에 링크되거나 DLL 로 동작한다 . 이 드라이버는 하드웨어에 완전히 종속적이어서 정해진 인터페이스를

제공하지 않는 경우가 많다 .

Page 8: Windows CE .NET Device Driver

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 구조

Page 9: Windows CE .NET Device 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) 에 의해 로딩되어 동작한다 . 기본적으로 일관된 인터페이스를 가진다 .

Page 10: Windows CE .NET Device Driver

Embedded System Lab. II 10

WINCE device driver 의 종류

Page 11: Windows CE .NET 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 모듈이 제공되지 않거나 비교적 간단한 드라이버에 적용

Page 12: Windows CE .NET Device Driver

Embedded System Lab. II 12

WINCE device driver 의 종류

Page 13: Windows CE .NET 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:’ 형태로 사용한다 . ‘:’ 를 항상 붙여야 한다 .

Page 14: Windows CE .NET Device Driver

Embedded System Lab. II 14

Stream device driver

Page 15: Windows CE .NET 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 을 통해 드라이버를 사용한다 .

Page 16: Windows CE .NET Device Driver

Embedded System Lab. II

Device Driver Device Driver 제작방법제작방법

Page 17: Windows CE .NET Device Driver

Embedded System Lab. II 17

Device driver 제작

기본적으로 필요한 파일 *.c – source file *.def – definition file makefile sources – target name, source files 등을 설정한다 .

Page 18: Windows CE .NET Device Driver

Embedded System Lab. II

GPIO_LED device driverGPIO_LED device driver

Page 19: Windows CE .NET 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 한다 .

Page 20: Windows CE .NET Device Driver

Embedded System Lab. II 20

[\wince40\platform\PXA255PRO3\drivers\gpio_led]

필요한 모든 파일은 위 디렉토리에 저장한다 .

Page 21: Windows CE .NET Device Driver

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

Page 22: Windows CE .NET Device Driver

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);}

Page 23: Windows CE .NET Device Driver

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; }

Page 24: Windows CE .NET Device Driver

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") ));

Page 25: Windows CE .NET Device Driver

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

Page 26: Windows CE .NET Device Driver

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

Page 27: Windows CE .NET Device Driver

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

Page 28: Windows CE .NET Device Driver

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;

Page 29: Windows CE .NET Device Driver

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;}

Page 30: Windows CE .NET Device Driver

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

Page 31: Windows CE .NET Device Driver

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){}

Page 32: Windows CE .NET Device Driver

Embedded System Lab. II 32

gpio_led.defLIBRARY GPIO_LED

EXPORTS LED_InitLED_DeinitLED_OpenLED_CloseLED_ReadLED_WriteLED_SeekLED_IOControlLED_PowerDownLED_PowerUp

Page 33: Windows CE .NET Device Driver

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

Page 34: Windows CE .NET Device Driver

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

Page 35: Windows CE .NET Device Driver

Embedded System Lab. II 35

sources(2)DEFFILE=gpio_led.def

PREPROCESSDEFFILE=1

DLLENTRY=DllEntry

INCLUDES=..\..\inc

SOURCES=gpio_led.c

Page 36: Windows CE .NET Device Driver

Embedded System Lab. II 36

Compile device driver

Platform builder 에서 [Build]->[Open build release directory] 를 선택한다 .

Page 37: Windows CE .NET Device Driver

Embedded System Lab. II 37

현재 device driver 를 구현한 directory 로 이동한다 . [SET WINCEREL=1] 을 입력한다 .

위 환경변수를 설정하면 , 자동으로 release directory 에 복사된다 .

[build –cfs] 를 입력한다 .

Page 38: Windows CE .NET Device Driver

Embedded System Lab. II 38

Build 가 에러없이 완료되었다 .

Page 39: Windows CE .NET Device Driver

Embedded System Lab. II

GPIO LED Test Application GPIO LED Test Application 제작제작

Page 40: Windows CE .NET Device Driver

Embedded System Lab. II 40

gpio_led test application

Platform builder 에서 [File]->[New Project or File…] 을 선택한다 .

Page 41: Windows CE .NET Device Driver

Embedded System Lab. II 41

[WCE Application] 을 선택한다 . Project Name 에는 적절한 이름을 적은 후 , [OK] 를 선택한다 .

Page 42: Windows CE .NET Device Driver

Embedded System Lab. II 42

[A simple Windows CE application] 을 선택한다 . [Finish] 를 선택한다 .

Page 43: Windows CE .NET Device Driver

Embedded System Lab. II 43

위와 같이 새로운 project 가 생성된 것을 볼 수 있다 . [Source Files]->[gpio_led_test.cpp] 의 내용을 수정해야 한다 .

Page 44: Windows CE .NET Device Driver

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;

Page 45: Windows CE .NET Device Driver

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){

Page 46: Windows CE .NET Device Driver

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;

}

Page 47: Windows CE .NET Device Driver

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;}

Page 48: Windows CE .NET Device Driver

Embedded System Lab. II 48

Build gpio_led_test app

Platform builder 에서 [Build]->[Build gpio_led_test.exe] 를 선택한다 .

Page 49: Windows CE .NET Device Driver

Embedded System Lab. II 49

에러없이 컴파일이 완료되었다 .

Page 50: Windows CE .NET Device Driver

Embedded System Lab. II

Making OS ImageMaking OS Image

Page 51: Windows CE .NET Device Driver

Embedded System Lab. II 51

Making OS image

GPIO_LED 를 build 한 다음 , 이 device driver 를 OS image 에 포함 시켜야 한다 .

OS image 에 포함시키기 위해 platform.bib, platform.reg 파일을 변경하여야 한다 .

Page 52: Windows CE .NET Device Driver

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

Page 53: Windows CE .NET Device Driver

Embedded System Lab. II 53

dirs

[WINCE420\PLATFORM\PXA255PRO3\DRIVERS] 에 있다 .

이 파일을 수정함으로써 자동으로 gpio_led.dll 을 생성할 수 있다 .

gpio_sw_drvr \gpio_led \ 추가

Page 54: Windows CE .NET Device Driver

Embedded System Lab. II 54

이전 설정을 적용하기 위해 커널 이미지를 다시 빌드해야 한다 .

[Build]->[Rebuild platform] 을 선택한다 .

Page 55: Windows CE .NET Device Driver

Embedded System Lab. II 55

OS Image 생성이 완료되었다 .

Page 56: Windows CE .NET Device Driver

Embedded System Lab. II

BoardBoard 에 에 DownloadDownload 하기하기

Page 57: Windows CE .NET Device Driver

Embedded System Lab. II 57

Board 에 download 하기

먼저 , OS Image 를 board 에 download 한다 .

과정은 이전과 동일하다 .

Page 58: Windows CE .NET Device Driver

Embedded System Lab. II 58

Platform builder 가 debugging 모드로 바뀌었다 . [Target]->[Run Programs…] 을 선택한다 .

Page 59: Windows CE .NET Device Driver

Embedded System Lab. II 59

Run programs 대화상자가 뜬다 . [gpio_led_test.exe] 파일을 선택하고 , [Run] 을 선택한다 .

Board 와 debugging 메시지를 보며 device driver 가 잘 동작하는지 확인한다 .

Page 60: Windows CE .NET Device Driver

Embedded System Lab. II

KEYPAD Device Driver KEYPAD Device Driver 제작제작

Page 61: Windows CE .NET 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 방식을 사용하여야 한다 .

Page 62: Windows CE .NET Device Driver

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

Page 63: Windows CE .NET Device Driver

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>

Page 64: Windows CE .NET Device Driver

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() 함수

Page 65: Windows CE .NET Device Driver

Embedded System Lab. II 65

OEMInterruptDisable() 함수

OEMInterruptDone() 함수

Page 66: Windows CE .NET Device Driver

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

Page 67: Windows CE .NET Device Driver

Embedded System Lab. II 67

[\wince420\platform\pxa255pro3\kernel\hal\arm\intxsc1.c] 에 다음을 추가한다 . OEMInterruptHandler() 함수

Page 68: Windows CE .NET Device Driver

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()

Page 69: Windows CE .NET Device Driver

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;

Page 70: Windows CE .NET Device Driver

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);}

Page 71: Windows CE .NET Device Driver

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);

Page 72: Windows CE .NET Device Driver

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) {

Page 73: Windows CE .NET Device Driver

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()));

Page 74: Windows CE .NET Device Driver

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();

Page 75: Windows CE .NET Device Driver

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; }

Page 76: Windows CE .NET Device Driver

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;

}

Page 77: Windows CE .NET Device Driver

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

Page 78: Windows CE .NET Device Driver

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

Page 79: Windows CE .NET Device Driver

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;

Page 80: Windows CE .NET Device Driver

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;}

Page 81: Windows CE .NET Device Driver

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;}

Page 82: Windows CE .NET Device Driver

Embedded System Lab. II 82

Keypad_drvr.defLIBRARY KEYPAD_DRVR

EXPORTS KPD_InitKPD_DeinitKPD_OpenKPD_CloseKPD_ReadKPD_WriteKPD_SeekKPD_IOControlKPD_PowerDownKPD_PowerUp

Page 83: Windows CE .NET Device Driver

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

Page 84: Windows CE .NET Device Driver

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

Page 85: Windows CE .NET Device Driver

Embedded System Lab. II 85

sources(2)DEFFILE=keypad_drvr.def

PREPROCESSDEFFILE=1

DLLENTRY=DllEntry

INCLUDES=..\..\inc

SOURCES=keypad_drvr.c

Page 86: Windows CE .NET Device Driver

Embedded System Lab. II 86

Compile device driver

Platform builder 에서 [Build]->[Open build release directory] 를 선택한다 .

Page 87: Windows CE .NET Device Driver

Embedded System Lab. II 87

현재 device driver 를 구현한 directory 로 이동한다 . [SET WINCEREL=1] 을 입력한다 .

위 환경변수를 설정하면 , 자동으로 release directory 에 복사된다 .

[build –cfs] 를 입력한다 .

Page 88: Windows CE .NET Device Driver

Embedded System Lab. II 88

Build 가 에러없이 완료되었다 .

Page 89: Windows CE .NET Device Driver

Embedded System Lab. II

KEYPAD Test ApplicationKEYPAD Test Application

Page 90: Windows CE .NET Device Driver

Embedded System Lab. II 90

KEYPAD test application

Platform builder 에서 [File]->[New Project or File…] 을 선택한다 .

Page 91: Windows CE .NET Device Driver

Embedded System Lab. II 91

[WCE Application] 을 선택한다 . Project Name 에는 적절한 이름을 적은 후 , [OK] 를 선택한다 .

Page 92: Windows CE .NET Device Driver

Embedded System Lab. II 92

[A simple Windows CE application] 을 선택한다 . [Finish] 를 선택한다 .

Page 93: Windows CE .NET Device Driver

Embedded System Lab. II 93

위와 같이 새로운 project 가 생성된 것을 볼 수 있다 . [Source Files]->[keypad_test.cpp] 의 내용을 수정해야 한다 .

Page 94: Windows CE .NET Device Driver

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;

Page 95: Windows CE .NET Device Driver

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 ) );

Page 96: Windows CE .NET Device Driver

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;}

Page 97: Windows CE .NET Device Driver

Embedded System Lab. II 97

Build keypad_test app

Platform builder 에서 [Build]->[Build keypad_test.exe] 를 선택한다 .

Page 98: Windows CE .NET Device Driver

Embedded System Lab. II 98

에러없이 컴파일이 완료되었다 .

Page 99: Windows CE .NET Device Driver

Embedded System Lab. II

Making OS ImageMaking OS Image

Page 100: Windows CE .NET Device Driver

Embedded System Lab. II 100

Making OS image

Keypad_drvr 를 build 한 다음 , 이 device driver 를 OS image 에 포함 시켜야 한다 .

OS image 에 포함시키기 위해 platform.bib, platform.reg 파일을 변경하여야 한다 .

Page 101: Windows CE .NET Device Driver

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

Page 102: Windows CE .NET Device Driver

Embedded System Lab. II 102

dirs

[WINCE420\PLATFORM\PXA255PRO3\DRIVERS] 에 있다 .

이 파일을 수정함으로써 자동으로 gpio_led.dll 을 생성할 수 있다 .

gpio_sw_drvr \gpio_led \keypad \ 추가

Page 103: Windows CE .NET Device Driver

Embedded System Lab. II 103

이전 설정을 적용하기 위해 커널 이미지를 다시 빌드해야 한다 .

[Build]->[Rebuild platform] 을 선택한다 .

Page 104: Windows CE .NET Device Driver

Embedded System Lab. II 104

OS Image 생성이 완료되었다 .

Page 105: Windows CE .NET Device Driver

Embedded System Lab. II

BoardBoard 에 에 DownloadDownload 하기하기

Page 106: Windows CE .NET Device Driver

Embedded System Lab. II 106

Board 에 download 하기

먼저 , OS Image 를 board 에 download 한다 .

과정은 이전과 동일하다 .

Page 107: Windows CE .NET Device Driver

Embedded System Lab. II 107

Platform builder 가 debugging 모드로 바뀌었다 . [Target]->[Run Programs…] 을 선택한다 .

Page 108: Windows CE .NET Device Driver

Embedded System Lab. II 108

Run programs 대화상자가 뜬다 . [keypad_test.exe] 파일을 선택하고 , [Run] 을 선택한다 .

Board 와 debugging 메시지를 보며 device driver 가 잘 동작하는지 확인한다 .

Page 109: Windows CE .NET Device Driver

Embedded System Lab. II

KEYPAD, GPIO_LEDKEYPAD, GPIO_LED 를 이용한 를 이용한 applicationapplication제작제작

Page 110: Windows CE .NET Device Driver

Embedded System Lab. II 110

GPIO_LED, KEYPAD test app

Platform builder 에서 [File]->[New Project or File…] 을 선택한다 .

Page 111: Windows CE .NET Device Driver

Embedded System Lab. II 111

[WCE Application] 을 선택한다 . Project Name 에는 적절한 이름을 적은 후 , [OK] 를 선택한다 .

Page 112: Windows CE .NET Device Driver

Embedded System Lab. II 112

[A simple Windows CE application] 을 선택한다 . [Finish] 를 선택한다 .

Page 113: Windows CE .NET Device Driver

Embedded System Lab. II 113

위와 같이 새로운 project 가 생성된 것을 볼 수 있다 . [Source Files]->[gpio_led_key.cpp] 의 내용을 수정해야 한다 .

Page 114: Windows CE .NET Device Driver

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;

Page 115: Windows CE .NET Device Driver

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){

Page 116: Windows CE .NET Device Driver

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;

Page 117: Windows CE .NET Device Driver

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 ) );

Page 118: Windows CE .NET Device Driver

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;

}

Page 119: Windows CE .NET Device Driver

Embedded System Lab. II 119

Build gpio_led_key app

Platform builder 에서 [Build]->[Build gpio_led_key.exe] 를 선택한다 .

Page 120: Windows CE .NET Device Driver

Embedded System Lab. II 120

에러없이 컴파일이 완료되었다 .

Page 121: Windows CE .NET Device Driver

Embedded System Lab. II

BoardBoard 에 에 DownloadDownload 하기하기

Page 122: Windows CE .NET Device Driver

Embedded System Lab. II 122

Board 에 download 하기

먼저 , OS Image 를 board 에 download 한다 .

과정은 이전과 동일하다 .

Page 123: Windows CE .NET Device Driver

Embedded System Lab. II 123

Platform builder 가 debugging 모드로 바뀌었다 . [Target]->[Run Programs…] 을 선택한다 .

Page 124: Windows CE .NET Device Driver

Embedded System Lab. II 124

Run programs 대화상자가 뜬다 . [gpio_led_key.exe] 파일을 선택하고 , [Run] 을 선택한다 .

Board 와 debugging 메시지를 보며 application 이 잘 동작하는지 확인한다 .

Page 125: Windows CE .NET Device Driver

Embedded System Lab. II 125

Debug message 로 application 이 잘 동작하는 것을 확인할 수 있다 .