diff --git a/Makefile.am b/Makefile.am index 5981b93..fb9728f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ EXTRA_DIST = MIGRATION README.rst libmodbus.spec -SUBDIRS = src tests +SUBDIRS = src doc tests pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libmodbus.pc diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..09dfe2f --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,44 @@ +dnl ############################################################################## +dnl # AC_LIBMODBUS_CHECK_DOC_BUILD # +dnl # Check whether to build documentation and install man-pages # +dnl ############################################################################## +AC_DEFUN([AC_LIBMODBUS_CHECK_DOC_BUILD], [{ + # Allow user to disable doc build + AC_ARG_WITH([documentation], [AS_HELP_STRING([--without-documentation], + [disable documentation build even if asciidoc and xmlto are present [default=no]])]) + + if test "x$with_documentation" = "xno"; then + ac_libmodbus_build_doc="no" + ac_libmodbus_install_man="no" + else + # Determine whether or not documentation should be built and installed. + ac_libmodbus_build_doc="yes" + ac_libmodbus_install_man="yes" + # Check for asciidoc and xmlto and don't build the docs if these are not installed. + AC_CHECK_PROG(ac_libmodbus_have_asciidoc, asciidoc, yes, no) + AC_CHECK_PROG(ac_libmodbus_have_xmlto, xmlto, yes, no) + if test "x$ac_libmodbus_have_asciidoc" = "xno" -o "x$ac_libmodbus_have_xmlto" = "xno"; then + ac_libmodbus_build_doc="no" + # Tarballs built with 'make dist' ship with prebuilt documentation. + if ! test -f doc/modbus.7; then + ac_libmodbus_install_man="no" + AC_MSG_WARN([You are building an unreleased version of libmodbus and asciidoc or xmlto are not installed.]) + AC_MSG_WARN([Documentation will not be built and manual pages will not be installed.]) + fi + fi + + # Do not install man pages if on mingw + if test "x$ac_libmodbus_on_mingw32" = "xyes"; then + ac_libmodbus_install_man="no" + fi + fi + + AC_MSG_CHECKING([whether to build documentation]) + AC_MSG_RESULT([$ac_libmodbus_build_doc]) + + AC_MSG_CHECKING([whether to install manpages]) + AC_MSG_RESULT([$ac_libmodbus_install_man]) + + AM_CONDITIONAL(BUILD_DOC, test "x$ac_libmodbus_build_doc" = "xyes") + AM_CONDITIONAL(INSTALL_MAN, test "x$ac_libmodbus_install_man" = "xyes") +}]) diff --git a/configure.ac b/configure.ac index ffc2472..5c83973 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,9 @@ AC_CHECK_HEADERS([ \ netdb.h \ ]) +# Check whether to build docs / install man pages +AC_LIBMODBUS_CHECK_DOC_BUILD + # Checks for header files. AC_HEADER_STDC @@ -125,6 +128,7 @@ AC_CONFIG_FILES([ Makefile src/Makefile src/modbus-version.h + doc/Makefile tests/Makefile libmodbus.pc ]) diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..a8ba017 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,71 @@ +MAN3 = \ + modbus_close.3 \ + modbus_connect.3 \ + modbus_flush.3 \ + modbus_free.3 \ + modbus_get_header_length.3 \ + modbus_get_timeout_begin.3 \ + modbus_get_timeout_end.3 \ + modbus_new_rtu.3 \ + modbus_new_tcp_pi.3 \ + modbus_new_tcp.3 \ + modbus_read_bits.3 \ + modbus_read_input_bits.3 \ + modbus_read_input_registers.3 \ + modbus_read_registers.3 \ + modbus_set_debug.3 \ + modbus_set_error_recovery.3 \ + modbus_set_slave.3 \ + modbus_set_timeout_begin.3 \ + modbus_set_timeout_end.3 \ + modbus_strerror.3 \ + modbus_write_bits.3 \ + modbus_write_bit.3 \ + modbus_write_registers.3 \ + modbus_write_register.3 +MAN7 = libmodbus.7 + +MAN_DOC = $(MAN3) $(MAN7) + +MAN_TXT = $(MAN3:%.3=%.txt) +MAN_TXT += $(MAN7:%.7=%.txt) +MAN_HTML = $(MAN_TXT:%.txt=%.html) + +if INSTALL_MAN +dist_man_MANS = $(MAN_DOC) +doc : $(MAN_DOC) +endif + +EXTRA_DIST = asciidoc.conf $(MAN_TXT) +if BUILD_DOC +EXTRA_DIST += $(MAN_HTML) +html : $(MAN_HTML) +endif + +MAINTAINERCLEANFILES = $(MAN_DOC) $(MAN_HTML) + +dist-hook : $(MAN_DOC) $(MAN_HTML) + +html: $(MAN_HTML) + +if BUILD_DOC +SUFFIXES=.html .txt .xml .1 .3 .7 + +.txt.html: + asciidoc -d manpage -b xhtml11 -f asciidoc.conf \ + -alibmodbus_version=@LIBMODBUS_VERSION@ $< +.txt.xml: + asciidoc -d manpage -b docbook -f asciidoc.conf \ + -alibmodbus_version=@LIBMODBUS_VERSION@ $< +.xml.1: + xmlto man $< +.xml.3: + xmlto man $< +.xml.7: + xmlto man $< + +clean: + rm -f *.1 *.3 *.7 + rm -f *.html + +endif diff --git a/doc/asciidoc.conf b/doc/asciidoc.conf new file mode 100644 index 0000000..5d62608 --- /dev/null +++ b/doc/asciidoc.conf @@ -0,0 +1,51 @@ +[paradef-default] +literal-style=template="literalparagraph" + +[macros] +(?su)[\\]?(?Plinkmb):(?P\S*?)\[(?P.*?)\]= + +ifdef::backend-docbook[] +[linkmb-inlinemacro] +{0%{target}} +{0#} +{0#{target}{0}} +{0#} +endif::backend-docbook[] + +ifdef::backend-xhtml11[] +[linkmb-inlinemacro] +{target}{0?({0})} +endif::backend-xhtml11[] + +ifdef::doctype-manpage[] +ifdef::backend-docbook[] +[header] +template::[header-declarations] + + +{mantitle} +{manvolnum} +libmodbus +{libmodbus_version} +Libmodbus Manual + + + {manname} + {manpurpose} + +endif::backend-docbook[] +endif::doctype-manpage[] + +ifdef::backend-xhtml11[] +[footer] + +{disable-javascript%

} + + + +endif::backend-xhtml11[] diff --git a/doc/libmodbus.txt b/doc/libmodbus.txt new file mode 100644 index 0000000..8592bc1 --- /dev/null +++ b/doc/libmodbus.txt @@ -0,0 +1,184 @@ +libmodbus(7) +============ + + +NAME +---- +libmodbus - fast and portable Modbus library + + +SYNOPSIS +-------- +*#include * + +*cc* \`pkg-config --cflags --libs libmodbus` 'files' + + +DESCRIPTION +----------- +libmodbus is a library to send/receive data with a device which respects the +Modbus protocol. This library contains various backends to communicate over +different networks (eg. serial in RTU mode or Ethernet in TCP/IPv6). The +http://www.modbus.org site provides documentation about the protocol at +http://www.modbus.org/specs.php. + +libmodbus provides an abstraction of the lower communication layers and offers +the same API on all supported platforms. + +This documentation presents an overview of libmodbus concepts, describes how +libmodbus abstracts Modbus communication with different hardware and platforms +and provides a reference manual for the functions provided by the libmodbus +library. + + +Contexts +~~~~~~~~ +The Modbus protocol contains many variants (eg. serial RTU or Ehternet TCP), to +ease the implementation of a variant, the library was designed to use a backend +for each variant. The backends are also a convenient way to fulfill other +requirements (eg. real-time operations). Each backend offers a specific function +to create a new 'modbus_t' context. The 'modbus_t' context is an opaque +structure containing all necessary information to etablish a connection with +others Modbus devices according to the selected variant. + +You can choose the best context for your needs among: + +RTU Context +^^^^^^^^^^^ +The RTU backend (Remote Terminal Unit) is used in serial communication and makes +use of a compact, binary representation of the data for protocol +communication. The RTU format follows the commands/data with a cyclic redundancy +check checksum as an error check mechanism to ensure the reliability of +data. Modbus RTU is the most common implementation available for Modbus. A +Modbus RTU message must be transmitted continuously without inter-character +hesitations (extract from Wikipedia, Modbus, http://en.wikipedia.org/wiki/Modbus +(as of Mar. 13, 2011, 20:51 GMT). + +Many Modbus devices can be connected together on the same physical link so you +need to define which slave is concerned by the message with +linkmb:modbus_set_slave[3]. If you're running a slave (server) the slave number +is used to filter messages. + +Create a Modbus RTU context:: + linkmb:modbus_new_rtu[3] + +TCP (IPv4) Context +^^^^^^^^^^^^^^^^^^ +The TCP backend implements a Modbus variant used for communications over +TCP/IPv4 networks. It does not require a checksum calculation as lower layer +takes care of the same. + +Create a Modbus TCP context:: + linkmb:modbus_new_tcp[3] + + +TCP PI (IPv4 and IPv6) Context +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The TCP PI (Protocol Indepedent) backend implements a Modbus variant used for +communications over TCP IPv4 and IPv6 networks. It does not require a checksum +calculation as lower layer takes care of the same. + +Contrary to the TCP IPv4 only backend, the TCP PI backend offers hostname +resolution but it consumes about 1Kb of additional memory. + +Create a Modbus TCP context:: + linkmb:modbus_new_tcp_pi[3] + + +Common +^^^^^^ +Before using any libmodbus functions, the caller must allocate and initialize a +'modbus_t' context with functions explained above, then the following functions +are provided to modify and free a 'context': + +Free libmodbus context:: + linkmb:modbus_free[3] + +Context setters and getters:: + linkmb:modbus_set_debug[3] + linkmb:modbus_set_error_recovery[3] + linkmb:modbus_set_slave[3] + linkmb:modbus_get_timeout_begin[3] + linkmb:modbus_set_timeout_begin[3] + linkmb:modbus_get_timeout_end[3] + linkmb:modbus_set_timeout_end[3] + linkmb:modbus_get_header_length[3] + +A libmodbus 'context' is thread safe and may be shared among as many application +threads as necessary, without any additional locking required on the part of the +caller. + + +Connection +~~~~~~~~~~ +The following functions are provided to establish and close a connection with +Modbus devices: + +Establish a connection:: + linkmb:modbus_connect[3] + +Close a connection:: + linkmb:modbus_close[3] + +Flush a connection:: + linkmb:modbus_flush[3] + + +Data +~~~~ +The Modbus protocol defines different data types and functions to read and write +them from/to remote devices. + +Read data:: + linkmb:modbus_read_bits[3] + linkmb:modbus_read_input_bits[3] + linkmb:modbus_read_registers[3] + linkmb:modbus_read_input_registers[3] + +Write data:: + linkmb:modbus_write_bit[3] + linkmb:modbus_write_register[3] + linkmb:modbus_write_bits[3] + linkmb:modbus_write_registers[3] + + +ERROR HANDLING +-------------- +The libmodbus functions handle errors using the standard conventions found on +POSIX systems. Generally, this means that upon failure a libmodbus function +shall return either a NULL value (if returning a pointer) or a negative value +(if returning an integer), and the actual error code shall be stored in the +'errno' variable. + +The _modbus_strerror()_ function is provided to translate libmodbus-specific +error codes into error message strings; for details refer to +linkmb:modbus_strerror[3]. + + +MISCELLANEOUS +------------- +The _LIBMODBUS_VERSION_STRING_ constant indicates the libmodbus version the +program has been compiled against. The variables 'libmodbus_version_major', +'libmodbus_version_minor', 'libmodbus_version_micro' give the version the +program is linked against. + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + + + +RESOURCES +--------- +Main web site: + +Report bugs on the issue tracker at +. + + +COPYING +------- +Free use of this software is granted under the terms of the GNU Lesser General +Public License (LGPL). For details see the files `COPYING` and `COPYING.LESSER` +included with the libmodbus distribution. diff --git a/doc/modbus_close.txt b/doc/modbus_close.txt new file mode 100644 index 0000000..485915f --- /dev/null +++ b/doc/modbus_close.txt @@ -0,0 +1,52 @@ +modbus_close(3) +=============== + + +NAME +---- +modbus_close - close a Modbus connection + + +SYNOPSIS +-------- +*int modbus_close(*modbus_t 'ctx');* + + +DESCRIPTION +----------- +The _modbus_close()_ function shall close the connection established with the +backend set in the context. + + +RETURN VALUE +------------ +The _modbus_close()_ function shall return 0 if successful. Otherwise it shall +return -1 and set errno. + + +EXAMPLE +------- +[source,c] +------------------- +modbus_t *ctx; + +ctx = modbus_new_tcp("127.0.0.1", 502); +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(ctx); + return -1; +} + +modbus_close(ctx); +modbus_free(ctx); +------------------- + +SEE ALSO +-------- +linkmb:modbus_connect[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_connect.txt b/doc/modbus_connect.txt new file mode 100644 index 0000000..f03361b --- /dev/null +++ b/doc/modbus_connect.txt @@ -0,0 +1,52 @@ +modbus_connect(3) +================= + + +NAME +---- +modbus_connect - establish a Modbus connection + + +SYNOPSIS +-------- +*int modbus_connect(*modbus_t 'ctx');* + + +DESCRIPTION +----------- +The _modbus_connect()_ function shall etablish a connection to a Modbus server, +a network or a bus using the context information of libmodbus context given in +argument. + + +RETURN VALUE +------------ +The modbus_connect() function shall return 0 if successful. Otherwise it shall +return -1 and set errno to one of the values defined by the system calls of the +underlying platform. + + +EXAMPLE +------- +[source,c] +------------------- +modbus_t *ctx; + +ctx = modbus_new_tcp("127.0.0.1", 502); +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(ctx); + return -1; +} +------------------- + + +SEE ALSO +-------- +linkmb:modbus_close[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_flush.txt b/doc/modbus_flush.txt new file mode 100644 index 0000000..be7cefc --- /dev/null +++ b/doc/modbus_flush.txt @@ -0,0 +1,30 @@ +modbus_flush(3) +=============== + + +NAME +---- +modbus_flush - flush non-transmitted data + + +SYNOPSIS +-------- +*int modbus_flush(*modbus_t 'ctx');* + + +DESCRIPTION +----------- +The _modbus_flush()_ function shall discard data received but not read to the +socket or file descriptor associated to the context 'ctx'. + + +RETURN VALUE +------------ +The _modbus_flush()_ function shall return 0 or the number of flushed bytes if +successful. Otherwise it shall return -1 and set errno. + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_free.txt b/doc/modbus_free.txt new file mode 100644 index 0000000..7f97dfd --- /dev/null +++ b/doc/modbus_free.txt @@ -0,0 +1,33 @@ +modbus_free(3) +============== + + +NAME +---- +modbus_free - free a libmodbus context + + +SYNOPSIS +-------- +*void modbus_free(*modbus_t 'ctx');* + + +DESCRIPTION +----------- +The _modbus_free()_ function shall free an allocated modbus_t structure. + + +RETURN VALUE +------------ +There is no return values. + + +SEE ALSO +-------- +linkmb:libmodbus[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_get_header_length.txt b/doc/modbus_get_header_length.txt new file mode 100644 index 0000000..7e45e3d --- /dev/null +++ b/doc/modbus_get_header_length.txt @@ -0,0 +1,35 @@ +modbus_get_header_length(3) +=========================== + + +NAME +---- +modbus_get_header_length - retrieve the current header length + + +SYNOPSIS +-------- +*int modbus_get_header_length(*modbus_t 'ctx');* + + +DESCRIPTION +----------- +The _modbus_get_header_length()_ function shall retrieve the current header +length from the backend. This fonction is convenient to manipulate a message and +so its limited to low-level operations. + + +RETURN VALUE +------------ +The header length as integer value. + + +SEE ALSO +-------- +linkmb:libmodbus[7] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_get_timeout_begin.txt b/doc/modbus_get_timeout_begin.txt new file mode 100644 index 0000000..c40d692 --- /dev/null +++ b/doc/modbus_get_timeout_begin.txt @@ -0,0 +1,53 @@ +modbus_get_timeout_begin(3) +=========================== + + +NAME +---- +modbus_get_timeout_begin - get timeout of begin of message + + +SYNOPSIS +-------- +*void modbus_get_timeout_begin(*modbus_t 'ctx', struct timeval *'timeout');* + + +DESCRIPTION +----------- +The _modbus_get_timeout_begin()_ function shall store the current timeout of +begin of message in the 'timeout' argument. + + +RETURN VALUE +------------ +There is no return values. + + +EXAMPLE +------- +[source,c] +------------------- +struct timeval timeout_begin_old; +struct timeval timeout_begin_new; + +/* Save original timeout */ +modbus_get_timeout_begin(ctx, &timeout_begin_old); + +/* Define a new and too short timeout! */ +timeout_begin_new.tv_sec = 0; +timeout_begin_new.tv_usec = 0; +modbus_set_timeout_begin(ctx, &timeout_begin_new); +------------------- + + +SEE ALSO +-------- +linkmb:modbus_set_timeout_begin[3] +linkmb:modbus_get_timeout_end[3] +linkmb:modbus_set_timeout_end[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_get_timeout_end.txt b/doc/modbus_get_timeout_end.txt new file mode 100644 index 0000000..fe4214b --- /dev/null +++ b/doc/modbus_get_timeout_end.txt @@ -0,0 +1,47 @@ +modbus_get_timeout_end(3) +=========================== + + +NAME +---- +modbus_get_timeout_end - get timeout of end of message + + +SYNOPSIS +-------- +*void modbus_get_timeout_end(*modbus_t 'ctx', struct timeval *'timeout');* + + +DESCRIPTION +----------- +The _modbus_get_timeout_end()_ function shall store the current timeout between +the begin and the end of message in the 'timeout' argument. + + +RETURN VALUE +------------ +There is no return values. + + +EXAMPLE +------- +[source,c] +------------------- +struct timeval timeout_end; + +/* Save original timeout */ +modbus_get_timeout_end(ctx, &timeout_end); +------------------- + + +SEE ALSO +-------- +linkmb:modbus_get_timeout_begin[3] +linkmb:modbus_set_timeout_begin[3] +linkmb:modbus_set_timeout_end[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_new_rtu.txt b/doc/modbus_new_rtu.txt new file mode 100644 index 0000000..15def19 --- /dev/null +++ b/doc/modbus_new_rtu.txt @@ -0,0 +1,78 @@ +modbus_new_rtu(3) +================= + + +NAME +---- +modbus_new_rtu - create a libmodbus context for RTU + + +SYNOPSIS +-------- +*modbus_t modbus_new_rtu(const char *'device', int 'baud', + char 'parity', int 'data_bit', int 'stop_bit')* + + + +DESCRIPTION +----------- + +The _modbus_new_rtu()_ function shall allocate and initialize a modbus_t +structure to communicate in RTU mode on a serial line. + +The _device_ argument specifies the name of the serial port handled by the OS, +eg. '/dev/ttyS0' or '/dev/ttyUSB0'. On Windons, it's necessary to prepend COM +name with '\\.\' for COM number greater than 9, eg. '\\\\.\\COM10'. See +http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx for details + +The _baud_ argument specifies the baud rate of the communication, eg. 9600, +19200, 57600, 115200, etc. + +The _parity_ argument can have one of the following values::: +* _N_ for none +* _E_ for even +* _O_ for odd + +The _data_bits_ argument specifies the number of bits of data, the allowed +values are 5, 6, 7 and 8. + +The _stop_bits_ argument specifies the bits of stop, the allowed values are 1 +and 2. + + +RETURN VALUE +------------ +The _modbus_new_rtu()_ function shall return a pointer to a *modbus_t* structure +if successful. Otherwise it shall return NULL and set errno to one of the values +defined below. + + +ERRORS +------ +*EINVAL*:: +An invalid argument was given. + + +EXAMPLE +------- +[source,c] +------------------- +modbus_t *ctx; + +ctx = modbus_new_ru("/dev/ttyUSB0", 115200, 'N', 8, 1); +if (ctx == NULL) { + fprintf(stderr, "Unable to create the libmodbus context\n"); + return -1; +} +------------------- + +SEE ALSO +-------- +linkmb:modbus_new_tcp[3] +linkmb:modbus_free[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_new_tcp.txt b/doc/modbus_new_tcp.txt new file mode 100644 index 0000000..220e037 --- /dev/null +++ b/doc/modbus_new_tcp.txt @@ -0,0 +1,70 @@ +modbus_new_tcp(3) +================= + + +NAME +---- +modbus_new_tcp - create a libmodbus context for TCP/IPv4 + + +SYNOPSIS +-------- +*modbus_t modbus_new_tcp(const char *'ip', int 'port');* + + +DESCRIPTION +----------- +The _modbus_new_tcp()_ function shall allocate and initialize a modbus_t +structure to communicate with a Modbus TCP/IPv4 server. + +The _ip_ argument specifies the IP address of the server to which the client +wants etablish a connection. + +The _port_ argument is the TCP port to use. Set the port to +_MODBUS_TCP_DEFAULT_PORT_ to use the default one (502). It’s convenient to use a +port number greater than or equal to 1024 because it’s not necessary to have +administrator privileges. + + +RETURN VALUE +------------ +The _modbus_new_tcp()_ function shall return a pointer to a *modbus_t* structure +if successful. Otherwise it shall return NULL and set errno to one of the values +defined below. + + +ERRORS +------ +*EINVAL*:: +An invalid IP address was given. + + +EXAMPLE +------- +[source,c] +------------------- +modbus_t *ctx; + +ctx = modbus_new_tcp("127.0.0.1", 1502); +if (ctx == NULL) { + fprintf(stderr, "Unable to allocate libmodbus context\n"); + return -1; +} + +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(ctx); + return -1; +} +------------------- + +SEE ALSO +-------- +linkmb:modbus_new_rtu[3] +linkmb:modbus_free[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_new_tcp_pi.txt b/doc/modbus_new_tcp_pi.txt new file mode 100644 index 0000000..fa3cc92 --- /dev/null +++ b/doc/modbus_new_tcp_pi.txt @@ -0,0 +1,72 @@ +modbus_new_tcp_pi(3) +==================== + + +NAME +---- +modbus_new_tcp_pi - create a libmodbus context for TCP Protocol Independent + + +SYNOPSIS +-------- +*modbus_t modbus_new_tcp_pi(const char *'node', const char *'service');* + + +DESCRIPTION +----------- +The _modbus_new_tcp_pi()_ function shall allocate and initialize a modbus_t +structure to communicate with a Modbus TCP IPv4 or Ipv6 server. + +The _node_ argument specifies the host name or IP address of the host to connect +to, eg. '192.168.0.5' , '::1' or 'server.com'. + +The _service_ argument is the service name/port number to connect to. To use the +default Modbus port use the string "502". On many Unix systems, it’s +convenient to use a port number greater than or equal to 1024 because it’s not +necessary to have administrator privileges. + + +RETURN VALUE +------------ +The _modbus_new_tcp_pi()_ function shall return a pointer to a *modbus_t* structure +if successful. Otherwise it shall return NULL and set errno to one of the values +defined below. + + +ERRORS +------ +*EINVAL*:: +The node string is empty or has been truncated. The service string is empty or +has been truncated. + + +EXAMPLE +------- +[source,c] +------------------- +modbus_t *ctx; + +ctx = modbus_new_tcp_pi("::1", "1502"); +if (ctx == NULL) { + fprintf(stderr, "Unable to allocate libmodbus context\n"); + return -1; +} + +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(ctx); + return -1; +} +------------------- + +SEE ALSO +-------- +linkmb:modbus_new_tcp[3] +linkmb:modbus_new_rtu[3] +linkmb:modbus_free[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_read_bits.txt b/doc/modbus_read_bits.txt new file mode 100644 index 0000000..1d7a26b --- /dev/null +++ b/doc/modbus_read_bits.txt @@ -0,0 +1,48 @@ +modbus_read_bits(3) +=================== + + +NAME +---- +modbus_read_bits - read many bits + + +SYNOPSIS +-------- +*int modbus_read_bits(modbus_t *'ctx', int 'addr', int 'nb', uint8_t *'dest')* + + +DESCRIPTION +----------- +The _modbus_read_bits()_ function shall read the status of the 'nb' bits (coils) +to the address 'addr' of the remote device. The result of reading is stored in +'dest' array as unsigned bytes (8 bits) set to _TRUE_ or _FALSE_. + +You must take care to allocate enough memory to store the results in 'dest' +(at least 'nb' * sizeof(uint8_t)). + +The function uses the Modbus function code 0x01 (read coil status). + + +RETURN VALUE +------------ +The _modbus_read_bits()_ function shall return the number of read bits if +successful. Otherwise it shall return -1 and set errno. + + +ERRORS +------ +EMBMDATA:: +Too many bits requested + + +SEE ALSO +-------- +linkmb:modbus_write_bit[3] +linkmb:modbus_write_bits[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_read_input_bits.txt b/doc/modbus_read_input_bits.txt new file mode 100644 index 0000000..129b419 --- /dev/null +++ b/doc/modbus_read_input_bits.txt @@ -0,0 +1,47 @@ +modbus_read_input_bits(3) +========================= + + +NAME +---- +modbus_read_input_bits - read many input bits + + +SYNOPSIS +-------- +*int modbus_read_input_bits(modbus_t *'ctx', int 'addr', int 'nb', uint8_t *'dest');* + + +DESCRIPTION +----------- +The _modbus_read_input_bits()_ function shall read the content of the 'nb' input +bits to the address 'addr' of the remote device. The result of reading is stored +in 'dest' array as unsigned bytes (8 bits) set to _TRUE_ or _FALSE_. + +You must take care to allocate enough memory to store the results in 'dest' +(at least 'nb' * sizeof(uint8_t)). + +The function uses the Modbus function code 0x03 (read input status). + + +RETURN VALUE +------------ +The _modbus_read_input_status()_ function shall return the number of read +input status if successful. Otherwise it shall return -1 and set errno. + + +ERRORS +------ +EMBMDATA:: +Too many discrete inputs requested + + +SEE ALSO +-------- +linkmb:modbus_write_input_bits[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_read_input_registers.txt b/doc/modbus_read_input_registers.txt new file mode 100644 index 0000000..0edeca7 --- /dev/null +++ b/doc/modbus_read_input_registers.txt @@ -0,0 +1,50 @@ +modbus_read_input_registers(3) +============================== + + +NAME +---- +modbus_read_input_registers - read many input registers + + +SYNOPSIS +-------- +*int modbus_read_input_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest')* + + +DESCRIPTION +----------- +The _modbus_read_input_registers()_ function shall read the content of the 'nb' +input registers to address 'addr' of the remote device. The result of the +reading is stored in 'dest' array as word values (16 bits). + +You must take care to allocate enough memory to store the results in 'dest' (at +least 'nb' * sizeof(uint16_t)). + +The function uses the Modbus function code 0x04 (read input registers). The +holding registers and input registers have different historical meaning, but +nowadays it's more common to use holding registers only. + + +RETURN VALUE +------------ +The _modbus_read_input_registers()_ function shall return the number of read +input registers if successful. Otherwise it shall return -1 and set errno. + + +ERRORS +------ +EMBMDATA:: +Too many bits requested + + +SEE ALSO +-------- +linkmb:modbus_read_[3] +linkmb:modbus_write_bit[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_read_registers.txt b/doc/modbus_read_registers.txt new file mode 100644 index 0000000..eb5f81d --- /dev/null +++ b/doc/modbus_read_registers.txt @@ -0,0 +1,48 @@ +modbus_read_registers(3) +======================== + + +NAME +---- +modbus_read_registers - read many registers + + +SYNOPSIS +-------- +*int modbus_read_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest')* + + +DESCRIPTION +----------- +The _modbus_read_registers()_ function shall read the content of the 'nb' +holding registers to the address 'addr' of the remote device. The result of +reading is stored in 'dest' array as word values (16 bits). + +You must take care to allocate enough memory to store the results in 'dest' +(at least 'nb' * sizeof(uint16_t)). + +The function uses the Modbus function code 0x03 (read holding registers). + + +RETURN VALUE +------------ +The _modbus_read_registers()_ function shall return the number of read registers +if successful. Otherwise it shall return -1 and set errno. + + +ERRORS +------ +EMBMDATA:: +Too many registers requested + + +SEE ALSO +-------- +linkmb:modbus_write_register[3] +linkmb:modbus_write_registers[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_set_debug.txt b/doc/modbus_set_debug.txt new file mode 100644 index 0000000..840a358 --- /dev/null +++ b/doc/modbus_set_debug.txt @@ -0,0 +1,37 @@ +modbus_set_debug(3) +=================== + +NAME +---- +modbus_set_debug - set debug flag of the context + + +SYNOPSIS +-------- +*void modbus_set_debug(*modbus_t 'ctx', int 'boolean');* + + +DESCRIPTION +----------- +The _modbus_set_debug()_ function shall set the debug flag of the *modbus_t* +context by using the argument 'boolean'. When the 'boolean' value is set to +'TRUE', many verbose messages are displayed on stdout and stderr. For example, +this flag is useful to display the bytes of the Modbus messages. + +[verse] +___________________ +[00][14][00][00][00][06][12][03][00][6B][00][03] +Waiting for a confirmation... +<00><14><00><00><00><09><12><03><06><02><2B><00><00><00><00> +___________________ + + +RETURN VALUE +------------ +There is no return values. + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_set_error_recovery.txt b/doc/modbus_set_error_recovery.txt new file mode 100644 index 0000000..d50b300 --- /dev/null +++ b/doc/modbus_set_error_recovery.txt @@ -0,0 +1,48 @@ +modbus_set_error_recovery(3) +============================ + + +NAME +---- +modbus_set_error_recovery - set the error recovery mode + + +SYNOPSIS +-------- +*int modbus_set_error_recovery(modbus_t *'ctx', int 'enabled');* + + +DESCRIPTION +----------- +The _modbus_set_error_recovery()_ function shall set the error recovery mode to +apply when the connection fails. + +By default there is no error recovery so the application must check the error +values returned by libmodbus functions and handle them if necessary. + +When enabled, the library will attempt an immediate reconnection which may hang +for several seconds if the network to the remote target unit is down. The write +will try a infinite close/connect loop until to be successful and the +select/read calls will just try to retablish the connection one time then will +return an error (if the connecton was down, the values to read are certainly not +available anymore after reconnection, except for slave/server). + +It's not recommanded to enable error recovery for slave/server. + + +RETURN VALUE +------------ +The _modbus_close()_ function shall return 0 if successful. Otherwise it shall +return -1 and set errno to one of the values defined below. + + +ERRORS +------ +*EINVAL*:: +The value of the argument 'enabled' is not 'TRUE' of 'FALSE'. + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_set_slave.txt b/doc/modbus_set_slave.txt new file mode 100644 index 0000000..70f22d4 --- /dev/null +++ b/doc/modbus_set_slave.txt @@ -0,0 +1,51 @@ +modbus_set_slave(3) +=================== + + +NAME +---- +modbus_set_slave - set slave number in the context + + +SYNOPSIS +-------- +*int modbus_set_slave(modbus_t *'ctx', int 'slave')* + + +DESCRIPTION +----------- +The _modbus_set_slave()_ function shall set the slave number in the libmodbus +context. + +The behavior depends of network and the role of the device: + +*RTU*:: +Define the slave ID of the remote device to talk in master mode or set the +internal slave ID in slave mode. According to the protocol, a Modbus device must +only accept message holing its slave number or the special broadcast number. + +*TCP*:: +The slave number is only required in TCP if the message must reach a device +on a serial network. The special value 'MODBUS_TCP_SLAVE' (0xFF) can be used in TCP mode to restore +the default value. + +The broadcast address is 'MODBUS_BROADCAST_ADDRESS'. This special value must be +use when you want all Modbus devices of the network receive the request. + + +RETURN VALUE +------------ +The _modbus_set_slave()_ function shall return 0 if successful. Otherwise it +shall return -1 and set errno to one of the values defined below. + + +ERRORS +------ +*EINVAL*:: +The slave number is invalid. + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_set_timeout_begin.txt b/doc/modbus_set_timeout_begin.txt new file mode 100644 index 0000000..10a211a --- /dev/null +++ b/doc/modbus_set_timeout_begin.txt @@ -0,0 +1,54 @@ +modbus_set_timeout_begin(3) +=========================== + + +NAME +---- +modbus_set_timeout_begin - set timeout of begin of message + + +SYNOPSIS +-------- +*void modbus_set_timeout_begin(*modbus_t 'ctx', struct timeval *'timeout');* + + +DESCRIPTION +----------- +The _modbus_set_timeout_begin()_ function shall set the timeout of begin of +message. If the waiting before receiving a message is longer than the given +timeout, an error will be raised. + + +RETURN VALUE +------------ +There is no return values. + + +EXAMPLE +------- +[source,c] +------------------- +struct timeval timeout_begin_old; +struct timeval timeout_begin_new; + +/* Save original timeout */ +modbus_get_timeout_begin(ctx, &timeout_begin_old); + +/* Define a new and too short timeout! */ +timeout_begin_new.tv_sec = 0; +timeout_begin_new.tv_usec = 0; +modbus_set_timeout_begin(ctx, &timeout_begin_new); +------------------- + + +SEE ALSO +-------- +linkmb:modbus_get_timeout_begin[3] +linkmb:modbus_get_timeout_end[3] +linkmb:modbus_set_timeout_end[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_set_timeout_end.txt b/doc/modbus_set_timeout_end.txt new file mode 100644 index 0000000..1f5a08f --- /dev/null +++ b/doc/modbus_set_timeout_end.txt @@ -0,0 +1,37 @@ +modbus_set_timeout_end(3) +=========================== + + +NAME +---- +modbus_set_timeout_end - set timeout of end of message + + +SYNOPSIS +-------- +*void modbus_set_timeout_end(*modbus_t 'ctx', struct timeval *'timeout');* + + +DESCRIPTION +----------- +The _modbus_set_timeout_end()_ function shall set the timeout of end of +message. If the delay between the begin and the end of message is longer than +the given timeout, an error will be raised. + + +RETURN VALUE +------------ +There is no return values. + + +SEE ALSO +-------- +linkmb:modbus_get_timeout_begin[3] +linkmb:modbus_set_timeout_begin[3] +linkmb:modbus_get_timeout_end[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_strerror.txt b/doc/modbus_strerror.txt new file mode 100644 index 0000000..6badc5d --- /dev/null +++ b/doc/modbus_strerror.txt @@ -0,0 +1,54 @@ +modbus_strerror(3) +================= + + +NAME +---- +modbus_strerror - return the error message + + +SYNOPSIS +-------- +*const char *modbus_strerror(*int 'errnum');* + + +DESCRIPTION +----------- +The _modbus_strerror()_ function shall return a pointer to an error message +string corresponding to the error number specified by the 'errnum' argument. As +libmodbus defines additional error numbers over and above those defined by the +operating system, applications should use _modbus_strerror()_ in preference to +the standard _strerror()_ function. + + +RETURN VALUE +------------ +The _modbus_strerror()_ function shall return a pointer to an error message +string. + + +ERRORS +------ +No errors are defined. + + +EXAMPLE +------- +.Displaying an error message when a Modbus connection cannot be established +[source,c] +------------------- +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + abort(); +} +------------------- + +SEE ALSO +-------- +linkmb:libmodbus + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_write_bit.txt b/doc/modbus_write_bit.txt new file mode 100644 index 0000000..b2607cc --- /dev/null +++ b/doc/modbus_write_bit.txt @@ -0,0 +1,38 @@ +modbus_write_bit(3) +=================== + + +NAME +---- +modbus_write_bit - write a single bit + + +SYNOPSIS +-------- +*int modbus_write_bit(modbus_t *'ctx', int 'addr', int 'status')* + + +DESCRIPTION +----------- +The _modbus_write_bit()_ function shall write the status of 'status' at the +address 'addr' of the remote device. The value must be set to _TRUE_ or _FALSE_. + +The function uses the Modbus function code 0x05 (force single coil). + + +RETURN VALUE +------------ +The _modbus_write_bit()_ function shall return 1 if successful. Otherwise it +shall return -1 and set errno. + + +SEE ALSO +-------- +linkmb:modbus_read_bits[3] +linkmb:modbus_write_bits[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_write_bits.txt b/doc/modbus_write_bits.txt new file mode 100644 index 0000000..06c3978 --- /dev/null +++ b/doc/modbus_write_bits.txt @@ -0,0 +1,45 @@ +modbus_write_bits(3) +==================== + + +NAME +---- +modbus_write_bits - write many bits + + +SYNOPSIS +-------- +*int modbus_write_bits(modbus_t *'ctx', int 'addr', int 'nb', const uint8_t *'src')* + + +DESCRIPTION +----------- +The _modbus_write_bits()_ function shall write the status of the 'nb' bits +(coils) from 'src' at the address 'addr' of the remote device. The +'src' array must contains bytes set to _TRUE_ or _FALSE_. + +The function uses the Modbus function code 0x0F (force multiple coils). + + +RETURN VALUE +------------ +The _modbus_write_bits()_ function shall return the number of written bits if +successful. Otherwise it shall return -1 and set errno. + + +ERRORS +------ +EMBMDATA:: +Writing too many bits + + +SEE ALSO +-------- +linkmb:modbus_read_bits[3] +linkmb:modbus_write_bit[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_write_register.txt b/doc/modbus_write_register.txt new file mode 100644 index 0000000..6b91c03 --- /dev/null +++ b/doc/modbus_write_register.txt @@ -0,0 +1,38 @@ +modbus_write_register(3) +======================== + + +NAME +---- +modbus_write_register - write a single register + + +SYNOPSIS +-------- +*int modbus_write_register(modbus_t *'ctx', int 'addr', int 'value')* + + +DESCRIPTION +----------- +The _modbus_write_register()_ function shall write the value of 'value' +holding registers at the address 'addr' of the remote device. + +The function uses the Modbus function code 0x06 (preset single register). + + +RETURN VALUE +------------ +The _modbus_write_register()_ function shall return 1 if successful. Otherwise +it shall return -1 and set errno. + + +SEE ALSO +-------- +linkmb:modbus_read_register[3] +linkmb:modbus_write_registers[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_write_registers.txt b/doc/modbus_write_registers.txt new file mode 100644 index 0000000..1116256 --- /dev/null +++ b/doc/modbus_write_registers.txt @@ -0,0 +1,39 @@ +modbus_write_registers(3) +========================= + + +NAME +---- +modbus_write_registers - write many registers + + +SYNOPSIS +-------- +*int modbus_write_registers(modbus_t *'ctx', int 'addr', int 'nb', const uint16_t *'src')* + + +DESCRIPTION +----------- +The _modbus_write_registers()_ function shall write the content of the 'nb' +holding registers from the array 'src' at address 'addr' of the +remote device. + +The function uses the Modbus function code 0x10 (preset multiple registers). + + +RETURN VALUE +------------ +The _modbus_write_registers()_ function shall return the number of written registers +if successful. Otherwise it shall return -1 and set errno. + + +SEE ALSO +-------- +linkmb:modbus_read_register[3] +linkmb:modbus_write_register[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/src/modbus-tcp.c b/src/modbus-tcp.c index 1d46bb0..a3d50d6 100644 --- a/src/modbus-tcp.c +++ b/src/modbus-tcp.c @@ -665,6 +665,7 @@ modbus_t* modbus_new_tcp(const char *ip, int port) return ctx; } + modbus_t* modbus_new_tcp_pi(const char *node, const char *service) { modbus_t *ctx;