wince流驱动入门讲解_第1页
wince流驱动入门讲解_第2页
wince流驱动入门讲解_第3页
wince流驱动入门讲解_第4页
wince流驱动入门讲解_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第一章 驱动的准备1. 驱动程序完成以下功能:对设备初始化和释放;把数据从内核传送到硬件和从硬件读取数据;读取应用程序传送给设备文件的数据和回送应用程序请求的数据; 检测和处理设备出现的错误 。2. 整个硬件系统资源在驱动程序面前是赤裸裸的,驱动可以使用所有系统资源,编写驱动程序时我们必须格外小心驱动代码的边界条件,确保它们不会损坏整个操作系统。3. WinCE毕竟是一个嵌入式系统,有其自身的特殊性,为了提高运行效率,所有驱动皆为动态链接库,驱动实现中可以调用所有标准的 API。而在其他 Windows系统中可能的驱动 文件还有.vxd, .sys和动态链接库。4. Windows支持的驱动:

2、1) 虚拟设备驱动程序( Virtual Device Driver ): Windows3.1 ( Windows95/98/Me)2) 内核模式驱动程序( Kernel Mode Driver ): Windows NT3) Win32 驱动程序模型(Win32 Driver Mode ):从 Windows98 开始使用。其中WDM是目前主流,然而在 WinCE系统中,由于硬件资源有限和嵌入式系统的特点, 对其的支持非常有限。第二章 WINCE驱动1.WINCE驱动模型目前Windows CE提供了 4种设备模型,其中2种专门用于 Windows CE模型,另外2种模型来自于其它的操系统

3、,如图1所示:1图1 Windows CE各种驱动模型的关系2我们的工作为了帮助开发者快速地开发Windows CE驱动程序,微软在 Platform Builder中提供了大量的驱动程序例源代码,同时,芯片厂商或OEM厂商有时也提供一些设备的驱动程序源代码,这些驱动程序源代码在多数情况下可以直接拿来使用,但是在少数情况下需要开发者根据自己的设备硬件特性做一些移植的工作,修改例源代码,重新编译和调试驱动程序。移植工作虽然没有像开发一个全新的驱动程序那样富有挑战性,但它仍具有相当大的难度,其原因如下:移植工作仍然要求开发者具有良好的软、硬件基础,熟悉驱动程序的基本开发和调试 方法,并要求具有一定

4、的开发环境和测试手段。移植工作仍然需要了解驱动程序的架构,需要确切知道驱动程序对外暴露哪些接口, 微软提供了哪些接口,还必须实现哪些接口等。对于同一设备的驱动程序,其源代码往往位于Platform Builder多个不同的安装目录,移植工作首先需要找出所移植驱动程序的所有源代码的位置。移植工作需要在所移植驱动程序的所有源代码中区分出与硬件有关的代码和独立于硬件的代码,熟悉每个软件模块的大致功能,找出需要更改的与特定硬件有关的代码,并详细分析这些代码。大部分驱动程序的代码放在目录下,这些驱动程序都是与平台无关的。此外,对于不同的平台,在BSP目录中也有一些驱动程序的代码,它们在中,这些驱动都是与

5、平台相关的。移植工作所修改的源代码有可能仅仅只有几十行甚至几行代码,但在修改之前却需要 花费大量的时间了解驱动架构、熟悉驱动接口、分析源程序代码、找出需要修改的位置。本质上讲,移植与从头开发一个驱动的差别仅仅在于少写了很多程序。省去了编写这部分程序的时,但对驱动程序开发者的水平要求似乎并没有丝毫的降低。第三章 流接口函数流接口函数也称作流接口驱动程序的入口点,每个流接口驱动程序必须实现一组标准的函数,用来实现标准的文件I/O函数和电源管理函数,这些函数提供给Windows CE操作系统的内核使用。这些函数通常叫做流接口驱动程序的DLL接口。以下介绍几个主要的流接口驱动接口函数。(1)DWORD

6、 XXX_Open (DWORD hDeviceContext.DWORD AccessCode,DWORD ShareMode)参数:DWORD hDeviceCo ntext,设备驱动的句柄,由XXX_ I nit函数创建的时候返回。DWORD AccessCode,传给驱动程序使用的地址,这个地址跟读和写有关。DWORD ShareMode,共享模式,这个参数用于一些特殊的设备。例如一些PC卡的设备读或写的时候是否可以共享。返回值:返回驱动程序引用事例句柄。描述:这个函数用于打开一个设备驱动程序,当应用程序 准备对某一个设备进行读或写操作时,系统必须先执行 CreateFile()这个函

7、数用于打开这个设备。这个函数执行以后系 统才能够执行读和写操作。(2)BOOL XXX _ Close( DWORD hOpenContext )参数:DWORD hOpenCnntext,设备驱动的引用事例句柄,由XXX_Open创建。返回值:调用成功返回TRUE,失败返回FALSE 口描述:这个函数用于关闭一个驱动程序的引用实例。应用程序通过CloseHandle()来调用这个函数,当执行完这个函数的时候驱动程序引用的事例,hOpenContext将不再有效。(3)DWORD XXX_ Init( DWORD dwC on text )参数:DWORD dwContext,指向字符串的指针

8、。通常这个参数都为一个流接口驱动在注册表内的设置。返回值:如果调用成功返回一个驱动程序的句柄。描述:当用户开始使用一个设备的时候,例如,当PC卡初始化的时候,设备管理器调用这个函数来初始化PC卡设备。这个函数并不是由应用程序直接调用的,而是通过设备管理器 提供的ActivateDeviceEx()函数来调用的。函数执行后如果成功则返回一个设备的句 柄。(4) BDOL XXX_ Deinit( DWORD hDeviceContext )参数:DWORD hDeviceC on text,由xxx_ Init创建时生成的设备句柄。返回值:调用成功返回 TRUE,失败返回FALSE。描述:当一个

9、用户需要卸载一个驱动程序的时候,设备管理器调用这个函数来卸载这个驱动程序,应用程序不能够直接调用这个函数,设备管理器 通过DeactivateDeviec()函数调用这个函数。(5) DWORD XXX_ Read (DWORD hOpenContext,LPVOID pBuffer,DWORD Count)参数:DWORD hOpe nCo ntext,CreateFile()函数返回的句柄。LPVOID pBuffer,一个缓冲区地址用于从驱动读数据。DWORD Count,需要读缓冲区的长度。返回值:实际读取字节的长度。描述:这个函数与 ReadFile很相似,当一个流接口驱动程序已经被

10、打开后,应用程序可以使用ReadFile()函数对这个设备进行读操作,ReadFile()里面的hFile参数就是这个设备的引用实例句柄hOpenContext,而参数lpBuffer将传给pBuffer,用于表示要读/写缓冲区的地址。参数nNumberofBytesToRead将传送给 Count,用于表示要读写缓冲区的长度。同样,返回 的参数,如果操作成功则返回实际读/写的地址,如果操作失败则返回值为-1。(6)DWORD XXX_Write (DWDRD hOpenContext,LPCVOID puffer,DWDRD Count)参数:DWDRD hOpenContext,由 Cre

11、ateFile()函数返回的句柄。LPVOID pBuffer , 一个缓冲区地址,用于从驱动写数据。DWORD Count,需要写缓冲区的长度。返回值:实际写入字节的长度。描述:当一个流接口驱动程序打开以后,应用程序可以使用WriteFile ()函数进行写操作。(7) BOOL XXX_ lOControl (DWORD hQpenContext.WORD dwCode,PBYTE pBufI n,DWORD dwLe nln,PBYTE pBufOut,DWORD dwLe nDut,PDWORD pdwActualOut )参数:DWORD hOpenContext,由 CreateF

12、ile()函数返回的句柄。WORD dwCode,特殊的 WORD 型用于描述这次lOControl操作的语义,一 般这个都由用户自己定义。PBYTE pBufIn,缓冲区指针指向需要传送给驱动程序使用的数据。DWORD dwLenln,要传送给驱动程序使用数据的长度。PI3YTE pBufOut,缓冲区指针指向 驱动程序传给应用程序使用的数据:DWDRD dwLEnOut,要传送给应用程序使用数据的 长度。PDWORD pdwActualOut,DWORD型指针用于返回 实际处理数据的长度。返回值:调用成功返回 TRUE,调用失败返回 FALSE。描述:这个函数通常用于向设备发送命令。应用程

