杨贵福,胡佑蓉,刘淑霞,刘振邦,包 宇
(1.东北师范大学信息科学与技术学院,吉林 长春 130117; 2.广州大学化学化工学院分析科学技术研究中心,广东 广州 510006; 3.广州大学土木工程学院,广东 广州 510006)
高分辨扫描电致发光显微成像系统是计算机控制的通用电化学测量分析系统,为国家重大科研仪器研制项目。其内部由快速数字波形发生器、高速数据采集电路、多功能恒电位/电流仪、低通滤波器、溶液电阻补偿电路等组成,分析仪需要由安装在PC上的成像系统软件进行控制,仪器与PC机通过USB 2.0/3.0接口进行通信,实验测量结果最终存储和显示在PC机上。
现如今,操作系统更新换代速度越来越快,而硬件设备升级较慢,对于驱动不适应新的操作系统的遗留系统将面临着越来越大的压力。遗留系统[1]是指不再支持操作系统或其他计算机技术有关的源代码。当平台升级(或被取代)时,遗留代码不能再正常工作,不能运行在更高版本的系统上,需要兼容层才能正常运行执行代码。
在软硬件设备协同开发[2]中,由于操作系统的升级或变更,当软件与硬件设备进行通信时,如果驱动与操作系统位数不匹配,原软件的驱动便不能运行在更高版本的操作系统上,从而影响设备的使用。想要解决设备驱动[3]不兼容新的操作系统的问题,第1种方案是购买新的设备[4],但会增加额外的费用开支;第2种方案是对软件的遗留代码进行处理,这种方式是开发人员常用方式。遗留代码的处理方式一般有2种:1)建立新的软件系统、新的数据,摒弃原有的代码,这样做能够从根本上改观遗留代码带来的困扰;2)使用技术和方案来改进和维护已有的遗留代码,在本质上不改变遗留代码[5-6]的整体架构,保留系统的体系结构部件,来达到预期的功能,显然这种方式为更佳之选。
针对遗留系统[7]复用和系统升级的问题,研究者从各种角度对其进行剖析。文献[8]提出基于面向服务的体系结构架构的再工程方法,将遗留系统封装成服务器对外提供服务。文献[9]通过面向对象的分析和设计方法,运行POSIX线程模式来取代遗留系统中的进程模式,以提升系统的功能、性能以及系统的可维护性。文献[10]对基于Spring Cloud微服务框架实现的购物商城遗留系统提供了重构方法和实践,重构系统后明显改善了系统的运行效率和系统可用性。文献[11]提出利用中间件技术通过构件化实现对遗留系统改造的方法,挖掘了遗留系统的可用价值,增强了系统的演化能力。上述研究通过不同的角度推动了遗留系统的发展,节省了开发和维护成本,然而,仍旧存在以下2个不足:1)由于没有很好地解决遗留代码遗留的风险,限制了其遗留系统[12]的应用;2)修改了较多的代码来复用遗留系统,工作量较大。
针对驱动升级的问题,文献[13]通过VFN技术实现软硬件分离,一定程度上解除了VNF层和NFVI的强耦合关系,使VNF层和NFVI层能够独立完成升级,减少升级时间,提高升级效率,有助于尽快降低其他站点的负载,减少了网络的风险率。文献[14]使上位机通过CAN将本地的闪存驱动和文件传输到控制器中,弥补了MCU的FlashROM空间不足,同时也提高了代码的执行速度和效率。上述研究通过不同的方法解决了驱动升级的问题,提高了执行效率。然而,这2类方法不适用遗留系统的驱动升级。
据此,本文通过研究和分析用户所遇到的问题以及解决方案的优缺点,最终采用命名管道[15]技术作为中间件[11]的方案实现对遗留代码的改造,从而使系统与设备成功通信。在通信过程中,系统与设备通过驱动进行通信,利用命名管道技术实现一个接收多客户机的服务端,不需要大量更改系统的遗留代码,通过增加一个中间层,便能解决驱动不适用于新的操作系统的问题,实现了系统的低耦合、高内聚。利用软件复用的思想,在已有遗留系统开发劳动成果的基础上实现复用,开发满足用户新需求的系统,消除了重复的劳动,提高了软件开发的质量和效率。
命名管道是Windows操作系统提供的一种简单的进程间通信[16](Inter-Process Communication,IPC)机制[17],可在本地和网络的不同进程之间,支持可靠的、单向或双向的数据通信。命名管道是一种内存缓冲区,系统在一个进程写命名管道和另一个进程读命名管道时在其中保存数据。命名管道不需要基层网络协议来实现数据传输。命名管道代码实现起来比较简洁和灵活,且更有利于维护。
每个命名的管道都有一个唯一的名称,将其与系统的命名对象列表中的其它命名管道区分开来。管道服务器在调用CreateNamedPipe函数时创建一个或多个命名管道实例。管道客户端在调用CreateFile或CallNamedPipe函数来连接命名管道实例时指定管道名称,管道名称使用的格式为:\ServerNamepipePipeName。其中ServerName是远程计算机的名称,用于指定本地计算机,PipeName指定的管道名称字符串可以包括除反斜杠之外的任何字符,包括数字和特殊字符。管道服务端无法在另一台计算机上创建管道,CreateNamedPipe必须使用服务器名称的句点,格式为:\.pipePipeName,管道服务器可以向其管道客户端提供管道名称,以便它们连接到管道。
一个程序创建命名管道时,命名管道就会存在。创建命名管道的程序为命名管道服务端,而其他的进程为客户端。命名管道的服务端可创建单个管道实例连接单个客户端进行通信。命名管道服务器也可以使用单个管道实例来连接多个管道客户端,支持一对一的C/S和一对多的C/S通信。通常采用管道服务端创建多个管道实例以有效地同时处理多个客户端[12]。
命名管道的通信流程如图1所示。
图1 命名管道的通信流程
服务器端首先使用API函数CreateNamedPipe创建一个命名管道实例句柄,并使用API函数ConnectNamedPipe在命名管道实例上监听客户机的连接请求,再分别使用API函数ReadFile和WriteFile从客户机接收数据或将数据发送给客户机,最后使用API函数DisconnectNamedPipe和CloseHandle关闭命名管道的连接和关闭命名管道实例句柄。客户端首先使用API函数WaitNamedPipe和CreateFile检测管道并建立与命名管道的连接,再使用API函数WriteFile和ReadFile分别向服务器发送数据或从中接收数据,最后使用API函数CloseHandle关闭打开的命名管道会话[12]。
命名管道通信方式有很多优点:1)本地和网络都可以使用;2)可以在不相关进程间进行通信;3)可以打开指定文件进行通信;4)支持多客户端连接;5)支持单/双向通信;6)支持异步重叠I/O操作[15]。由于命名管道使用的灵活性,其常被用来解决进程间通信和数据安全传输的问题,在各个领域都应用广泛。
随着网络和技术的发展,在信息安全等领域,为了保证科研信息管理系统安全,研究人员通常会采用命名管道技术编程实现数据安全通信[17]。命名管道作为数据通信的传输通道,可以保证数据安全可靠地传输。对于冶金、化工等领域,开发人员也常使用命名管道机制实现过程控制计算机服务器和上位机、下位机以及同位机人机接口(Human Machine Interface, HMI)的通信[18]。采用这样的方法和这样的设计,开发进程通信程序,方便可靠、开发成本小,并且可以很方便地扩展HMI客户端的使用数量。
本文对比了WinDriver、WDM、VxD、WinUSB等多个主流驱动。WinDriver[20]驱动制作程序简单,但调错困难;WDM[21]开发复杂,驱动功能有限;VxD[22]新操作系统不兼容驱动。升级高分辨率扫描电致发光显微成像系统最终使用WinUSB[23]作为新的驱动,WinUSB支持Windows不同版本,且WinUSB支持多种USB的功能,满足设备对驱动的需求,且开发简单。WinUSB由于一次只能有一个实例,在不修改遗留软件代码[24]的原则上,WinUSB[25]不能与上位机遗留软件通信。对比信号量、匿名管道、命名管道、Socket等多种进程通信的方式,本文最终选择命名管道技术作为中间件,以命名管道和WinUSB驱动的异构通信方式来使上位机和下位机通信[26]。使用原驱动的通信和使用命名管道和WinUSB技术进行驱动升级的新通信如图2所示。
图2 2种通信方式
在原驱动通信中,上位机应用直接通过原驱动来与硬件进行通信,驱动扮演沟通的角色,把硬件的功能告诉上位机应用系统,并且也将系统的指令传达给硬件,让它开始工作。由于原驱动已经不适应新的操作系统了,于是提出了命名管道结合驱动异构通信。
在命名管道通信中,P1、P2是命名管道2个实例,一个用于上行数据,一个用于下行数据。当上位机应用写数据时,触发命名管道服务端响应,响应的动作是写数据给WinUSB驱动,这个过程为下行数据。当下位机返回数据时,WinUSB驱动使用命名管道技术结合驱动方法代替原版本的驱动,让上位机应用软件与硬件设备进行通信。本文将命名管道实现的服务器称为MARIO(Mario’s Access Redirection I/O)。
MARIO是基于命名管道技术实现的服务端,MARIO在主线程中创建2个命名管道实例,分别对应于2个子线程。一个命名管道实例用于下行数据,即下行子线程,通过该命名管道实例,从上位机读数据,然后将数据写给驱动,驱动将数据写给下位机。另一个命名管道实例用于上行数据,即上行子线程,通过该命名管道实例,MARIO读取驱动数据,然后将数据写给上位机,上位机根据下位机返回的协议数据,处理后绘制实验曲线。MARIO的功能结构如图3所示。
图3 MARIO的功能结构图
图3中,上位机中的Writer程序的作用是负责向下位机写数据,上位机的Reader程序的作用是从下位机读数据。WinUSB是使用WinUSB技术实现的动态链接库。MARIO的功能是打开驱动、读/写驱动和读写管道,MARIO读取上位机Writer的数据后,将数据写给驱动WinUSB,驱动WinUSB将数据传给下位机。下位机收到数据之后,会返回数据,然后MARIO读取驱动WinUSB的数据,将数据写给上位机的Reader,上位机再通过Reader的数据处理后绘制曲线,上位机的Writer和Reader程序是命名管道MARIO的客户端,MARIO是一服务端多客户端实现的模型。对于上位机和下位机程序而言,MARIO是透明的,这使得MARIO具有通用性,能够适用驱动升级和驱动更新等多种应用场景。
上位机与下位机的一般的通信方式是上位机通过驱动与下位机进行通信。本文提供了一种使用命名管道技术结合驱动方法代替旧版本的驱动[26],让上位机与下位机进行通信。
命名管道结合驱动方法在传送上位机和下位机的数据时,可以由用户运行软件发送下行指令,也可以是下位机收到下行指令后,下位机发送上行指令。上行和下行都打开WinUSB提供同一个文件(不关闭,只打开一次),上层的上位机通过访问命名管道服务端提供的管道进行通信。使用命名管道进行上下位机通信的系统结构如图4所示。
图4 利用命名管道的上下位机通信的系统结构图
为验证本文提出的命名管道结合驱动方法更新驱动的有效性,本文选用遗留系统中10种电化学实验进行测试,具体如表1所示。表中check为连接测试,其他实验数据为10种电化学实验每个实验上行和下行数据包的大小以及每个实验的数据包的个数,本研究在Win10 64位系统、Win8 64系统、Win7 32位系统下进行了实验验证。
表1 待检测实验的数据汇总表
实验协议数据包大小/B协议数据包个数Check644CV64350CA256178CC1024213ITC102425LSV64183CP256662DPV6435NPV6422SWV6420OCV64350
Win7 32位系统上位机与下位机[27]通信使用原驱动。Win10 64位和Win8 64位系统上位机与下位机通信使用MARIO和WinUSB异构通信,在Win7 32位系统下和在Win10 64位系统下,在做上下位机通信实验时,都使用Bus Hound抓取数据。
表1中所有的实验在64位系统下用MARIO结合驱动的方法升级的软件都成功地得到了与Win7 32位系统类似的曲线和实验数据,将64位系统得到的实验数据与Win7 32位系统原驱动的实验数据作比较,两者实验数据的相对误差在0.000~0.001之间。如表2所示,以CA实验为例在4950组数据随机截取一小段(10组)实验数据做对比,绝对误差在0.00E-05~0.03E-05。
表2 64位和32位系统下CA实验结果
32位64位误差时间/s电位/V电流/A时间/s电位/V电流/A电流/A0.2710.56.80E-050.2710.56.80E-050.00E-050.2720.56.71E-050.2720.56.71E-050.00E-050.2730.56.65E-050.2730.56.65E-050.00E-050.2740.56.59E-050.2740.56.56E-050.03E-050.2750.56.46E-050.2750.56.46E-050.00E-050.2760.56.40E-050.2760.56.43E-050.03E-050.2770.56.34E-050.2770.56.31E-050.03E-050.2780.56.28E-050.2780.56.28E-050.00E-050.2790.56.19E-050.2790.56.22E-050.03E-050.2800.56.09E-050.2800.56.09E-050.00E-05
将64位系统与32位系统的全部实验数据使用Excel画在同一坐标图中展示,如图5所示,32位系统和64位系统的实验数据生成的曲线重合。
图5 CA(计时电流法)实验
升级后的电化学软件,在Win10 64位系统和Win8 64位系统上做实验,Bus Hound抓取的下行指令和上行指令,观察到的与遗留系统软件使用原驱动在Win7 32位系统上做实验,Bus Hound抓取的下行数据与上行数据一致。图6、图7以2个典型的实验(NPV实验、SWV实验)为例,在64位系统下和32位系统下设置相同的实验参数进行实验。
如表3所示,64位系统得到的NPV实验数据与32位系统原驱动的NPV实验数据做了比较,两者实验数据的绝对误差在0.00E-05~0.19E-05。图6将在Win7 32位系统的电脑上用原驱动的电化学软件测试得到的结果数据与在Win10 64位系统用MARIO升级的电化学软件测试得到的结果数据画在同一幅图中。从图6可以看出,在误差范围内,使用MARIO结合驱动方法与原驱动生成的NPV曲线重合。
表3 64位和32位系统下NPV实验结果
64位32位误差电压/V电流/A电压/V电流/A电流/A0.11.11E-050.11.07E-050.04E-050.22.13E-050.21.94E-050.19E-050.33.12E-050.33.05E-050.07E-050.44.14E-050.44.00E-050.14E-050.55.09E-050.55.05E-050.04E-050.66.17E-050.66.13E-050.04E-050.77.16E-050.77.03E-050.13E-050.88.14E-050.88.23E-050.09E-050.99.10E-050.99.19E-050.09E-051.01.11E-051.01.07E-050.04E-05
图6 NPV(常规脉冲伏安法)实验图
如表4所示,表中将64系统得到的SWV实验数据与32位系统原驱动的SWV实验数据做了比较,两者的实验数据完全一致,误差为0。图7将在Win7 32位系统的电脑上用原驱动的电化学软件测试得到的结果数据与在Win10 64位系统用MARIO升级的电化学软件测试得到的结果数据画在同一幅图中。从图7可以看出,使用异构通信方法与原驱动生成的SWV曲线重合。
表4 64位和32位系统下SWV实验结果
32位64位误差电压/V电流/A电压/V电流/A电流/A0.050013.28E-060.050013.28E-060.00E-060.152.98E-060.152.98E-060.00E-06
图7 SWV(方波伏安法)实验图
上述的实验数据和实验曲线表明,使用MARIO和WinUSB代替原有的驱动,从而使遗留系统[28-29]驱动升级这种方法是有效的,且MARIO和WinUSB异构通信具有低耦合的特性,驱动升级后的电化学软件能够适用于现有主流的Windows系统,并在性能和功能上满足用户需求。
实践证明,基于命名管道结合驱动方法来实现上位机与下位机的通信,是简单、方便和高效的。不仅解决了软件不适应新的操作系统和遗留系统驱动升级的问题,而且使得数据可以得到备份。本文的方法只需修改很少的遗留系统代码,减少了遗留系统迁移的工作量,使遗留代码得到复用。本文的异构通信策略为解决遗留系统升级和驱动不适用于新的操作系统的问题提供了一个很好的方案,利用命名管道技术作为2个进程之间数据通信的桥梁,减少了设备对驱动的依赖。本文所述的方法具有通用性,已经在某电化学项目上得到了应用,极大简化了开发人员的工作。