1、2022-5-31北京理工大学珠海学院 计算机教研室1第五章 驱动程序设计北京理工大学珠海学院 计算机教研室22022-5-31教学目的教学目的 nWindows CE5.0驱动程序设计的基本概念;掌握Windows CE5.0动态链接库的编制方法;掌握Windows CE5.0动态链接库的静态加载方法 北京理工大学珠海学院 计算机教研室32022-5-31项目项目9:驱动程序的编制驱动程序的编制本节课程主要知识点n驱动程序模型n动态链接库n动态链接库的特点与实现(重点)n动态链接库的加载n动态链接库的静态加载(难点)北京理工大学珠海学院 计算机教研室42022-5-31n教学重点驱动程序的基
2、本概念动态链接库n教学难点动态链接库的编制及静态加载方法 北京理工大学珠海学院 计算机教研室52022-5-315.1驱动程序基本知识n5.1.1 驱动程序的功能驱动程序是操作系统与硬件交互的方式,是连接硬件与操作系统之间的桥梁;独立的“黑盒子”,定义好的编程接口,隐藏设备工作的细节;驱动程序的作用是实现这组接口,并映射到具体的对硬件的某项操作上。驱动程序接口北京理工大学珠海学院 计算机教研室62022-5-31应用程序操作系统网卡驱动程序1网卡驱动程序2网卡1网卡2Send()SendPackage()MySendPackage1()MySendPackage2()系统调用驱动程序接口硬件操
3、作图5.1 驱动程序模型北京理工大学珠海学院 计算机教研室72022-5-31n5.1.2 何时编写驱动程序操作系统没有内置支持的硬件扩展已有驱动的功能提供软件层面的服务n伪驱动(Pseudo Driver):所谓的伪驱动,就是不是真正意义上的驱动;而挂着驱动的名号,却又是因为和底层驱动有着千丝万缕的联系. n5.1.3 驱动程序模型为简化驱动程序的编写,把驱动程序分层提取某一类外设的共性,作为独立的一层,并提供通用的代码和库北京理工大学珠海学院 计算机教研室82022-5-31n5.1.4 编写驱动程序的几个要素了解驱动程序所针对的硬件(Datasheet)了解目标操作系统下驱动的工作机制n
4、驱动程序的加载和卸载;n驱动程序的初始化工作;n外设I/O的访问;n中断的处理;nDMA的处理;n内存的使用以及异步操作的进行方式等。了解驱动程序的模型n不同的操作系统会提供不同的驱动模型北京理工大学珠海学院 计算机教研室92022-5-315.2 Windows CE驱动程序n5.2.1 Windows CE驱动程序开发简介驱动程序的两种形式n.LIB库文件,随操作系统的启动和关闭进行加载和卸载;n操作系统启动后对硬件进行延迟加载。Windows CE的所有驱动程序都以用户态下的DLL文件形式存在,运行在用户态。北京理工大学珠海学院 计算机教研室102022-5-31驱动程序作为用户态DLL
5、的优点:n给操作系统和驱动程序带来了很大的灵活性,动态加载所需的驱动程序,可实现外设的即插即用;n增强系统的稳定性;n给驱动开发人员提供便利。n5.2.2 Windows CE驱动程序的宿主DLL无法单独被加载和运行,必须先有一个EXE进程将DLL加载到自己的地址空间Windows CE中有3个系统进程会加载和执行驱动程序的DLL,分别是Device.exe,GWES.exe,FileSys.exe北京理工大学珠海学院 计算机教研室112022-5-31Device.exe网卡电池声卡串口NLEDUSB HOSTHIDPrinterrNDISMass StoragePCMCIAHostATAD
6、iskSerCardGWES.exe鼠标驱动键盘驱动触摸屏驱动打印机驱动显示驱动FileSys.exe文件系统驱动图5.2 系统进程与其加载的驱动程序北京理工大学珠海学院 计算机教研室122022-5-31Device.exe在Windows CE中称做设备管理器。负责加载和管理Windows CE下绝大多数的设备驱动程序,包括网卡驱动、电池驱动、声卡驱动、串口驱动、USB设备驱动及PCMCIA驱动等;GWES.exe通常是一些与图形界面相关的I/O设备驱动。例如鼠标键盘驱动、显卡的驱动及触摸屏驱动等。FileSys.exe在系统中负责管理Windows CE中的对象存储和文件系统。故File
7、Sys.exe须负责加载所有的文件系统驱动程序。如FAT文件系统驱动和CDFS文件系统驱动等。北京理工大学珠海学院 计算机教研室132022-5-31n5.2.3 分层驱动程序与单体驱动程序GWESDDI函数DDI函数分层驱动程序MDDDDSI函数PDD单体驱动程序硬件图5.3 单体驱动程序与分层驱动程序北京理工大学珠海学院 计算机教研室142022-5-315.2.3.1 单体驱动程序n即所有的驱动程序代码(包括中断处理、I/O操作及硬件控制等)都被放在一起。n会暴露DDI接口(Device Driver Interface)给操作系统。DDI函数是操作系统与驱动程序交互的接口协议。5.2.
8、3.2 分层驱动程序n分两层:上面一层是模型设备驱动(Model Device Driver,MDD),下面一层是平台相关驱动(Platform Dependence Driver,PDD)nMDD层包含某一类型的驱动程序所通用的代码;PDD层包含特定的硬件或平台专用的代码。n操作系统访问硬件时,MDD层会调用特定的PDD函数nPB会自带某类型驱动的MDD代码,无须修改;只须修改PDD层的代码。驱动程序代码相对紧凑,对于效率要求较高的场合,可以选择。同时此模型相对清晰北京理工大学珠海学院 计算机教研室152022-5-31n给驱动程序分层后,MDD和PDD之间还需要一个接口协议。故分层驱动中有
9、两类接口函数:操作系统与MDD之间的DDI与MDD和PDD之间的DDSI(Device Driver Service provider Interface)n通常,MDD层的代码与PDD层的代码被编译成独立的静态LIB库,然后进行链接,形成可执行的驱动程序。MDD与PDD的划分只是在源代码逻辑层面,在驱动程序的二进制可执行代码中不存在分层概念nMDD的特性:包含某一类驱动程序所通用的代码;调用PDD层访问硬件设备;与PDD层代码进行链接,定义PDD层必须实现的DDSI函数,并在代码中使用这些函数;对于操作系统实现DDI函数,供操作系统与驱动程序交互;北京理工大学珠海学院 计算机教研室16202
10、2-5-31nMDD的特性:进行中断处理;对于同一类型的驱动程序,代码可重用;编译后生成的lib库可与不同的PDD库进行链接;通常无须改动;中断处理线程IST通常位于这一层。nPDD层的特性:包含与某款硬件相关的代码;对于不同的硬件产品或标准有不同的实现;只能与某一类MDD协同工作;实现MDD所需要的DDSI函数。在PB中自带的驱动程序中,声卡驱动程序的代码是典型的分层驱动程序例子。 %_WINCEROOT%PUBLICCOMMONOAKDRIVERSWAVEDEV目录下北京理工大学珠海学院 计算机教研室172022-5-31n5.2.4 Windows CE驱动程序的分类(P202)n5.2
11、.5 示例驱动程序代码PB自带了大量的驱动程序代码Production-Quality Device Driver(P205)特性n不经修改就可在总线工作;n尽量减少驱动程序在不同的硬件平台上移植所作的改动n对于特定的驱动技术,实现尽量多的功能;n在PB IDE的Catalog View中要有对应的可选项;n对硬件设备所依赖的总线不作任何假设;n对源代码有充分的注释;n尽量使用Windows CE5.0的特性;n尽量减少PDD的代码,使驱动程序更加方便移植;n对于资源的分配,尽量使用注册表进行配置;n提供可重用平台无关的库。北京理工大学珠海学院 计算机教研室182022-5-31大部分驱动程序
12、的代码放在目录%_WINCEROOT%PUBLICCOMMONOAKDRIVERS下,这些驱动程序都是与平台无关的。在BSP目录中也有一些驱动程序的代码,在目录%_WINCEROOT%PLATFORMSRCDRIVERS中,这些驱动都是与平台相关的。北京理工大学珠海学院 计算机教研室192022-5-31EXE文件n比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。n可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。n在构造软件系统时,常常将所有模块的源代码都静态编译到整个应用程序EXE文件中。北京理工大学珠海学院 计算机教研
13、室202022-5-31EXE文件的软肋n源代码都静态编译到整个应用程序EXE文件中,会产生一些问题。一是增加了应用程序的大小,占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费。另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。 北京理工大学珠海学院 计算机教研室212022-5-31Windows CE中如何解决问题?nWindows CE中内存资源更少,甚至都没有硬盘,资源问题更为突出。nWindows系统平台上提供了一种有效的编程和运行环境,你可以将独立的程序模块创建为较小的文件,并可
14、对它们单独编译和测试。n这些较小的模块就是动态链接库DLL。北京理工大学珠海学院 计算机教研室222022-5-31Windows CE中的DLLn在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。nWindows自己就将一些主要的系统功能以DLL模块的形式实现。北京理工大学珠海学院 计算机教研室232022-5-31动态链接库(Dynamic Link Library)n动态链接库缩写为DLL。nDLL是一些编译过的可执行程序模块、数据或其他资源,可以被应用程序或其他DLL调用。nDLL的应用非常广泛,可以实现多个应用程序的代码和资源共享。北京理工大
15、学珠海学院 计算机教研室242022-5-31动态链接库的组成nDLL是一种磁盘文件,以dll、DRV、FON、SYS和许多以EXE为扩展名的系统文件都可以是DLL。n它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。n如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。北京理工大学珠海学院 计算机教研室252022-5-31动态链接库的几点注意nDLL中包含各种导出函数,用于向外界提供服务。nDLL有自己的数据段,但没有自己的堆栈,使用与调用它的程序相同的堆栈。n一个DLL在内存中只有一个实例。nDLL的编制与具体的编程语言及编
16、译器无关。 北京理工大学珠海学院 计算机教研室262022-5-31动态链接库的特点动态链接库的特点北京理工大学珠海学院 计算机教研室272022-5-31共享资源n共享代码、资源和数据。DLL不仅可以包含可执行的代码,还可以包括数据和各种资源等,扩大了库文件的使用范围。北京理工大学珠海学院 计算机教研室282022-5-31方便应用程序的扩展n由于DLL能被应用程序动态载入内存。所以,应用程序可以在需要时才将DLL载入到内存中,这让程序的可维护性变得很高。n比如微软的操作系统经常需要升级,微软的程序员不必将操作系统代码都重写一遍,只需将需要升级的相关DLL文件重写即可。北京理工大学珠海学院
17、计算机教研室292022-5-31DLL与语言无关n一个小组成员共同完成一个软件项目。每个人所使用的编程工具并不同,每人负责的部分所使用的编程语言都不同,如何合作完成项目呢?n使用DLL就可以解决这个问题,程序员提供自己完成代码的DLL即可,主程序调用这些DLL即可。北京理工大学珠海学院 计算机教研室302022-5-31节省内存n如果多个应用程序调用的是同一个动态链接库,那么这个DLL文件不会被重复加载到内存中,而是由这些应用程序共享同一个已载入内存的DLL。n在一个办公室中,一般大家会共用一个网络打印机,不会为每一个员工配置一台打印的。 n在嵌入式系统中更有意义。北京理工大学珠海学院 计算
18、机教研室312022-5-31隐藏程序的细节n在某些情况下,用户可能想隐藏程序的源代码,就可以采用DLL来实现,DLL的例程可以被应用程序访问,而不显示其中代码的细节。n可以有效地保护自己的知识产权。北京理工大学珠海学院 计算机教研室322022-5-31节省内存n如果多个应用程序调用的是同一个动态链接库,那么这个DLL文件不会被重复加载到内存中,而是由这些应用程序共享同一个已载入内存的DLL。n在一个办公室中,一般大家会共用一个网络打印机,不会为每一个员工配置一台打印的。 n在嵌入式系统中更有意义。北京理工大学珠海学院 计算机教研室332022-5-31动态链接库的实现动态链接库的实现北京理
19、工大学珠海学院 计算机教研室342022-5-31DLL入口函数n每一个DLL必须有一个入口点,DLLMain是一个缺省的入口函数。nDLLMain负责初始化(Initialization)和结束(Termination)工作,每当一个新的进程或者该进程的新的线程访问DLL时,或者访问DLL的每一个进程或者线程不再使用DLL或者结束时,都会调用DLLMain。北京理工大学珠海学院 计算机教研室352022-5-31DLLMain的函数原型nint WINAPI DLLMain(HINSTANCE hinstance,DWORD fdwReason,PVOID pvReserved )nswit
20、ch(fdwReason) ncase DLL_PROCESS_ATTACH:ncase DLL_THREAD_ATTACH:ncase DLL_THREAD_DETACH:ncase DLL_PROCESS_DETACH:nreturn TRUE;nn北京理工大学珠海学院 计算机教研室362022-5-31DLLMain的函数的参数nhinstance是动态库被调用时所传递来的一个指向自己的句柄。nfdwReason是一个说明动态库被调原因的标志。当进程或线程装入或卸载动态连接库的时候,操作系统调用入口函数,并说明动态连接库被调用的原因。它所有的可能值为DLL_PROCESS_ATTACH
21、进程被调用DLL_THREAD_ATTACH 线程被调用DLL_PROCESS_DETACH 进程被停止DLL_THREAD_DETACH 线程被停止nlpReserved是一个被系统所保留的参数。北京理工大学珠海学院 计算机教研室372022-5-31动态链接库的加载动态链接库的加载北京理工大学珠海学院 计算机教研室382022-5-31动态链接库的加载n动态链接库的加载分为即静态加载方式和动态加载方式。n静态加载方式是在编译程序代码时即完成对DLL的加载,应用程序结束时卸载DLL。n动态加载方式是使用用API函数来加载和卸载DLL的。 北京理工大学珠海学院 计算机教研室392022-5-3
22、1动态链接库的静态加载动态链接库的静态加载北京理工大学珠海学院 计算机教研室402022-5-31动态链接库的静态加载n静态加载方式由编译系统完成对DLL的加载。n应用程序完成对DLL的卸载。n加载方法简单,但不够灵活。北京理工大学珠海学院 计算机教研室412022-5-31LIB文件用来做什么?n在生成一个DLL文件时,链接程序会自动生成一个与之对应的LIB文件。nLIB文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。北京理工大学珠海学院 计算机教研室422022-5-31编译应用程序n把生成动态连接库时生成的LIB文件和DLL文件加入到应用程序的工程中。n通过
23、静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号进入到生成的EXE文件中。nLIB文件作为DLL的替代文件被编译到应用程序工程中。北京理工大学珠海学院 计算机教研室432022-5-31DLL中函数的调用(1/2)n当应用程序运行过程中需要加载DLL文件时,Windows CE根据LIB中的信息发现并加载DLL。n然后通过符号名或标识号实现对DLL函数的动态调用。北京理工大学珠海学院 计算机教研室442022-5-31DLL中函数的调用(2/2)n所有被应用程序调用的DLL文件都会在应用程序EXE文件加载时被加载在到内存中。n可执行程序直接通过
24、函数名调用DLL的输出函数,调用方法和程序内部其他的函数是一样的。北京理工大学珠海学院 计算机教研室452022-5-31DLL如何共享?nDLL静态加载后,系统会建立对该DLL的调用记录。n如还有其它程序使用该动态链接库,则Windows CE对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它。北京理工大学珠海学院 计算机教研室462022-5-31DLL静态加载实例n利用PB或VS2005生成动态链库wcedll.dll和wcedll.lib文件。n利用EVC创建一个测试工程wcetest,用以测试动态链接库的静态加载。北京理工大学珠海学院 计算机教研室472022-
25、5-31设置依赖关系 n将两个库文件wcedll.dll和wcedll.lib拷贝到当前测试工程wcetest所在的文件夹下。n选择Projects菜单,选择Setting,进入Link标签,在Category下拉框中找到Input,在Object/library modules编辑框中添加wcedll.lib一项内容。北京理工大学珠海学院 计算机教研室482022-5-31运行测试代码n编译并下载wcetest.exe,保证代码没有错误。n在目标平台上找到wcetest.exe应用程序,双击它,让其运行起来。n通过EVC的Remote Process Viewer就可以看到wcetest.e
26、xe已经运行,而且wcedll.dll已经加载。北京理工大学珠海学院 计算机教研室492022-5-31动态链接库的动态加载动态链接库的动态加载北京理工大学珠海学院 计算机教研室502022-5-31动态链接库的动态加载n动态调用方式是由程序员编程使用API函数来加载和卸载DLL。n使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。n是一般常见的动态链接库的加载方法。n在嵌入式系统中更为常见。北京理工大学珠海学院 计算机教研室512022-5-31如何实现DLL动态调用?n在应用程序中用LoadLibrary显式的将自己所做的动态连接库调进来。n用GetProcAddres
27、s()获取想要引入的函数。n如同本应用程序自定义的函数一样来调用该引入函数。n在应用程序退出之前,用FreeLibrary释放动态连接库。北京理工大学珠海学院 计算机教研室522022-5-31DLL动态加载实例n利用EVC创建一个测试工程wcetest1,用以测试动态链接库的动态加载。n与静态调用DLL相比,程序中增加以下代码添加wcedll动态链接库工程的实现函数的定义。利用LoadLibrary API函数动态加载动态链接库,利用GetProcAddress API函数获取需要引用的函数。北京理工大学珠海学院 计算机教研室532022-5-31测试程序的源代码 n#include nty
28、pedef void (*printH) (void);nint WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR szCmdLine,int iCmdShow)n HANDLE hModule=LoadLibrary(TEXT(“wcedll.dll”);n if(hModule=NULL)n return 0; n elsen printH PrintHello= (printH) GetProcAddress(hModule,TEXT(PrintHello);n PrintHello(); n FreeLi
29、brary(TEXT(wcedll.dll);n return 0;n北京理工大学珠海学院 计算机教研室542022-5-31运行测试代码n编译并下载wcetest1.exe,保证代码没有错误。n在目标平台上找到wcetest1.exe应用程序,让其运行起来。n通过EVC的Remote Process Viewer就可以看到wcetest1.exe已经运行而且wcedll.dll已经加载。北京理工大学珠海学院 计算机教研室552022-5-31Windows CE如何定位DLLn定位DLL的搜索顺序包含EXE文件的目录 进程的当前工作目录 Windows CE系统目录 Windows CE目录列在Path环境变量中的一系列目录