1、基础知识:
1)体系调用是操作体系内核和应用程序之间的接口,设备驱动程序是操作体系内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件细节,在应用程序看来硬件仅仅一个设备文件,应用程序能够像操作一般文件相同对硬件设备进行操作。设备驱动是内核的一部分。
2)驱动程序完结以下功用:
——对设备初始化和开释;
——把数据从内核传送到硬件和从硬件读取数据;
——读取应用程序传送给设备文件的数据和回送应用程序恳求的数据;
——检测和处理设备呈现的过错。
3)上层应用程序运转在用户形式(非特权形式,Ring 3),代码被严厉束缚履行。如不能履行硬件IO指令。一切的这些被阻挠的操作假如想运转有必要经过圈套门来恳求操作体系内核。
4)操作体系内核运转在内核形式(特权形式,Ring 0),能够履行一切有用的CPU指令。包括IO操作,可拜访任何内存区。
5)整个硬件体系资源在驱动程序面前是光秃秃的,驱动能够运用一切体系资源,编写驱动程序时咱们有必要分外当心驱动代码的边界条件,保证它们不会损坏整个操作体系。
2、Windows支撑的驱动:
1)虚拟设备驱动程序(Virtual Device Driver):Windows3.1(Windows95/98/Me)
2)内核形式驱动程序(Kernel Mode Driver):Windows NT
3)Win32驱动程序模型(Win32 Driver Mode):从Windows98开始运用。
其间WDM是现在干流,然而在WinCE体系中,因为硬件资源有限和嵌入式体系的特色,对其的支撑十分有限。
3、WinCE体系驱动简介:
1)WinCE毕竟是一个嵌入式体系,有其本身的特别性,为了进步运转功率,一切驱动皆为动态链接库,驱动完成中能够调用一切规范的API。而在其他Windows体系中或许的驱动文件还有.vxd, .sys和动态链接库。
2)WinCE驱动从结构上讲分为本地驱动(Native Driver)和流接口驱动(Stream Driver)。
——本地驱动首要用于初级、内置的设备。完成它们的接口并不一致,而是针对不同类型的设备相应规划。因而开发进程相对杂乱,没有固定的形式,一般做法是经过移植、定制现有的驱动样例来完成。
——流接口驱动是最基本的一种驱动结构,它的接口是一组固定的流接口函数,具有很高的通用性,WinCE的一切驱动程序都能够经过这种方法来完成。流接口驱动程序经过文件体系调用从设备办理器和应用程序接纳指令。该驱动程序封装了将这些指令转换为它所操控的设备上的恰当操作所需的悉数信息。
流接口驱动是动态链接库,由一个叫做设备办理程序的特别应用程序加载、办理和卸载。与本地驱动程序比较,一切流接口驱动程序运用同一组接口函数集,包括完成函数:XXX_Init、XXX_Deinit、XXX_Open、XXX_Close、XXX_Read、XXX_Write、XXX_PowerUp、XXX_PowerDown、XXX_Seek、XXX_IOControl,这些函数与硬件打交道。用户函数:CreateFile、DeviceIoControl、 ReadFile、 WriteFile,这些函数便利用户运用驱动程序。
3)WinCE下驱动的加载方法:
——经过GWES(Graphics, Windowing, and Events Subsystem):首要加载与显现和输入有关的驱动,如鼠标、键盘驱动等。这些驱动一般为本地驱动。
——经过设备办理器:两种结构的驱动都加载,加载的本地驱动首要由PCMCIA Host Controller,USB Host Controller driver,首要是总线类的驱动;流接口驱动首要有音频驱动,串并口驱动。
——动态加载:前两者都是体系启动时加载的,动态加载则答应设备挂载上体系时将驱动调入内核,首要有外接板卡驱动,USB设备驱动等。
4、流接口驱动函数介绍:
1)DWORD XXX_Init(LPCTSTR pContext, LPCVOID lpvBusContext);
pContext:指向一个字符串,包括注册表中该流接口活动键值的途径
lpvBusContext:
该函数是驱动挂载后第一个被履行的。首要担任完结对设备的初始化操作和驱动的安全性查看。由ActiveDeviceEx经过设备办理器调用。其回来值一般是一个数据结构指针,作为函数参数传递给其他流接口函数。
2)BOOL XXX_Deinit(DWORD hDeviceContext);
hDeviceContext:XXX_Init的回来值。
整个驱动中最终履行。用来中止和卸载设备。由DeactivateDevice触发设备办理器调用。成功回来TRUE。
3)DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode , DWORD ShareMode);
hDeviceContext:XXX_Init的回来值。
AccessCode:拜访形式标志,读、写或其他。
ShareMode:驱动的同享方法标志。
翻开设备,为后边的操作初始化数据就够,预备相应的资源。应用程序经过CreateFile函数直接调用之。回来一个结构指针,用于区别哪个应用程序调用了驱动,这个值还作为参数传递给其他接口函数XXX_Read、XXX_Write、XXX_Seek、XXX_IOControl。
4)BOOL XXX_Close(DWORD hOpenContext);
hOpenContext:XXX_Open回来值。
封闭设备,开释资源。由CloseHandle函数直接调用。
5)DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count);
hOpenContext:XXX_Open回来值。
pBuffer:缓冲区指针,接纳数据。
Count:缓冲区长度。
由ReadFile函数直接调用,用来读取设备上的数据。回来读取的实践数据字节数。
6)DWORD XXX_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count);
hOpenContext:XXX_Open回来值。
pBuffer:缓冲区指针,接纳数据。
Count:缓冲区长度。
由WriteFile函数直接调用,把数据写到设备上,回来实践写入的数据数。
7)BOOL XXX_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);
hOpenContext:XXX_Open回来值。
dwCode:操控指令字。
pdwActualOut:实践输出数据长度。
用于向设备发送指令,应用程序经过DeviceIoControl调用来完成该功用。要调用这个接口还需要在应用层和驱动之间树立一套相同的指令,经过宏界说CTL_CODE(DeviceType, Function, Method, Access来完成。如: