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);
}
沒有留言:
張貼留言