模块化的设备驱动程序设计方法
摘要:介绍了WindowsNT下设备驱动程序的开发环境,一种模块化的设计方法,应用程序与驱动程序之间的同步以及驱动程序的安装。
关键词:WindowsNT;设备驱动程序;Event对象
1引言
WindowsNT/2K以其形象直观的界面、简单方便的操作,基本上已经取代DOS成为测控软件的操作平台。又因为WindowsNT/2K出于安全性、稳定性的考虑,为了防止用户应用程序访问和更改重要的操作系统数据,WindowsNT/2K使用两种“处理器访问模式”:用户态和核心态。在用户态,应用程序不能直接对硬件进行访问和操作;而在核心态中,程序对任何I/O设备有全部的访问权,还能访问任何虚地址和控制虚拟内存硬件。为了使用户态的程序访问和操作硬件,必须通过某种机制,也就是使用设备驱动程序跨越操作系统的边界对物理硬件进行访问操作。同时提供一些控制接口,进而用户态的应用程序利用设备驱动程序提供的接口间接地对物理硬件进行访问操作。
2设备驱动程序的开发环境
安装4种软件:MicrosoftVisualC++6.0、PlatformSDK(SoftwareDevelopKit)forWindowsNT、DDK(DeviceDevelopKit)forWindowsNT、DriverStudio2.0。然后进行一些系统环境变量的设置:
(1)变量名:MSTOOLS,值:SDK在操作系统中的安装路径(如:C:mstools);
(2)变量名:CPU,值:i386;
(3)变量名:BASEDIR,值:DDK在操作系统中的安装路径(如:C:NTDDK)。
在开发驱动程序时,首先要生成DriverStudio需要的库文件vdw.lib(通过编译DriverStudio安装目录下\DriverWorks\Source\vdw.dsw)。然后运用DriverStudio2.0生成一个编程框架,并删除DriverStudio所生成的编程框架中的所有文件,就可以在这个框架中编写自己的设备驱动程序;编写完以后可以直接在VisualC++6.0下Build生成设备驱动程序*.sys。
3模块化驱动程序的编写
3.1设备驱动程序包括的几大模块
设备驱动程序管理实际数据传输和控制物理设备的操作,包括开始和完成I/O操作、处理中断和执行设备要求的任何操作。
一般通用的设备驱动程序可以分为主要4个模块:初始化例程、卸载例程、驱动程序和应用程序之间的数据交换例程、中断服务例程。
3.1.1初始化例程(DrvierEntry)
是驱动程序的入口。在这个例程中主要包括以下步骤:
(1)初始化Driver对象;
(2)调用IoCreateDevice创建一个Device对象,并通过调用IoCreateSymbolicLinks使设备对Win32子系统可见;
(3)初始化Device对象的DeviceExtension;
(4)查找和分配驱动程序要管理的任何硬件;
(5)把一个设备连接到一个Interrupt对象,如果需要并初始化驱动程序的DPC对象。
3.1.2卸载例程(DriverUnload)
它与驱动程序的初始化例程刚好相反。
(1)把与设备连接的Interrupt对象断开。一旦Interrupt对象消失,设备不产生任何中断请求,这是最重要的;
(2)释放驱动程序所占用的任何系统资源;
(3)使用IoDeleteSymbolicLink从Win32名字空间删除设备,并用IoDeleteDevice删除Device对象自身。
3.1.3驱动程序与应用程序之间的数据交换例程
首先简单介绍一下I/0请求包(IRP):IRP是I/O系统用来存储I/O请求信息的地方。IRP由两部分组成:固定部分(称作标题)和一个或多个堆栈单元。固定部分信息包括:请求的类型和大小、同步请求还是异步请求,用于缓冲I/O的指向缓冲区的指针和由于请求的进展而变化的状态信息;IRP的堆栈单元包括一个功能码、功能特定参数和一个指向调用者文件对象的指针。
应用程序与驱动程序交换数据主要是由Win32CreateFile、CloseHandle、ReadFile、WriteFile和DeviceIoControl函数发出请求,接着I/O管理器把这些请求转化为叫做I/O请求包(IRP)的数据结构形式,再由I/O管理器把这些I/O请求包发送到驱动程序。数据交换例程的主要作用是接收I/O管理器所发出的IRP,然后解析这些IRP,从而得知IRP从应用程序传递过来的数据。解析IRP主要是运用C语言的switch语句,根据IRP的堆栈单元中的参数(如IRP_MJ_CREATE、IRP_MJ_READ、IRP_MJ_DEVICE_CONTROL等)进行不同的处理。最后IRP的完成处理也非常重要,它要做的是返回系统,完成一个I/O请求的信息,系统根据返回的信息释放IRP,以便使系统顺利进行下一个IRP的处理。这里需要说明的是这个例程只是完成了数据从应用程序到驱动程序的传递,而没有进行任何实际的设备操作。
3.1.4中断服务例程
中断服务例程主要是进行直接的任何设备的操作。驱动程序与应用程序之间的数据交换例程只完成了数据从用户空间到核心空间的传递,而中断服务例程根据传递过来的数据,直接对I/O端口进行访问操作。
3.2设备驱动程序的模块化实
- 基于FPGA的DSP设计方法(08-26)
- 专家指导:Linux操作系统密码恢复方法(05-16)
- 基于多核DSP Bootload代码加载方法研究(01-16)
- 基于DSP 的大容量无线传输技术中高性能的启动方法(03-16)
- 多核调试新方法探讨(10-22)
- 有备无患Linux操作系统备份方法介绍(06-06)