用PB编写流接口驱动

工具: 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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值