用PB编写流接口驱动

来源:互联网 发布:php引号转义函数 编辑:程序博客网 时间:2024/06/07 15:16

工具: PB

过程:

1、  PB中新建工程:File -> New Project or File Name… -> WCE Dynamic~Link Library -> (Enter your project name, for example: “MyDriver”) -> (choose the kind of windows CE dll , there are three choices: “An empty project” to create a new project with nothing; “A simple Windows CE.net DLL project ” to create a simple DLL project with the entry points ; “A DLL that exports some symbols” to create a project with some output functions.)  An empty project -> Finish.

2、  完成流接口驱动程序必须有的接口函数。首先选择一个设备文件名前缀用于表示这个流接口驱动程序的类别,设备文件名是由三个大字字母、一个数字和冒号组成的,例如:“COM1:”、“FDS1:”都是合法的,选择“AAA”作为设备文件名前缀。所有接口函数的代码如下:

#include <windows.h>

#include <tchar.h>

#include <smbus.h>

#include "platform.h"

#include "bceddk.h"

 

#define BUFSIZE 256

#define KEYADDR *((PWORD)0xB9000000)

 

WCHAR achBuffer[BUFSIZE];

DWORD dwAAASysIntr;

HANDLE hAAAInterruptEvent;

HANDLE hAAAInterruptThread;

 

enum {

    IOCTL_SMBUS_READDATA = 0x80002000,  // some arbirary base

    IOCTL_SMBUS_WRITEDATA

};

 

 

BOOL WINAPI DllEntryPoint(HANDLE hinstDLL,

                          DWORD dwReason,

                          LPVOID lpvReserved)

{

    switch(dwReason) {

    case DLL_PROCESS_ATTACH:

        RETAILMSG(1, (TEXT("STRINGS:DLL_PROCESS_ATTACH/n")));

        break;

       

    case DLL_THREAD_ATTACH:

        RETAILMSG(1, (TEXT("STRINGS:DLL_THREAD_ATTACH/n")));

        break;

       

    case DLL_THREAD_DETACH:

        RETAILMSG(1, (TEXT("STRINGS:DLL_THREAD_DETACH/n")));

        break;

       

    case DLL_PROCESS_DETACH:

        RETAILMSG(1, (TEXT("STRINGS:DLL_PROCESS_DETACH/n")));

        break;

       

#ifdef UNDER_CE

    case DLL_PROCESS_EXITING:

        RETAILMSG(1, (TEXT("STRINGS:DLL_PROCESS_EXITING/n")));

        break;

       

    case DLL_SYSTEM_STARTED:

        RETAILMSG(1, (TEXT("STRINGS:DLL_SYSTEM_STARTED/n")));

        break;

#endif

       

    }

   

    return TRUE;

   

}

 

 

DWORD ThreadProc(PVOID pArg)

{

    DWORD           dw;

    WORD                         nKey;

    int             i;

    BYTE            bVk = 'A';

 

 

    while (1) {

        dw = WaitForSingleObject(hAAAInterruptEvent, INFINITE);

        switch(dw) {

        case WAIT_OBJECT_0:

           

            nKey = KEYADDR;

            RETAILMSG(1, (TEXT("AAA9554: psmPCA9554->Data[0] = %02X/r/n"), nKey));

           

            for (i = 0; i < 7; i++)

            {

            if (!(nKey & (1 << i)))

            {

                       bVk = 'A' + i;

                       keybd_event(bVk, 0, 0, 0);

                       //keybd_event(bVk, 0, KEYEVENTF_KEYUP, 0);

                       break;

            }

            }

            ResetEvent(hAAAInterruptEvent);

            InterruptDone(dwAAASysIntr);

            break;

        }

    }

    return 1;

   

}

 

 

DWORD AAA_Init(DWORD dwContext)

{

    DWORD dwRet = 0;

    DWORD dwAAAthreadID;

    int   x = 0;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Init/n")));

   

    // 初始化驱动程序

    memset(achBuffer, 0, BUFSIZE * sizeof(WCHAR));

   

    // 返回一个不为零的数

    dwRet = 1;

   

    dwAAASysIntr = InterruptConnect(Internal, 0, HWINTR_GPIO7, 0);

   

    if (SYSINTR_NOP == dwAAASysIntr) {

        RETAILMSG(1, (TEXT("AAA9554: Can't allocate AAA9554 SYSINTR/r/n")));

        goto ErrorReturn;

       

    }

   

    hAAAInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

   

    if (NULL == hAAAInterruptEvent) {

        RETAILMSG(1, (TEXT("AAA9554: Can't create AAA9554 interrupt event/r/n")));

        goto ErrorReturn;

       

    }

   

    hAAAInterruptThread = CreateThread(NULL, 0, ThreadProc, &x, CREATE_SUSPENDED, &dwAAAthreadID);

    if (NULL == hAAAInterruptThread) {

        RETAILMSG(1, (TEXT("AAA9554: Call to CreateThread failed/r/n")));

        goto ErrorReturn;

    }

   

    CeSetThreadPriority(hAAAInterruptThread, 145);

   

    if (!InterruptInitialize(dwAAASysIntr, hAAAInterruptEvent, NULL, 0)) {

        RETAILMSG(1, (TEXT("AAA9554: Call to InterruptInitialize failed/r/n")));

        goto ErrorReturn;

       

    }

   

    ResumeThread(hAAAInterruptThread);

   

    return dwRet;

   

ErrorReturn:

    dwRet = 0;

    return dwRet;

   

}

 

 

