更全的杂志信息网

基于SWIG的Python仪器驱动封装技术

更新时间:2009-03-28

0 引言

虚拟仪器是自动测试系统的基础,测试软件是虚拟仪器的核心。目前虚拟仪器和测试软件常见的开发平台包括:NI公司的LabVIEW,LabWindows / CVI,C#,C++和Java等。LabVIEW和LabWindows具有丰富的图形化测试控件库;C#便于开发Windows图形界面程序;C,C++和Java是目前使用最广的编程语言。

在实际的产品测试开发中,这些平台或编程语言也存在一些局限。比如,LabVIEW图形化语言不便于代码管理和维护,LabWindows / CVI使用面向过程的C语言,模块化开发需要大量的编程技巧,开发效率较低,手工管理内存容易导致软件缺陷(如缓冲区溢出)。设计功能较复杂的测试软件时,静态语言在不重新编译的情况下难以对软件的功能进行动态配置。

Python是面向对象的高级编程语言,动态类型、自动内存管理、解释执行、原生跨平台,可拓展性极强,具有丰富的开源库,能快速实现应用程序所需的各种功能[1]。Python在仪器编程方面已有少量应用[2],主要障碍是大量仪器没有提供Python的编程接口。SWIG(Simple Wrapper and Interface Generator)是跨语言接口转换工具,支持Python/Perl/ PHP等动态脚本语言与C,C++,C#,Java等静态编译型语言之间的接口转换[3],Python中的很多拓展库实际上来自SWIG对C库的封装。

本文采用Python设计和开发自动测试软件,提出将SWIG用于仪器驱动的跨语言、跨平台封装,弥补Python在仪器编程方面的短板,希望能够促进Python在虚拟仪器和自动测试领域的推广和应用。

基础组给予患者得宝松肌肉注射,剂量1 ml,连续治疗3周[3]。联合组患者给予得宝松与套管针联合治疗;得宝松治疗方法同基础组,套管针治疗方法:患者最痛点,以该点上7㎝左右位置作为进针位置,消毒,沿着水平方向进针,进针毕,不锈钢针芯抽出,皮下留置塑料软套管,并将软套管用胶布固定,留置24小时后,拔出塑料软套管。套管针治疗根据患者病灶范围而定,适量加刺数针[4-5]。

1 系统组成

1.1 硬件结构

整个测试系统由测试计算机、测试服务器和控制主机组成,通过交换机组网,如图1所示。测试计算机采用RS-232,GPIB或PXI等测试总线连接测试资源(模块化仪器或可程控的台式仪器),通过仪器驱动程序控制仪器设备;测试服务器运行数据库和测试应用软件;控制主机实现人机交互,对整个测试系统进行控制。

  

图1 系统硬件组成

可根据测试需求,调整和缩放系统规模,如将三者合为一体,即以传统的单机方式运行整个测试系统。

1.2 软件组成

用Python开发自动测试软件,其基本层次结构如图2所示。

  

图2 系统软件层次结构

最上层为测试应用层,负责测试用例执行、数据存储和分析、测试报告生成等具体的测试业务。应用层之下为仪器驱动层,在Python仪器驱动模块中封装和调用底层硬件的API,对测试资源进行配置和管理。

对于支持NI-VISA和NI-IVI标准驱动的测试设备,Python中的开源拓展库pyvisa和pyivi分别提供了二者的API封装,可以直接调用已封装好的与具体仪器无关的函数接口或可互换类驱动接口[4]

高校内部的绩效评价还处于起步探索时期,一些院校对于财务绩效评价体系的构建还有很多的欠缺。高校当中的财政性资金等应用收益,并没有合理并且健全的管理考评机制。此外,内部财务工作人员的绩效评价体系与财政体制的改革脚步有些不符。因此,难以满足现代高校在教育改革过程中的具体需求。高校财务人员绩效考核存在的问题主要体现在以下几个方面。

