1 数据字典

自动组块:通讯协议支持按照连续地址、或者一次请求可以访问多个数据的设备,如常见的PLC协议、modbus、OPC、AB CIP协议等。协议按照一个一个变量配置后,自动分析变量之间关系,自动组块请求。这样可以提交数据访问效率。

2 开发准备

  1. 使用VS2013开发环境,根据eview版本是64位还是32位,确定VS2013编译的驱动的位数。


  1. 开发包需要的include、lib、source(例子代码)目录,请单独从eview-yyyy-mm-dd-sdk.zip中获取。


  1. 例子代码在开发包的source\drivers\sampledrv下,该目录有VS2013可打开的sln,如果linux/unix下请使用QT或CMake编译CMakeLists.txt文件。


  1. 实际驱动如xxxxdrv请将sampledrv目录下的vcproj, sampledrv.sln, sampledrv.cpp, CMakeLists.txt这几个文件用记事本/EditPlus打开,替换sampledrv为xxxxdrv目录,并将sampledrv目录改为xxxxdrv名称。

3 手工生成驱动工程

利用vs2013向导生成win32 dll驱动工程,在工程属性->Configuration Properties->C/C++->GeneralàAdditional Include Directories下增加“eview安装目录\include目录”;在工程属性->Linker->General->Additoinal Library Directories下增加“eview安装目录\library目录”。

4 驱动的调试运行

