Linux下环境部署

<< 点击显示目录 >>

主页  PVI通信 > 应用例程 > Linux >

Linux下环境部署

 

 

例程环境代码可点击此处下载,此代码仅供参考,具体以PVI安装包提供的资源为准

 

1 Linux环境下的编译

1.1. 将以下文件夹放入某目录。

 

clip0018

 

1.2 每个文件夹内放入相关文件,包括inc内的h文件,lib内的库文件,src内的c主程序。

 

clip0019

 

1.3 使用libANSLUIF.so共享库:修改/etc/ld.so.conf ,在该文件中添加一行libANSLUIF.so共享库的路径,保存后在console 输入命令ldconfig刷新。否则无法执行程序。

 

1.4 打开makefile文件,确保里面填写正确。

 

clip0020

 

1.5 打开ANSLSample.c文件,修改编写程序,检查确认PLC的IP地址,TASK名字,变量名字,变量数量等正确。

 

 

1.6 在终端Konsole上使用cd到makefile所在路径,输入make

 

clip0021

 

1.7 如果编译成功,makefile所在文件夹生成ANSLSample可执行文件

 

clip0022

 

1.8 在终端Konsole上输入./ANSLSample, 执行该文件。原始程序执行方法请参考文件夹里面的<readme>。

 

clip0023

 

2 函数的调用说明

ANSL is an interface based on service objects. Each of these service objects represents an object group or an individual object on the PLC (e.g. CPU, task, process variable, group of all global process variables, etc.). Service objects are created on both sides of an ANSL communication connection (client and server). Each of these service object pairs forms a separate communication channel within an ANSL communication connection. Each ANSL service (request/response, event) is mapped to a service object and executed via the respective communication channel. All communication channels with pending data to be transmitted are entered on a transmit list. The transmit list (and the associated sending of data) then takes place asynchronously in a separate thread (or task). The ANSL interface has a symmetrical structure. For this reason, all stations participating in communication (client and server) use the same transfer strategy. (from PVI help)

此应用类似于PVICOM interface, 可参考PVI help.

 

2.1 主要函数的调用图示,这些函数均封装在libANSLUIF库中。

 

clip0024

 

2.1.1  ANSLI_Initialize() 该无参函数应在ANSL连接前使用,仅使用一次。

 

2.1.2 ANSLI_CPU_Connect(pAddressCPU, commParameter, pIdentCPU, pCBFunction, pUserData)

 

通过该函数连接CPU object,得到它的ident。 该CPU object调用pCBFunction回调函数。

 

I/O

Name

Data type

Description

IN

pAddressCPU

const char*

输入PCC的IP地址,如”10.86.12.220”。

IN

commParameter

const char*

输入通讯参数, 如  "Timeout=\"35000\" Port=\"11169\" SendDelay=\"1\" Buffer=\"4096\""

OUT

pIdentCPU

UDINT*

可得到CPU对象的ident值。

IN

pCBFunction

ANSL_CALL_BACK

输入回调函数,做为消息响应函数,当CPU或TASK或PV对象Status变化,该函数会将变化情况反馈出来。

IN

pUserData

void*

客户自定义的数值。用法例如,主程序内对某变量PV01对象做读操作时,赋值pUserData=1;对变量PV02对象做读操作时,赋值pUserData=2。最后pUserData传递到call back函数内,如果pUserData==1,则printf(“Reading PV01” ),如果pUserData==2,则printf(“Reading PV02”)。

OUT

Status

UDINT

0 – no error

 

2.1.3 ANSLI_TASK_Connect(parentIdent, taskName, pIdentTask, pCBFunction, pUserData)

 

通过该函数连接TASK object,得到它的ident, 该TASK object 调用pCBFunction回调函数。

 

I/O

Name

Datentyp

Description

IN

parentIdent

UDINT

调用ANSLI_CPU_Connect ()时得到的CPU ident。

IN

taskName

const char*

PLC 内的program/task名字

OUT

pIdentTask

UDINT*

可得到task 对象的ident值

IN

pCBFunction

UDINT

输入回调函数,做为消息响应函数,当CPU或TASK或PV对象Status变化,该函数会将变化情况反馈出来。

IN

pUserData

void*

客户自定义的数值。用法例如,主程序内对某变量PV01对象做读操作时,赋值pUserData=1;对变量PV02对象做读操作时,赋值pUserData=2。最后pUserData传递到call back函数内,如果pUserData==1,则printf(“Reading PV01” ),如果pUserData==2,则printf(“Reading PV02”)。