但实际的测试需求往往丰富多变,因为各种原因,测试系统还会使用很多缺少VISA或IVI驱动支持的测试仪器,如各种总线通讯接口卡、数据采集卡、多功能复合仪器,以及一些自研或定制的非标准设备,有时也包括一些暂时无法升级的老旧测试设备。这类不被VISA或IVI驱动支持的测试资源,常被称作专有设备或非标设备。

将Python作为测试开发平台的主要技术障碍,就是如何在Python中对这类专有设备进行编程控制。

2 非标仪器驱动的封装和调用

仪器驱动通常采用C或C++编写,一般会以C语言动态链接库的形式发布,并提供头文件、库文件等供二次开发。常见的仪器驱动程序(或SDK)中包含的文件类型及作用,如表1所示。

 

表1 非标仪器设备驱动程序的常见结构

  

文件类型说明动态链接库(∗.dll)仪器所有功能的底层函数、常量、变量等资源,以动态链接方式加载到内存中运行,供其他程序调用引入库/附加库(∗.lib)DLL动态库导出的函数名称、内存地址静态链接库(∗.lib)功能同动态链接库,但采用静态链接Windows驱动(∗.sys)Windows硬件驱动文件配置工具等(∗.exe)仪器的参数信息头文件(∗.h)API函数、常量、变量等的定义和声明

用C,C++调用专有仪器驱动的API函数时,一般只需要正确设置编译器的链接路径和链接方式。在C#中,需要用declare语句对API函数的参数和返回值类型等进行声明,之后方可调用仪器API进行编程。有些厂商提供了LabVIEW,C#等环境的驱动接口声明代码(或SDK),以简化编程工作。

在以上4种方案中,可能并不存在绝对的最佳方案。自动测试系统经常搭配使用模块化仪器、台式仪器以及其他程控测试资源,并根据测试需求灵活地增加或置换仪器。在选择驱动封装方案时,建议根据驱动API的数量和复杂度,结合开发人员对相关工具的熟悉程度,使用ctypes,libcffi或SWIG。

Python语言在虚拟仪器开发中使用比例比较低,大多数仪器厂商并没有为仪器提供Python SDK支持。Python不支持指针操作,完全使用引用类型表示变量、参数等(传递内存地址而不是值拷贝),编译成中间二进制字节码后通过解释器解释运行。Python与C语言虽然语句类似,但在数据类型、内存操作、设计模式、运行方式等方面存在很大的差异,Python无法简单直接地调用针对C语言编程而设计的仪器驱动。

本文对在Python中跨语言调用仪器驱动程序,进行了技术研究和方案验证。

1.2 文献纳入与排除标准 ①病理学明确诊断为卵巢癌的患者;②文献中明确指出MMR基因定性或定量检测的方法,或检测MMR基因相关蛋白表达产物;③涉及MMR基因表达与OS、无瘤生存期(DFS)或无进展生存率(PFS),且能直接或间接提取HR值和95%CI的研究;④原文可获得。排除标准:①单案例报告、评论、社论、综述和与主题不相关文章;②重复发表的文献;③原文献无法提取相应数据的研究;④无预后指标(OS,DFS或PFS)的文献。

2.1 仪器驱动调用和封装

Python本身是开放、可拓展的,除了可使用大量的第三方开源拓展库,还可自行编写Python拓展模块。借助于一些开源库,可以实现在Python脚本中调用外部DLL动态链接库中的C程序。

>>>from D2K_DASK import D2K_AI_AsyncCheck

2)libcffi库提供了比ctypes更友好的编程接口,用更少的代码可完成同样的功能。

3)用CPython将外部DLL库封装为原生的Python拓展模块。该方案需要编写C代码,将仪器驱动头文件中定义的各种API函数、数据类型等转换为相应的Python对象。由于需要了解Python解释器的底层实现机制,工作量和开发难度都很大。

4)SWIG可自动解析C或C++的代码和头文件,提取API函数的参数类型、返回值类型,自动生成CPython接口转换代码。该方案通用性和自动化程度较高,只要熟悉SWIG的配置语法,无需手工编写底层的转换代码,即可快速批量地进行API封装。Python中的pyivi模块,实际上就是NI-IVI的SWIG封装。

