Wince驱动结构分析

来源:互联网 发布:mac能玩gta5吗 编辑:程序博客网 时间:2024/05/18 18:55

作者:Raul.c

转自:http://www.cnblogs.com/Torres_fans/archive/2009/10/11/1580761.html


摘自:http://blog.chinaunix.net/u2/83682/showart.php?id=1911472
摘自:WinCE OAL中的中断处理  http://msdn.microsoft.com/zh-cn/library/ms836807.aspx

对于wince驱动或者linux驱动,或者其他操作系统驱动。基本上就是两个部分,1,访问硬件寄存器。2,编写操作系统接口。从访问硬件上来说,可以有总线驱动,一般的I/O驱动等。从操作系统来说,就wince而言,可以分为,built-driverstream driver,也可以从另外的一个角度,分为 Layered Device Driver Monolithic driver。总之,驱动的叫法和种类很多,一般都要根据具体开发的驱动再仔细研究。其实大多数工作都是要看E文的datasheet,了解硬件的工作原理,对CPU工作方式有一定的理解,问题就不大了。这里简单介绍一下如何编写wince下的stream driver

首先讲一下框架,很简单,按照wince的联机帮助文档,完成下面的接口函数就好了。

XXX_Close (Device Manager)

XXX_Deinit (Device Manager)

XXX_Init (Device Manager)

XXX_IOControl (Device Manager)

XXX_Open (Device Manager)

。。。。

无非就是一些读写IOCTL,POWER管理的接口而已。下面就是写的一个FOO driver从它慢慢谈起。FOO取代了上面函数中的XXX,FOO就是说不明白的意思。呵呵。

实际上,不需要实现上面的所有函数。

 

FOO.h

 

#pragma once

 

 

#define SETFNAME(n)     LPCWSTR pszFname = L##n

 

#define  FOO_DEBUG

 

#ifdef  FOO_DEBUG

 

#define DEBUG_OUT(x,y)    RETAILMSG(x,y)

 

#elif

 

#define  DEBUG_OUT(x,y)

 

 

#endif

 

 

#define       FOO_DEV_NAME L"Foo1:"

 

typedef struct {

    char* pBuffer1;

    char* pBuffer2;

    int nLen;

 

}COPY_STRUCT;

 

 

// {1F9A46C2-F419-4285-A78D-2553023C3C35}

DEFINE_GUID(DEVICE_IFC_FOO_GUID,

0x1f9a46c2, 0xf419, 0x4285, 0xa7, 0x8d, 0x25, 0x53, 0x2, 0x3c, 0x3c, 0x35);

 

 

 

//define IOCTL code

#define       IOCTL_FOO_COPYCMD "

    CTL_CODE(FILE_DEVICE_UNKNOWN ,0x350,METHOD_BUFFERED ,FILE_ANY_ACCESS)

 

#define       IOCTL_FOO_LOCKBUS      "

    CTL_CODE(FILE_DEVICE_UNKNOWN,0x351,METHOD_BUFFERED,FILE_ANY_ACCESS)

 

#define       IOCTL_FOO_UNLOCKBUS "

    CTL_CODE(FILE_DEVICE_UNKNOWN,0x352,METHOD_BUFFERED,FILE_ANY_ACCESS)

 

#define       IOCTL_FOO_XER "

    CTL_CODE(FILE_DEVICE_UNKNOWN,0X353,METHOD_BUFFERED,FILE_ANY_ACCESS)

 

这里面定义了一个GUID,暂时驱动没有使用。还定义了IOCTLcode,代表具体的功能。

 

FOO.C

 

#include <windows.h>

#include <ddkreg.h>

#include <ceddk.h>

#include <nkintr.h>

#include <pm.h>

#include <Mmsystem.h>

#include  "foo.h"

 

#ifdef DEBUG

DBGPARAM dpCurSettings = {

    TEXT("FOO"),

    {

        TEXT("Error"),TEXT("Warning"),TEXT("Init"),TEXT("IST"),

        TEXT("Foo1"),TEXT("Foo2"),TEXT("Fooxx"),TEXT("Fooyy"),

        TEXT(""),TEXT("Resume"),TEXT(""),TEXT(""),

        TEXT(""),TEXT(""),TEXT(""),TEXT(""),

    },

    0x0007   // ZONE_ERROR | ZONE_WARN | ZONE_INIT

};

#endif  // DEBUG

 

 

#define       FOO_DEV_COOKIE     'FooD'

#define       FOO_INS_COOKIE      'FooI'

 

#define       LOCK()                 EnterCriticalSection(cs)

#define UNLOCK()           LeaveCriticalSection(cs)

 

 

typedef struct foo_dev

{

    DWORD   foo_val;

    DWORD   dwCookie;

    long        instance;

 

    //Critical section

//  CRITICAL_SECTION cs;

   

}FOO_DEV;

 

 

typedef struct foo_instance

{

    FOO_DEV  *pDev;

    DWORD   dwCookie;

   

 

}FOO_INSTANCE;

 

 

static  CRITICAL_SECTION cs;

 

BOOL FOO_Deinit(DWORD dwContext);

 

 

 

/**

  * Function FOO_Init

  *

  * Description

  * brief handles initialization of the matrix keypad driver.

  */

DWORD

FOO_Init(DWORD dwContext)

