基于WDF的PCI—E驱动设计和实现

时间:2022-09-27 10:56:14

基于WDF的PCI—E驱动设计和实现

【摘要】简要介绍了基于PCI-E的数据采集系统构成、开发工具选择、WDF对象模型及特点,重点介绍了WDF开发PCI-E驱动程序的主要方法步骤、DMA方式进行数据传输和事件通知的实现方法。经过现场实际测试,该系统高效稳定可靠,所开发的驱动程序完全可以实现数据的高速传输。

【关键词】PCI-E总线;WDF模型;驱动程序;直接存储器访问

1.引言

PCI-Express是一种最具发展前景的总线和接口标准,早在2001年的春季英特尔开发者论坛(IDF)上,Intel公布了第三代I/O互联技术(3GIO),用以取代PCI总线和多种芯片的内部连接。2001年底,包括Intel、AMD、Dell、IBM等20多家业界主导公司起草了新技术的规范,对其正式命名为PCI Express,简称PCI-E,代表着下一代I/O接口标准。PCI-E采用与全双工通信技术类似的双通道传输模式,具有速度快、点对点串行传输,是两端设备可以独享带宽,扩展灵活方便,支持热插拔以及服务质量(QoS)的优点。PCI-E总线具有极高的传输速率,规格从x1通道到x32通道,其中x1通道双向传输速度为5Gbps,而PCI-E 3.0规范中x32通道双向传输速度可达320Gbps,满足目前绝大部分场合的需要。PCI-E设备连接到计算机系统必须有相应的驱动程序才能在计算机系统上正常工作。PCI-E驱动程序的优劣直接关系到整个系统的性能和稳定性,因此,设计和开发稳定高效的PCI-E驱动程序具有重要意义。

2.硬件系统

在设计PCI-E驱动程序之前,先对要控制的硬件系统和工作流程做简要的分析介绍。硬件系统的基本结构框图如图1所示。这是一套自行开发的基于PCI-E接口的分布式数据采集系统,主要实现了分布式高速数据采集及传输。

图1左侧是基于FPGA的数据采集单元,采集单元不间断采集实际运行数据,数据同步单元将多个采集单元的数据汇总打包,然后通过PCI-E传送到PC后台服务器。数据同步单元与采集单元、PC后台服务之间均采用PCI-E连接,传输介质为光纤。采集系统的核心是基于PowerPC处理器的数据同步单元,数据同步单元选用了FreeScale公司的MPC8536处理器,该处理器内部集成PCI-E、USB、以太网、内存等部件。用MPC8536配置与PC后台服务器相连接的PCI-E总线接口,包括PCI-E接口寄存器、基地址寄存器、Memory空间。为了实现高速数据传输,本设计把MPC8536作为DMA主控制器,MPC8536自带PCI-E有四路DMA通道,通过MPC8536来实现采集同步后的数据向PC后台服务器的高速传输。

3.驱动开发工具选择

Jungo公司开发的WinDriver驱动程序开发软件包,易于使用,不需要熟悉操作系统的内核知识及系统相关底层的东西,整个驱动程序中的所有函数都工作在用户态,所以该软件包开发的驱动程序灵活和工作效率都很低。

NuMega公司开发的DriverStudio驱动程序开发软件包,采用面向对象的方式,将驱动程序编写所需的与内核访问及对硬件的访问封装成类,加上驱动程序代码生成向导DriverWizard等工具,简化了驱动程序开发的难度,减少了工作量,灵活性也很好。但该软件目前已经停止开发,不支持Windows7、8等新版本的操作系统。

WDK(Windows Driver Kit)是Microsoft公司开发一种完全集成的驱动程序开发系统,包括WDF、头文件重构(Windows Vista和更高版本)、验证程序和静态分析工具。极大地简化Windows驱动程序的开发,利用WDF开发驱动程序具有代码简单,结构清晰,效率高,而且对整个体系结构有很好的理解和把握。本文采用WDK进行PCI-E的驱动程序开发。