13、序 使用DevicelOControl函数来通知操作系统调用这个函数。 通过参数dwCode来通知驱动程序要执行的操作 。这个函数扩展了 流接口驱动程序的功能(8) VOID XXX_ PowerDown (DWORD hDeviceContext)参数:DWORD hDeviceCo ntext,由XXX_ I nit创建时生成的设备句柄。返回值:无返回值。(9) VOID XXX_PowerUp ( DWORD hDeviceContext )参数:WORD hDeviceContext,由XXX_ init创建时生成的设备句柄。返回值:无返回值。描述:PowerDown和PowerUp这

14、两个函数通常都必须要硬件的支持才能够有效,也是 说相关的硬件必须支持PowerDown和PowerUp这两个模式。(10) VOID XXX_Seek (hDeviceContext.Long Amount,WORD Type)参数:hDeviceContext,由XXX_ init创建时生成的设备句柄。Long Amount定义要移动的设备数据的指针的字节数WORD Type 定义数据指针的起始点返回值:无返回值描述:当一个应用程序调用SetFilePointer函数移动设备数据指针 时,操作系统会调用 XXX_Seek函数。如果一个设备可以被多次打开,这个函数只修改由 hDeviceCon

15、text定义的设备实例的数据指针。第四章最简单的流接口函数对于一个驱动我们要认清楚里面到底有哪些文件,他们的作用又是干什么的 呢?下面以SimpleDriver为例,进行第一个简单流接口驱动的讲解。.Makefile 文件这里的Makefile 文件请不要和其他环境下(GCC,VS200)的Makefile文 件弄混,它是BSP里面的Makefile。WindowsCE中的Makefile 比较特别,它包 含对所有项目都通用的配置信息。其内容很简单,只有一句话:!INCLUDE $(_MAKEENVROOT)makefile.def当build.exe查找dirs和source文件之后,它就会

16、设置一个内部环境变量。这个环境变量可以被Nmake.exe传递给编译器、连接器或其他工具。* 2.source 文件source也是一个文本文件,它 为子目录中的源代码设置了不少宏定义。TARGETNAME=SimpleDriverRELEASETYPE=PLA TFORMTARGETTYPE=DYNLINKTARGETLIBS=$(_COMMONSDKROOT)lib$(_CPUINDPATH)coredllibDEFFILE=$(TARGETNAME).defDLLENTRY=DllE ntrySOURCES=SimpleDriver.c以上是simpledriver 里面source的内

17、容,具体解释如下:TARGETNAME=SimpleDriver指定生成最终生成的.exe,.lib,.dll文件的名称,这里是 SimpleDriver.dllRELEASETYPE=PLATFOR它设置两种旗标:RELEASEDI和 RELEASELIBDIR用 于指定编译生成二进制和库文件存放的目录。默认情况下,为目标生成的二进制 和库文件存放在目录 _PROJECTROOT%下al这里存放在 D:WINCE600PLATFORMMi ni2440targetARMV4lretail目录下。TARGETTYPE=DYNL;I这个宏定义指定构建文件的最终类型,可以把TARGETTYPE 类

18、型设置为以下四种类型中的任意一种。1) MANAGED_EXE;2) MANAGED_DLL;3) MANAGED_WINEXE;4) MANAGED_MODULE;这里设置的最终类型为dll。TARGETLIBS=$(_COMMONSDKROOT)lib$(_CPUINDPATH)coredll.lib ;_COMMONSDKF等OTF WINCE600publiccommo nsdk它指定了额外的库文件(.lib )和目标文件(.Obj )链接为目标可执行文件(.exe或.dll). 这里将coredll.lib链接生成最终的目标文件 SimpleDriver.dllDEFFILE=$(T

19、ARGETNAME).def它指定模块定义文件(.def )的名称,这里指定 了模块定义文件的名称为SimpleDriver.defDLLENTRY=DllEntry;它为一个DLL文件指定DLL的入口函数,此时TARGETTYPE 被设置为DYNLINK如果DLLENTR对应的值没有被设置时,走DllMainCRTStartU是DLL的的C程序运行入口点。这里 DLLENTR的入口函数被 指定为DllEntry,因而,上面的 TARGETTYP被设置成DYNLINK;SOURCES=SimpleDriver.c;它包含编译过程的文件列表,这些列表中包含汇编 文件和源文件,这些文件的类型有.c

20、xx,.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 SimpleDriverEXPORTSSPL_I nitSPL_Dei nitSPL_Ope nSPL_CloseSPL_Read