BOOL AAA_Deinit(DWORD hDeviceContext)

{

    BOOL bRet = TRUE;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Deinit/n")));

   

    return bRet;

   

}

 

 

DWORD AAA_Open(DWORD hDeviceContext,

               DWORD AccessCode,

               DWORD ShareMode)

{

    DWORD dwRet = 0;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Open/n")));

   

    // 必须返回一个不为空的句柄

    dwRet = 1;

    return dwRet;

   

}

 

 

BOOL AAA_Close(DWORD hOpenContext)

{

    BOOL bRet = TRUE;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Close/n")));

   

    return bRet;

   

}

 

 

BOOL AAA_IOControl(DWORD hOpenContext,

                   DWORD dwCode,

                   PBYTE pBufIn,

                   DWORD dwLenIn,

                   PBYTE pBufOut,

                   DWORD dwLenOut,

                   PDWORD pdwActualOut)

{

    BOOL bRet = TRUE;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_IOControl/n")));

   

    return bRet;

   

}

 

 

void AAA_PowerDown(DWORD hDeviceContext)

{

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_PowerDown/n")));

   

}

 

 

void AAA_PowerUp(DWORD hDeviceContext)

{

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_PowerUp/n")));

   

}

 

 

DWORD AAA_Read(DWORD hOpenContext,

               LPVOID pBuffer,

               DWORD Count)

{

    DWORD dwRet = 0;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Read/n")));

   

    // 确定读取的字节大小读取数据

    DWORD cbBuffer = wcslen(achBuffer);

    dwRet = min(cbBuffer, Count);

   

    wcsncpy((LPWSTR)pBuffer, achBuffer, dwRet);

   

    // 返回实际读取的字节数

    return dwRet;

   

}

 

 

DWORD AAA_Seek(DWORD hOpenContext,

               long Amount,

               WORD Type)

{

    DWORD dwRet = 0;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Seek/n")));

   

    return dwRet;

   

}

 

 

DWORD AAA_Write(DWORD hOpenContext,

                LPCVOID pBuffer,

                DWORD Count)

{

    DWORD dwRet = 0;

   

    RETAILMSG(1, (TEXT("MYSTRINGS:AAA_Write/n")));

   

    // 确定实际要写入字节的大小,写入数据

    dwRet = min(BUFSIZE, Count);

    wcsncpy(achBuffer, (LPWSTR)pBuffer, dwRet);

   

    // 返回实际写入的字节数

    return dwRet;

   

}

 

3、  编写DEF文件

用记事本创建一个文件名为“AAA.def”的文件,然后把需要导出的接口函数添加进入。

LIBRARY         MyDriver

 

EXPORTS         AAA_Init

                AAA_PowerUp

                AAA_PowerDown

                AAA_Deinit

                AAA_Open

                AAA_Close

                AAA_Read

                AAA_Write

                AAA_Seek

                    AAA_IOControl

EXPORTS段后面列出要从DLL中输出的函数的名称。在LIBRARY后面必须加上要编译文件的实际名。

4、  编写注册表:我们希望驱动程序在系统启动的时候能够自动运行,所以在“HKEY_LOCAL_MACHINE/Drivers/BuiltIn/”下面添加一个自己的注册表项。设备前缀为“AAA”,索引从1开始,驱动程序的文件名为“MyDriver.dll”,根据以上内容编写注册表为:

[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/AAA]

   "Prefix"="AAA"

   "Dll"="MyDriver.dll"

   "Index"=dword:1

       "Order"=dword:0

编写注册表有两种方式:直接修改PB下面的REG文件,自己写一个注册表文件通过添加组件的方式添加到内核中。

5、  编写CEC文件:有了驱动程序和注册表还不能够正确运行,因为它还没有被加入到CEC内核中,添加一个文件到定制的内核中的方法有两种:一是更改BIB文件,另一种是做一个CEC文件添加到PB中。编写CEC文件的方法如下:

PB中:Tools -> CEC Editor… -> In the “CEC 文件编辑器” -> Catalog 右键选择“Insert Feature Group…-> name: MyDriver -> Group: Self Driver -> OK

在这个基础上再加入一个“Feature”,“Build Method”主要完成对定制内核的注册表部分的修改,“BIB File”负责把编译完成的“MyDriver.dll”文件添加到系统内核中去。

步骤:右键“MyDriver-> Insert Catalog Item … -> General标签下: name: MyDriver -> Variables标签下: Name: MODULE_NAME,  Value: MyDriver.dll -> Comatibility标签下 选择CPU 保存为“MyDriver.cec”。

6、  PB下: File -> Manage Catalog Features -> choose the CEC file you create just now: MyDriver.cec  -> press “Import” ->OK

7、  Platform.bib Platform.reg中把 DLL和注册表加进去:

Platform.reg中添加:

#include "$(DRIVERS_DIR)/MyDriver/MyDriver.reg"

Platform.bib中添加:

MyDriver.dll             $(_FLATRELEASEDIR)/MyDriver.dll                          NK SH

 

原创粉丝点击