1、COM技术及OPC技术,主要内容,COM基础知识OPC的概念OPC的作用OPC基础知识实验室OPC组相关的工作,一、COM基础知识,COM(Component Object Model,组件对象模型)是Microsoft创建并已取得广泛认可的一种组件标准。 在COM标准中,COM对象被很好的封装起来,客户无法访问对象的实现细节,提供给用户的唯一的访问途径是通过COM接口来访问。对于COM接口有两方面的含义: 首先它是一组可供调用的函数,由此客户可以让该对象做某些事情;其次,接口是组件程序及其客户程序之间的协议。也就是说接口不但定义了可用什么函数,也定义了当调用这些函数时对象要做什么。 COM提
2、供了编写组件的一个标准方法,遵循COM标准的组件可以被组合起来以形成应用程序。组件和客户之间通过“接口”来发生联系,至于这些组件是谁编写的、如何实现的都是无关紧要的。,IOPCAsyncIO : public IUnknown public: virtual HRESULT STDMETHODCALLTYPE Read( /* in */ DWORD dwConnection, /* in */ OPCDATASOURCE dwSource, /* in */ DWORD dwCount, /* size_isin */ OPCHANDLE _RPC_FAR *phServer, /* out
3、 */ DWORD _RPC_FAR *pTransactionID, /* size_issize_isout */ HRESULT _RPC_FAR *_RPC_FAR *ppErrors) = 0; virtual HRESULT STDMETHODCALLTYPE Write( /* in */ DWORD dwConnection, /* in */ DWORD dwCount, /* size_isin */ OPCHANDLE _RPC_FAR *phServer, /* size_isin */ VARIANT _RPC_FAR *pItemValues, /* out */
4、DWORD _RPC_FAR *pTransactionID, /* size_issize_isout */ HRESULT _RPC_FAR *_RPC_FAR *ppErrors) = 0; virtual HRESULT STDMETHODCALLTYPE Refresh( /* in */ DWORD dwConnection, /* in */ OPCDATASOURCE dwSource, /* out */ DWORD _RPC_FAR *pTransactionID) = 0; virtual HRESULT STDMETHODCALLTYPE Cancel( /* in *
5、/ DWORD dwTransactionID) = 0; ;,OPC与COM间关系,OPC(OLE for process control)是建立在微软公司OLE/COM技术基础上。COM技术的出现为简单地实现控制设备和控制管理系统之间的数据交换提供了技术基础。但如果不提供一个工业标准化的COM接口,各个控制设备厂家开发的COM组件之间的相互连接仍然是不可能的。OPC是作为工业标准定义的特殊的COM接口。对相关COM技术的理解是对OPC技术理解的关键所在。OPC技术还有着它本身的独特性,理解了COM技术只是理解OPC技术的第一步。,COM组件的特点,遵循COM规范编写的组件具有以下特点:CO
6、M组件是以二进制的形式发布,所以COM组件是完全与语言无关的。COM组件可以在不妨碍老客户的情况下被升级。COM提供了一种实现同一组件不同版本的标准方法。升级其实就是在现有的组件上增加新的接口就可以了。COM组件可以透明地在网络上被重新分配位置。对远程机器上的组件同本地机器上的组件的处理方式没有什么差别。COM组件是一种给其他应用程序提供面向对象的API服务的极好方法。,COM接口,客户程序和组件程序通过接口进行相互之间的通信。组件程序就是通过接口暴露它的功能给客户程序的,而COM客户程序是不可能看见组件对象本身的。仅有接口是可见的,它告诉客户程序能利用组件能干什么,如何利用它的功能。在组件内
7、,接口以虚函数表的形式实现的。实际上,COM标准就是标准的接口和使用它所需协议的描述,所以说接口是COM允许对象跨进程、跨计算机进行交互的关键技术。,接口的定义、结构与分类,COM对于接口的定义和接口的实现作了严格的区分。通过下面的IUnknown接口可以知道,在接口中只有接口方法的描述,而没有实现。COM接口的名字以字母I打头。其中IUnknown接口最重要,因为所有其它接口都是从IUnknown接口直接或间接继承而来的。IUnkown接口定义了三个方法:1、HRESULT QueryInterface(in REFIID riid,out void *ppv);2、ULONG AddRef
8、();3、ULONG Release();,COM定义的每一个接口都必须从IUnkown接口继承过来。原因在于IUnkown接口提供了两个非常重要的特性:生存期控制和接口查询。客户程序只能通过接口与COM对象进行通信,虽然客户程序可以不管对象内部实现的细节,但它要控制对象存在与否。如果客户还要继续对对象进行操作,则它必须保证对象一直存在于内存中;如果客户对对象的操作已经完成,以后也不再需要该对象了,则应该及时地把对象释放掉,以提高系统资源的利用率。IUnkown接口中的AddRef()和Release()负责对象引用计数,实现组件对象生命周期的管理。每当COM组件被引用一次就应调用一次AddR
9、ef()方法。而当客户端在释放COM组件的某个接口时就需要调用Release()方法。如果一个COM对象实现了多个接口,在初始时刻客户程序不太可能得到该对象的所有接口指针,它只会拥有一个接口指针。如果客户程序需要其它的指针,则利用IUnkown接口中的QueryInterface()方法是用于查询组件对象所实现的其它接口。,OPC对象接口定义,OPC服务器采用的就是以EXE方式实现的COM组件,它可以运行在本地计算机上,也可以运行在网络上的远程计算机上。实际上就是一个典型的进程外COM组件,只不过OPC服务器的接口是有OPC标准组织规定的标准接口。OPC技术实际上就是COM技术在工业控制中的一
10、个具体的应用。,客户/服务器模型,客户/服务器模型是一种发展比较成功的软件模型。组件对象和客户程序之间的相互作用是建立在客户/服务器模型的基础之上的,并且COM组件是运行在分布式环境中的。COM不仅仅是简单的客户/服务器模型,有时客户也反过来提供服务,或服务器本身也需要其它对象的一些功能。一个组件对象可能既是服务器也是客户,COM能有效地处理这些情况。在OPC异步通信访问方式中,当OPC服务器触发OPC应用程序的异步访问完成事件时,OPC服务器此时就扮演了客户端的角色,将数据访问结果传送给OPC应用程序。,组件存在的类型,一般而言,组件具有三种类型:进程内组件、进程外组件和远程组件。第一种是驻
11、留在本地机器上以DLL形式提供,该服务程序被调用时,嵌入到调用程序的线程中运行。此时客户程序和组件程序位于同一台计算机上,客户程序调用组件时,客户程序会把组件程序装入自己的进程空间,即客户程序和组件程序在同一个进程地址空间内。由于它占用和客户端应用程序同样的地址空间,它可以与客户端更快地通信。在客户端和服务器端组件有大量数据转移操作的情况下是最理想的,进程内服务器会更快地装载。第二种是驻留在本地机器上以EXE形式提供,具有独立的进程。客户程序和组件程序也位于同一台计算机上,但客户程序和组件程序分别在不同的进程地址空间中。在COM中,采用了本地过程调用LRC(Local Procedure Ca
12、ll)来进行本地通信。第三种驻留在远端机器上以EXE形式提供,服务程序通过网络被调用,它在远端机器上运行,结果通过网络返回给调用者。这种功能是使用DCOM实现的。DCOM的优点在于它并不要求任何特别的编程来使其具有功能。另外服务器和客户端通信是通过RRC(Remote Procedure Call)通信协议进行的。虽然客户程序和组件程序交互的内在方式是完全不同的,但是对于功能相同的进程内和进程外组件,从程序编写的角度看,客户程序是以同样的方法来使用组件程序的。OPC服务器采用的就是以EXE方式实现的COM组件。,通过COM库创建COM对象,COM库充当了组件程序和客户程序之间的桥梁,在Micr
13、osoft Windows操作系统环境下,这些库以DLL文件的形式存在。在组件对象的创建过程、对象管理、内存管理、以及在标准化操作等方面,都起了重要的作用。COM库可以保证所有的组件按统一的方式进行交互操作,而且它使我们在编写COM时,可不编写为进行COM通信而必需的大量基础代码,而是直接利用COM库的API进行编程,从而大大加快开发的速度。,客户程序通过COM库访问组件程序的步骤,(1)在进行函数调用以前,必须调用COM库的初始化函数:HRESULT= CoInitialize(NULL);(2)通过函数CLSIDFromProgID()或CLSIDFromProgIDEx()ProgID,
14、查找注册表中相关组件的CLSID。(3)客户端程序调用CoCreateInstance(),创建COM对象,传递组件对象类的CLSID以及所要接口的IID。(4)COM库在HKEY_CLASSES_ROOTCLSID.键值下查找服务器的CLSID键值,这个键值包含服务器的注册信息。(5)COM库读取服务器的全路径并将组件程序加载。(6)COM库为组件对象类请求类工厂。COM库在类工厂中调用CreateInstance()方法创建客户端程序请求的COM对象。(7)CreateInstance()返回一个接口指针给客户端程序。,通过COM库删除COM对象,IUnknown是每一个COM对象必须实现
15、的接口,其中有一个Release()方法。调用这个方法通知COM对象你不再需要对象。一旦调用了这个方法之后,就不能再次使用这个接口,因为这个COM对象可能从此就从内存中消失了。如果应用程序使用许多不同的COM对象,因此在用完某个接口后调用Release()就显得非常重要。如果你不释放接口,这个COM对象将保留在内存中,这会增加不必要的开销。如果应用程序要长时间运行,就应该在应用程序处于空闲期间调用CoFreeUnusedLibraries()API函数。这个API函数将卸载任何没有明显引用的COM服务器,因此这也降低了应用程序使用的内存开销。,/ 像上面一样创建COM对象,然后,if ( SU
16、CCEEDED ( hr ) )/通知COM对象不再使用它m_IOPCServer -Release();应用程序对COM库进行初始化之后,可以调用COM库提供的各种服务,在调用过程中必然要消耗COM库管理的资源。因此,COM程序在完成COM库服务之后,通常在程序退出之前,终止COM库服务函数,以便释放COM库所维护的资源。COM库的终止函数为:void CoUninitialize(void);凡是调用CoInitialize函数返回S_OK的进程或者程序模块,都一定要调用对应的CoUninitialize函数以保证COM库资源的有效利用。,C+调用OPC服务器的关键性代码,OPC服务器实际
17、上就是一种COM组件,以下是一个OPC客户程序调用OPC服务器对象的关键性代码,创建一个OPCServer对象的实例并请求指向这个对象m_IOPCServer接口指针。HRESULT hr; / 首先声明一个接受CoCreateInstance()返回值的HRESULTbool m_bComInitialized;IOPCServer* m_IOPCServer;/ 指向IID_IOPCServer接口的指针hr= CoInitialize(NULL) /初始化COM库m_bComInitialized = SUCCEEDED (hr);if (!m_bComInitialized)retur
18、n (FALSE); /如果初始化COM库失败,程序就不必向下执行/通过ProgID,查找注册表中的相关CLSID,hr = CLSIDFromProgID(LNAPOPC.Svr, ,/创建OPC服务器对象,并查询对象的IID_IOPCServer接口hr = CoCreateInstance ( clsid, /coclass的CLSIDNULL, /不是用聚合CLSCTX_LOCAL_SERVER, /服务器类型IID_IOPCServer, /接口的IID(void*) /调用CoUninitialize函数释放COM库的资源调用CoCreateInstance()来创建新的OPC服务
19、器对象。如果hr接受到一个表示成功的代码,即S_OK,则SUCCEEDED宏返回TRUE,否则返回FALSE。FAILED是一个与SUCCEEDED对应的宏用来检查失败代码。,二、 OPC的概念,OLE for Process Control (用于过程控制的OLE(Object Lingking and Embedding))OPC是一种过程控制中的标准化技术该技术基于OLECOMDCOM,采用客户服务器模式。OPC建立了一组符合工业控制要求的接口规范,主要包括:OPC数据访问规范,OPC报警与事件规范,OPC历史数据存取规范,OPC安全规范,OPC批处理规范,OPC服务器数据交换规范和OP
20、C XML规范。,其中应用最多的是数据访问规范。不同的规范定义了不同的接口集合,以及这些接口需要实现的功能。只要硬件开发商提供了实现OPC接口的服务器,任何支持OPC接口的客户程序均可采用统一的方式对不同硬件厂商的设备数据进行存取。,OPC 特性,OPC标准前,OPC 特性,OPC标准后,OPC是连接数据源(OPC服务器)和数据的使用者(OPC应用程序)之间的接口标准。数据源可以是PLC,DCS,条形码读取器等控制设备。服务器既可以是本地服务器,也可以是远程服务器。OPC是具有高度柔软性的接口标准。目前,OPC技术主要应用于以下几大工业控制:在线数据监测,报警和事件处理,历史数据访问远程数据访
21、问。,OPC 的客户/服务器模型(C/S),OPC一般采用客户/服务器模式。通常把符合OPC规范的设备驱动程序称为OPC服务器,它是一个典型的数据源程序。将符合OPC规范的应用软件称为OPC客户,它是一个典型的数据接受程序。服务器充当客户和硬件设备之间的桥梁。客户对硬件设备的读写操作由服务器代理完成。,在客户端和服务器端都各自定义了统一的标准接口,接口具有不变特性。接口明确定义了客户同服务器间的通信机制,是连接客户同服务器的桥梁和纽带。客户通过接口实现与服务器通信,获取现场设备的各种信息。统一的标准接口是OPC的实质和灵魂。,三、OPC的作用,OPC的优势,在于异构系统的集成可以通过OPC技术
22、来解决(也可以通过协议转换桥来解决)。OPC服务器集成了多种总线协议,在服务器中实现协议转换,并将接收到的数据通过COM或DCOM传给客户端。OPC服务器由硬件厂商提供,因为硬件厂商了解底层协议,方便编写OPC服务器。上层用户可以用任意一个客户端(很多组态软件集成OPC客户端),从接口把数据读出即可。,异构网络互联的实现,现场总线至今仍然是多种总线共存的局面,致使系统集成和异构网段之间的数据交换面临许多困难。以OPC作为异构网段集成的中间件可以形成如下图所示的系统集成软件解决方案。每个总线段提供各自的OPC服务器,任一OPC客户端软件都可以通过一致的OPC接口访问这些OPC服务器,从而获得各个
23、总线段的数据。,OPC优势异构网络的互联,利用协议转换桥实现异构网络集成,四、OPC基础知识,OPC客户端模型,OPC服务器的结构,OPC数据访问服务器在结构上由服务器(Server)、组(Group)、项(Item)三级对象组成。逻辑关系上,服务器和组之间是聚合关系,组和项之间是包容关系。其中项对应着硬件设备中某个具体设备单元,它包括当前设备单元数据值、当前设备单元的数据时间标签、数据品质信息等。,客户端与服务器的关系,服务器中组与项目的关系:,OPC数据传输方式:,同步和异步方式是OPC Client与OPC Server之间交换数据的两种方式: 同步方式是按照一定的时间频率交换所有数据的
24、方式,方法简单,但效率较低。适用于发送数据量教少的场合。 异步方式则当服务器缓冲区发生更改时,向客户发出通知,客户得到通知后在进行处理的一种方式。异步方式需要在客户程序中实现服务器的回调函数。适用于发送数据量大的场合。,同步访问方式,异步访问方式,Cache方式与Device方式:,OPC Server有一个数据缓冲区,存储来自设备最新的数据值,OPC Client通过该缓冲区读写数据的方式为Cache方式 不通过数据缓冲区,直接从设备读取数据的方式为Device方式,OPC DA服务器对象接口,OPC DA组对象的接口,客户端需实现的接口,IOPCDataCallbackIOPCShutdo
25、wnIAdviseSink (old),三、OPC组所做的工作,以前版本的OPC服务器OPC服务器开发工具包新版本的OPC服务器,OPC服务器模型,1、基于EPA的OPC服务器模型,OPC服务器总体结构由OPC标准接口实现模块、服务器界面模块、存储缓冲区模块、硬件驱动模块组成,OPC服务器与EPA协议中的详细交互部分,如图所示。这样,OPC保证了EPA与其它标准的产品互联互通,解决了EPA设备与其它标准设备间的互操作性问题。,OPC服务器工作流程图,存储缓冲区模块,存储缓冲区中缓存从EPA现场设备采集到的实时数据,和存储来自OPC客户端的数据,而且在OPC客户端需要时传给客户端。存储缓冲区高速
26、缓存现场设备的数据,使得OPC客户端的调用不需等待而快速地从OPC服务器中返回,减少了OPC客户端的应用程序阻塞时间,加快了其应用程序的执行。,服务器界面模块,服务器界面的主要功能是方便用户配置服务器的参数。组对象是用来管理标签的,实际上就是对标签的分类。最后就是创建标签对象,数值就是服务器从现场设备取得的实时变化的数据。标签对象和现场设备是一一对应的,OPC客户端程序从OPC服务器读取标签对象的数据,就等于从现场设备读取数据。,硬件驱动模块,现场设备通过驱动程序与OPC服务器进行数据交互,简单的说,即对现场设备进行读写操作。在这里,我们通过EPA协议与主控制器的通信来实现OPC服务器的驱动部
27、分。这里用到的EPA应用层服务是变量访问服务,包含读服务、写服务和信息分发服务。,由于EPA协议数据传输是基于TCP(UDP)/IP传输协议的,为了使数据传输的效率提高,OPC服务器采用UDP套接字进行通信,其中,读写服务的通信过程采用客户机/服务器(C/S)模式进行通信。下面结合上图以变量读服务来说明数据传输流程。首先,EPA通信发起方通过链接对象标识ID查找与其相对应的EPA链接对象,将EPA链接对象中本次通信所需的EPA链路信息,包括EPA通信应答方的设备IP地址、功能块实例ID。其次,当获得这些信息后,调用相应的应用层服务,进行EPA报文的编码。,把EPA报文头和变量读请求服务报文封装
28、好后,EPA服务报文下传到EPA套接字映射接口实体。套接字映射接口主要完成两个功能:第一,按照应用层服务内容(本例中为读服务)确定其优先级,并将报文送到相应的优先级缓冲队列中去;第二,监控EPA链路,当链路空闲时按优先级顺序进行报文的发送。第三,EPA现场设备收到读请求报文后,采用EPA服务中的变量读正响应服务回答,OPC硬件驱动程序模块接收线程函数通过套接字接收到报文数据后,按照变量读正响应报文进行报文解析,刷新OPC数据。,系统结构图,下面采用EPA服务中的信息分发服务为例说明数据传输过程。整个过程的流程如图所示。首先,现场设备中集成了EPA协议栈,把现场实时数据打包成EPA数据,发送到E
29、PA网络上;然后,OPC服务器中的硬件驱动模块把接收到EPA报文解包,并把数据放到存储缓冲区中;第三,OPC客户端从存储缓冲区中读取数据;最后,OPC客户端将数据显示出来。,基于OPC的EPA监控系统界面,EPA系统中集成的现场设备数据监控界面如图所示。图中显示了当前控制网络现场设备的设备名、当前值、标签质量、时间戳、设备的IP地址等属性。现场设备名表明网络中的具体设备,当前值表明当前设备的实时值;标签质量表明设备实时值的正确性;时间戳表明数据从接收模块中解包后存放到数据缓冲区的当时时间;设备IP表明不同无线现场设备接入点或网关的IP地址。,2、OPC服务器开发工具包,由于OPC数据访问服务器
30、的编写工作涉及到对OPC DA规范的深刻理解和对COM/DCOM知识的掌握,使得OPC数据访问服务器的编写工作变得比较困难。本文针对这种情况,设计开发了OPC数据访问服务器的开发工具包,把OPC DA协议和COM相关知识封装成DLL,这样一来,用户无需了解复杂的COM机制和OPC DA协议。,通过调用DLL,用户只需要实现自己的协议通信程序,就可以编写出相应协议的OPC数据访问服务器。,完整的服务器开发工具包应该包括四个文件和一个说明文档四个文件是:OPC_CQUPT_Svr.dll,OPC_CQUPT_Svr.lib,OPC_CQUPT_SvrAPI.h,OPC_CQUPT_SvrExtAP
31、I.h,其中,两个头文件里边包含所有动态链接库函数声明,用来告诉用户所调用函数原形。,OPC_CQUPT_Svr.dll包含五大功能块:调用返回定义、初始化和注册函数、OPC项函数、实时信息函数和辅助功能函数。各个模块间的关系如图 。,OPC服务器开发工具包设计框图,OPC框架模块,该模块负责创建所有OPC规范必须要实现的COM对象,如OPC服务器接口对象,OPC组接口对象,实现OPC规范规定的全部功能。该模块实现的主要功能如下:完成OPCServer COM对象的创建,并用OPCServerlist来维护OPC服务器链表;完成OPCGroup COM对象的创建,并用GroupList来维护OPC组链表;完成对Tag的添加、删除、刷新、读操作、写操作等功能;实现数据的同步和异步访问方式;维护了一张Tag名字的Hash树,协助CIOPCBrowse实现浏览Tag。,3、基于OPC服务器开发工具包开发的OPC服务器,该OPC服务器是利用OPC服务器开发工具包开发出来的。通过调用该开发包,用户只要实现相应的通信协议模块即可。,测试系统结构,OPC服务器显示界面,OPC客户端显示界面,