21、SPL_WriteSPL_SeekSPL_IOC on trolSPL_PowerDow nSPL_PowerUp主要是针对当前流接口函数,将相应的函数导出* 4. SimpleDriver.h这个而就不用多介绍了吧,主要是一些头文件的声明,定义等等* 5.SimpleDriver.c下面给出基本的代码,有些函数给出了空定义,方便以后实现,同时方便理解。* 6. platform.reg配置文件的编写。涉及到的文件有.platform.bib,platform.reg,dirs,source,SimpleDriver.def,其中后面两个文件在前文已有绍,这里就以前两个配置文件为主。首先,从注

22、册表说起,先简单的介绍一下注册表:Makeimg.exe使用.reg文件来 为CE镜像建立注册表并添加默认的键值。也就是说,在.reg中写入的注 册表的键值会被默认地放入CE镜像的初始化注册表中。其中Platform.reg 定义 了目标设备硬件的注册表设置,Project.reg 定义基于 Windows CE项目工程的 注册表设置。注册表键值的类型如下:1. REG_S表示一个字符串类型,如 reg_sz: ” my string ”。2. REG_DWO表示一个双字节类型,如 dword:12345678(十六进制数)。3. REG_MULTI_S表示多字符串类型,女口 multi_sz

23、 :“ my string ” , “my string ”。4. REG_BINAR二进制类型在实际应用中可以使用IF/ENDIF关键字来引入一个注册表设置块,通过设 置一个环境变量或一个特殊的值来达到这个目的。为了包含一个注册表设置块,当一个环境变量没有被设置或者没有等于一个 特定的值的时候,引入的注册表设置块的行尾应使用一个空格和“! ”。这里比较好找,一目了然,在目录D:WINCE600PLATFORMSMDKXXXXFilesplatform.reg 下添加:Builtln SPL"Prefix"="SPL""DII"=&q

24、uot;SimplDriver.DII ""Frie ndlyName" ="Simple Driver""Order"=dword:0 驱动安装顺序"Index "=dword:0 /驱动名的数字部分注:Order给所有的驱动设置相对安装顺序。Order为0的驱动先安装,依次安装Order 为1,2,的驱动。Oder可以让开发者保证有相到依赖关系的多个驱动以适当的 顺序进行安装。Index指定在文件系统中的驱动名的数字部分。在默认情况下,带有前缀 COM勺驱动 在文件系统中分配名字为COM1下一个即为C

25、OM2为了保证驱动总是安装成 COM2必须提供Index = 2。这样在WINCES动时,就自动加载该驱动了* 7. platform.bib接着我们介绍platform.bib 文件,关于bib文 件,这里做一个简要的介绍: 二进制镜像文件构建文件(.bib )定义了哪个模块或者文件被包含到运行时的CE镜像中。在编译期间,makeimg.exe使若干个.bib文 件合并成ce.bib文件, 然后,romimage.exe使用ce.bib决 定哪些文件应该被打包进运行时 CE镜像中, 它同时还使用ce.bib来决定如何加载模块和文件到 CE镜像(下载到目标设备的 CE镜像)所在的内存中。按照功