4.WDF对象模型

WDF(Windows Driver Foundation)是微软提出的下一代全新的驱动程序模型,是以WDM(Windows Driver Model)为基础进行建模和封装,完全基于面向对象技术实现,支持属性、方法和事件。提供了高度灵活、可扩展、可诊断的驱动程序框架。WDF框架管理了大部分与操作系统相关的交互,实现了公共的驱动程序功能,如电源管理、即插即用pnp等,降低了驱动程序开发的难度。WDF提供了两个框架:KMDF内核模式驱动程序框架和UMDF用户模式驱动程序框架。本文介绍的PCI-E驱动程序属于KMDF内核模式。KMDF框架支持面向对象、事件驱动的驱动程序模型。它定义了一系列的对象用来表示设备、驱动、中断等,每个对象有对应的属性、方法和事件。驱动程序利用这些方法创建对象、设置属性和响应事件。

WDF的对象模型是层次化的模型。WDFD-RIVER对象是根对象,其他对象都是它的子对象。对于大多数对象,驱动程序在创建它们的时候可以指定父对象,如果没有指定,则框架默认其父对象为WDFDRIVER对象。

WDF大大简化了WDM中的pnp和电源管理的开发。WDF框架为设备停止、设备删除、电源状态切换等事件提供了适合的缺省行为,驱动程序本身不再纠缠于复杂的pnp和电源管理事件处理。此外,WDF还集成了请求队列的支持,一个设备可以有多个请求队列,每个请求队列可以有一种模式。

最简单的是WdfIoQueueDispatchSerial模式,在这种模式下,请求队列将请求串行化后再处理;而WdfIoQueueDispatchParallel模式则自动在每个请求到来时调用相应的回调函数;最后WdfIoQueueDispatchManual模式允许驱动程序手工分发请求,类似于WDM的工作方式。

5.PCI-E驱动程序设计

5.1 驱动程序初始化

第一次加载驱动程序时调用DriverEntry例程,DriverEntry是WDF驱动程序的标准入口函数,DriverEntry例程负责驱动程序和框架的初始化。在DriverEntry例程中主要创建驱动程序对象WDFDRIVER和设置EvtDeviceAdd例程地址,驱动程序对象WDFDRIVER代表PCI-E驱动程序。

PCI-E驱动程序整体框体如图2所示,驱动程序初始化后,当PnP管理器检测到新的PCI-E硬件设备时,PnP管理器根据安装驱动程序时inf文件中的设备识别号和厂商识别号找到相应的设备驱动,然后调用在DriverEntry例程中设置的EvtDeviceAdd对应的回调例程。完成PCI-E设备驱动程序的初始化。初始化过程主要完成创建设备对象、创建I/O队列、设备GUID接口、初始化中断处理、创建DMA操作对象,并设置各种事件的回调处理例程,如即插即用、电源管理、I/O处理等等。在该例程中创建设备对象作为目标I/O设备,并将该设备对象附着到设备堆栈中。驱动程序还将完成设备内存空间的获取及转换,这点非常重要,因为这将直接影响驱动程序工作时的正确性和稳定性,具体过程是通过调用EvtDevicePrepareHardware例程获取设备的内存的物理地址和长度,部分代码如下:

用WdfCmResourceListGetCount函数获取配置资源的个数,用WdfCmResourceListGetDescriptor函数获取该资源的描述符,其类型属性包括CmResourceTypeMemory(存储器)、CmResource-TypePort(IO端口)、CmResourceTypeInterrupt(中断)等,对于存储器地址,用MmMapIoSpace将物理地址转换成系统内核模式地址,并将该内核模式地址保存到设备扩展对象中供以后使用,

5.2 数据传输

