好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

Windows2000设备驱动程序的研制开发 .doc

7页
  • 卖家[上传人]:l****6
  • 文档编号:38008306
  • 上传时间:2018-04-25
  • 文档格式:DOC
  • 文档大小:36.50KB
  • / 7 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 1Windows2000 设备驱动程序的研制开发 引言:由于工作关系,我经常涉及 PC 机与外围设备接口的工作,从 PC 机这方面要做的工作看来,主要是通过接口处理外围设备的中断,通过 I/O 端口或内存地址与外设互相传递数据从计算机原理的角度看,所要达到的目的很简单,那么如何编写程序完成上述功能呢?目前国内流行的 PC 操作系统有三种:DOS,Win95/98 系列,WindowsNTDOS 是单用户、单任务操作系统,由于 PC 机硬件处理速度不断提高,基于单用户、单任务的操作系统越来越不能充分发挥硬件的功能,现在只应用于一些老式 PC 及其它个别场合,有逐渐被淘汰的趋势;Win95/98 系列和 WindowsNT 属于多任务操作系统,不论从其原理还是界面上看,这两种操作系统都比 DOS 有着无可比拟的优越性,这两种操作系统虽然在界面和操作上及其相似,但其内部实现的诸多方面有许多区别,有些区别是本质上的Win95/98 设计目标是针对一般家庭用户,安全性及可靠性存在许多薄弱环节,就可靠性而言,Win95/98 系列不能很好的防止多任务环境中某个进程的非法操作导致系统中其它程序甚至整个系统的崩溃,而 WindowsNT 在这方面及其它诸多方面设计的相当严谨。

      这两种操作系统是Microsoft 公司同一时期的产品,但针对不同的使用群,所以在一些重要场合及生产实践中应该选择 WindowsNT 作为计算机的操作系统,此外,从发展趋势来看,WindowsNT 已经成为定型产品,具有相对稳定性在不同操作系统下编写驱动程序是有很大区别的,在 DOS 平台上,应用程序和设备驱动程序之间没有标准的接口,它们在外部表现为一个扩展名为 EXE 的文件,2驱动程序的作用被柔和在应用程序中,这样,应用程序为了使用不同厂商的同一类设备,必须了解这些设备在接口上具体的硬件实现,同时,对于一个特定型号的硬件产品,所有支持它的应用软件中对于控制整个设备动作的这部分代码,可能被多次重写这种情况不适应硬件及应用软件的飞速发展Windows 系统在这方面,进行了根本性改进,把控制设备动作的这部分代码独立出来,提出了设备驱动程序的概念,驱动程序是应用程序和硬件设备之间的一个桥梁,应用程序与驱动程序之间有明确的接口,应用程序通过与驱动程序交换信息,达到控制外设的目的接口定义的操作是面向设备的,这就是说,在应用程序的设计中,并不用关心对外设操作的具体硬件实现,只是对驱动程序发出一系列指令既可;驱动程序接受来自上层应用程序的指示,具体操纵实际硬件,完成用户功能。

      具体实现上,Win95/98 系列与 WindowsNT 又有所区别,WindowsNT 是严格按照上述思路设计的;而 Win95/98 系列不那么严格,其支持上述思路,但同时应用程序也可以绕过驱动程序直接访问实际物理 I/O,这样做,增加程序设计的灵活性,但同时,对系统可靠性造成一定隐患这也正是 Win95/98 系列可靠性低于 WinNT 的原因之一表 1-1 三种操作系统下访问接口比较操作系统应用程序访问接口方式访问权限DOS直接访问3所有[注]Windows95/98通过设备驱动程序*.VXD所有[注]直接访问仅 I/O 端口WindowsNT通过设备驱动程序*.SYS所有[注][注]‘所有’指 I/O 端口,RAM 总线,中断,DMAWindowsNT 设备驱动程序的组成原理WindowsNT 操作系统结构分为用户模式和内核模式,用户模式下的编程为应用程序的设计,而开发设备驱动程序,则属于内核模式下的编程,内核模式组件包括 NT Executive(ExXxx),内核(KeXxx),硬件抽象层(HalXxx)其层次如图 2-1 所示,其中 NT Executive 包括几个独立的软件组件,它们是系统服务接口(ZwXxx),对象管理器(ObXxx),配置管理器,进程管理器(PsXxx),安全监视器(SeXxx),虚拟空间管理器(MemXxx),本地进程调用,I/O 管理器(IoXxx)。

      内核模式的系统服务并不是全部公开的,而是提供了一系列开发设备驱动程序需要的函数(上文括号内为函数形式,函数手册参见[2]Kernel-Mode Drivers-Reference 章节),换言之,这些函数功能是所有内核模式的系统服务功能的子集驱动程序由一系列相对独立的函数组成,由 I/O 管理器根据需要调用这些函数,4对于一个需要处理中断的最简单的驱动程序也需要由以下几个函数构成:1.DriverEntry() 运行于 PASSIVE_LEVEL 驱动程序入口点,当驱动程序被手动或自动装入系统后,驱动程序从这点开始执行,主要用于定位硬件资源,建立指向其它驱动程序函数的指针等其它初始化工作2.XxUnload() 运行于 PASSIVE_LEVEL 用于驱动程序从系统卸出之前,释放由驱动程序占用的所有系统资源3.XxIsr() 运行于 DIRQL 中断服务程序4.XxDpcForIsr() 运行于 DISPATCH_LEVEL 中断服务程序后处理程序,以排队方执行不太关键代码的执行,由于排队机制及优先级,不会造成代码拥塞从而提高中断服务程序的响应并且提高系统总体 I/O吞吐率5.XxOpen() 运行于 PASSIVE_LEVEL 处理应用程序 Win32 函数 CreateFile()请求。

      6.XxClose() 运行于 PASSIVE_LEVEL 处理应用程序 Win32 函数 CloseHandle()请求7.XxDispatch() 运行于 PASSIVE_LEVEL 处理应用程序 Win32 函数 DeviceIoControl()请求,通过一系列自定义命令,驱动程序与应用程序交换特定的信息WindowsNT 使用一个抽象化的 CPU 优先级方案, IRQL 代表中断请求级,任一时刻 CPU 总处在某一级上,这个数越大,表示当前的任务重要性越大,如表 2-1所示,从上至下 IRQL 越来越小所有上述驱动程序的函数及内核模式函数都必5须运行于各自的 IRQL 级上,如果违反这一调用规定,会造成系统崩溃例如,中断服务程序(XxIsr)运行于 DIRQL 及上,那幺在编写中断服务程序时,只能调用允许在这一级运行的内核模式函数(并不是所有内核模式函数都能运行于 DIRQL 级)至于每个内核模式函数运行级别的说明,详见[2]Kernel-Mode Drivers-Reference章节WindowsNT 是一多任务系统,许多设备的驱动程序同时存在系统中,这样各个设备所占用的资源(中断,I/O 及 RAM 地址空间)很有可能冲突,如果设备驱动程序在运行之前不进行‘探测’而使用自己硬件设备的资源,有可能和系统内其它设备占用的资源冲突,后果不堪设想。

      WindowsNT 通过注册表管理硬件资源的占用信息,作为内核模式信任的组件,驱动程序使用硬件资源之前必须遵循‘查询-申请-使用-释放’的原则(如图 2-2 所示)表 2-1来源 IRQL硬件 HIGHEST_LEVELPOWER_LEVELIPI_LEVELCLOCK2_LEVELCLOCK1_LEVELPROFILE_LEVEL6DIRQLs(I/O 设备中断平台相关的级数)软件DISPATCH_LEVELAPC_LEVELPASSIVE_LEVELWindowsNT 设备驱动程序的编写步骤与实例 现以一实际例子简要说明设备驱动程序的开发步骤,本例以 CINRAD 天气雷达测试卡实际应用为原型,加以简化、抽象第一步,了解被控设备的接口情况本例为一 ISA 卡,占用 PC 机 9 号中断,I/O 地址 360H 及 RAM 地址 D0228H 分别一个字空间 第二步,确定驱动程序的功能驱动程序每当 9 号中断达到时,检查运行标志变量 RunFlag(为一 BOOL 变量),如果等于 TRUE,中断累积计数器 counter(为一 unsigned short 变量)增一,把这个值写入 RAM 地址 D0228H,再从这个地址读出,如果读出值等于写入值,把这个值写入 I/O 地址 360H,这个地址的内容会驱动板卡上的 LED 显示,把写入值显示出来;如果读出值不等于写入值,设置运行标志变量 FALSE。

      如果运行标志变量等于 FALSE,什幺也不做,返回第三步,定义驱动程序与应用程序的软件接口本例定义两个接口命令:7IOCTL_IOCardA_START:应用程序设置驱动程序内部的运行标志变量等于TRUE IOCTL_IOCardA_READ:应用程序查询驱动程序内部的中断累积计数器的值 第四步,画流程图这里列举本例实现的几个主要流程图, (图略)系统传给驱动程序入口函数系统定义的‘设备驱动对象’DrObj,通过初始化这个对象的一些成员变量,把驱动程序其它函数与这个对象联系起来 ISA 卡为非即插即用设备,事先把资源占用信息手工添加注册表如下: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IOCardA\parame ters]“IRQ“=dword:00000009“IOSPAN“=dword:00000004“IOAdd“=dword:00000360“RAMAdd“=dword:000d0228“RAMSPAN“=dword:00000002其中 IOCardA 以下各子键及其值为自定义,设备驱动程序利用相应函数检索出这些值。

      3)每个设备驱动程序可以创建若干系统定义的‘设备对象’,本例根据需要只创建了一个‘设备对象’Dev ‘设备对象’其中一个成员变量为指向一非分页的物理内存块 DeviceExtension,这块内存大小及内容为用户自定义,由于 Dev 或DeviceExtension 对象会被系统传给驱动程序的其它函数,这样驱动程序各函数通过访问这块内存区,实际上达到互相传递信息的功能本例在这里存储设备硬件资源信息及 RunFlag 和中断计数器 counter,这些数值在 DriverEntry()初始化后,8供驱动程序的其它函数使用图 3-2 为中断服务程序 IOCardAIsr()流程图操作系统接受中断,连同DeviceExtension 等参数传给中断服务程序,中断服务程序利用这些参数,实现要求功能图 3-3 为 IOCardADispatch()流程图,这个函数用于处理来自上层应用程序的命令上层应用程序通过以下程序段设置驱动程序中 RunFlag 值为 TRUE,从而启动中断服务程序开始计数BOOL cmd=TRUE;hTest = CreateFile(...); //打开设备DeviceIoControl(hTest, //设备句柄IOCTL_IOCardA_START,//命令cmd,sizeof(BOOL), //输入缓冲区地址及大小NULL,0,c,NULL); CloseHandle(hTest); //关闭设备上层应用程序通过以下程序段查询当前的中断计数器的值并存于变量 w 中。

      unsigned short w;hTest = CreateFile(...); DeviceIoControl(hTest,IOCTL_IOCardA_READ, //命令9NULL,0,w,sizeof(unsigned short),//输出缓冲区地址及大小c,NULL);CloseHandle(hTest);其中 DeviceIoControl()执行后,操作系统调用 IOCardADispatch()函数,如流程图所示,这个函数内部通过一个开关语句,根据命令执行相应的分支驱动程序与应用程序通过此函数接口交换数据时,操作系统提供 4 种可选数据缓冲方式,本例由于数据 I/O 量比较小,故选用‘缓冲 I/O’ (METHOD_BUFFERED)过程是,I/O管理器首先分配一个非分页池,它的大小为。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.