MODBUS通讯:libmodbus库使用方法
libmodbus是一个快速、跨平台的Modbus库,目前支持Linux, Mac OS X, FreeBSD, QNX和Windows系统。libmodbus版本号:v3.0.8(已加入v3.1.6版本补充)。
libmodbus是可以与使用Modbus协议的设备进行数据发送/接收的库。该库包含各种后端(backends)以支持通过不同网络进行通信(例如,RTU模式下的串口或TCP / IPv6中的以太网)。
http://www.modbus.org网站提供了协议规范文档http://www.modbus.org/specs.php。
libmodbus提供了较低通信层的抽象,并在所有支持的平台上提供相同的API。
环境(contexts)
Modbus协议包含许多变体(例如串行RTU或Ehternet TCP)。为了简化变体的实现,该库被设计成为每个变体使用后端(backends)。
后端也是满足其他要求(例如实时操作)的便捷方法。每个后端都提供了一个特定的函数来创建一个新的modbus_t环境。
modbus_t环境是一个不透明的结构,包含根据所选变体与其他Modbus设备建立连接的所有必要信息。
你可以选择以下最适合你需要的环境:
RTU环境
RTU后端(远程终端单元)用于串口通信,并使用用于协议通信的数据紧凑二进制表示形式。
RTU格式遵循命令/数据和CRC(cyclic redundancy check,循环冗余校验)作为错误检查机制,以确保数据的可靠性。
Modbus RTU是可用于Modbus的最常用的实现方式。Modbus RTU消息必须连续发送,不能有字符间隔。
Modbus RTU框架包含一个处理Modbus请求的设备/服务器(从站),以及一个发送请求的客户端(主站)。通信始终由主站服务端发起。
许多Modbus设备可以在同一个的物理链路上连接在一起(总线结构),因此在发送消息之前,必须使用modbus_set_slave设置从站(接收设备 )ID。如果您正在运行一个从站,则其从站号将用于过滤接收的消息。
RTU的libmodbus实现不像最初的Modbus规范中所述的那样基于时间,相反,所有字节都被尽可能快地发送,当收到所有预期的字符时,一个响应或指示被认为是完成的。
这个实现提供了非常快的通信,但是您必须注意将从服务器的响应超时设置为小于主服务器的响应超时(否则,当其中一个从服务器没有响应时,其他从服务器可能会忽略主服务器请求)。
相关函数如下:
创建一个Modbus RTU环境:modbus_new_rtu(3)
设置串行模式:modbus_rtu_get_serial_mode(3) modbus_rtu_set_serial_mode(3) modbus_rtu_get_rts(3) modbus_rtu_set_rts(3) modbus_rtu_set_custom_rts(3) modbus_rtu_get_rts_delay(3) modbus_rtu_set_rts_delay(3)
TCP(IPv4)环境
TCP后端实现了用于通过TCP / IPv4网络进行通信的Modbus变体。它不需要校验和计算,因为底层TCP会处理相同的功能。
相关函数如下:
创建一个Modbus TCP环境:modbus_new_tcp(3)
TCP PI(IPv4 and IPv6)环境
TCP PI(协议独立)后端实现了Modbus变体,用于在TCP IPv4和IPv6网络上进行通信。它不需要校验和计算,因为较低层负责相同的工作。
与TCP IPv4后端相反,TCP PI后端提供主机名解析,但它会消耗大约1Kb的额外内存。
相关函数如下:
创建一个Modbus TCP环境:modbus_new_tcp_pi(3)
通用函数:
在使用任何libmodbus函数之前,调用者必须分配和初始化一个modbus_t上下文,然后提供以下函数来修改和释放上下文:
释放libmodbus上下文:modbus_free(3)
设置从站ID:modbus_set_slave(3)
启用调试模式:modbus_set_debug(3)
超时时间设置:modbus_get_byte_timeout(3) modbus_set_byte_timeout(3) modbus_get_response_timeout(3) modbus_set_response_timeout(3) modbus_get_indication_timeout(3) modbus_set_indication_timeout(3)
错误恢复模式:modbus_set_error_recovery(3)
内部套接字的Setter/getter方法:modbus_set_socket(3) modbus_get_socket(3)
头信息:modbus_get_header_length(3)
用于数据操作的宏:
-
MODBUS_GET_HIGH_BYTE(data), extracts the high byte from a byte
-
MODBUS_GET_LOW_BYTE(data), extracts the low byte from a byte
-
MODBUS_GET_INT64_FROM_INT16(tab_int16, index), builds an int64 from the four first int16 starting at tab_int16[index]
-
MODBUS_GET_INT32_FROM_INT16(tab_int16, index), builds an int32 from the two first int16 starting at tab_int16[index]
-
MODBUS_GET_INT16_FROM_INT8(tab_int8, index), builds an int16 from the two first int8 starting at tab_int8[index]
-
MODBUS_SET_INT16_TO_INT8(tab_int8, index, value), set an int16 value into the two first bytes starting at tab_int8[index]
-
MODBUS_SET_INT32_TO_INT16(tab_int16, index, value), set an int32 value into the two first int16 starting at tab_int16[index]
-
MODBUS_SET_INT64_TO_INT16(tab_int16, index, value), set an int64 value into the four first int16 starting at tab_int16[index]
位和字节的处理:modbus_set_bits_from_byte(3) modbus_set_bits_from_bytes(3) modbus_get_byte_from_bits(3)
设置或获取浮点数:
modbus_get_float_abcd(3) modbus_set_float_abcd(3)
modbus_get_float_badc(3) modbus_set_float_badc(3)
modbus_get_float_cdab(3) modbus_set_float_cdab(3)
modbus_get_float_dcba(3) modbus_set_float_dcba(3)
modbus_get_float(3) (弃用) modbus_set_float(3) (弃用)
连接
提供以下功能来建立和关闭与Modbus设备的连接。
建立连接:modbus_connect(3)
关闭连接:modbus_close(3)
Flush连接:modbus_flush(3)
客户端
Modbus协议定义了不同的数据类型和函数来从远程设备读取和写入数据。下面的函数被客户端用来发送Modbus请求。
读取数据:modbus_read_bits(3) modbus_read_input_bits(3) modbus_read_registers(3) modbus_read_input_registers(3) modbus_report_slave_id(3)
写入数据:modbus_write_bit(3) modbus_write_register(3) modbus_write_bits(3) modbus_write_registers(3)
读写数据:modbus_write_and_read_registers(3)
原始请求:modbus_send_raw_request(3) modbus_receive_confirmation(3)
回复例外:modbus_reply_exception(3)
服务器
服务器在等待来自客户端的请求,并且必须在与请求相关时做出回应。
在TCP模式下,您不能使用通常的modbus_connect(3)来建立连接,而是使用一对accept/listen调用modbus_tcp_listen(3) modbus_tcp_accept(3) modbus_tcp_pi_listen(3) modbus_tcp_pi_accept(3).
然后就可以使用modbus_receive(3)接收数据了,响应可以用modbus_reply(3) modbus_reply_exception(3)发送。
为了处理你的Modbus数据的映射,你必须使用:modbus_mapping_new(3) modbus_mapping_free(3)。
错误处理
libmodbus函数使用POSIX系统上的标准约定处理错误。
通常,这意味着在失败时,libmodbus函数要么返回NULL值(如果返回指针),要么返回负值(如果返回整数),而实际的错误代码将存储在errno变量中。
库提供了modbus_strerror()函数来将libmodbus特定的错误代码转换成错误消息字符串;详情请参考modbus_strerror(3)。
杂项
LIBMODBUS_VERSION_STRING常量表示程序编译时所针对的libmodbus版本。
变量libmodbus_version_major, libmodbus_version_minor, libmodbus_version_micro给出程序链接的版本。
作者
libmodbus文档由Stephane Raimbault < stephane.raimbault@gmail.com >编写
资源
主要网站:http://www.libmodbus.org/
错误报告:http://github.com/stephane/libmodbus/issues.
版权
本软件的免费使用是在GNU Lesser General Public License (LGPL v2.1+)的条款下授予的。有关详细信息,请参阅包含在libmodbus发行版中的文件 COPYING.LESSER
。