分类: WINDOWS
2010-01-26 10:52:16
我们以前面一个LEDdriver为例子总结一下怎样将一个驱动加入到WINCE中。
一,完成驱动程序。为了简单起见,直接就把DRIVERS下的LEDdriver整个目录拷贝一下,并把目录名改为WDDdriver,接下来把该目录下的所有”LED”(字符)改为”WDD”,为了跟原来的驱动有点差别,把宏定义改成相反的,即ON改为OFF,OFF改为ON。
修改后的WDDDriver如下:
#include
//#include
#include
#include
#include "pmplatform.h"
#include "Pkfuncs.h"
#include "s2440.h"
#define IO_CTL_WDD_1_OFF 0x01
#define IO_CTL_WDD_2_OFF 0x02
#define IO_CTL_WDD_3_OFF 0x03
#define IO_CTL_WDD_4_OFF 0x04
#define IO_CTL_WDD_ALL_OFF 0x05
#define IO_CTL_WDD_1_ON 0x06
#define IO_CTL_WDD_2_ON 0x07
#define IO_CTL_WDD_3_ON 0x08
#define IO_CTL_WDD_4_ON 0x09
#define IO_CTL_WDD_ALL_ON 0x
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
volatile INTreg *s2440INT = (INTreg *)INT_BASE;
BOOL mInitialized;
void Virtual_Alloc(); // Virtual allocation
void Virtual_Alloc()
{
// GPIO Virtual alloc
s2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
if(s2440IOP == NULL) {
RETAILMSG(1,(TEXT("For s2440IOP: VirtualAlloc faiWDD!\r\n")));
}
else {
if(!VirtualCopy((PVOID)s2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE | PAGE_NOCACHE )) {
RETAILMSG(1,(TEXT("For s2440IOP: VirtualCopy faiWDD!\r\n")));
}
}
}
BOOL WINAPI
DllEntry(HANDLE hinstDLL,
DWORD dwReason,
LPVOID /* lpvReserved */)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hinstDLL);
return TRUE;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
#ifdef UNDER_CE
case DLL_PROCESS_EXITING:
break;
case DLL_SYSTEM_STARTED:
break;
#endif
}
return TRUE;
}
BOOL WDD_Deinit(DWORD hDeviceContext)
{
BOOL bRet = TRUE;
RETAILMSG(1,(TEXT("USERWDD: WDD_Deinit\r\n")));
return TRUE;
}
BOOL WDDGpioInit()
{
RETAILMSG(1,(TEXT("WDD_Gpio_Setting----\r\n")));
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 10)) | (1<< 10); // GPB5 == OUTPUT.
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 12)) | (1<< 12); // GPB6 == OUTPUT.
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.
return TRUE;
}
DWORD WDD_Init(DWORD dwContext)
{
RETAILMSG(1,(TEXT("WDD_Init----\r\n")));
// 1. Virtual Alloc
Virtual_Alloc();
WDDGpioInit();
mInitialized = TRUE;
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL WDD_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
WDDGpioInit();
switch(dwCode)
{
case IO_CTL_WDD_1_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<5);
break;
case IO_CTL_WDD_2_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<6);
break;
case IO_CTL_WDD_3_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<7);
break;
case IO_CTL_WDD_4_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<8);
break;
case IO_CTL_WDD_ALL_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0xF<<5);
break;
case IO_CTL_WDD_1_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<5);
break;
case IO_CTL_WDD_2_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<6);
break;
case IO_CTL_WDD_3_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<7);
break;
case IO_CTL_WDD_4_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<8);
break;
case IO_CTL_WDD_ALL_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0xF<<5);
break;
default:
break;
}
RETAILMSG(1,(TEXT("WDD:Ioctl code = 0x%x\r\n"), dwCode));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD WDD_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
RETAILMSG(1,(TEXT("USERWDD: WDD_Open\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL WDD_Close(DWORD hOpenContext)
{
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&(0xF<<5);
RETAILMSG(1,(TEXT("USERWDD: WDD_Close\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void WDD_PowerDown(DWORD hDeviceContext)
{
RETAILMSG(1,(TEXT("USERWDD: WDD_PowerDown\r\n")));
//RETAILMSG(1,(TEXT("CAMERA: WDD_PowerDown, m_Dx = D%u, init %d \r\n"), m_Dx, mInitialized));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void WDD_PowerUp(DWORD hDeviceContext)
{
RETAILMSG(1,(TEXT("USERWDD: WDD_PowerUp\r\n")));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD WDD_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
RETAILMSG(1,(TEXT("USERWDD: WDD_Read\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD WDD_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
RETAILMSG(1,(TEXT("USERWDD: WDD_Seek\r\n")));
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD WDD_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
RETAILMSG(1,(TEXT("USERWDD: WDD_Write\r\n")));
return 0;
}
二, 修改DRIVERS目录下的dirs,加入一项WDDdriver \
三, 修改FILES目录下的platform.bib,加入一项
wdddriver.dll $(_FLATRELEASEDIR)\wdddriver.dll NK SHK
就是指内核映像(NK.nb0 或NK.bin 文件)中的wdddriver.dll 模块来自该目录下的wdddriver.dll 文件,SH 指名该文件的属性:S 为SYSTEM file,H 为HIDDEN file。
四,修改FILES目录下的platform.reg,加入下面几行,让WINCE 启动时自动加载该驱动。
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\WDDdriver]
"Prefix"="WDD"
"Dll"="WDDdriver.dll"
"Order"="200"
五,最后用VS编译成NK.bin,再用我上一篇文章里的测试程序测试一下。当然CreateFile()的时候要把LED1:改成WDD1:了。见http://blog.chinaunix.net/u3/107046/showart.php?id=2159811
PS:如果对一个驱动作了修改,没必要重新编译整个系统,只要在该驱动目录下右击选择Build就可以了。不要浪费太多的时间在等待上。