星期一, 6月 14, 2010

Windows CE 5, 6 Device Driver Concept

Windows CE 5, 6 Device Driver Concept

Windows CE Device Driver 依架構可分為 Layered driver 與 Monolithic driver:

Layered driver: divided driver to PDDs and MDDs (MDD 與 PDD 分開)

Monolithic driver: combines all PDDs and MDDs into one driver. (MDD 與 PDD 合在一起)

大部份的 Windows CE Driver 是由 PDD (Platform Dependent Driver) 與 MDD (Model Device Driver) 所組成的.

PDD: Platform Dependent Driver (平台相關驅動, 負責與 MDD 與 Hardware 溝通, 提供 DDSI 給 MDD 呼叫)

MDD: Model Device Driver (邏輯層, 介於 PDD 與 OS 中間, 提供 DDI 給 OS 呼叫)

DDSI (Device Driver Service Provide Interface): 一般由 PDD layer 所提供(expose)給 MDD layer 呼叫使用.

DDI (Device Driver Interface): 由 MDD 提供(expose)給 OS 呼叫的介面.

* Monolithic 理論上不會有 DDSI.

* MDD should not require any modify.
 MDD 提供了標準介面 DDI 給 OS 呼叫如 xxx_Open, xxx_Close, xxx_Init, 並透過 DDSI 來呼叫 PDD 提供的 function.

* PDD may need modify to fit your hardware platform.
 PDD 提供 DDSI functions 給 MDD 呼叫, 但如果是 monolithic driver 則不需要 DDSI, 因為可以直接呼叫函式.

physical devices: network adapters, timers, and universal asynchronous receiver-transmitters (UARTs).

virtual devices: file system.

sream interfaces driver (基本空架構, 不含 power management):

////////////////////////////////////////////////////////////////////////////////

#include
#include
#include
#include
#include

#define XXX_MSG_INFO    0
#define XXX_MSG_DEBUG   0
#define XXX_MSG_ERROR   1
#define XXX_OPEN_ALLOWED 5L

////////////////////////////////////////////////////////////////////////////////

#define IOCTL_GET_SOMETHING 1
#define IOCTL_SET_SOMETHING 2

////////////////////////////////////////////////////////////////////////////////

static DWORD g_dwOpenCount = 0;

////////////////////////////////////////////////////////////////////////////////

DWORD XXX_Init(DWORD dwContext)
{
    /* reading values from registry */
    HKEY hKey;

    RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: XXX_Init:: dwContext (%s).\r\n"), dwContext));

    hKey = OpenDeviceKey((LPCTSTR)dwContext);
    if (!hKey) {
        RETAILMSG(XXX_MSG_ERROR, (TEXT("[XXX] ERROR: Failed to open device key (%s).\r\n"), dwContext));
    } else {
        // Read values from registry if needed
        RegCloseKey (hKey);
    }

    RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] INFO: XXX_Init Sucessfully. \r\n")));

    return 1;
}


BOOL XXX_Deinit(DWORD dwContext)
{
    RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: XXX_Deinit:: dwContext (%s).\r\n"), dwContext));
    return TRUE;
}   // XXX_Deinit


DWORD XXX_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
    if (g_dwOpenCount >= XXX_OPEN_ALLOWED) {
        return 0;
    }
    g_dwOpenCount++;
    RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: XXX_Open:: dwContext(%d), dwOpenCount(%d).\r\n"), dwData, g_dwOpenCount));
    return dwData;
}   // XXX_Open


BOOL XXX_Close(DWORD Handle)
{
    if (!g_dwOpenCount) {
        return FALSE;
    }
    g_dwOpenCount--;
    RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: XXX_Close:: dwContext(%d), g_dwOpenCount(%).\r\n"), Handle, g_dwOpenCount));
    return TRUE;
}   // XXX_Close


BOOL XXX_IOControl(
    DWORD Handle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{

    BOOL bErr = FALSE;
    UINT32 param1;
    UINT32 param2;

    RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: XXX_IOControl.\r\n")));

    switch (dwIoControlCode)
    {

        case IOCTL_GET_SOMETHING:
            RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: +IOCTL_GET_SOMETHING.\r\n")));
            if (nInBufSize >= 2)
            {
                param1 = *((UINT32 *)pInBuf);

                // add the code to get param2 here
                param2 = 1234;

                *((UINT32 *)(pInBuf+4)) = param2;
                bErr = TRUE;
            }
        break;

        case IOCTL_SET_SOMETHING:
            RETAILMSG(XXX_MSG_DEBUG, (TEXT("[XXX] DEBUG: +IOCTL_SET_SOMETHING.\r\n")));
            if (nInBufSize >= 2)
            {
                param1 = *((UINT32 *)pInBuf);
                param2 = *((UINT32 *)(pInBuf+4));
                bErr = TRUE;
            }
        break;


        default:
            RETAILMSG(XXX_MSG_ERROR, (TEXT("[XXX] ERROR: Undefined ID of Device IO Control (%d)!"), dwIoControlCode));
        break;
    }

    if (bErr == FALSE) {
        RETAILMSG(XXX_MSG_INFO, (TEXT("[XXX] ERROR: Device IO Control Error!")));
    }

    return bErr;
}   // XXX_IOControl

DWORD XXX_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
    return 0;
}

DWORD XXX_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
    return 0;
}

DWORD XXX_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
    return 0;
}

void XXX_PowerUp(void)
{
    return;
}

void XXX_PowerDown(void)
{
    return;
}

BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch ( dwReason )
    {
        case DLL_PROCESS_ATTACH:
            RETAILMSG(XXX_MSG_INFO, (TEXT("XXX: DLL_PROCESS_ATTACH\r\n")));
            DisableThreadLibraryCalls((HMODULE) hInstDll);
            break;

        case DLL_PROCESS_DETACH:
            RETAILMSG(XXX_MSG_INFO, (TEXT("XXX: DLL_PROCESS_DETACH\r\n")));
            break;
    }

    return (TRUE);
}

沒有留言: