例程环境代码可点击此处下载,此代码仅供参考,具体以PVI安装包提供的资源为准
1 Linux环境下的编译
1.1. 将以下文件夹放入某目录。
1.2 每个文件夹内放入相关文件,包括inc内的h文件,lib内的库文件,src内的c主程序。
1.3 使用libANSLUIF.so共享库:修改/etc/ld.so.conf ,在该文件中添加一行libANSLUIF.so共享库的路径,保存后在console 输入命令ldconfig刷新。否则无法执行程序。
1.4 打开makefile文件,确保里面填写正确。
1.5 打开ANSLSample.c文件,修改编写程序,检查确认PLC的IP地址,TASK名字,变量名字,变量数量等正确。
1.6 在终端Konsole上使用cd到makefile所在路径,输入make
1.7 如果编译成功,makefile所在文件夹生成ANSLSample可执行文件
1.8 在终端Konsole上输入./ANSLSample, 执行该文件。原始程序执行方法请参考文件夹里面的<readme>。
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库中。
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. 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. |
IN |
dataLength |
UDINT |
Data length of the target memory for PV data. |
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函数的图示
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,显示如下:
例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,显示如下:
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
}