我静下心来左思右想,突然想到以前我们都是一起吃汉堡的。3个人吃3个汉堡用了3分钟,1个人吃1个汉堡也是3分钟,那么9个人吃9个汉堡,也是3分钟。我反反复复地想了几遍,觉得应该没有问题了,就把答案告诉了妈妈。妈妈点点头笑了笑,夸我是个爱动脑筋的孩子。

本文所设计的测试系统中使用了较多的非标仪器,API数量和类型都比较丰富,因此使用SWIG对仪器驱动进行封装,通过自动化处理提高开发效率。

2.1 用SWIG封装仪器驱动为Python拓展模块

仪器API大多将操作的状态码作为返回值,但由于C / C++函数不支持多返回值,为了输出额外的数据,一般会使用指针作为参数、间接地绕开这一限制。以函数D2K_AI_AsyncCheck为例,其函数原型为I16 D2K_AI_AsyncCheck (U16 CardNumber,BOOLEAN *Stopped,U32*AccessCnt)。其中,指针类型的参数BOOLEAN*Stopped和U32 *AccessCnt,被用于输出数据采集状态和已采集数据的个数。该API函数实际上并不关心这些形参的初始值,只是单向地将输出数据写入指针所指向的内存。

DAQ2206为PXI模块仪器,测试资源包括64个AD通道,2个DA通道,2个定时/计数器和24个IO口。在工业控制、自动测试中使用多功能复合测试设备,可以提高资源密度、减小设备体积。但此类多功能复合设备,往往缺少VISA和IVI驱动的支持。

人类命运共同体作为应对全球问题提出的中国方案,是具有实践意义的行动纲领。学术界认为,人类命运共同体并不是一种“乌托邦”幻想,在理论与实践上具有构建的可能性。

公司提供了专有驱动包D2K_DASK,支持包括DAQ2206在内的多种模块化仪器。用SWIG对其进行接口封装的核心工作是按照SWIG库的配置语法,在拓展名为*.i的API接口描述文件中对特殊的API参数类型进行声明,以便于SWIG能够正确地进行类型转换和封装。示例如下(片段):

%module D2KDASK

%include"D2K_DASK.h"

乡村旅游的发展离不开村民优质的服务。为了培养村民们乡村旅游发展的意识,提升其发展理念,专合社在镇政府的指导支持下,组织社员前往陕西袁家村等地考察学习。对比中,村民们对袁家村精致的建筑印象深刻,对统一有序的管理方式赞叹不已,对其丰富的旅游体验项目深感羡慕。考察后,星光村村民们开始思考如何留住游客等问题,对乡村旅游有了更为感性的认识。此外,为了提升村民在乡村旅游接待服务中的规范化程度,不定期聘请职业院校老师、旅游企业前来指导,组织村民学习技能操作并进行考核。

%include"typemaps.i"

将仪器驱动封装为Python模块后,还可参考IVI可互换类驱动的实现机制,利用Python面向对象的特性,将具体的底层API操作封装在类内部,对外抽象出与仪器无关的高级操作接口,逐步将测试软件与底层仪器API解耦,提高仪器的可互换性。

%apply double *OUTPUT { F64 *voltage };

首先用%include指令包含驱动API的头文件。一般情况下SWIG能自动识别大部分函数原型、变量和常量[5],并将其转换为相应的Python对象。Python采用动态数据类型和自动内存管理,无法通过指针直接操作内存,所以仪器驱动中经常使用的指针类型的参数通常需要特殊处理。

本文以某公司的多功能数据采集模块PXI-nuDAQ2206为例(以下简称DAQ2206),简要介绍将其厂商专有驱动用SWIG转换为Python拓展模块的关键步骤。

总之,科研工作中如何与团队中的研究成员进行有效的沟通是一门艺术,通过哈佛管理导师的课程,学到了很多积极有效的沟通手段,也深刻剖析了自己曾经所犯的错误。相信在未来的工作中,这门课程会帮助我正确化解沟通矛盾,有效说服他人,最后获得积极的工作成果。