26、能划分,.bib文件可以分为如下几种类型(1)Platform.bib 。 Platform.bib 位于目录D:WINCE600PLATF0RMSMDK6410Files 它包含硬件平台相关的 模块和文件,如目标设备的驱动文件。这些模块和文件是CE镜像的入口,比如.exe文件,如波形音频文件(.wav)等。(2)Project.bib 。 Project.bib位于目录D:WINCE600PUBLICCEBASEOAKFILESQ 果我们新建一个工程 项目(OSDesign1则这个工程位于目录:D:WINCE600OSDesig ns'OSDesig n1OSDesig n1Wi n

27、ce600SMDK64 10_ARMV4IOAKfiles下。Project.bib文件定义与创建CE镜像的工程相关的模块,如果在OSDesign1中创建了一个自己的模块或者 应用程序,那么就要把它们添加到Project.bib 文件中的MODILES 部分。(3) Commo n.bibb Com mon .bib 位于目录 D:WINCE600PUBLICCOMMONOAKFILES 它定义了 CE镜像文 件包含的通用显示驱动和核心系统模块。(4) Config.bib。Config.bib 位于目录 D:WINCE600PLATFORMSMDK6410File下,它定义了 ROM和 RA

28、M 的配置信息。它同样包含了 CE镜像文件的MEMOR和CONFIG?分。Config.bib的MEMORY分定义了运行时CE镜像内存分配表,指 定了名称、地址、大小和 MEMORY域的类型。.bib文件可以被分为四个部分,分别是MEMOR9ONFIG MODULE® FILES。 下 面将分别说明这四个部分各自的含义。(1) MEMORY定义可用的物理内存,包括起始地址、大小和内存类型。(2) CONFIG定义romimage.exe输出的配置选项。默认情况下,这个区 域是在config.bib 文件中。不过,也并不是.bib文件中必须要包含 CONFIG?分。(3) FILES。

29、指定放在CE镜像中的文件列表。(4) MODULES指定放在CE镜像 总的模块列表,包括 EXE® DLL文件, 与FILES的 区别是放在MODULE中的文件通常是代码文件,并且构 建系统时不会压缩这些文件。这里我们主要介绍Modules部分。Modules部分指定了哪些基于 Windows CE的模块包含到CE镜像中,以 及如何给加载到config.bib 文件中的MEMORY分建立内存表。这个部分 可以包含200个模块,这些模块有源代码和数据两个部分组成。MODULE的语法格式如下:Name Path Memory block Sect ion override Memory

30、Type各参数之间用空格分隔。NAME这个参数指定了 MODULE模块的名称。通常情况下,它就像被路径 引用的文件名称一样。PATH指定要打包进CE镜像的MODULE模块的完整路径。MEMORY BLOCK个参数指定romimage.exe加载目标模块 到内存区域的 ramimage (镜像)部分。这个内存位于config.bib 文件中memory部分指定 的某一段内存。SECTIOKDVERRID:这个参数的设置时可选的,它可以为modules、files 或者空。如果设置了这个参数,那么构建系统就会根据它来决定这一项是 modules 还是 files 。TYPE这个参数指定文件的类型,

31、主要有以下几种类型,在实际的使用中 可以选用其中的一种或者多种组合。1. S:定义一个系统文件2. H:定义一个隐藏文件3. R:压缩资源,只应用于 MODULE部分4. C:如果应用于一个模块,则压缩全部内容5. D:运行时不允许调试。6. N:标记一个模块为不可信任的,只应用 MODULE部分。7. K:指定romimage.exe必须修正模块到一个内核地址。在这个过程中romimage.exe分配一个固定的虚拟地址给 DLL,设置了此标志的 模块只可以被loadKernelLibrary()函数加载。8. P:指定romimage.exe禁止在头文件中检查指定的 CPU类型。这个 旗标只

32、用于资源dll,可以在一种CPUffi编译,在不同CPU±使用。9. M:表示对此页禁止按序调页。10. U:表示不压缩此文件。在目录 D:WINCE600PLATFORMSMDKXXXXFilesplatform.bib 文件中有如下定 义:NamePathMemory Type13#SimpleDriver (caichang714) simpledriver.dll $(_FLATRELEASEDIR)simpledriver.dll NK SHKCESYSGEN ENDIF CE MODULES DEVICE其中,_$(_FLATRELEASEDIR)甘旨的是生成的镜像所在目

33、录,即D:WINCE600OSDesig nsSMDKXXXXSMDKXXXXRelDir结合上面的说明,我们可以知道,上面的语句的意思是将编译生成的 simpledriver.dll模块加载到CE运行时镜像NK中。它的文件属性是系统文件,隐藏文件和内核模块,由romimage.exe分配一个固定的虚拟地址给 simpledriver.DLL 。接 着在 D:WINCE600PLATFORMSMDKXXXXSrcDrive目录下找到 dirs 文件, 在里面添加:SimpleDriver最后点击build或者在dos环境下build -cOK到这里点击编译就可以了。这个新驱动程序的动态链接库将

34、会被编译进内 核。当调用CreateFile()函数(第一个参数是SPL)时就搜索注册表,设备管理 器可以找到这个驱动,驱动的入口点可以用到其他程序。第五章需要注意的事项1.驱动程序的内存访问及函数入口当要在内核模式下执行代码时,必要时需访问整个物理内存空间,这一点与用户模式下执行是截然不同的。因为一个在用户模式运行的IST需要通过访问一个物理内存块来与一个设备进行交互,所以必须要把这个物理内存块映射到IST运行的地址空间。把一个物理内存块映射到执行IST的地址空间有两种方法:VirtualAlloc()申请虚拟内存块 和VirtualCopy()绑 定物理内存块与虚拟内存块1)申请一个虚拟内