OUT

Status

UDINT

0 - no error

 

2.1.4 ANSLI_VAR_Connect(parentIdent, addressVar, pIdentVar, pCBFunction, pUserData, pEventParameters)

该函数连接某特定变量object,得到它的ident。 该Variable object 调用pCBFunction回调函数。

 

I/O

Name

Datentyp

Description

IN

parentIdent

UDINT

如果连接global变量,则输入CPU对象的ident;

如果连接某任务内local变量,则输入task对象的ident.

IN

addressVar

const char*

输入该变量的名字;如果结构体xxx内的变量yyy,则形式为“xxx.yyy”

OUT

pIdentVar

UDINT*

获得该变量对象的ident

IN

pCBFunction

ANSL_CALL_BACK

输入回调函数,做为消息响应函数,当CPU或TASK或PV对象Status变化,该函数会将变化情况反馈出来。

IN

pUserData

void*

客户自定义的数值。用法例如,主程序内对某变量PV01对象做读操作时,赋值pUserData=1;对变量PV02对象做读操作时,赋值pUserData=2。最后pUserData传递到call back函数内,如果pUserData==1,则printf(“Reading PV01” ),如果pUserData==2,则printf(“Reading PV02”)。

IN

pEventParameters

ANSL_VARIABLE_EVENT_PARAMETER*

The optional variable-attribute.
If NULL is given, a PV with default attribution will be generated.
In this case, the PV will not be read cyclically.

struct ANSL_VARIABLE_EVENT_PARAMETER

{

unsigned int m_EventFlags; /* a bitwise combination of event flags see enum ANSL_VARIABLE_EVENT_FLAGS*/

unsigned int m_RefreshTime; /* refresh time (ms) 0 no automatic refresh*/

int m_IntegerHyst; /* hyst: 0=disabled 0!= integer hysterese is enabled**/

float m_FloatHyst; /* hyst: 0=disabled 0!= float hysterese is enabled**/

};

OUT

Status

UDINT

0 – no error

 

2.1.5 ANSLI_VAR_ReadValue(IdentPv, pData, dataLenth);

 

该函数对某一个变量对象进行读操作后,把一组参数传递入该PV object对应的CALLBACK回调函数,最后把该变量数值以string形式printf出来。

 

I/O

Name

Datentyp

Description

IN

IdentPV

UDINT

ANSLI_VAR_Connect()  获得的变量对象的ident

IN

pDataPV

UDINT*

Address of the target memory for PV data.
NULL, if a reading requisition should be signaled.

IN

dataLength

UDINT

Data length of the target memory for PV data.
0, if a reading requisition should be signaled.

OUT

Status

UINT

0 – no error.

 

参考写法:构造一个读参函数

unsigned int ReadVariable(unsigned int varIdent)

{

 unsigned int status = 0;

 status = ANSLI_VAR_ReadValue(varIdent, NULL, 0);

 if (status !=0)

 {

         printf("ERROR %u READ PV ident=%u \n", status, varIdent);

 }

 return status;

}

 

2.1.6 ANSLI_VAR_SetValue(IdentPV, pDataPV, dataLength)

 

该函数将pDataPV的值赋予IdentPV.

 

I/O

Name

Datentyp

Description

IN

IdentPV

UDINT

ANSLI_VAR_Connect  获得的变量对象的ident

IN

pDataPV

UDINT*

数值指针

IN

dataLength

UDINT

数值的长度sizeof(pDataPV)

OUT

Status

UINT

0 – no error.

 

参考写法:构造两个写参函数

unsigned int WriteVariableInt(unsigned int varIdent, long varValue)

{

 unsigned int status = 0;

 status = ANSLI_VAR_SetValue(varIdent, &varValue, sizeof(varValue));

 if (status !=0)

 {

         printf("ERROR %u SET PV ident=%u \n", status, varIdent);

 }

 return status;

}

unsigned int WriteVariableReal(unsigned int varIdent, float varValue)

{

 unsigned int status = 0;

 status = ANSLI_VAR_SetValue(varIdent, &varValue, sizeof(varValue));

 if (status !=0)

 {

         printf("ERROR %u SET PV ident=%u \n", status, varIdent);

 }

 return status;

}

 

2.1.7 ANSLI_VAR_Disconnect(IdentPV)

 

I/O

Name

Datentyp

Description

IN

IdentPV

UDINT

ANSLI_VAR_Connect  获得的变量对象的ident

OUT

Status

UINT

0 – no error

 

2.1.8 ANSLI_TASK_Disconnect(identTask)

 

I/O

Name

Datentyp

Description

IN

IdentTask

UDINT

ANSLI_TASK_Connect  获得的变量对象的ident

OUT

Status

UINT

0 – no error

 

2.1.9 ANSLI_CPU_Disconnect(IdentCPU)

 

I/O

Name

Datentyp

Description

IN

IdentPV

UDINT

ANSLI_CPU_Connect  获得的变量对象的ident

OUT

Status

UINT

0 – no error

 

2.2.0 ANSLI_TASK_ListVariables(unsigned int identTask, unsigned short filter)

 

例如:ANSLI_TASK_ListVariables(identTask, 0xFFFF) 可列出所有全局变量和该TASK任务内的局部变量,但不可列出结构体变量内的变量。

 

I/O

Name

Datentyp

Description

IN

identTask

UINT

ANSLI_TASK_Connect  获得的任务对象的ident

IN

filter

Unsigned short

0xFFFF表示不筛选变量类型;ANSL_PV_SCOPE_GLOBAL筛选出全局变量;ANSL_PV_SCOPE_LOCAL筛选出局部变量;ANSL_PV_SCOPE_DYNAMIC 筛选出动态变量; ANSL_PV_SCOPE_STATIC筛选出静态变量。

OUT

Status

UINT

0 – no error.

 

Note:在测试的V3版本,ANSLI_CPU_ListVariables()功能未实现。

 

3 Call Back Function的说明

 

3.1 CALLBACK函数的图示

 

clip0025

 

 

3.2 CALLBACK函数的结构

 

ANSLSample.c  的回调函数使用:通过系统API调用回调函数。

 

当调用ANSLI_CPU_Connect(),CPU object对应调用ANSLCB_all回调函数。

 

当调用ANSLI_TASK_Connect(), TASK object对应调用ANSLCB_all 回调函数。

 

当调用ANSLI_VAR_Connect(),  每个variable object 对应调用ANSLCB_all回调函数。

 

通过以上功能块,每一个object都会对应有一个ident,并且有一个对应的回调函数。当使用任何ANSLUIF库的API,如 ANSLI_VAR_ReadValue(), ANSLI_TASK_ListVariables() 等,对某个object(ident)操作后(回调的时机),把object相应参数传入并执行回调函数。如object没有任何操作,则不调用回调函数。

 

该函数写在.c 主程序文件中,可修改。可通过修改CALLBACK函数来得到想要的输出形式。 可将CALLBACK函数内的字符串赋值给global的字符串在主程序内操作。

 

ANSL_CALL_BACK ( errorCode, ident, objectType, cbType, pData, dataLen, pUserData )

 

Name

Data type

Description

errorCode

unsigned int

当某对象有action,把故障号码传递给该函数,0代表无故障

Ident

unsigned int

当某对象有action,此对象的ident传递给该函数

objectType

ANSL_OBJECT_TYPES

执行action的对象的类型,看下表

cbType

ANSL_CALLBACK_TYPES

action的类型,看下表

pData

void*

对象的的数值/字符串指针

dataLen

unsigned int

对象的的数值长度

pUserData

void*

客户自定义的数值。用法例如,主程序内对某变量PV01对象做读操作时,赋值pUserData=1;对变量PV02对象做读操作时,赋值pUserData=2。最后pUserData传递到call back函数内,如果pUserData==1,则printf(“Reading PV01” ),如果pUserData==2,则printf(“Reading PV02”)。

 

 

例1 在主程序中调用ANSLI_VAR_Connect() 连接某task内的local变量“PviVar.PVInt01”,该变量对象依次把数组参数传递入CALLBACK函数,CALLBACK函数将被调用数次,数组参数为:

 

1)        errorCode = 0                                        2)        errorCode = 0,

 ident = 5                                                        ident = 5

 objectType = ANSL_OBJTYPE_TASKPV                        objectType = ANSL_OBJTYPE_TASKPV

 cbType = ANSL_EVENT_STATUS                        cbType = ANSL_RESP_GET_FORMAT

 pData = NULL                                                pData =  NULL

 dataLen = 0                                                        dataLen = 46        

 pUserData = NULL                                                pUserData =  变量“PviVar.PVInt01”的自定义数值

 