数据传输是驱动程序和同步单元MPC8536的Memory之间进行的数据传输,本设计把待传输的数据分为两类,一类是控制命令类数据,另一类是采集的数据,即MPC8536同步单元需要传送到PC后台服务器的数据。控制命令类数据通过发送IoControl命令的方式进行传输。采集的数据则通过DMA方式传送,因为对于高速数据流来说,需要速度更快,传输效率更高,DMA方式传送能满足性能要求,而且也保证了数据在传输过程中不丢失。

控制命令类数据的传输,操作系统检测到硬件设备并加载相应的驱动程序后,应用程序就可以通过DeviceIoControl发起一个device I/O control请求,控制命令类数据定义成device I/O control请求功能码,通过这个请求即可发送各种控制命令类数据,驱动程序中EvtIoDeviceControl例程将接受并处理DeviceIoControl请求,DeviceIoControl可以通过参数传送不同的功能请求码,驱动程序中根据不同的功能码做不同的响应处理,例如,启动/停止数据传输、复位设备、设置句柄等等,具体功能码和用途见表1所示。

采集的数据传输,由于采集数量大,为了及时可靠的完成数据传输,采用DMA方式传输。DMA方式传输的工作流程如下:用WdfDmaTransactionInitializeUsingRequest函数初始化DMA传输,调用WdfDmaTransactionExecute启动DMA编程。在EvtProgramDmaDMA中对MPC8536的DMA寄存器进行编程进行数据传输。当DMA传输中断发生,在DPC例程中测试DMA是否结束,没有结束则调用WdfDmaTransactionExecute函数继续执行DMA。若DMA传输结束则完成该I/O请求。同步单元中的MPC8536作为DMA的主控制器,当缓冲区区中的采集数据达到一定数量后,MPC8536利用DMA方式将缓冲区中的数据直接写到PC后台服务器的内存空间,并产生一个DMA中断通知驱动程序,驱动程序收到中断后调用中断响应例程来处理内存空间的数据。PC后台服务器中用于DMA读写的内存空间由驱动程序分配,应用程序利用这段内存空间直接与同步单元的MPC8536进行DMA方式的数据传输。

为了提高驱动程序和应用程序之间的处理效率,驱动程序采用事件方式与应用程序进行通信。应用程序中用CreateEvent创建事件hEvent,调用DeviceIoControl函数将事件传递给驱动程序,驱动程序响应该请求,从输入缓冲区中取出这个事件句柄存在设备扩展对象中。当驱动程序处理完DMA传输中断后将该事件设置为信号状态,此时应用程序就可以处理已经传送到PC后台服务器内存空间中的数据了。

6.结束语

PCI-E作为一种高性能的总线,已经得到了广泛的应用,文章阐述了基于WDF的PCI-E驱动程序开发,经测试在windows2003系统下驱动程序运行稳定,在数据链路x1通道的条件下用DMA方式传输,数据率可以达到100MB/s,数据传输速率比较理想,满足项目的要求,目前已经成功运用于某海上采油平台的数据采集中,经现场实际运行验证,工作稳定可靠。

参考文献

[1]王齐.PCI Express体系结构导读[M].北京:机械工业出版社,2010.

[2]武安河.Windows设备驱动程序WDF开发[M].北京:电子工业出版社,2009.

[3]MPC8536E PowerQUICC III.Integrated Processor Reference Manual Rev.0 10/2008.

[4]Microsoft Corporation.Architecture of the Windows Driver Foundation[EB/OL].2005.http:///whdc/driver/wdf/default.mspx1

[5]杨阿锋,吴帅,刘凯.PCIe接口高速数据传输卡的驱动程序开发[J].中国测试技术,2008,3:67-68.

作者简介:石美传(1977—),女,黑龙江齐齐哈尔人,硕士,工程师,主要从事继电保护及嵌入式系统研发工作。

上一篇:一种小型物料自动导引小车的设计及分析 下一篇:浅述中国传统器具与现代工业化产品的比较与思...