4.1 调试准备

  • 将驱动二次开发包下的bin目录下的exe拷贝到“eview安装路径\bin\drivers\xxxxdrv\”路径下;
  • 重命名exe为“xxxxdrv.exe”
  • 在驱动工程属性-> Configuration Properties ->Linker->General选项下设置Output  File为“eview安装路径\bin\drivers\ xxxxdrv \ xxxxdrv.dll”,例如C:\eview\bin\drivers\ xxxxdrv \ xxxxdrv.dll(注意:驱动工程生成的dll名称、pkdriver拷贝后重新命名的名称、以及存放的文件目录名称三者必须保持一致,否则驱动在运行时将无法正确的和我们的系统集成
  • 设置驱动工程属性-> Configuration Properties->Debugging选项下选择“Local Windows Debugger”,设置command为“eview安装路径\bin\drivers\ xxxxdrv \ xxxxdrv.exe”,例如C:\eview\bin\drivers\ xxxxdrv \ xxxxdrv.exe;设置Working Directory为“eview安装路径\bin\”,例如C:\eview\ xxxxdrv \(此处应设置执行路径为eview安装目录下的bin目录);
  • 在代码中设置断点进行调试,“exe”程序启动时会自动加载“xxxxdrv.dll”,调用。“xxxxdrv.dll”中的相关接口,关于接口调用顺序和接口何时被调用见第7节。

4.2 驱动调试

4.2.1 在配置中配置驱动

  • 在系统中增加驱动基本信息

进入配置界面->设备配置->系统配置,在对话框中添加驱动。

其中驱动名称为用户自定义的英文驱动名。

  • 在Scada中添加驱动

添加配置后,可在设备中增加该驱动的一个设备.

  • 配置类及类的属性,属性地址部分选择该驱动及对应的驱动地址
  • 配置类的对象

4.2.2 调试

驱动配置部署后,eview会自动启动你的驱动程序。调试前需要先关闭你的驱动程序,因为系统仅仅允许启动你的一个驱动进程,停止驱动的方法如下:任务管理器杀掉该驱动。


4.3 运行驱动

直接点击xxxxdrv.exe启动驱动。或者通过pkservermgr自动启动所有程序包括驱动。

5 驱动框架实现的主要功能

驱动框架实现的主要功能如下:

  1. 实现了驱动配置的自动加载读取
  2. 对于TCP连接设备,根据配置自动建立、断开和管理与设备的连接状态

6 编写驱动DLL中的导出函数

向导生成的文件中主要有以下10个导出函数:

6.1 初始化驱动函数

long InitDriver(PKDRIVER *pDriver)

参数说明:驱动结构体

功能说明:初始化函数,驱动EXE启动时该函数被调用,可在该函数中实现用户自定义初始化操作(例如使用com接口时调用com初始化函数)。

注意:如无特别需要,可以不实现。

6.2 退出驱动处理

long UnInitDriver(PKDRIVER *pDriver)

参数说明:无

返回值:返回PK_SUCCESS代表成功,其余值为失败

功能:驱动退出时该函数被调用。在该函数中可以释放用户自定义资源、对于非TCP连接设备断开设备连接等操作。

注意:如无特别需要,可以不实现。

1.1 初始化具体设备函数

long InitDevice(PKDEVICE *pDevice)

参数说明:设备结构体

功能说明:每个设备配置被加载后会调用该初始化函数,可在该函数中实现用户自定义的具体设备相关初始化操作。常用操作包括:创建定时器、自组块等。

注意:必须实现开启定时器的功能,否则无法执行OnTimer函数

6.3 退出具体设备处理

long UnInitDevice(PKDEVICE *pDevice)

参数说明:无

返回值:返回PK_SUCCESS代表成功,其余值为失败

功能:驱动退出时该函数被调用。在该函数中可以释放用户自定义资源、对于非TCP连接设备断开设备连接等操作。

注意:可以不实现。


6.4 处理定时数据读取

long OnTimer(PKDEVICE *pDevice, PKTIMER *timerInfo);

参数说明:

PKDEVICE *pDevice [输入参数]:设备句柄

PKTIMER *timerInfo [输入参数]:定时器句柄

返回值:返回PK_SUCCESS代表成功,其余值为失败

功能说明:该函数会在InitDevice时创建一定周期的定时器(Drv_CreateTimer(pDevice,&timerInfo))后自动被调用。对于块设备,轮询周期往往是指块的轮询周期。对于一次读取所有状态的设备,轮询周期是指设备的轮询周期。通常该函数实现如下功能:

1、数据的发送和接收

2、更新变量实时数据的值、数据状态和时间戳

3、对于非tcp通信协议,通常需要在该接口检查连接状态

注意:该函数必须实现


6.5 处理控制命令

long OnControl(PKDEVICE *pDevice, PKTAG *pTag, const char *szStrValue, long lCmdId)

参数说明:

PKDEVICE *pDevice [输入参数]:设备指针

PKTAG *pTag [输入参数]:变量指针

const char *szStrValue [输入参数]:用字符串表示的变量值(如数字16这里传入”16” 

lCmdId [输入参数]:控制命令的编号id

返回值:控制返回结果

功能说明:当有控制命令时该函数被调用,通过该函数向设备下发控制命令

注意:对于需要通过驱动实现控制功能的,该函数必须实现

7 驱动框架提供给驱动DLL调用的接口函数

7.1 将字符串表示的值转变为二进制数值

int Drv_TagValStr2Bin(PKTAG *pTag, const char *szTagStrVal, char *szTagValBuff, int nTagValBuffLen,

    int *pnRetValBuffLenBytes, int *pnRetValBuffLenBits);

参数说明:


7.2 更新一组变量数据

int Drv_UpdateTagsData(PKDEVICE *pDevice, PKTAGVECTOR &vecTags)

参数说明:

7.3 设置设备连接状态

int Drv_SetConnStatus(PKDEVICE *pDevice, unsigned char bConnected);

参数说明:

Drv_SetUserData(hDrv, 1, lUserData2);

7.4 获取变量当前值

int Drv_GetTagData(PKDEVICE *pDevice, PKTAGDATA *pTagData);

参数说明:


7.5 创建定时器

int Drv_CreateTimer(PKDEVICE *pDevice, PKTIMER *timerInfo);

参数说明:


7.6 销毁定时器

int Drv_DestroyTimer(PKDEVICE *pDevice, PKTIMER *pTimer);

参数说明:

7.7 从设备接收多个字节

int Drv_Recv(PKDEVICE *pDevice, char *szBuffer, int nBufLen, int nTimeOutMS);

参数说明:当前暂仅支持TCP作为客户端、串口的连接方式。

PKDEVICE *pDevice [输入参数]:设备句柄

char *szBuffer [输入参数]:接收数据的缓冲区

int nBufLen [输入参数]:接收数据的缓冲区的长度

int nTimeOutMS [输入参数]:接收数据超时时间,单位是毫秒

返回值:返回接收的字节数

功能说明:当用户使用TCP连接时可调用该接口从设备接收数据


7.8 向设备发送多个字节

int Drv_Send(PKDEVICE *pDevice, const char *szBuffer, int nBufLen, int nTimeOutMS );

参数说明:当前暂仅支持TCP作为客户端、串口的连接方式。

PKDEVICE *pDevice [输入参数]:设备句柄

const char *szBuffer [输入参数]:待发送数据的缓冲区

int nBufLen [输入参数]:待发送数据的缓冲区长度

int nTimeOutMS [输入参数]:发送超时时间,单位是毫秒

返回值:返回成功发送的字节数

功能说明:当用户使用TCP、串口、UDP连接时可调用该接口发送数据到设备


7.9 建立与设备的连接

int Drv_Connect(PKDEVICE *pDevice, int nTimeOutMS);

参数说明:


7.10 断开与设备的连接

int Drv_Disconnect(PKDEVICE *pDevice);

参数说明:


  • 无标签