wince mysql驱动_WINCE入门的第一个驱动程序

WINCE的第一个驱动程序是什么呢?有的说是GPIO,有的说是LED,也有的说是SimpleDriver,我个人也是同意后者的。

因此这里就以SimpleDriver为例讲解如何开始自己的第一个驱动程序。

首先,要认识到一个驱动有哪些开发模型。这个相信大家都知道,比如本机驱动,分层驱动,流接口驱动等等,这些都闭着眼睛都知道,可是真正的实现呢?具体什么情况用什么模型呢?

关于分层驱动,介绍饿时最多的,尤其是网上和教科书还有一些所谓的论文,真正在产品中用这种方法的又有几个呢?不是分层驱动不好,只是要看具体情况,这个主要看个人喜好,个人能力还有就是在PUBLIC目录下是否有驱动的MDD。

因此,对于一个外设来说,尤其是一片子来说,个人认为单体驱动和流接口驱动用的更实际点,尤其涉及数据的传输,个人认为流接口驱动更容易一些。以上仅代表个人观点,欢迎拍砖。

其次,对于一个驱动我们要认清楚里面到底有哪些文件,他们的作用又是干什么的呢?下面以SimpleDriver为例,进行第一个简单流接口驱动的讲解。

1.Makefile文件

这里的Makefile文件请不要和其他环境下(GCC,VS2005)的Makefile文件弄混,它是BSP里面的Makefile。Windows CE中的Makefile比较特别,它包含对所有项目都通用的配置信息。

其内容很简单,只有一句话:

!INCLUDE $(_MAKEENVROOT)\makefile.def

当build.exe查找dirs和source文件之后,它就会设置一个内部环境变量。这个环境变量可以被Nmake.exe传递给编译器、连接器或其他工具。

2.source文件

source也是一个文本文件,它为子目录中的源代码设置了不少宏定义。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png代码

TARGETNAME=SimpleDriver

RELEASETYPE=PLATFORM

TARGETTYPE=DYNLINK

TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib

DEFFILE=$(TARGETNAME).def

DLLENTRY=DllEntry

SOURCES=SimpleDriver.c

以上是simpledriver里面source的内容,具体解释如下:

TARGETNAME=SimpleDriver; 指定生成最终生成的.exe,.lib,.dll文件的名称,这里是SimpleDriver.dll

RELEASETYPE=PLATFORM;它设置两种旗标:RELEASEDIR和RELEASELIBDIR,用于指定编译生成二进制和库文件存放的目录。默认情况下,为目标生成的二进制和库文件存放在

;目录%_PROJECTROOT%\oak下,这里存放在D:\WINCE600\PLATFORM\Mini2440\target\ARMV4I\retail目录下。

TARGETTYPE=DYNLINK;这个宏定义指定构建文件的最终类型,可以把TARGETTYPE类型设置为一下四种类型中的任意一种。

1)MANAGED_EXE;

2) MANAGED_DLL;

3) MANAGED_WINEXE;

4) MANAGED_MODULE;

这里设置的最终类型为dll。

TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib    ;它指定了额外的库文件(.lib)和目标文件(.Obj)链接为目标可执行文件(.exe或.dll).

;这里将 coredll.lib 链接生成最终的目标文件SimpleDriver.dll

DEFFILE=$(TARGETNAME).def;它指定模块定义文件(.def)的名称,这里指定了模块定义文件的名称为SimpleDriver.def

DLLENTRY=DllEntry;它为一个DLL文件指定DLL的入口函数,此时TARGETTYPE被设置为DYNLINK。如果 DLLENTRY对应的值没有被设置时,那么_DllMainCRTStartUp是DLL的C程序

;运行入口点。这里 DLLENTRY的入口函数被指定为DllEntry,因而,上面的 TARGETTYPE被设置成DYNLINK;

SOURCES=SimpleDriver.c;它包含编译过程的文件列表,这些列表中包含汇编文件和源文件,这些文件的类型有.cxx,.cpp,.c,.asm,.s,.src,.rc,.obj,.ire,.res,.odl,.tlb,.i,.cs,.resx等。

;这些文件编译之后可能是静态库文件(.lib),也有可能是动态库文件(.dll)。这里编译过程中需要用到的源文件有SimpleDriver.c,

;编译之后的生成SimpleDriver.dll的动态链接库文件。

3.SimpleDriver.def文件

.def文件定义了DLL的导出函数列表。

这里包括的内容如下:

LIBRARY SimpleDriver

EXPORTS

SPL_Init

SPL_Deinit

SPL_Open

SPL_Close

SPL_Read

SPL_Write

SPL_Seek

SPL_IOControl

SPL_PowerDown

SPL_PowerUp

主要是针对当前流接口函数,将相应的函数导出。

4. SimpleDriver.h

这个而就不用多介绍了吧,主要是一些头文件的声明,定义等等

5.SimpleDriver.c

下面给出基本的代码,有些函数给出了空定义,方便以后实现,同时方便理解。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png代码

#include#includestaticBYTE g_Tmp=0;/*暂存数据变量*/staticDWORD g_OpenCount=0;/*驱动打开计数器*//*******************************************************************************************

函数名称: DllEntry

描    述: 驱动程序动态库入口

输入参数:

输出参数:

返    回:

*******************************************************************************************/BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)

{switch( dwReason )

{caseDLL_PROCESS_ATTACH:

RETAILMSG(1, (TEXT("SPL: DLL_PROCESS_ATTACH.\r\n")));/*提示动态库加载*/DisableThreadLibraryCalls((HMODULE) hInstDll);break;caseDLL_PROCESS_DETACH:

RETAILMSG(1, (TEXT("SPL: DLL_PROCESS_DETACH.\r\n")));/*提示动态库卸载*/break;

}return(TRUE);

}/*******************************************************************************************

函数名称: SPL_Init

描    述: 驱动程序初始化函数

输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置

输出参数: 无

返    回: 驱动程序句柄

*******************************************************************************************/DWORD SPL_Init(DWORD dwContext)

{

RETAILMSG(1, (TEXT("::: SPL_Init.\r\n")));/*提示驱动加载*/g_Tmp=0;/*初始化全局变量的值*/g_OpenCount=0;return1;/*返回一个不为零的数表示成功*/}/*******************************************************************************************

函数名称: SPL_Deinit

描    述: 驱动程序卸载函数

输入参数: DWORD dwContext: 驱动程序句柄

输出参数: 无

返    回: FALSE: 失败    TRUE: 成功

*******************************************************************************************/BOOL SPL_Deinit(DWORD dwContext)

{

RETAILMSG(1, (TEXT("::: SPL_Deinit.\r\n")));/*提示驱动卸载*/g_Tmp=0;/*恢复全局变量的值*/g_OpenCount=0;returnTRUE;

}/*******************************************************************************************

函数名称: SPL_Open

描    述: 打开驱动程序

输入参数: DWORD hDeviceContext: 设备驱动程序引用实例句柄

DWORD AccessCode    : 访问请求代码,是读和写的组合

DWORD ShareMode      : 共享模式

输出参数:

返    回: 驱动程序引用事例句柄

*******************************************************************************************/DWORD SPL_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)

{

RETAILMSG(1, (TEXT("::: SPL_Open.\r\n")));/*提示驱动打开*///不允许多个应用程序打开本驱动if(g_OpenCount!=0)

{

RETAILMSG(1, (TEXT("SPL Open failed.\r\n")));/*提示驱动打开失败*/return0;

}

g_OpenCount++;/*驱动打开计数器加1*/returng_OpenCount;/*必须返回一个不为空的句柄*/}/*******************************************************************************************

函数名称: SPL_Close

描    述: 驱动程序关闭函数

输入参数: DWORD hOpenContext:驱动程序引用事例句柄

输出参数: 无

返    回: FALSE: 失败    TRUE: 成功

*******************************************************************************************/BOOL SPL_Close(DWORD hOpenContext)

