用PB编写流接口驱动

    技术2022-05-11  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] = X/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

     

     


    最新回复(0)