借助于SWIG的指针类型处理模块typemaps.i,通过指令%apply int *OUTPUT { BOOLEAN *Stopped,U32 *AccessCnt },可将对应的参数声明为Python整数类型,参数用途为OUTPUT。

编写好SWIG接口文件后,调用swig命令可自动生成接口的包装代码(如D2KDASK_wrap.c),将其编译为动态链接库(Windows下还需要修改拓展名为*.pyd),即得到仪器驱动的Python拓展模块。在Python中可直接import导入仪器驱动拓展模块。受益于Python语法简单、多返回值、动态类型、自动内存管理等特性,无需繁琐的定义、声明和底层操作,可以简洁、自然地调用驱动模块中的资源,如:

结合RPyC库和“猴子补丁”,通过本地测试软件中的代理对象,可通过RPyC库,透明地操作远程计算机所连接的测试设备,如图3所示。

1)ctypes库,使用方式与C#中非托管方式调用DLL类似,手工编写接口代码、声明每个API函数的参数和返回值类型。该方案简单易行,但工作量大、难以自动化处理,适合API函数较少的情况。

>>>status,stop,count=D2K_AI_AsyncCheck(0)

>>>status,stop,count

(0,1,50)

以上只是使用SWIG封装仪器驱动的简单示例。除typemaps.i外,SWIG还提供了windows.i,cpointer.i,carrays.i,cstring.i,cmalloc.i,cdata.i等拓展库,能够处理Windows编程中使用的各种头文件,在Python脚本中操作函数指针、数组、字符串、结构体和联合体等C语言数据类型,通过malloc动态申请和释放内存,直接对内存进行不受保护地读写。SWIG大大丰富和扩充了Python的底层编程能力,基本能满足用Python进行仪器编程的需求。

2.2 进一步功能封装

%apply int *OUTPUT { BOOLEAN *Stopped,U32 *AccessCnt};

2.3 实现分布式和跨平台调用

设计和开发测试系统时,有时需要在测试软件中集中管理和操作连接到多台测试计算机的仪器资源。可能的原因包括:计算机接口类型和数量有限,仪器设备空间分布较广,系统中不同的测试设备所要求的软件运行环境无法统一等。随着计算机软硬件平台不断升级,测试设备会逐渐过时,在需要对老旧的测试系统进行升级维护时,上述问题可能会更加突出[6]。将仪器设备接入到多台测试计算机后,传统的测试开发平台或编程语言往往难以用比较简单的方式,解决在分布式、跨平台的环境下,对仪器驱动进行远程操作和远程调试等问题。

Python具有数量众多且功能强大的网络编程库。其中,RPyC(Remote Python Call)库采用对象代理(Object Proxying)技术,可以像操作本地对象一样操作远程主机上的Python模块和程序。Python作为弱类型的动态语言,允许在运行时修改和替换对象,该技术被称为“猴子补丁”(MonkeyPatch),可用于在不改变源码的情况下、对软件功能进行追加或变更。

外卖逐渐深入大学生的生活,这与其便利性优点有着不可分割的关系,未来外卖行业应针对不同性别、不同阶层和不同消费等级的人群做出更加鲜明的决策,制定更多外卖实施方案,吸引更多的顾客[8].

石油醚、氢氧化钠、无水乙醚、异丙醇、无水硫酸钠、三氯甲烷、冰乙酸、碘化钾、硫代硫酸钠、可溶性淀粉、无水碳酸钠、盐酸、乙醇、高氯酸、磷酸二氢铵、硝酸钯、甲醛、百里香酚酞、邻苯二甲酸氢钾、重铬酸钾:均为分析纯;65%硝酸、30%过氧化氢:优级纯,均购自成都市科龙化工试剂厂;铅元素标准溶液:批号GSB04-1742-2004,购自国家有色金属及电子材料分析测试中心。