35、存块LPVOID_VirtualAlloc_(/申请虚拟内存块的 起始地址/申请内存块的大小,以B为单位,不能设为 0/申请的类型,分为 COMMIT 和RESERVELPVOID lpAdress,DWORD dwsize,DWORD flAllocatio nType,/COMMIT:在内存或者磁盘上为指定的页面区域分配物理存储/RESERVE:保留一定范围的IST进程的虚拟地址空间不分配物理存储DWORD flProtect/访问权限);如果调用成功,返回分配的首地址,调用失败,返回NULL你可以通过GetLastError 函 数来获取错误信息。注:VirtualAlloc ()函数对

36、虚拟内存块的申请分为两步,首先是执行保留动作,它在 此期间做的工作只是在进程的虚拟地址空间内保留一段空间,并没有分配实际的物理 内存,保留的虚拟内存并不能被应用程序直接使用。其次,执行提交动作后,这样后 才真正的为虚拟内存块映射一段物理内存。执行成功之后,将返回一个内存块指针给 用户。2) 一个物理地址块与一个虚拟内存块的绑定BOOL VirtualCopy(LPVOID lpvDest,绑定目的地址:虚拟内存块LPVOID lpvSrc,/绑定源地址:物理内存块DWORD cbSize,要绑定的大小DWORD fdwProject 访问权限)返回值:成功返回TRUE,失败返回FALSE注:当

37、虚拟内存所要的工作处理完成,需要调用VirtualFree()函数来释放此虚拟内存。VirtualCopy()函数支持 PAGE PHYSICAL 旗标,当映射驻留在 512MB之外的物理内存时,也就是在物理地址大于0X1FFFFFFF时,必须设置此标志。3) 释放内存BOOL VirtualFree(LPVOID IpAddress, / 区域地址SIZE_T dwSize, / 区域大小,字节 DWORD dwFreeType / 类型);LPVOID lpAddress ,要释放的页的区域的地址,如果dwFreeType指定为MEM_RELEASE这个区域是被保留 的话,那么这个地址就要

38、指定为分配区域的首地址SIZE_T dwSize ,要释放页的大小,如果dwFreeType类型中包含了 MEM RELEAS则dwSize必须为0DWORD dwFreeType 类型说明MEM_DECOMMI消 VirtualAlloc提交的页MEM_RELEASE指定页,如果指定了这个类型,则dwSize应设置为0,否则函数会调用失败 返回值:如果调用成功,返回一个非0值 调用失败,返回04)BOOL WINAPI DIIEntry ( HINSTANCE Dlllnstance, INT Reason, LPVOID Reserved )这个函数是动态链接库的入口,每个动态链接库都需要

39、输岀这个函数,它只在动态库被加载和卸载时被调用,也就是设备管理器调用LoadLibrary 而引起它被装入内存和调用 UnloadLibrary 将其从内存释放时被 调用,因而它是每个动态链接库最早被调用的函数,一般用它做一些全局变量的初始化。参数:DllInstance : DLL的句柄,与一个EXE文件的句柄功能类似, 一般可以通过它在得到 DLL中的一些资源, 例如对话框,除此之外一般没什么用处。Reason: 一般我们只关心两个值:DLL_PROCESS_ATTACH DLL_PROCESS_DETACReason 等于前者是 动态库被加载,等于后者是动态库被释放|。所以,我们可以在 Reason等于前者是初始化一些资源,等于后者 时将其释放。2.MDD 与 PDD一个驱动程序通常会被分成硬件相关(PDD)与硬件无关(MDD )层两部分。当然,这种分层不是必须的,只是采用这种分层以后可以少写很多代码,因为微软提供了很多驱动程序的 MDD。即使CE中没有我们所写的驱动程序的样例,采用这种结构以后,当 需要写第二个程序时,就可以重用它的代码,就可以提高开发效率。MDD是提供同类型的设备(比如串口)都会有的功能,这样PDD基本上就只有寄存器操作了。像串口的中断处

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论