3)        errorCode = 0                                        4)        errorCode = 0,

 ident = 5                                                        ident = 5

 objectType = ANSL_OBJTYPE_TASKPV                        objectType = NULL

 cbType = ANSL_EVENT_FORMAT                        cbType = ANSL_EVENT_VALUE

 pData = NULL                                                pData = 数值33的地址指针

 dataLen = 46                                                dataLen = 2

 pUserData = 变量“PviVar.PVInt01”的自定义数值        pUserData = 变量“PviVar.PVInt01”的自定义数值

 

CALLBACK函数再根据参数输入在Konsole终端显示中打印变量对象的status,显示如下:

clip0026

 

例2在主程序中调用ANSLI_VAR_ReadValue()对全局变量“gPV”进行读操作,“gPV”object把相关参数传递入CALLBACK函数,参数如下:

 

errorCode = 0

ident = 19

objectType = ANSL_OBJTYPE_CPUPV

cbType = ANSL_RESP_GET_VALUE

pData = 数值88的地址指针

dataLen = 4

pUserData = 变量名字“gPV”对应的用户自定义数值

 

CALLBACK函数再根据参数输入在Konsole终端显示中打印变量对象的status,显示如下:

clip0027

 

 

NOTE: CALLBACK函数中还调用了GetObjTypeString(), GetCBTypeString(), GetFormatString(), DataToString(),  请仔细看ANSLSample.c 。

 

3.3 enum类型

enum ANSL_OBJECT_TYPES        //回调函数中objectType的取值范围
{
    ANSL_OBJTYPE_SERVER = 0,      // ANSL- Server Objekt (in V1.x nicht verfügbar)
    ANSL_OBJTYPE_CPU = 1,          // CPU- Objekt
    ANSL_OBJTYPE_CPUPV = 2,        // Globales Variablen- Objekt
    ANSL_OBJTYPE_MODULE = 3,    // Modul- Objekt (in V1.x nicht verfügbar)
    ANSL_OBJTYPE_LOGGER = 4,     // Logger- Objekt (in V1.x nicht verfügbar)
    ANSL_OBJTYPE_LIBRARY = 5,     // Library- Objekt (in V1.x nicht verfügbar)
    ANSL_OBJTYPE_TASK = 6,         // Task- Objekt (in V1.x nur für den lokalen PV Zugriff implementiert)
    ANSL_OBJTYPE_TASKPV = 7,      // Lokales Variablen- Objekt
    ANSL_OBJTYPE_IOPV = 8          // IO Variablen- Objekt (in V1.x nicht verfügbar)
}

enum ANSL_CALLBACK_TYPES           //回调函数中cbType 的取值范围
{
    ANSL_UNKNOWN,                    // Unbekannter Ereignis Typ
    ANSL_RESP_CONNECT,              // Antwort auf einen Connect- Request.
    ANSL_RESP_DISCONNECT,          // Antwort auf einen Disconnect- Request
    ANSL_EVENT_ERROR,                // Fehler- Ereignis
    ANSL_EVENT_STATUS,              // Status- Ereignis
    ANSL_RESP_GET_DATETIME,      // Antwort auf die Abfrage des CPU Datums
    ANSL_CANCEL_GET_DATETIME,  // Abbruch eines Leseauftrages für die CPU zum Ermitteln des Datums
    ANSL_RESP_SET_DATETIME,      // A
    ANSL_CANCEL_SET_DATETIME,  // A
    ANSL_RESP_WARM_RESTART,    // A
    ANSL_CANCEL_WARM_RESTART, // A
    ANSL_RESP_COLD_RESTART,      // A
    ANSL_CANCEL_COLD_RESTART,  // A
    ANSL_RESP_UPLOAD,               // A
    ANSL_CANCEL_UPLOAD,           // A
    ANSL_RESP_DOWNLOAD,           // A
    ANSL_CANCEL_DOWNLOAD,       // A
    ANSL_EVENT_FORMAT,            // A
    ANSL_RESP_GET_FORMAT,        // A
    ANSL_EVENT_VALUE,               // A
    ANSL_RESP_GET_VALUE,          // A
    ANSL_CANCEL_GET_VALUE,      // A
    ANSL_RESP_SET_VALUE,          // A
    ANSL_CANCEL_SET_VALUE,      // A
    ANSL_CANCEL_EVENT_VALUE    // A
}