以上就是本人对高中阶段社团活动的有效管理的粗浅认识,但限于我校的实际情况,可能有些观点有一点片面,鉴于此本人将持续关注我校和城区周边学校社团活动的发展情况,在未来的实践中不断总结经验,使得我校的社团管理日趋完善,社团活动更加成功并使之成为学校对外宣传的一张名片!

  

图3 实现远程、跨平台调用仪器驱动

>>>import rpyc

>>>server_ip=′192.168.1.22′

>>>server=rpyc.classic.connect(host=server_ip,port=18812)

>>>D2K_AI_AsyncCheck=server.D2K_DASK.D2K_AI_AsyncCheck

>>>status,stop,count=D2K_AI_AsyncCheck(0)

在实现远程调用的同时,以上方案还支持跨平台操作,即远程计算机和本地计算机可分别使用不同类型的操作系统(Windows/Linux/Unix等),不同版本的Python,SWIG。

使用pyvisa,pyivi以及SWIG封装的Python拓展调用仪器驱动,结合RPyC和“猴子补丁”,可将单机测试软件无缝迁移到分布式、跨平台的网络环境中。该方案能非常好地解决测试软件设计中远程调试、远程操作以及运行环境无法统一的问题,为老旧测试设备的联网升级改造、多台测试机的组网运行,提供了一种简单易行的技术方案。

本研究中参与干预监测的研究对象共255人,其中男学龄儿童139人(占54.5%);女学龄儿童116人(占45.5%)。年龄7~11岁之间,平均年龄10.2±0.1岁。

3 性能测试与分析

Python脚本在运行时首先会被编译为中间字节码,再通过解释器解释执行,执行过程中解释器会进行大量的类型检查、自省等操作,导致Python代码的运行效率和实时性表现较差[7]。虚拟仪器程序和自动测试软件,对运行性能和实时性往往有较高的要求。调用经SWIG封装的仪器驱动模块时,隐含的类型转换、数据拷贝等跨语言调用,必然会引入一定的封装延迟。因此,有必要定量测量和研究经SWIG封装后的Python仪器驱动模块的运行效率。

本文选取了DAQ2206的5个API函数,分别用C语言直接调用和用Python调用经SWIG封装后的驱动模块,统计执行耗时、计算封装开销。

在C程序中精确测量时间的原理是:北桥提供了高精度性能计数器,调用QueryPerformanceCounter和QueryPerformanceFrequency这两个API可分别获取其计数值和计数频率。在被测函数前后插桩、获取计数差值,除以计数频率,即得到函数的执行耗时。

 

表2 测试环境

  

项目本地测试环境远程测试环境操作系统Windows7(32位)Ubuntu 16.04(64位)硬件凌华嵌入式控制器 cPCI-2510桌面PCCPUIntel Core i7-2610UE @ 1.5 GHzIntel Core i7-2600 @ 3.4 GHzPythonv2.7.13(32位)v3.5.2(64位)SWIGv3.0.10v3.0.10网络100 Mbps 有线局域网

嵌入式控制器 cPCI-2510计数频率测得约为1.46 MHz(硬件决定),相当于计时分辨力可达1 μs以上。测试次数1000次,数据统计如表3所示。

衡量基本公共服务的指标通常分为两类,一类为投入指标,即根据劳动、资本、土地等生产要素投入情况(如地方财政支出、教室医院密度等)来表示公共服务均等化程度。这是大部分研究所采用的办法。另一类基本公共服务的指标为产出指标,即根据公共服务供给绩效来表示公共服务均等化程度,如De Witte和Geys把公共服务的生产分为一个过程的两个阶段,使用了一个非参数模型来评估公共图书馆的供给效率;[5]卢洪友等从投入、产出、受益三个维度,系统分析了中国的基本公共服务的均等化程度。[3]

 

表3 性能测试数据 μs

  

API函数运行时间(C语言)运行时间(Python)封装耗时平均值标准差Register_Card430421.5430435.213.73.4Release_Card119739.0119754.515.53.2AI_ReadChannel29.032.03.01.0AI_VoltScale0.32.82.50.5AI_AsyncCheck7.410.53.12.3

