1、 基于 PCI 总线数据采集卡的实时测控技术作者:孙业,张鹏,张哲,梁敏【摘要】 我们从软件技术的角度,论述了在 Windows XP 环境下基于 PCI 总线数据采集卡实现实时测控所需要的关键技术、软件体系结构和开发方法。遵循本文所讨论的技术路线,开发了 DFQ 系列多方位牵引床的测控软件,提高了被控系统的控制精度和可靠性,增强了系统的可用性。 【关键词】 PCI 总线;WDM 设备驱动程序;软件体系结构;计算机测量与控制Abstract:The key techniques, software architecture and development method used to impl
2、ement real-time measurement and control based on PCI bus data acquisition card in Windows XP environment are discussed from the viewpoint of software technology. The measurement and control software for DFQ multidimensional traction bed are developed according to the techniques provided in this pape
3、r,the precision, high reliability and better usability of the object system are improved.Key words:PCI Bus;WDM device driver;Software architecture;Computer measurement and control1 引 言计算机测控技术在生产实践中有着广泛的应用。基于计算机技术的测控系统主要分为两种类型。一类是以各种单片机、可编程逻辑芯片为核心组成的测控系统,这类测控系统一般适用于功能要求相对简单的被控对象,可独立构成测控系统,或以 PC 机作为上位
4、机构成两级级联的测控系统,此时 PC 机一般负责界面处理。一类是以 PC 机为核心构成的测控系统,PC 机通过数据采集卡及接口电路连接到被控对象。由于 PC 机具有高性能、易用性、可扩展性和丰富的软件资源等,此类系统可适用于功能要求较为复杂的被控对象。Windows XP 是一个多任务的并能够满足实时要求的操作系统,是目前 PC 机普遍采用的操作系统之一。PCI 总线是高性能的局部总线,支持高速数据传输,是 PC 机上流行的总线接口标准。我们从软件技术的角度,讨论了在 Windows XP 操作系统下,基于 PCI 总线数据采集卡,在工业现场实现实时数据测控的关键技术,包括实时 I/O 端口读
5、写和定时数据采集的实现方法。本研究的技术已成功应用于 DFQ 多方位牵引床的软件研发,取得了良好的效果。由于是在 Windows XP 操作系统下采用实时测控技术,最终设计完成的牵引床系统功能丰富,控制精确,可靠性高,具有良好的用户界面。2 系统的关键点和技术难点Windows XP 是一个多用户、多任务的操作系统。由于允许多个任务并发执行以及允许多个用户同时登录操作系统,安全性和稳定性是 Windows XP 操作系统设计的主要目标之一。在 Windows XP操作系统下,计算机的运行状态被强制为用户态和核心态两种状态。对于一个程序,在一个确定的时刻,要么在用户态执行,要么在核心态执行。在用
6、户态运行的程序处于系统最低的中断请求级(interrupt request level,IRQL)上,随时可以被具有更高中断请求级的中断请求所打断1。因此,为了能够在给定的时间约束内发出控制信号和采集数据,满足系统的实时性要求,提高系统可靠性,必须使得测控程序能够在核心态执行。其次,为了满足自身的稳定性,Windows XP 将对硬件的访问封装在了系统底层。用户态的应用程序不能直接访问硬件资源,包括读写 I/O 端口和内存,响应中断,执行 DMA 操作等。在 Windows XP 下,程序只有转入核心态,并通过系统调用才能直接访问硬件资源。显然,若能够获得直接访问硬件的能力,则可明显提高测控程
7、序的实时性和效率。综上所述,在 Windows XP 操作系统下,测控软件要获得本质上的实时性和高可靠性,必须具有在操作系统核心态运行的能力。设备驱动程序是 Windows XP 留给用户的允许用户获得核心态运行能力的唯一开发接口1。WDM(windows driver model)驱动程序模型是 Windows XP 下的设备驱动程序的模型之一,测控软件可借助WDM 驱动程序实现所要求的实时性和高可靠性。3 系统组成和开发环境如图 1 所示,牵引床控制系统由 PC 机、PCI 总线数据采集卡、外围接口电路和牵引床四部分组成2。PCI 总线数据采集卡是通用的标准模块,可供选择的产品很多,本系统
8、使用凌华公司的 PCI 9111 数据采集卡3。接口电路完成模拟信号和数字信号的调理和传输。系统测控程序由上层主程序和下层设备驱动程序两部分组成。主程序完成系统的总体逻辑功能和界面交互,运行于操作系统的用户态。设备驱动程序采集数据,完成牵引床的各种基本控制动作,运行于操作系统的核心态。主程序和驱动程序之间通过事件通知的机制完成通信联络,驱动程序向下调用操作系统的系统服务完成基本控制动作。软件开发环境由 Windows XP DDK(Driver Development Kit)、DriverStudio 3.1 和 Visual C 6.0 组成。Visual C 6.0 是系统主程序和驱动程
9、序的集成开发调试环境,DriverStudio 3.1和 Windows XP DDK 用于编译生成驱动程序。4 测控程序设计我们本节论述测控程序设计的几个关键问题,包括访问 PCI 9111数据采集卡,读写 I/O 端口,定时中断的实现方法和主程序与驱动程序的通信共四部分。4.1 访问 PCI 9111 数据采集卡PCI 9111 是一块集成的多功能数据采集卡,具有数字量输入输出、模拟量输入输出、定时计数的基本功能,支持软件查询方式、中断方式、DMA 方式多种数据传输方式,AD 采样频率最高支持 100 KHz。 PCI 9111 板卡上使用 PCI 90524作为 PCI 总线接口芯片,支
10、持 PnP 即插即用功能,用户无需手工设置板卡使用的硬件资源(如 IO 基地址、中断请求号等),这些硬件资源由计算机的 PnP子系统自动分配。用户通过基地址 BASE 加偏移量的 IO 端口读写方式,访问 PCI 9111 的各寄存器,实现对 PCI 9111 的控制命令写入和数据输入输出。因此,要访问 PCI 9111,必须首先要获得 PnP 子系统分配给 PCI 9111 的基地址。根据 PCI 总线规范, PnP 子系统分配给 PCI 设备的基地址,存储在 PCI 接口芯片的 BAR0BAR5 共六个 PCI 配置寄存器(PCI configuration registers,PCRs)
11、中。对于 PCI 9111 板卡而言,BAR1中存储的是 PCI 9052 芯片局部配置寄存器(local configuration registers,LCRs )的起始地址,BAR2 中存储的是局部地址空间 0 的基地址,即 PCI 9111 板卡寄存器的基地址 BASE。PnP 子系统为 PCI 设备分配的硬件资源,由操作系统的 PnP 管理程序通知给 PCI 设备的设备驱动程序。在 DriverStudio 的 WDM 设备驱动程序框架下,该信息以 IO 请求包(Irp)的形式传递给驱动程序设备类(是 KPnpDevice 的子类)的 OnStartDevice()成员函数。在 On
12、StartDevice()函数中,通过如图 2 中的代码,可获得 BAR1 寄存器和 BAR2 寄存器的值。NTSTATUS DfqDevice:OnStartDevice(KIrp I)PCMRESOURCELIST pResListRaw=I.AllocatedResources();PCMRESOURCELIST pResListTranslated=I.TranslatedResources();KPciConfiguration PciConfig(mLower.TopOfStack();/BAR1mIoLCR.Initialize(pResListTranslated, pResL
13、istRaw,PciConfig.BaseAddressIndexToOrdinal(1);/BAR2mIoPortRange.Initialize(pResListTranslated, pResListRaw,PciConfig.BaseAddressIndexToOrdinal(2);图 2 初始化 mIoLCR 和 mIoPortRangeFig 2 Initialization of mIoLCR and mIoPortRange在图 2 所示的代码中,mIoLCR 和 mIoPortRange 都是 DfqDevice类的 KIoRange 类型的成员变量。图 2 所示代码实际上是
14、使用 BAR1和 BAR2 寄存器的值分别对 mIoLCR 和 mIoPortRange 进行了初始化。mLower 是 DfqDevice 类的 KPnpLowerDevice 类型的成员变量,该成员变量指向代表 PCI 设备的底层物理设备对象。 4.2 读写 IO 端口一旦初始化 mIoPortRange 和 mIoLCR,进行 IO 端口读写就非常容易。使用 KIoRange 类的成员函数 inx()/outx(),可完成对指定端口的读写,其中 x 可为 b、w、d,分别表示 8 位数据、16 位数据和 32位数据。于是,调用 m_IoPortRange 对象的 IO 读写成员函数,可访
15、问 PCI 9111 板卡的各寄存器;调用 mIoLCR 对象的 IO 读写成员函数,可访问 PCI 9052 芯片的各局部配置寄存器。参照 PCI 9111 的用户手册3,就可以方便地完成 PCI 9111 数据采集卡的数字量输入、数字量输出、软件查询式 AD 转换和模拟量输出功能。4.3 定时中断对于实时过程监控,最为关键的是能够定时检测被控对象的状态,一旦达到预定义的条件,则发出相应的控制命令。这就需要设备驱动程序能够提供精确的定时中断。PCI 9111 板卡上提供了 8254 定时/计数器,可用于实现定时中断。通过编程设置 PCI 9111,可令 8254 定时/ 计数器的输出作为中断
16、源发起定时中断请求。在中断服务程序内,可以完成 AD 数据采集(从而实现定时中断式 AD 转换)、数字量数据输入输出等各种定时执行的任务。对于中断式 AD 转换,也可以编程设置 PCI 9111,令 8254 定时/计数器的输出作为 AD 转换触发信号,而 AD 转换器的 AD 转换结束信号作为中断源发起中断请求。由于 AD 转换器是定时触发,此时亦可实现定时中断式 AD 转换。要使得驱动程序能够响应来自 PCI 9111 的硬件中断,首先需要编写在设备类里的中断服务程序链接到 PnP 子系统,分配给 PCI 9111 的中断请求号(IRQ)上。代码见图 3。NTSTATUS DfqDevic
17、e:OnStartDevice(KIrp I)mInterrupt.InitializeAndConnect(pResListTranslated, LinkTo(ISR), this);图 3 链接中断服务程序到系统分配的中断请求号Fig 3 Link interrupt service routine to interrupt request number ofsystem distribution图 3 的代码中,mInterrupt 是定义在 DfqDevice 类中的 KInterrupt类型的中断对象。ISR 是 DfqDevice 类的成员函数,即实际的中断服务程序。由于 Win
18、dows XP 是一个多任务的操作系统,在编写中断服务程序时,要考虑留给其他程序执行的机会,因此,在中断服务程序中,通常完成当前最为紧迫的任务。由于多个物理设备可能共享同一个中断请求号,因此在中断服务程序中,首先判断所响应的中断请求是否来自 PCI 9111。若不是,则立即返回,以节省时间。然后清除硬件中断,以便下一次中断请求能够正常产生(而不被阻塞)。然后针对具体被控对象的定时执行的任务。在 DFQ 牵引床控制软件中,编程使 PCI 9111 板卡的 8254 定时技术芯片每 160 s 产生一次中断。在每次中断中完成 AD 数据采集和数字量输入,检测当前动作的执行情况。当 AD 采样值达到
19、主程序设定要求时,即牵引床动作到位,中断服务程序及时发出动作结束信号。牵引床的每个动作的执行都在频率为 6 KHz 的 AD 采样监视之下完成。首先,由于 AD 采样频率高,牵引床动作(如距离、角度等)的执行非常精确。牵引床动作的实际误差基本不受测控软件的影响,而主要取决于牵引床本身的机械结构所带来的误差。其次,由于牵引床的动作控制信号是在设备驱动程序中发出的,而设备驱动程序具有比任何 Windows 线程更高的中断请求级(IRQL ),牵引床工作的可靠性明显提高。在连续长时间的测试以及大量用户的反馈中,牵引床系统几乎没有出现错误动作。值得提出的是,由于 PCI 9111 的 AD 转换频率最
20、高可达 100 KHz,因此在实际使用中,8254 的定时常数可以设置得比 160 s 更低,如十微秒级,这样可以完成对于更加快速控制过程的实时监控。另外,在许多系统中,人们也使用 Windows 提供的软件定时器或编写已有驱动程序的回调函数实现过程监控,但这并不能从根本上满足实时要求。其原因为:(1)软件定时器工作在用户态,不具有严格的实时性。(2)由于受 Windows 操作系统线程调度模型的制约,软件定时器和回调函数只能实现毫秒级或十毫秒级的定时,不能满足高速的实时测控要求。因此,设备驱动程序设计的方法保证了数据采集和过程监控的实时性、高精度和可靠性。4.4 主程序和设备驱动程序的通信主
21、程序和设备驱动程序是功能相对独立的两个程序,它们之间通过通信联络完成控制命令和数据的传输。主程序和设备驱动程序之间通信的典型方法有异步 IO、事件通知等3,5。DFQ 牵引床系统采用事件通知的方法完成主程序和设备驱动程序之间的通信。在此,以牵引床的一个基本动作的执行过程为例,说明主程序和设备驱动程序之间的通信。首先,主程序调用 SDK 函数 CreateEvent(NULL, FALSE, FALSE, NULL)创建事件句柄 hEvent,其中第二个参数 FALSE 表示所创建的事件为自动重置事件,第三个参数 FALSE 表示事件的初始状态为无信号状态。然后主程序调用SDK 函数 Devic
22、eIoControl()向设备驱动程序发出控制命令,命令参数中含有事件句柄 hEvent。最后,主程序调用 SDK 函数WaitForSingleObject()等待事件 hEvent 变为有信号状态 ,从而主程序线程进入阻塞状态。设备驱动程序在控制命令处理函数中通过new(NonPagedPool) KEvent(hEvent, OBJECTTYPEALLACCESS)创建KEvent 类对象 pEvent,然后启动动作执行,并中断对动作进行定时监控。当检测到动作执行到位(或遇到异常情况中止)后,设备驱动程序调用 pEvent-Set()将事件对象 hEvent 设置为有信号状态。此时主程序
23、线程被操作系统唤醒,继续向下执行。主程序可进一步访问设备驱动程序获得动作的执行情况以做出相应的处理。事件通知的方法,在保证牵引床动作执行的实时性、可靠性和精确性的同时,还符合多任务系统的设计原则,主程序和设备驱动程序并不会持续长时间独占 CPU 而影响计算机整体性能。这是因为:(1)在牵引床动作执行期间,主程序因调用 WaitForSingleObject()而一直处于阻塞状态,并没有获得执行。(2)在牵引床动作执行期间,设备驱动程序通过定时中断的方法,只是每隔设定的一段时间(在牵引床系统中设置为 160 s),检测一次动作的执行情况,设备驱动程序也没有在动作执行期间独占 CPU。这样,CPU
24、 就会有充足的时间执行其他的程序。于是,可在主程序中进一步使用多线程技术,实现更为复杂的逻辑控制功能。如牵引床的快速牵引、复合牵引等各种治疗功能就是使用多线程技术实现的。5 结束语本研究从操作系统底层的角度,对 Windows XP 操作系统的实时测控技术进行了研究和探讨。通过 WDM 设备驱动程序设计的方法,使程序获得在系统核心态执行的能力,从而实现实时过程监控。以DFQ 牵引床系统为例,剖析了在 Windows XP 操作系统下,基于PCI 总线数据采集卡进行实时过程监控的关键技术。遵循本文的技术路线,我们设计了 DFQ 牵引床系统的测控软件,产品质量检测和实际应用均表明,DFQ 牵引床工作可靠性高,动作完成精确到位,测控软件具有良好的易用性。本研究所论述的实时测控技术可适用于一般的控制系统。【