{

    SETFNAME("FOO::Init");

   

 

    DWORD rc = (DWORD)NULL;

 

    FOO_DEV*    pFoo;

 

    pFoo = LocalAlloc(LPTR,sizeof(struct foo_dev));

 

    if(pFoo==NULL)

    {

           DEBUG_OUT(1,(TEXT("Foo_init error,not enough mem!"r"n")));

           goto cleanUp;

    }

 

    //initialize

    pFoo->dwCookie = FOO_DEV_COOKIE;

 

    //initialize the critcal section

    InitializeCriticalSection(&cs);

 

 

    rc = (DWORD)pFoo;

 

 

cleanUp:

    if(rc==0)

    {

           FOO_Deinit((DWORD)pFoo);

           DEBUG_OUT(1,(TEXT("Foo_Init error"r"n")));

    }

 

    return rc;

}

 

 

 

/**

  * Function: FOO_Deinit

  *

  * Description

  * brief handles deinitialization of the remote driver.

  */

BOOL

FOO_Deinit(DWORD dwContext)

{

    SETFNAME("FOO::Deinit");

    FOO_DEV *pDevice = (FOO_DEV*)dwContext;

 

    // Delete critical section

    DeleteCriticalSection(&cs);

 

 

    if(pDevice!=NULL)

           LocalFree(pDevice);

 

    DEBUG_OUT(1,(TEXT("FOO_Deinit"r"n")));

   

    return TRUE;

}

 

 

 

 

/**

  * Function: FOO_Open

  *

  * Description

  *

  * Note

  * This call must succeed for FOO1: to open an IOCTL channel

  */

 

DWORD

FOO_Open(DWORD dwContext, DWORD AccessCode, DWORD ShareMode)

{

    SETFNAME("FOO::Open");

   

    DWORD rc = (DWORD)NULL;

    FOO_DEV *pFoo = (FOO_DEV *)dwContext;

    FOO_INSTANCE   *pIns=NULL;

 

    DEBUG_OUT(1, (TEXT("%s"r"n"), pszFname));

 

    if(pFoo==NULL)

    {

           DEBUG_OUT(1,(TEXT("Open error:error parameter"r"n")));

           goto cleanUp;

    }

 

    pIns = LocalAlloc(LPTR,sizeof(struct foo_instance));

 

    if(pIns==NULL)

    {

           DEBUG_OUT(1,(TEXT("Open error:error parameter"r"n")));

           goto cleanUp;

    }

 

    pIns->dwCookie = FOO_INS_COOKIE;

    pIns->pDev = pFoo;

 

    // Increment number of open instances

    InterlockedIncrement(&pFoo->instance);

 

    rc = (DWORD)pIns;

 

cleanUp:

    if(rc==0)

    {

           DEBUG_OUT(1,(TEXT("Open Failed"r"n")));

    }

   

    return rc;

}

 

 

 

/**

 * Function FOO_Close

  *

  * Description

  * brief Teardown context created by _Open

  */

 

BOOL

FOO_Close(DWORD dwContext)

{

    SETFNAME("FOO::Close");

 

    DWORD rc = 0;

 

    FOO_DEV *pFoo;

    FOO_INSTANCE *pIns =(FOO_INSTANCE*)dwContext;

 

    DEBUG_OUT(1, (TEXT("%s: FOO driver close"r"n"), pszFname));

 

 

    if((pIns==NULL)||(pIns->dwCookie!=FOO_INS_COOKIE))

    {

           DEBUG_OUT(1, (TEXT("Close Foo device error"r"n")));

           return rc;

    }

 

    pFoo = pIns->pDev;

 

    InterlockedDecrement(&pFoo->instance);

 

    //free memory

    LocalFree(pIns);

 

    rc = TRUE;

   

    return rc;

}

 

 

 

 

/**

  * Function FOO_IOControl

  *

  * Description

  * brief process IOCTL's

  */

 BOOL

FOO_IOControl(DWORD dwContext,DWORD dwIOControlCode,

                    PBYTE pInBuf, DWORD nInBufSize,

                    PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)

{

    BOOL bResult = FALSE;

    char* pMap1;

    char* pMap2;

    COPY_STRUCT *pcs;

 

    FOO_INSTANCE   *pIns = (FOO_INSTANCE*)dwContext;

    DEBUG_OUT(1, (

           L"+FOO_IOControl(0x%x, 0x%x, 0x%x, %d, 0x%x, %d, 0x%x)"r"n",

           dwContext, dwIOControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned

           ));

 

    if((pIns==NULL)||(pIns->dwCookie!=FOO_INS_COOKIE))

    {

           DEBUG_OUT(1,(TEXT("Error:FOO_IOControl: Incorrect context parameter"r"n")));

           return bResult;

    }

 

    switch(dwIOControlCode)

    {

           case IOCTL_FOO_COPYCMD:

                 

                  if((pInBuf==NULL))

                  {

                         SetLastError(ERROR_INVALID_PARAMETER);

                         break;

                  }

 

                  pcs = (COPY_STRUCT*)pInBuf;

                 

                  __try{

                         pMap1 =  MapPtrToProcess(pcs->pBuffer1,GetCallerProcess());

                         pMap2 =  MapPtrToProcess(pcs->pBuffer2,GetCallerProcess());

                         DEBUG_OUT(1, (TEXT("+FOO_IOControl(0x%x,0x%x)"r"n"),pcs->pBuffer1,pcs->pBuffer2));

                         DEBUG_OUT(1, (TEXT("After map")));

                         DEBUG_OUT(1, (TEXT("+FOO_IOControl(0x%x,0x%x)"r"n"),pMap1,pMap2));

 

                         memcpy(pMap2,pMap1,pcs->nLen);

 

                         bResult = TRUE;

                         }

                  __except(EXCEPTION_EXECUTE_HANDLER){

                         DEBUG_OUT(1,(TEXT("Exception:FOO_IOCTL"r"n")));

                         break;                         

                  }

                 

                  break;

           case IOCTL_FOO_LOCKBUS:

                  break;

 %


原创粉丝点击