0 引言
OPC 全称OLE for Process CONtrol,它是由OPC 基金会制定的自动化领域过程控制标准。
实际上,OPC 代表一系列的标准,包括OPC 数据访问(OPC Data AccESS),OPC 报警与事件(Alarms & Events ),历史数据访问(OPC Historical Data Access),OPC XML-DA(1.0)等。目前,OPC 标准在现代工业控制领域,特别是在数据采集和软实时控制方面已有很好的应用。
1 OPC 标准介绍
在 OPC 标准制定之前,工业软件制造商需要为不同的硬件开发各自独立的驱动接口。对于开发典型监控程序软件的技术人员来说,约有20%-30%的时间是用于编写通讯驱动程序。当供应商提供一个新的硬件时,应用软件研发人员就不得不重新编写一个新的程序。欢迎转载,本文来自电子发烧友网(http://www.elecfans.com/)
而OPC 标准的出现为此解决该问题提供了一个方案,它制定了一系列的数据存取,事件,报警等规范,使得当有新的硬件出现时,供应商只需提供实现的OPC 标准接口,而上层应用软件则不需重新改写。这样,在系统与设备之间,车间现场与信息管理之间,甚至更远的距离上,都可以通过OPC 标准实现无缝通讯,而不必担心设备升级带来的不便和额外费用。
OPC 为不同的应用制定了不同的标准,OPC DA 是针对现场数据进行存取的接口规范,该标准基于OLE / COM / DCOM / COM+技术,采用Client / Server 模式。数据通过特定的采集卡或串口等,从现场设备中获得,然后OPC DA 服务器将这些从数据源采集到的数据,以OPC 标准接口形式提供给外部应用程序,例如工控软件,实时数据库等。OPC 服务器可以通过本地或远程服务服务器两种方式,为依照OPC 标准实现的客户端提供服务。
2 OPC DA 服务器的设计
本文通过使用 VC++编程实现的一个OPC DA 服务器框架,来介绍OPC DA 服务器设计中需要解决的主要问题。在OPC 服务器的设计中,引入适配器模式,通过适配层将数据访问同具体的数据源操作相分离,以便针对不同的数据来源时,进行快速的二次开发。实现 OPC DA 服务器,需要依照OPC 基金会提供的OPC DA 标准,将从数据源中采集数据,以标准规定的接口形式提供给外部。其中,OPC 规范为OPC 服务器规定了两套接口方式:定制接口(Custom interface)和自动化接口(AutomATIon Interface)。其中,前者是OPC 服务器必须实现的接口,后者则是为方便VB 等脚本语言而提供,可以选择性实现。
2.1 OPC DA 服务器中的对象
根据 OPC 标准,在OPC DA 服务器中,主要包含三个层次的对象:服务器对象(Server),组对象(Group)和数据项(Item)。其中,服务器对象与组对象是一对多的关系,一个Server 对象可以包含0 到多个Group 对象,而一个组对象中可以包含0 到多个数据项。OPC DA 标准对Server 和Group 对象需要实现的接口,进行了详细的规定说明。
在 OPC DA 标准中,客户端对服务器的数据存取是以Group 为单位的,每次将需要存取的数据项item 加入一个Group,然后对该Group 进行整体读写操作。Group 对象通过标准定义的IOPCDataMgt 接口,对Item 进行添加,删除等相关的管理;而Server 对象则通过IOPCServer 接口对Group 对象进行添加,删除等管理。
2.2 OPC DA 服务器的结构
开发一个 OPC DA 服务器需要注意以下问题:服务器的运行方式,各个接口与对象的相互关系,内部数据的组织形式,对外部数据源的访问等。在本实例中,OPC 数据存取服务器的框架结构如下图所示
图 1 OPC 服务器的结构
接口与对象:在各层次对象与接口的关系处理中,可以采用两种方法:多继承的方式,将Server/Group 对象继承自每个标准规定的接口;或者采用聚合的方式,Server/Group 对象包含接口对象。本例采用的是第二种方式,该方式可以将使接口的编写相对独立,以方便测试,并且有利于自动化接口的可选择实现。
服务器使用 VC++编程,包含以下几个主要的类:
COPCServer:Server 对象的类,管理IOPCCommon,IOPCServer,IConnectionContainer等接口;
COPCGroup:Group 对象的类,管理IOPCItemMgt,IOPCGroupStateMgt,IOPCSyncIO,IOPCAsyncIO,IConnectionContainer 等接口;
其他接口类:每个接口还对应一个实现类(如:CIOPCItemMgtImp 是IOPCItemMgt 的具体实现),该类完成OPC 标准规定的对应接口的功能函数,类的实例化对象将以聚合的方式接受Server 或Group 对象的管理;欢迎转载,本文来自电子发烧友网(http://www.elecfans.com/)
数据缓存区的构造:在 OPC 服务器中,Cache 是重要的部分,存储结构将直接影响数据访问的速度,它负责将从设备中读取的数据先存放在数据缓存区,供同步或异步读取。缓存区内存可以采用连续存储,链式存储和哈希存储。其中,考虑到存取速度和方便管理,该服务器选择采用连续存储的方式。该方式可以随机存取数据,但存取数据的数量不宜过大,如果需要存取较大数量的数据项,则推荐采用哈希存储方式。对于每个数据项,都包含有三个基本属性:数值(Value),时间戳(Time Stamp)和数据品质(Quality)。从数据源中访问到的数据项将按照线性方式存储到连续的内存区域中;每次对缓存区的访问都需要进行加锁,以防止出现同时进行读操作和写操作。
2.3 轮询方式对数据源进行访问:
由于服务器是单独不断从数据源读取数据,因此可以采用单独的线程,按时间轮询的方式,每隔一段时间对数据源进行访问,这个时间也就成为服务器支持的最短数据访问时间。服务器的主要工作流程:
(1) 每隔一段时间进行轮询操作;
(2) 如果扫描时间到,访问数据源;否则,至(3);如果有订阅请求,回调订阅函数;
(3) 如果有刷新请求,回调刷新函数;如果有异步读数据请求,读取数据并回调异步读函数;如果有异步写请求,将数据写入外部设备;
(4) 返回(1);
服务器中该循环的主要功能,主要用来进行异步数据存取,订阅及刷新。而对于同步访问等操作,由于需要服务器立即存取数据然后返回结果,因此其实现并不在该主循环中,而是针对其接口单独编写一个类,用来实现同步存取接口函数的功能。
2.4 OPC DA 的数据访问方式
OPC DA 对数据的访问主要分为以下几种:同步读,异步读,订阅和数据刷新;对数据源的操作又可以分为直接从设备读取和从Cache 中读取。这两者的组合构成了对数据源的访问规则,OPC 标准对访问规则进行了详细的描述。在这几种数据访问中,同步读接口可以实现少量,快速的数据读取,异步读则是提交一个请求,然后返回,等服务器完成数据读取后回调函数。与同步读相比,异步读更能提高OPC Client 的使用效率,防止OPC 服务器尚未访问到数据时,造成客户端的等待。订阅异步读大致相同,每当访问数据源后自动将数据提交给客户端。
图 2 OPC 服务器中采用的可连接对象结构模型
在 OPC DA2.0 和OPC DA3.0 中的异步通讯机制中,使用到了连接点容器/连接点接口[1],取代了原来OPC DA1.0 中的直接注册/回调的模式。能够更灵活的支持多个连接点和连接。在可连接对象模式中,每个可连接对象可以包含多个连接点,每个连接点支持一种回调接口;每个连接点上可以连接多个客户端;回调接口由客户端实现,可连接对象通过回调函数于客户端进行交互。
在 OPC DA 服务器中,可连接对象包括Server 对象和Group 对象两种,Server 对象只支持一个IOPCShutdown 回调接口,而异步数据交换等重要的功能位于Group 对象中。在OPC 组对象中,包含一个连接点对象,该对象支持IOPCDataCallback 回调接口,连接点可以连接多个客户端,当异步访问完成时,服务器同过可连接对象通过调用标准规定的回调函数,通知每个已经注册的客户端。
2.5 基于适配器模式的数据采集
OPC DA 服务器的最重要功能,就是从外部设备读取数据。由于数据源的多样性,可以是磁盘映射的数据文件,串口或者是专门的数据采集卡。为了设计一个通用的架构,便于以后升级或访问其他不同类型的数据源。一个可行的解决方法就是,添加一个适配层,设计相应的数据访问接口,对有不同数据格式的采集,写入等操作,都从该接口继承,从而针对不同的数据采集方式完成相应的功能。这样,使服务器在整体不需改变的情况下,能够适应多种数据源的情况。其大致的结构如下图所示
图 3 使用适配器模式的IOPCItem 接口
IOPCItem 接口:该接口定义了对外部数据进行访问的虚函数,包括读取(ReadValue),和写入(WriteValue)函数;在进行二次开发时,需针对不同的数据源需要具体实现。当一个组对象扫描该组成员项,进行数据访问时,它将直接调用IOPCItem 接口。该接口是一个虚基类,其具体实现与外部数据源有关;对于将要访问的外部设备,其存取数据的格式和驱动可能不同;IOPCItem 接口对此并不作具体规定,只是定义了虚函数,用来读取和写入数据;其具体的编码实现需要由OPC DA 服务器将要访问的外部设备决定。这样,将数据访问同具体的数据源分开,减少了耦合,使同一服务器架构可以满足多种业务需求。
3 OPC DA 服务器与客户端数据访问的交互过程
OPC 客户端对在进行数据访问时,是以组为单位的,每个组中可以加入客户端需要访问的数据项,具体的访问交互过程如下:
(1) OPC DA 客户端查找并访问一个OPC DA 服务器,此时在OPC DA 服务器端,创建一个Server 对象,并返回一个接口指针;
(2) 客户端由返回的指针找到接口IOPCServer,通过IOPCServer::AddGroup()函数添加一个Group;服务器端则生成一个Group 对象,返回一个该Group 对象的接口指针;
(3) 客户端利用该指针查找IOPCItemMgt 接口,调用函数AddItem()在服务器添加一个或多个item 数据项item 对象,然后便可对该组对象中的数据项进行存取等操作;
(4) 同步访问:查找Group 对象的IOPCSyncIO 接口,直接调用Read(),Write()函数;异步访问:a)注册,查找Group 对象的IConnnectionContianer 接口,找到一个支持OPCDataCallback 接口的连接点对象,客户端生成IOPCDataCallback 对象并在连接点IConnectionPoint 上注册;b)查找IAsyncIO 接口,客户端调用该接口的Read,Write,Refresh等函数,然后直接返回;c)完成数据存取后,服务器回调已经注册的IOPCDataCallback 接口的相关函数,如OnDataChange 等,此时客户端可以通过回调函数获到返回的结果;欢迎转载,本文来自电子发烧友网(http://www.elecfans.com/)
(5) 清理现场,释放接口指针并返回;
4 结束语
OPC 标准在硬件和软件厂商之间建立了规范的联系,其工控领域得到了广泛的应用,成为一个事实上的软件总线。可适配的OPC DA 服务器则是将其上层进行了封装,对下层数据源存取进行了接口抽象,将数据采集同具体的数据源分离,从而降低了数据访问的耦合性。采用可适配模式的OPC DA 服务器,可以针对不同的数据采集模式,依照具体采集卡情况实现适配接口,从而缩短软件整体开发的周期,提高实际应用的速度。