https://github.com/libplctag/libplctag
此部分本人会简要介绍一下常用API,用于个人记录。更详细的说明请自行移步2.5.0 API文档网址:
https://github.com/libplctag/libplctag/wiki/API#tag-life-cycle
plc_tag_create()
打开PLC标签的句柄,通过plc_tag_destroy()
释放与函数一起使用的资源。
- PLCTAG_STATUS_PENDING (1) - 操作正在进行中。不是错误。
- PLCTAG_STATUS_OK (0) - 无错误。操作成功或标签状态良好。
- PLCTAG_ERR_ABORT (-1) - 操作已中止。
- PLCTAG_ERR_BAD_CONFIG (-2) - 由于配置不正确,操作失败。通常从远程系统返回。
- PLCTAG_ERR_BAD_CONNECTION (-3) - 由于某种原因,连接失败。例如,这可能意味着远程 PLC 已重新通电。
- PLCTAG_ERR_BAD_DATA (-4) - 从远程 PLC 接收的数据无法破译或无法处理。也可以从无法处理发送给它的数据的远程系统返回。
- PLCTAG_ERR_BAD_DEVICE (-5) - 当寻址的内容不存在时,通常从远程系统返回。
- PLCTAG_ERR_BAD_GATEWAY (-6) - 通常在库无法连接到远程系统时返回。
- PLCTAG_ERR_BAD_PARAM (-7) - 当标签创建属性字符串不正确时返回的常见错误。
- PLCTAG_ERR_BAD_REPLY (-8) - 通常在远程系统返回意外响应时返回。
- PLCTAG_ERR_BAD_STATUS (-9) - 通常由远程系统在状态不佳时返回。
- PLCTAG_ERR_CLOSE (-10) - 尝试关闭某些资源时出错。
- PLCTAG_ERR_CREATE (-11) - 尝试创建某些内部资源时出错。
- PLCTAG_ERR_DUPLICATE (-12) - 当某些内容(即重复的连接 ID)被错误复制时,远程系统返回的错误。
- PLCTAG_ERR_ENCODE (-13) - 尝试对某些数据(如标签名称)进行编码时返回错误。
- PLCTAG_ERR_MUTEX_DESTROY (-14) - 内部库错误。看到这种情况是非常不寻常的。
- PLCTAG_ERR_MUTEX_INIT (-15) - 同上。
- PLCTAG_ERR_MUTEX_LOCK (-16) - 同上。
- PLCTAG_ERR_MUTEX_UNLOCK (-17) - 同上。
- PLCTAG_ERR_NOT_ALLOWED (-18) - 当不允许操作时,通常从远程系统返回。
- PLCTAG_ERR_NOT_FOUND (-19) - 通常在找不到某些内容时从远程系统返回。
- PLCTAG_ERR_NOT_IMPLEMENTED (-20) - 未实现有效操作时返回。
- PLCTAG_ERR_NO_DATA (-21) - 当预期数据不存在时返回。
- PLCTAG_ERR_NO_MATCH (-22) - 类似于NOT_FOUND。
- PLCTAG_ERR_NO_MEM (-23) - 内存分配失败时由库返回。
- PLCTAG_ERR_NO_RESOURCES (-24) - 当某些资源分配失败时,由远程系统返回。
- PLCTAG_ERR_NULL_PTR (-25) - 通常是内部错误,但在 API 调用中使用无效句柄时可能会返回。
- PLCTAG_ERR_OPEN (-26) - 打开套接字等资源时出错时返回。
- PLCTAG_ERR_OUT_OF_BOUNDS (-27) - 通常在尝试将值写入标签数据边界之外的标签或读取标签数据边界之外的值时返回。
- PLCTAG_ERR_READ (-28) - 在读取操作期间发生错误时返回。通常与套接字问题有关。
- PLCTAG_ERR_REMOTE_ERR (-29) - 未指定或无法转换的远程错误会导致此问题。
- PLCTAG_ERR_THREAD_CREATE (-30) - 内部库错误。如果你看到这一点,很可能一切都要崩溃了。
- PLCTAG_ERR_THREAD_JOIN (-31) - 另一个内部库错误。你不太可能看到这一点。
- PLCTAG_ERR_TIMEOUT (-32) - 操作花费的时间过长且超时。
- PLCTAG_ERR_TOO_LARGE (-33) - 返回的数据比预期的要多。
- PLCTAG_ERR_TOO_SMALL (-34) - 从远程系统返回的数据不足。
- PLCTAG_ERR_UNSUPPORTED (-35) - 远程系统上不支持该操作。
- PLCTAG_ERR_WINSOCK (-36) - 发生特定于 Winsock 的错误(仅在 Windows 上)。
- PLCTAG_ERR_WRITE (-37) - 尝试写入(通常是套接字)时出错。
- PLCTAG_ERR_PARTIAL (-38) - 收到部分数据或某些内容意外不完整。
- PLCTAG_ERR_BUSY (-39) - 无法执行该操作,因为正在执行其他操作。
const char *plc_tag_decode_error(int err);
plc_tag_check_lib_version()
函数来确认库版本是否满足需求。如果满足需求,函数返回PLCTAG_STATUS_OK
;如果不符合,则返回PLCTAG_ERR_UNSUPPORTED
。#define REQUIRED_VERSION 2,1,0 //程序需要的版本为2,1,0
/* check the library version. */
if(plc_tag_check_lib_version(REQUIRED_VERSION) != PLCTAG_STATUS_OK) {
fprintf(stderr, "Required compatible library version %d.%d.%d not available!", REQUIRED_VERSION);
exit(1);
}
//根据此模块判断是否满足需要
plc_tag_check_lib_version()
函数判断的内部逻辑如下:
int plc_tag_check_lib_version(int req_major, int req_minor, int req_patch);
plc_tag_create()
函数。该字符串的格式与URL类似,由键-值对组成,用&
符号分开。注意:创建或打开PLC中已存在的标签或字段的句柄,而不是在PLC中创建一个标签。(plc_tag_create_ex()
函数可看API文档)int32_t plc_tag_create(const char *attrib_str, int timeout);
//attrib_str:字符串(以NULL字符结尾),包含创建标签所需的所有信息
//timeout:等待句柄创建完成的值(以毫秒为单位)。如果该值为0,则函数可能会在PLC连接之前返回。
//举例:
int32_t tag = plc_tag_create("protocol=ab_eip&gateway=192.168.1.42&path=1,0&cpu=LGX&elem_count=10&name=myDINTArray[0]", 1000);
free()
函数。因为标签在内部并非一个内存块,所以要释放标签,需要调用下面的函数。程序要负责标签的创建和销毁。
int plc_tag_destroy(int32_t tag);
//返回状态码
void plc_tag_shutdown(void);
int plc_tag_register_callback(int32_t tag_id, void (*tag_callback_func)(int32_t tag_id, int event, int status));
int plc_tag_register_callback_ex(int32_t tag_id, void (*tag_callback_func)(int32_t tag_id, int event, int status, void *userdata), void *userdata);
int plc_tag_unregister_callback(int32_t tag_id);
每个标签可以注册0个或1个回调函数。
PLCTAG_ERR_DUPLICATE
。注册成功返回PLCTAG_STATUS_OK
。PLCTAG_ERR_NOT_FOUND
。移除成功返回PLCTAG_STATUS_OK
。库提供了一个在标签上注册回调的函数。以下事件会产生对回调函数的调用:
- PLCTAG_EVENT_CREATED (7) - 标签创建完成后调用回调。创建的最终状态也会传递给回调。在某些情况下,这不太受支持,因此仅依赖于普通标签,而不是像@tags这样的标签。
- PLCTAG_EVENT_READ_STARTED (1) - 已请求读取标记。在调用基础协议实现之前立即调用回调。
- PLCTAG_EVENT_READ_COMPLETED (2) - 读取完成后调用回调。读取的最终状态也会传递给回调。
- PLCTAG_EVENT_WRITE_STARTED (3) - 与读取一样,在请求写入时调用回调。回调可以更改标签中的数据,更改将发送到 PLC。
- PLCTAG_EVENT_WRITE_COMPLETED (4) - 当 PLC 指示写入已完成时调用回调。写入状态将传递给回调。
- PLCTAG_EVENT_ABORTED (5) - 当某些东西调用标签上的 plc_tag_abort() 时调用回调函数。
- PLCTAG_EVENT_DESTROYED (6) - 销毁标记时调用回调函数。此时对标记调用任何 API 函数是不安全的。这纯粹是为了回调来管理任何应用程序状态。
//注册函数
//tag_id:标签句柄
//debug_level:调试级别。不同的调试级别,对应不同的详细程度。具体内容见本文的调试部分。
//message:日志信息的文本字符串。由库管理,不归程序所有,不要释放字符串。如果要存储或更改,需要在副本上操作。
int plc_tag_register_logger(void (*log_callback_func)(int32_t tag_id, int debug_level, const char *message));
//删除注册
int plc_tag_unregister_logger(void);
stderr
。plc_tag_decode_error()
以外的任何标签API函数。否则,库可能会挂起。plc_tag_abort()
函数来停止任何正在进行的操作。int plc_tag_abort(int32_t tag);
int plc_tag_read(int32_t tag, int timeout);
//tag:标签句柄。
//timeout:以毫秒为单位。如果值为0,该函数将设置读取请求并立即返回。如果超时值大于0,则函数等待该毫秒数,以便读取操作完成。如果超时,则中止操作,返回PLCTAG_ERR_TIMEOUT。
PLCTAG_STATUS_OK
PLCTAG_STATUS_PENDING
int plc_tag_status(int32_t tag);
//返回当前标签状态的状态码
plc_tag_write()
函数写入目标PLC。但写之前,要通过plc_tag_set_X()
函数设置数据。int plc_tag_write(int32_t tag, int timeout);
int plc_tag_get_size(int32_t tag);
int plc_tag_set_size(int32_t tag, int new_size);
//tag:标签句柄
//offset:字节偏移量。比如,64字节的数据,要获取2字节开始的32位数据,则offset为2。
//函数返回32位(4字节)int值
int32_t plc_tag_get_int32(int32_t tag, int offset);
int plc_tag_set_int32(int32_t, int offset, int32_t val);
UINT_MAX
值,比如:get_uint16(),错误返回65535。有符号get出错时,返回INT_MIN
值。可以用plc_tag_status判断错误或正确。PLCTAG_STATUS_OK
,错误返回状态码。int plc_tag_get_int_attribute(int32_t tag, const char *attrib_name, int default_value);
int plc_tag_set_int_attribute(int32_t tag, const char *attrib_name, int new_value);
PLCTAG_STATUS_OK
PLCTAG_ERR_NOT_FOUND
PLCTAG_ERR_OUT_OF_BOUNDS
属性 | R/W | 标签/库 |
|
---|---|---|---|
debug | R/W | 库 | 获取/设置标签的调试级别。该功能与plc_tag_set_debug_level() 重复。 |
version_major | R | 库 | 获取库版本的主版本。例如,库版本为2.5.1,则该属性返回2。 |
version_minor | R | 库 | 获取库版本的次版本。例如,库版本为2.5.1,则该属性返回5。 |
version_patch | R | 库 | 获取库版本的补丁版本。例如,库版本为2.5.1,则该属性返回1。 |
size | R | 标签 | 获取标签使用的大小(以字节为单位)。该功能与plc_tag_get_size() 重复。 |
read_cache_ms | R/W | 标签 | 获取/设置缓存读取结果的时间量(以毫秒为单位)。 |
elem_size | R | 标签 | 获取标签单个元素的大小(以字节为单位)。类比,将标签视为数组,则大小返回1。 |
elem_count | R | 标签 | 如果标签是数组,则返回标签大小(以元素数为单位),否则返回1。 |
使用该库时,有三种方法可以设置调试级别(出于版本历史原因),不过首选第三个:
plc_tag_set_int_attribute() debug
函数设置属性plc_tag_set_debug_level()
函数调试级别如下,数字越大,输出信息越详细越多。请选择合适级别。
- PLCTAG_DEBUG_NONE (0) - 禁用调试输出
- PLCTAG_DEBUG_ERROR (1) - 仅输出错误。一般来说,这些错误对图书馆的运作是致命的。
- PLCTAG_DEBUG_WARN (2) - 输出警告,例如在检查格式错误的标记属性字符串或从 PLC 报告意外问题时发现错误。
- PLCTAG_DEBUG_INFO (3) - 输出有关库中内部调用的诊断信息。包括一些数据包转储。
- PLCTAG_DEBUG_DETAIL (4) - 输出有关库中执行的代码的详细诊断信息,包括数据包转储。
- PLCTAG_DEBUG_SPEW (5) - 输出非常详细的信息。除非您尝试调试有关每个互斥锁和释放的详细信息,否则不要使用它。每毫秒将输出多行输出。