可以看出,SWIG接口转换引入的封装耗时约为2~15 μs。Register_Card,Release_Card的延迟相对其他API较高,但由于只在初始化阶段和程序退出时调用,封装开销对性能的影响基本可忽略。其他3个API函数的封装开销为2~3 μs,与API本身的执行时间没有明显关联。受操作系统任务调度影响,Windows软件的实时性指标往往只能达到10 ms左右,因此微秒级的调用开销一般不会对测试任务产生严重影响。

在对程序性能要求非常严格的场合,不建议非常频繁(如每秒数千次以上)地调用SWIG封装后的API函数(如AI_VoltScale)。此时,可以将最耗时的底层关键代码用C语言实现,一并编译、封装到Python仪器驱动拓展模块中,作为整体进行调用,这样既可以使用Python语言进行高效率的开发,也不会由于SWIG封装和Python解释运行而导致软件整体的实时性受到破坏。

在100 Mbps局域网环境下,远程调用驱动API会再引入约2 ms的传输延迟,可能对软件的执行效率产生一定的影响。因此,远程调用一般更适用于软件调试、低速数据采集等实时性要求相对较低的场景。

4 总结

测试软件是虚拟仪器和自动测试系统的核心,传统的测试开发平台使用中存在较大的局限性。本文通过SWIG将仪器驱动程序转换为Python拓展模块,弥补了Python在底层编程方面的不足,解决了用Python进行仪器编程的主要障碍。

然而,年轻时候的出类拔萃并没有带给王维好运。很快,他因为遭人妒忌受到诬陷,被贬谪到山东一个地方看管粮库。期间,王维的妻子遭遇难产,他同时失去了妻子和孩子,此后他终生未娶。

受益于Python的自动内存管理、动态类型、面向对象以及丰富的拓展库,用Python开发测试软件,可提高编程效率,降低在分布式、跨平台的环境下设计和开发测试软件的难度,缩短复杂测控系统的开发时间,一定程度上也有助于提高仪器的可互换性。在对软件实时性、仪器操作性能等有较高要求的场合,可采用C语言和Python混合编程,在软件开发效率和运行效率之间,取得比较好的平衡。

参考文献

[1] 丁未.将工业与科技世界的运行统一在Python语言的开源框架中[J].中国仪器仪表,2013(08):23-25.

[2] Hughes J M.真实世界的Python仪器监控 : Real world Instrumentation with Python:数据采集与控制系统自动化[M].北京:电子工业出版社,2013.

[3] Beazley D M.SWIG: An Easy to Use Tool for Integrating Scripting Languages with C and C++[C]// Usenix Tcl/tk Workshop,1996.

[4] 黄建军,李宥谋,刘婧,等.基于Python语言的自动化测试系统的设计与实现[J].现代电子技术,2017,40(4):39-43.

[5] Beazley D M.Automated scientific software scripting with SWIG[J].Future Generation Computer Systems,2003,19(5):599-609.

[6] Weltzin C,Schlonsky S.Reducing obsolescence of Linux-based ATEs with virtualization[J].Instrumentation & Measurement Magazine IEEE,2011,14(4):1-3.

[7] 范浩杰.面向Python程序源代码的分析与编译优化研究[D].北京:北京信息科技大学,2015.

 
马宇,叶卫东
《计测技术》 2018年第02期
《计测技术》2018年第02期文献

服务严谨可靠 7×14小时在线支持 支持宝特邀商家 不满意退款

本站非杂志社官网,上千家国家级期刊、省级期刊、北大核心、南大核心、专业的职称论文发表网站。
职称论文发表、杂志论文发表、期刊征稿、期刊投稿,论文发表指导正规机构。是您首选最可靠,最快速的期刊论文发表网站。
免责声明:本网站部分资源、信息来源于网络,完全免费共享,仅供学习和研究使用,版权和著作权归原作者所有
如有不愿意被转载的情况,请通知我们删除已转载的信息