{

RETAILMSG(1, (TEXT("::: SPL_Close.\r\n")));/*提示驱动关闭*/if(g_OpenCount!=0)

g_OpenCount--;/*驱动打开计数减1*/returnTRUE;

}/*******************************************************************************************

函数名称: SPL_IOControl

描    述: 驱动程序 I/O 请求

输入参数:

输出参数:

返    回: TRUE: 成功   FALSE: 失败

*******************************************************************************************/BOOL SPL_IOControl(DWORD hOpenContext,

DWORD dwCode,

PBYTE pBufIn,

DWORD dwLenIn,

PBYTE pBufOut,

DWORD dwLenOut,

PDWORD pdwActualOut)

{

RETAILMSG(1, (TEXT("::: SPL_IOControl.\r\n")));/*提示I/O请求函数执行*/returnTRUE;

}/*******************************************************************************************

函数名称: SPL_Read

描    述: 从本驱动读取数据

输入参数: DWORD hOpenContext: 驱动程序引用事例句柄

DWORD Count        : 要读的字节数

输出参数: LPVOID pBuffer    : 接收缓冲区

返    回: 实际读到的字节数

*******************************************************************************************/DWORD SPL_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)

{

uchar*pReadBuffer;

RETAILMSG(1, (TEXT("::: SPL_Read.\r\n")));/*提示执行读函数*/if((pBuffer==NULL)||(Count<=0))

{/*读函数入口参数错误*/RETAILMSG(1, (TEXT("::: SPL_Read() parameter is error.\r\n")));return0;

}//映射地址空间pReadBuffer=MapPtrToProcess(pBuffer, GetCallerProcess());*pReadBuffer=g_Tmp;/*返回数据*/return1;/*返回读取的字节数*/}/*******************************************************************************************

函数名称: SPL_Write

描    述: 向本驱动写入数据

输入参数: DWORD hOpenContext: 驱动程序引用事例句柄

LPVOID pBuffer    : 发送缓冲区

DWORD Count        : 要写入的字节数

输出参数: 无

返    回: 实际写入的字节数

*******************************************************************************************/DWORD SPL_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count)

{

uchar*pWriteBuffer;

RETAILMSG(1, (TEXT("::: SPL_Write.\r\n")));/*提示执行写函数*/if((pBuffer==NULL)||(Count<=0))

{/*写函数入口参数错误*/RETAILMSG(1, (TEXT("::: SPL_Write() parameter is error.\r\n")));return0;

}//获取应用程序地址空间数据指针pWriteBuffer=MapPtrToProcess((LPVOID)pBuffer, GetCallerProcess());

g_Tmp=*pWriteBuffer;/*保存数据*/return1;

}/*******************************************************************************************

函数名称: SPL_Seek

描    述: 对设备的数据指针进行操作,本驱动不支持该函数

输入参数:

输出参数:

返    回:

*******************************************************************************************/DWORD SPL_Seek(DWORD hOpenContext,longAmount, DWORD Type)

{

RETAILMSG(1, (TEXT("::: SPL_Seek.\r\n")));/*提示执行本函数*/return0;

}/*******************************************************************************************

函数名称: SPL_PowerUp

描    述: 电源上电驱动处理函数

输入参数:

输出参数:

返    回: 无

*******************************************************************************************/voidSPL_PowerUp(void)

{

RETAILMSG(1, (TEXT("::: SPL_PowerUp.\r\n")));/*提示执行本函数*/}/*******************************************************************************************

函数名称: SPL_PowerDown

描    述: 电源下电驱动处理函数

输入参数:

输出参数:

返    回: 无

*******************************************************************************************/voidSPL_PowerDown(void)

{

RETAILMSG(1, (TEXT("::: SPL_PowerDown.\r\n")));/*提示执行本函数*/}

OK!

到这里点击编译就可以了。这个新驱动程序的动态链接库将会被编译进内核。当调用CreateFile()函数(第一个参数是SPL)时就搜索注册表,设备管理器可以找到这个驱动,驱动的入口点可以用到其他程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值