微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PCI驱动程序开发实例

PCI驱动程序开发实例

时间:02-21 来源:互联网 点击:

须具备PnP例程。PnP管理器使用PnP例程来管理驱动程序启动、停止和删除设备。

  (4)分发例程(Dispatch):用于管理驱动程序与应用程序之间的通信,从而实现应用程序控制PCI设备的目的。

  严格地说,驱动程序中只有“初始化”模块Drivet-Entry例程是一定不能少的。在实际工作中,所有驱动程序都有分发例程处理用户I/O请求。

2.2 IRP处理

  I/O请求包(IRP)是驱动程序操作的中心,是一个预先定义的数据结构,带有一组对它进行操作的I/O管理器例程。一个IRP有固定的首部和可变数目的 IRP栈单元。IRP的固定部分含有IRP的固定属性,每个栈单元含有大多数有关的IRP参数。当IRP由多个驱动程序处理时,使用多个IRP栈单元。每个驱动程序从当前IRP栈单元得到它的IRP参数。如果把IRP沿当前设备的驱动程序栈向下传递,必须在当前驱动程序中使用正确的参数设置下一个栈单元,然后在此驱动程序中利用函数IoCalldriver()调用更低层的驱动程序。驱动程序不必处理所有的IRP,但至少需要处理“创建”和“关闭”这两个 IRP。I/O管理器接收I/O请求,然后在把它传递到合适的驱动程序栈中的最高驱动程序之前,分配并初始化IRP。驱动程序处理IRP的过程如图2所示。

       

  IRP首先到达最高层的驱动程序1,驱动程序1使用函数IoGetCurrentIrpStackLocation()获得指向当前栈单元的指针。

  然后驱动程序1使用IoCallDriver()函数调用下一个驱动程序。I/O管理器现在改变“当前IRF’栈单元”指针,所以驱动程序2看到向下的第二个IRP栈单元(驱动程序1为它设置的栈单元)。这个过程继续,直到最底层的的驱动程序4收到这个IRP。

  驱动程序4现在处理这个IRP。当它完成IRP的处理时,驱动程序4调用IoCompleteRequest()函数。指示它已经完成IRP的处理。IRP再沿设备栈向上传递,直到它最终弹出栈顶,回到用户。

  2.3 IRP的完成

  当一个驱动程序完成对IRP的处理时,它必须告诉I/O管理器,这称为IRP完成。如下面代码所示,必须设置IRP IoStatus域结构中的几个域。IoStatus,Status设置为一个NTSTATUS状态码,IoStatus.In-formation通常存储传输的字节数。如:

  Irp一>loStatus.Status=S T ATUS_SUCCESS

  Irp一>IoStatus.Information=info;

  IoCompleteRequest(Irp,IO_NO_INCREMENT);

  调用IoCompleteRequest()表明低层驱动程序已经完成了IRP的请求,并将这个IRP返回给I/O管理器。IO_No_INCREMENT是个系统定义的常量,指定启动该IRP的优先级,需要驱动程序快速处理。

3 驱动程序功能实现

  当把板卡第一次插到计算机的PCI插槽以后,计算机的系统总线会检测到有个新设备没有安装驱动程序,并提示安装驱动程序。正确地安装驱动程序以后,用户就可以在应用程序中与驱动程序进行通信。

  3.1 打开设备

  在应用程序中调用系统提供的函数CreateFile()。如果系统根据设备名确实检测到设备并成功打开了这个设备,则返回一个指向这个设备的有效句柄;如果调用失败,则返回一个错误信息。

  3.2 读/写设备

  读/写设备包括读/写设备的配置空间、读/写设备的非配置空间,其中,非配置空间包括I/O空间、存储空间。

  设备被打开以后,应用程序就调用DeviceloCon-trol()函数来达到访问设备的目的。DeviceIoControl()函数有8个参数,其中第3个参数是应用程序传递给驱动程序的数据缓冲区地址,在这个数据缓冲区存放的是应用程序要读写的设备的空间、偏移量、长度,这些都需要在应用程序中配置好。

  这个调用由I/O系统服务接收。I/O管理器从这个请求构造一个合适的I/O请求包(IRP)。在最简单的情况下,I/O管理器只是把IRP传递给一个设备驱动程序,这个驱动程序调用硬件,并完成IRP的处理。I/O管理器把数据和结果返回给Win 32和用户应用程序。现在一个分层的设备驱动程序栈是很常见的。每个驱动程序把该请求划分为更简单的请求。高层次的驱动程序调用低层次的驱动程序,最后,最低层的驱动程序与硬件直接打交道完成用户的请求。I/O管理器把数据和结果返回给Win 32和用户应用程序。设备程序调用如图3所示。

  当应用程序读/写设备时,驱动程序工作的流程图如图4所示。

         

  首先,获取当前IRP栈单元的指针;然后再读取I/O控制代码,判断应用程序想达到什么样的目的:是读/写配置空间,还是读/写非配置空间,然后再调用相应的处理程序。

  4 结 语

  这里采用微软的驱动程序开发包Device Driver Kit(DDK)是因为它是其他几种工具的基础,它要求开发人员深刻了解驱动底层,虽然不易掌握,但开发出来的驱动程序通用性好,兼容性强。板卡与PC机的通信速度得到了很大的提高。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top