diff --git a/.gitignore b/.gitignore index b3c7d96..8c04291 100644 --- a/.gitignore +++ b/.gitignore @@ -10,11 +10,10 @@ .libs .DS_Store -# Emacs -GPATH -GRTAGS -GSYMS -GTAGS +# Editors +/*.sublime-* +/.vscode +/.venv # Generated by Autotools INSTALL @@ -28,17 +27,17 @@ Makefile.in /configure.scan /depcomp /install-sh +/libmodbus.pc /libtool /ltmain.sh /missing -/libmodbus.pc /stamp-h1 src/modbus-version.h src/win32/modbus.dll.manifest tests/unit-test.h -/*.sublime-* -/.vscode +# mkdocs +/site # Binary tests/bandwidth-client @@ -50,8 +49,3 @@ tests/unit-test-client tests/unit-test-server tests/version tests/stamp-h2 - -# Documentation -doc/*.html -doc/*.3 -doc/*.7 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b46f2e4..7495ead 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ How Do I Submit A Good Bug Report? Please, don't send direct emails to Stéphane Raimbault unless you want commercial support. -Take care to read the documentation at http://libmodbus.org/documentation/. +Take care to read the documentation at http://libmodbus.org/. - *Be sure it's a bug before creating an issue*, in doubt, post a message on https://groups.google.com/forum/#!forum/libmodbus or send an email to @@ -24,6 +24,6 @@ the clients are connected (TCP, RTU, ASCII) and the source code you are using. - *Enable the debug mode*, libmodbus provides a function to display the content of the Modbus messages and it's very convenient to analyze issues -(http://libmodbus.org/docs/latest/modbus_set_debug.html). +(http://libmodbus.org/docs/modbus_set_debug/). Good bug reports provide right and quick fixes! diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 9052889..ad34147 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -34,7 +34,7 @@ When you get here and you are still convinced that you want to report a bug: - *Enable the debug mode*, libmodbus provides a function to display the content of the Modbus messages and it's very convenient to analyze issues - (). + (). Good bug reports provide right and quick fixes! diff --git a/Makefile.am b/Makefile.am index cc1482d..202135e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,7 +9,7 @@ CLEANFILES += libmodbus.pc dist_doc_DATA = MIGRATION README.md AUTHORS NEWS -SUBDIRS = src doc +SUBDIRS = src if BUILD_TESTS SUBDIRS += tests diff --git a/README.md b/README.md index 56bbf1a..89f0c19 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ -A groovy modbus library -======================= +# A groovy modbus library ![Build Status](https://github.com/stephane/libmodbus/actions/workflows/build.yml/badge.svg) -Overview --------- +## Overview libmodbus is a free software library to send/receive data with a device which respects the Modbus protocol. This library can use a serial port or an Ethernet @@ -15,21 +13,15 @@ Protocol Reference Guide which can be obtained from [www.modbus.org](http://www. The license of libmodbus is *LGPL v2.1 or later*. -The documentation is available as manual pages (`man libmodbus` to read general -description and list of available functions) or Web pages -[www.libmodbus.org/documentation/](http://libmodbus.org/documentation/). The -documentation is licensed under the Creative Commons Attribution-ShareAlike -License 3.0 (Unported) (). - -The official website is [www.libmodbus.org](http://www.libmodbus.org). +The official website is [www.libmodbus.org](http://www.libmodbus.org). The +website contains the latest version of the documentation. The library is written in C and designed to run on Linux, Mac OS X, FreeBSD, Embox, QNX and Windows. You can use the library on MCUs with Embox RTOS. -Installation ------------- +## Installation You will only need to install automake, autoconf, libtool and a C compiler (gcc or clang) to compile the library and asciidoc and xmlto to generate the @@ -59,19 +51,7 @@ automake libtool`. To build under Embox, you have to use its build system. -Documentation -------------- - -The documentation is available [online](http://libmodbus.org/documentation) or -as manual pages after installation. - -The documentation is based on -[AsciiDoc](http://www.methods.co.nz/asciidoc/). Only man pages are built -by default with `make` command, you can run `make htmldoc` in *doc* directory -to generate HTML files. - -Testing -------- +## Testing Some tests are provided in *tests* directory, you can freely edit the source code to fit your needs (it's Free Software :). @@ -87,7 +67,15 @@ By default, all TCP unit tests will be executed (see --help for options). It's also possible to run the unit tests with `make check`. -To report a bug or to contribute --------------------------------- +## To report a bug or to contribute See [CONTRIBUTING](CONTRIBUTING.md) document. + +## Documentation + +You can serve the local documentation with: + +```shell +pip install mkdocs-material +mkdocs serve +``` diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index 47c7971..0000000 --- a/acinclude.m4 +++ /dev/null @@ -1,29 +0,0 @@ -dnl ############################################################################## -dnl # AC_LIBMODBUS_CHECK_BUILD_DOC # -dnl # Check whether to build documentation and install man-pages # -dnl ############################################################################## -AC_DEFUN([AC_LIBMODBUS_CHECK_BUILD_DOC], [{ - # 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" - else - # Determine whether or not documentation should be built and installed. - ac_libmodbus_build_doc="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" - fi - fi - - AC_MSG_CHECKING([whether to build documentation]) - AC_MSG_RESULT([$ac_libmodbus_build_doc]) - if test "x$ac_libmodbus_build_doc" = "xno"; then - AC_MSG_WARN([The tools to build the documentation aren't installed]) - fi - AM_CONDITIONAL(BUILD_DOC, test "x$ac_libmodbus_build_doc" = "xyes") -}]) diff --git a/configure.ac b/configure.ac index a90a75e..ad26abd 100644 --- a/configure.ac +++ b/configure.ac @@ -94,9 +94,6 @@ AC_CHECK_HEADERS([ \ unistd.h \ ]) -# Check whether to build docs / install man pages -AC_LIBMODBUS_CHECK_BUILD_DOC - # Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's necessary to # workaround that problem and Cygwin doesn't define MSG_DONTWAIT. AC_CHECK_DECLS([__CYGWIN__]) @@ -161,7 +158,6 @@ AC_CONFIG_FILES([ src/modbus-version.h src/win32/modbus.dll.manifest tests/Makefile - doc/Makefile libmodbus.pc ]) @@ -179,6 +175,5 @@ AC_MSG_RESULT([ cflags: ${CFLAGS} ldflags: ${LDFLAGS} - documentation: ${ac_libmodbus_build_doc} tests: ${enable_tests} ]) diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index 08eba6d..0000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,88 +0,0 @@ -TXT3 = \ - modbus_close.txt \ - modbus_connect.txt \ - modbus_flush.txt \ - modbus_free.txt \ - modbus_get_indication_timeout.txt \ - modbus_get_slave.txt \ - modbus_get_byte_from_bits.txt \ - modbus_get_byte_timeout.txt \ - modbus_get_float.txt \ - modbus_get_float_abcd.txt \ - modbus_get_float_badc.txt \ - modbus_get_float_cdab.txt \ - modbus_get_float_dcba.txt \ - modbus_get_header_length.txt \ - modbus_get_response_timeout.txt \ - modbus_get_socket.txt \ - modbus_mapping_free.txt \ - modbus_mapping_new.txt \ - modbus_mapping_new_start_address.txt \ - modbus_mask_write_register.txt \ - modbus_new_rtu.txt \ - modbus_new_tcp_pi.txt \ - modbus_new_tcp.txt \ - modbus_read_bits.txt \ - modbus_read_input_bits.txt \ - modbus_read_input_registers.txt \ - modbus_read_registers.txt \ - modbus_receive_confirmation.txt \ - modbus_receive.txt \ - modbus_reply_exception.txt \ - modbus_reply.txt \ - modbus_report_slave_id.txt \ - modbus_rtu_get_serial_mode.txt \ - modbus_rtu_set_serial_mode.txt \ - modbus_rtu_get_rts.txt \ - modbus_rtu_set_rts.txt \ - modbus_rtu_set_custom_rts.txt \ - modbus_rtu_get_rts_delay.txt \ - modbus_rtu_set_rts_delay.txt \ - modbus_send_raw_request.txt \ - modbus_set_bits_from_bytes.txt \ - modbus_set_bits_from_byte.txt \ - modbus_set_byte_timeout.txt \ - modbus_set_debug.txt \ - modbus_set_error_recovery.txt \ - modbus_set_float.txt \ - modbus_set_float_abcd.txt \ - modbus_set_float_badc.txt \ - modbus_set_float_cdab.txt \ - modbus_set_float_dcba.txt \ - modbus_set_indication_timeout.txt \ - modbus_set_response_timeout.txt \ - modbus_set_slave.txt \ - modbus_set_socket.txt \ - modbus_strerror.txt \ - modbus_tcp_accept.txt \ - modbus_tcp_pi_accept.txt \ - modbus_tcp_listen.txt \ - modbus_tcp_pi_listen.txt \ - modbus_write_and_read_registers.txt \ - modbus_write_bits.txt \ - modbus_write_bit.txt \ - modbus_write_registers.txt \ - modbus_write_register.txt -TXT7 = libmodbus.txt - -EXTRA_DIST = asciidoc.conf $(TXT3) $(TXT7) - -MAN3 = $(TXT3:%.txt=%.3) -MAN7 = $(TXT7:%.txt=%.7) - -if BUILD_DOC -man3_MANS = $(MAN3) -man7_MANS = $(MAN7) -endif - -HTML = $(TXT3:%.txt=%.html) $(TXT7:%.txt=%.html) - -htmldoc: $(HTML) - -.txt.html: - asciidoc -d manpage -b xhtml11 -f asciidoc.conf -alibmodbus_version=@LIBMODBUS_VERSION@ $< - -.txt.3 .txt.7: - a2x --doctype manpage --format manpage -alibmodbus_version=@LIBMODBUS_VERSION@ $< - -CLEANFILES = *.3 *.7 *.html diff --git a/doc/asciidoc.conf b/doc/asciidoc.conf deleted file mode 100644 index 39e67e4..0000000 --- a/doc/asciidoc.conf +++ /dev/null @@ -1,51 +0,0 @@ -[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 -v{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 deleted file mode 100644 index 716c684..0000000 --- a/doc/libmodbus.txt +++ /dev/null @@ -1,279 +0,0 @@ -libmodbus(7) -============ - - -NAME ----- -libmodbus - a fast and portable Modbus library - - -SYNOPSIS --------- -*#include * - -*cc* 'files' \`pkg-config --cflags --libs libmodbus` - -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 Ethernet 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 establish a connection with -other 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). - -The Modbus RTU framing calls a slave, a device/service which handle Modbus -requests, and a master, a client which send requests. The communication is -always initiated by the master. - -Many Modbus devices can be connected together on the same physical link so -before sending a message, you must set the slave (receiver) with -linkmb:modbus_set_slave[3]. If you're running a slave, its slave number will be -used to filter received messages. - -The libmodbus implementation of RTU isn't time based as stated in original -Modbus specification, instead all bytes are sent as fast as possible and a -response or an indication is considered complete when all expected characters -have been received. This implementation offers very fast communication but you -must take care to set a response timeout of slaves less than response timeout of -master (ortherwise other slaves may ignore master requests when one of the slave -is not responding). - -Create a Modbus RTU context:: - - linkmb:modbus_new_rtu[3] - - -Set the serial mode:: - - linkmb:modbus_rtu_get_serial_mode[3] - - linkmb:modbus_rtu_set_serial_mode[3] - - linkmb:modbus_rtu_get_rts[3] - - linkmb:modbus_rtu_set_rts[3] - - linkmb:modbus_rtu_set_custom_rts[3] - - linkmb:modbus_rtu_get_rts_delay[3] - - linkmb:modbus_rtu_set_rts_delay[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 Independent) 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] - -Set slave ID:: - - linkmb:modbus_set_slave[3] - -Enable debug mode:: - - linkmb:modbus_set_debug[3] - -Timeout settings:: - - linkmb:modbus_get_byte_timeout[3] - - linkmb:modbus_set_byte_timeout[3] - - linkmb:modbus_get_response_timeout[3] - - linkmb:modbus_set_response_timeout[3] - -Error recovery mode:: - - linkmb:modbus_set_error_recovery[3] - -Setter/getter of internal socket:: - - linkmb:modbus_set_socket[3] - - linkmb:modbus_get_socket[3] - -Information about header:: - - linkmb:modbus_get_header_length[3] - -Macros for data manipulation:: - - - 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] - -Handling of bits and bytes:: - - linkmb:modbus_set_bits_from_byte[3] - - linkmb:modbus_set_bits_from_bytes[3] - - linkmb:modbus_get_byte_from_bits[3] - -Set or get float numbers:: - - linkmb:modbus_get_float_abcd[3] - - linkmb:modbus_set_float_abcd[3] - - linkmb:modbus_get_float_badc[3] - - linkmb:modbus_set_float_badc[3] - - linkmb:modbus_get_float_cdab[3] - - linkmb:modbus_set_float_cdab[3] - - linkmb:modbus_get_float_dcba[3] - - linkmb:modbus_set_float_dcba[3] - - linkmb:modbus_get_float[3] (deprecated) - - linkmb:modbus_set_float[3] (deprecated) - - - -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] - - -Client -~~~~~~ -The Modbus protocol defines different data types and functions to read and write -them from/to remote devices. The following functions are used by the clients to -send Modbus requests: - -Read data:: - - linkmb:modbus_read_bits[3] - - linkmb:modbus_read_input_bits[3] - - linkmb:modbus_read_registers[3] - - linkmb:modbus_read_input_registers[3] - - linkmb:modbus_report_slave_id[3] - -Write data:: - - linkmb:modbus_write_bit[3] - - linkmb:modbus_write_register[3] - - linkmb:modbus_write_bits[3] - - linkmb:modbus_write_registers[3] - -Write and read data:: - - linkmb:modbus_write_and_read_registers[3] - -Raw requests:: - - linkmb:modbus_send_raw_request[3] - - linkmb:modbus_receive_confirmation[3] - -Reply an exception:: - - linkmb:modbus_reply_exception[3] - - -Server -~~~~~~ -The server is waiting for request from clients and must answer when it is -concerned by the request. The libmodbus offers the following functions to -handle requests: - -Data mapping:: - - linkmb:modbus_mapping_new[3] - - linkmb:modbus_mapping_free[3] - -Receive:: - - linkmb:modbus_receive[3] - -Reply:: - - linkmb:modbus_reply[3] - - linkmb:modbus_reply_exception[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 v2.1+). For details see the file `COPYING.LESSER` included -with the libmodbus distribution. diff --git a/doc/modbus_close.txt b/doc/modbus_close.txt deleted file mode 100644 index 5a0afc0..0000000 --- a/doc/modbus_close.txt +++ /dev/null @@ -1,51 +0,0 @@ -modbus_close(3) -=============== - - -NAME ----- -modbus_close - close a Modbus connection - - -SYNOPSIS --------- -*void modbus_close(modbus_t *'ctx');* - - -DESCRIPTION ------------ -The *modbus_close()* function shall close the connection established with the -backend set in the context. - - -RETURN VALUE ------------- -There is no return value. - - -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 deleted file mode 100644 index a4437ec..0000000 --- a/doc/modbus_connect.txt +++ /dev/null @@ -1,52 +0,0 @@ -modbus_connect(3) -================= - - -NAME ----- -modbus_connect - establish a Modbus connection - - -SYNOPSIS --------- -*int modbus_connect(modbus_t *'ctx');* - - -DESCRIPTION ------------ -The *modbus_connect()* function shall establish a connection to a Modbus server, -a network or a bus using the context information of libmodbus context given in -argument. - - -RETURN VALUE ------------- -The 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 deleted file mode 100644 index f4f9b16..0000000 --- a/doc/modbus_flush.txt +++ /dev/null @@ -1,30 +0,0 @@ -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 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 deleted file mode 100644 index f7b12f0..0000000 --- a/doc/modbus_free.txt +++ /dev/null @@ -1,33 +0,0 @@ -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_byte_from_bits.txt b/doc/modbus_get_byte_from_bits.txt deleted file mode 100644 index e0828f1..0000000 --- a/doc/modbus_get_byte_from_bits.txt +++ /dev/null @@ -1,35 +0,0 @@ -modbus_get_byte_from_bits(3) -============================ - -NAME ----- -modbus_get_byte_from_bits - get the value from many bits - - -SYNOPSIS --------- -*uint8_t modbus_get_byte_from_bits(const uint8_t *'src', int 'index', unsigned int 'nb_bits');* - - -DESCRIPTION ------------ -The *modbus_get_byte_from_bits()* function shall extract a value from many -bits. All _nb_bits_ bits from _src_ at position _index_ will be read as a -single value. To obtain a full byte, set nb_bits to 8. - - -RETURN VALUE ------------- -The function shall return a byte containing the bits read. - - -SEE ALSO --------- -linkmb:modbus_set_bits_from_byte[3] -linkmb:modbus_set_bits_from_bytes[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_byte_timeout.txt b/doc/modbus_get_byte_timeout.txt deleted file mode 100644 index d7ba070..0000000 --- a/doc/modbus_get_byte_timeout.txt +++ /dev/null @@ -1,50 +0,0 @@ -modbus_get_byte_timeout(3) -========================== - - -NAME ----- -modbus_get_byte_timeout - get timeout between bytes - - -SYNOPSIS --------- -*int modbus_get_byte_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* - - -DESCRIPTION ------------ -The *modbus_get_byte_timeout()* function shall store the timeout interval -between two consecutive bytes of the same message in the _to_sec_ and _to_usec_ -arguments. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno. - - -EXAMPLE -------- -[source,c] -------------------- -uint32_t to_sec; -uint32_t to_usec; - -/* Save original timeout */ -modbus_get_byte_timeout(ctx, &to_sec, &to_usec); -------------------- - - -SEE ALSO --------- -linkmb:modbus_set_byte_timeout[3] -linkmb:modbus_get_response_timeout[3] -linkmb:modbus_set_response_timeout[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_float.txt b/doc/modbus_get_float.txt deleted file mode 100644 index 023c0bb..0000000 --- a/doc/modbus_get_float.txt +++ /dev/null @@ -1,39 +0,0 @@ -modbus_get_float(3) -=================== - - -NAME ----- -modbus_get_float - get a float value from 2 registers - - -SYNOPSIS --------- -*float modbus_get_float(const uint16_t *'src');* - -Warning, this function is *deprecated* since libmodbus v3.2.0 and has been -replaced by *modbus_get_float_dcba()*. - -DESCRIPTION ------------ -The *modbus_get_float()* function shall get a float from 4 bytes in Modbus -format (DCBA byte order). The _src_ array must be a pointer on two 16 bits -values, for example, if the first word is set to 0x4465 and the second to -0x229a, the float value will be 916.540649. - - -RETURN VALUE ------------- -The function shall return a float. - - -SEE ALSO --------- -linkmb:modbus_set_float[3] -linkmb:modbus_set_float_dcba[3] -linkmb:modbus_get_float_dcba[3] - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_float_abcd.txt b/doc/modbus_get_float_abcd.txt deleted file mode 100644 index 6a491b2..0000000 --- a/doc/modbus_get_float_abcd.txt +++ /dev/null @@ -1,39 +0,0 @@ -modbus_get_float_abcd(3) -======================== - - -NAME ----- -modbus_get_float_abcd - get a float value from 2 registers in ABCD byte order - - -SYNOPSIS --------- -*float modbus_get_float_abcd(const uint16_t *'src');* - - -DESCRIPTION ------------ -The *modbus_get_float_abcd()* function shall get a float from 4 bytes in usual -Modbus format. The _src_ array must be a pointer on two 16 bits values, for -example, if the first word is set to 0x0020 and the second to 0xF147, the float -value will be read as 123456.0. - - -RETURN VALUE ------------- -The function shall return a float. - - -SEE ALSO --------- -linkmb:modbus_set_float_abcd[3] -linkmb:modbus_get_float_badc[3] -linkmb:modbus_get_float_cdab[3] -linkmb:modbus_get_float_dcba[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_float_badc.txt b/doc/modbus_get_float_badc.txt deleted file mode 100644 index 317770d..0000000 --- a/doc/modbus_get_float_badc.txt +++ /dev/null @@ -1,39 +0,0 @@ -modbus_get_float_badc(3) -======================== - - -NAME ----- -modbus_get_float_badc - get a float value from 2 registers in BADC byte order - - -SYNOPSIS --------- -*float modbus_get_float_badc(const uint16_t *'src');* - - -DESCRIPTION ------------ -The *modbus_get_float_badc()* function shall get a float from 4 bytes with -swapped bytes (BADC instead of ABCD). The _src_ array must be a pointer on two -16 bits values, for example, if the first word is set to 0x2000 and the second -to 0x47F1, the float value will be read as 123456.0. - - -RETURN VALUE ------------- -The function shall return a float. - - -SEE ALSO --------- -linkmb:modbus_set_float_badc[3] -linkmb:modbus_get_float_abcd[3] -linkmb:modbus_get_float_cdab[3] -linkmb:modbus_get_float_dcba[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_float_cdab.txt b/doc/modbus_get_float_cdab.txt deleted file mode 100644 index 82261b7..0000000 --- a/doc/modbus_get_float_cdab.txt +++ /dev/null @@ -1,39 +0,0 @@ -modbus_get_float_cdab(3) -======================== - - -NAME ----- -modbus_get_float_cdab - get a float value from 2 registers in CDAB byte order - - -SYNOPSIS --------- -*float modbus_get_float_cdab(const uint16_t *'src');* - - -DESCRIPTION ------------ -The *modbus_get_float_cdab()* function shall get a float from 4 bytes with -swapped words (CDAB order instead of ABCD). The _src_ array must be a pointer on -two 16 bits values, for example, if the first word is set to F147 and the second -to 0x0020, the float value will be read as 123456.0. - - -RETURN VALUE ------------- -The function shall return a float. - - -SEE ALSO --------- -linkmb:modbus_set_float_cdab[3] -linkmb:modbus_get_float_abcd[3] -linkmb:modbus_get_float_badc[3] -linkmb:modbus_get_float_dcba[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_float_dcba.txt b/doc/modbus_get_float_dcba.txt deleted file mode 100644 index cd98a04..0000000 --- a/doc/modbus_get_float_dcba.txt +++ /dev/null @@ -1,39 +0,0 @@ -modbus_get_float_dcba(3) -======================== - - -NAME ----- -modbus_get_float_dcba - get a float value from 2 registers in DCBA byte order - - -SYNOPSIS --------- -*float modbus_get_float_dcba(const uint16_t *'src');* - - -DESCRIPTION ------------ -The *modbus_get_float_dcba()* function shall get a float from 4 bytes in -inversed Modbus format (DCBA order instead of ABCD). The _src_ array must be a -pointer on two 16 bits values, for example, if the first word is set to 0x47F1 -and the second to 0x2000, the float value will be read as 123456.0. - - -RETURN VALUE ------------- -The function shall return a float. - - -SEE ALSO --------- -linkmb:modbus_set_float_dcba[3] -linkmb:modbus_get_float_abcd[3] -linkmb:modbus_get_float_badc[3] -linkmb:modbus_get_float_cdab[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 deleted file mode 100644 index 79f7cd9..0000000 --- a/doc/modbus_get_header_length.txt +++ /dev/null @@ -1,35 +0,0 @@ -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 function 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_indication_timeout.txt b/doc/modbus_get_indication_timeout.txt deleted file mode 100644 index 3af39d9..0000000 --- a/doc/modbus_get_indication_timeout.txt +++ /dev/null @@ -1,53 +0,0 @@ -modbus_get_indication_timeout(3) -================================ - - -NAME ----- -modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). - -SYNOPSIS --------- -*int modbus_get_indication_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* - - -DESCRIPTION ------------ - -The *modbus_get_indication_timeout()* function shall store the timeout interval -used to wait for an indication in the _to_sec_ and _to_usec_ arguments. -Indication is the term used by the Modbus protocol to designate a request -received by the server. - -The default value is zero, it means the server will wait forever. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno. - - -EXAMPLE -------- -[source,c] -------------------- -uint32_t to_sec; -uint32_t to_usec; - -/* Save original timeout */ -modbus_get_indication_timeout(ctx, &to_sec, &to_usec); -------------------- - - -SEE ALSO --------- -linkmb:modbus_set_indication_timeout[3] -linkmb:modbus_get_response_timeout[3] -linkmb:modbus_set_response_timeout[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_response_timeout.txt b/doc/modbus_get_response_timeout.txt deleted file mode 100644 index 3355802..0000000 --- a/doc/modbus_get_response_timeout.txt +++ /dev/null @@ -1,52 +0,0 @@ -modbus_get_response_timeout(3) -============================== - - -NAME ----- -modbus_get_response_timeout - get timeout for response - - -SYNOPSIS --------- -*int modbus_get_response_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* - - -DESCRIPTION ------------ -The *modbus_get_response_timeout()* function shall return the timeout interval -used to wait for a response in the _to_sec_ and _to_usec_ arguments. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno. - - -EXAMPLE -------- -[source,c] -------------------- -uint32_t old_response_to_sec; -uint32_t old_response_to_usec; - -/* Save original timeout */ -modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); - -/* Define a new and too short timeout! */ -modbus_set_response_timeout(ctx, 0, 0); -------------------- - - -SEE ALSO --------- -linkmb:modbus_set_response_timeout[3] -linkmb:modbus_get_byte_timeout[3] -linkmb:modbus_set_byte_timeout[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_slave.txt b/doc/modbus_get_slave.txt deleted file mode 100644 index 89e2ac0..0000000 --- a/doc/modbus_get_slave.txt +++ /dev/null @@ -1,41 +0,0 @@ -modbus_get_slave(3) -=================== - - -NAME ----- -modbus_get_slave - get slave number in the context - - -SYNOPSIS --------- -*int modbus_get_slave(modbus_t *'ctx');* - - -DESCRIPTION ------------ -The *modbus_get_slave()* function shall get the slave number in the libmodbus -context. - - -RETURN VALUE ------------- -The function shall return the slave number if successful. Otherwise it shall return -1 -and set errno to one of the values defined below. - - -ERRORS ------- -*EINVAL*:: -The libmodbus context is undefined. - - -SEE ALSO --------- -linkmb:modbus_set_slave[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_get_socket.txt b/doc/modbus_get_socket.txt deleted file mode 100644 index 8645fa4..0000000 --- a/doc/modbus_get_socket.txt +++ /dev/null @@ -1,35 +0,0 @@ -modbus_get_socket(3) -==================== - - -NAME ----- -modbus_get_socket - get the current socket of the context - - -SYNOPSIS --------- -*int modbus_get_socket(modbus_t *'ctx');* - - -DESCRIPTION ------------ -The *modbus_get_socket()* function shall return the current socket or file -descriptor of the libmodbus context. - - -RETURN VALUE ------------- -The function returns the current socket or file descriptor of the context if -successful. Otherwise it shall return -1 and set errno. - - -SEE ALSO --------- -linkmb:modbus_set_socket[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_mapping_free.txt b/doc/modbus_mapping_free.txt deleted file mode 100644 index 0a99f62..0000000 --- a/doc/modbus_mapping_free.txt +++ /dev/null @@ -1,34 +0,0 @@ -modbus_mapping_free(3) -===================== - - -NAME ----- -modbus_mapping_free - free a modbus_mapping_t structure - - -SYNOPSIS --------- -*void modbus_mapping_free(modbus_mapping_t *'mb_mapping');* - - -DESCRIPTION ------------ -The function shall free the four arrays of mb_mapping_t structure and finally -the mb_mapping_t referenced by _mb_mapping_. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_mapping_new[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_mapping_new.txt b/doc/modbus_mapping_new.txt deleted file mode 100644 index 71cde1d..0000000 --- a/doc/modbus_mapping_new.txt +++ /dev/null @@ -1,69 +0,0 @@ -modbus_mapping_new(3) -===================== - - -NAME ----- -modbus_mapping_new - allocate four arrays of bits and registers - - -SYNOPSIS --------- -*modbus_mapping_t* modbus_mapping_new(int 'nb_bits', int 'nb_input_bits', int 'nb_registers', int 'nb_input_registers');* - - -DESCRIPTION ------------ -The *modbus_mapping_new()* function shall allocate four arrays to store bits, -input bits, registers and inputs registers. The pointers are stored in -modbus_mapping_t structure. All values of the arrays are initialized to zero. - -This function is equivalent to a call of the -linkmb:modbus_mapping_new_start_address[3] function with all start addresses to -`0`. - -If it isn't necessary to allocate an array for a specific type of data, you can -pass the zero value in argument, the associated pointer will be NULL. - -This function is convenient to handle requests in a Modbus server/slave. - - -RETURN VALUE ------------- -The function shall return the new allocated structure if successful. Otherwise -it shall return NULL and set errno. - - -ERRORS ------- -*ENOMEM*:: -Not enough memory - - -EXAMPLE -------- -[source,c] -------------------- -/* The first value of each array is accessible from the 0 address. */ -mb_mapping = modbus_mapping_new(BITS_ADDRESS + BITS_NB, - INPUT_BITS_ADDRESS + INPUT_BITS_NB, - REGISTERS_ADDRESS + REGISTERS_NB, - INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB); -if (mb_mapping == NULL) { - fprintf(stderr, "Failed to allocate the mapping: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; -} -------------------- - -SEE ALSO --------- -linkmb:modbus_mapping_free[3] -linkmb:modbus_mapping_new_start_address[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_mapping_new_start_address.txt b/doc/modbus_mapping_new_start_address.txt deleted file mode 100644 index 0eaaa8e..0000000 --- a/doc/modbus_mapping_new_start_address.txt +++ /dev/null @@ -1,81 +0,0 @@ -modbus_mapping_new_start_address(3) -=================================== - - -NAME ----- -modbus_mapping_new_start_address - allocate four arrays of bits and registers accessible from their starting addresses - - -SYNOPSIS --------- -*modbus_mapping_t* modbus_mapping_new_start_address(int 'start_bits', int 'nb_bits', - int 'start_input_bits', int 'nb_input_bits', - int 'start_registers', int 'nb_registers', - int 'start_input_registers', int 'nb_input_registers');* - - -DESCRIPTION ------------ -The _modbus_mapping_new_start_address()_ function shall allocate four arrays to -store bits, input bits, registers and inputs registers. The pointers are stored -in modbus_mapping_t structure. All values of the arrays are initialized to zero. - -The different starting addresses make it possible to place the mapping at any -address in each address space. This way, you can give access to values stored -at high addresses without allocating memory from the address zero, for eg. to -make available registers from 10000 to 10009, you can use: - -[source,c] -------------------- -mb_mapping = modbus_mapping_new_start_address(0, 0, 0, 0, 10000, 10, 0, 0); -------------------- - -With this code, only 10 registers (`uint16_t`) are allocated. - -If it isn't necessary to allocate an array for a specific type of data, you can -pass the zero value in argument, the associated pointer will be NULL. - -This function is convenient to handle requests in a Modbus server/slave. - - -RETURN VALUE ------------- -The _modbus_mapping_new_start_address()_ function shall return the new allocated structure if -successful. Otherwise it shall return NULL and set errno. - - -ERRORS ------- -ENOMEM:: -Not enough memory - - -EXAMPLE -------- -[source,c] -------------------- -/* The first value of each array is accessible at the defined address. - The end address is ADDRESS + NB - 1. */ -mb_mapping = modbus_mapping_new_start_address(BITS_ADDRESS, BITS_NB, - INPUT_BITS_ADDRESS, INPUT_BITS_NB, - REGISTERS_ADDRESS, REGISTERS_NB, - INPUT_REGISTERS_ADDRESS, INPUT_REGISTERS_NB); -if (mb_mapping == NULL) { - fprintf(stderr, "Failed to allocate the mapping: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; -} -------------------- - -SEE ALSO --------- -linkmb:modbus_mapping_new[3] -linkmb:modbus_mapping_free[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_mask_write_register.txt b/doc/modbus_mask_write_register.txt deleted file mode 100644 index 7365503..0000000 --- a/doc/modbus_mask_write_register.txt +++ /dev/null @@ -1,41 +0,0 @@ -modbus_mask_write_register(3) -============================= - - -NAME ----- -modbus_mask_write_register - mask a single register - - -SYNOPSIS --------- -*int modbus_mask_write_register(modbus_t *'ctx', int 'addr', uint16_t 'and', uint16_t 'or');* - - -DESCRIPTION ------------ -The *modbus_mask_write_register()* function shall modify the value of the -holding register at the address 'addr' of the remote device using the algorithm: - - new value = (current value AND 'and') OR ('or' AND (NOT 'and')) - -The function uses the Modbus function code 0x16 (mask single register). - - -RETURN VALUE ------------- -The function shall return 1 if successful. Otherwise it shall return -1 and set -errno. - - -SEE ALSO --------- -linkmb:modbus_read_registers[3] -linkmb:modbus_write_registers[3] - - -AUTHORS -------- -Martijn de Gouw -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_new_rtu.txt b/doc/modbus_new_rtu.txt deleted file mode 100644 index 7a8eaac..0000000 --- a/doc/modbus_new_rtu.txt +++ /dev/null @@ -1,91 +0,0 @@ -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 Windows, 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. - -Once the _modbus_t_ structure is initialized, you must set the slave of your -device with linkmb:modbus_set_slave[3] and connect to the serial bus with -linkmb:modbus_connect[3]. - -RETURN VALUE ------------- -The 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. - -*ENOMEM*:: -Out of memory. Possibly, the application hits its memory limit and/or whole -system is running out of memory. - - -EXAMPLE -------- -[source,c] -------------------- -modbus_t *ctx; - -ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1); -if (ctx == NULL) { - fprintf(stderr, "Unable to create the libmodbus context\n"); - return -1; -} - -modbus_set_slave(ctx, YOUR_DEVICE_ID); - -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_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 deleted file mode 100644 index 5447aa6..0000000 --- a/doc/modbus_new_tcp.txt +++ /dev/null @@ -1,75 +0,0 @@ -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 to establish a connection. A NULL value can be used to listen any addresses in -server mode. - -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 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. - -*ENOMEM*:: -Out of memory. Possibly, the application hits its memory limit and/or whole -system is running out of memory. - - -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_tcp_listen[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 deleted file mode 100644 index 494c493..0000000 --- a/doc/modbus_new_tcp_pi.txt +++ /dev/null @@ -1,77 +0,0 @@ -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". A NULL value can be used to -listen any addresses in server mode. - -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 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. - -*ENOMEM*:: -Out of memory. Possibly, the application hits its memory limit and/or whole -system is running out of memory. - - -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_tcp_pi_listen[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 deleted file mode 100644 index 1e7fd1e..0000000 --- a/doc/modbus_read_bits.txt +++ /dev/null @@ -1,48 +0,0 @@ -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 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 deleted file mode 100644 index d7fd3e0..0000000 --- a/doc/modbus_read_input_bits.txt +++ /dev/null @@ -1,47 +0,0 @@ -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 0x02 (read input status). - - -RETURN VALUE ------------- -The 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_read_input_registers[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 deleted file mode 100644 index 20a5376..0000000 --- a/doc/modbus_read_input_registers.txt +++ /dev/null @@ -1,51 +0,0 @@ -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 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_input_bits[3] -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_read_registers.txt b/doc/modbus_read_registers.txt deleted file mode 100644 index dd29fdc..0000000 --- a/doc/modbus_read_registers.txt +++ /dev/null @@ -1,79 +0,0 @@ -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 function shall return the number of read registers -if successful. Otherwise it shall return -1 and set errno. - - -ERRORS ------- -*EMBMDATA*:: -Too many registers requested - - -EXAMPLE -------- -[source,c] -------------------- -modbus_t *ctx; -uint16_t tab_reg[64]; -int rc; -int i; - -ctx = modbus_new_tcp("127.0.0.1", 1502); -if (modbus_connect(ctx) == -1) { - fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); - modbus_free(ctx); - return -1; -} - -rc = modbus_read_registers(ctx, 0, 10, tab_reg); -if (rc == -1) { - fprintf(stderr, "%s\n", modbus_strerror(errno)); - return -1; -} - -for (i=0; i < rc; i++) { - printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); -} - -modbus_close(ctx); -modbus_free(ctx); -------------------- - - -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_receive.txt b/doc/modbus_receive.txt deleted file mode 100644 index 460d19b..0000000 --- a/doc/modbus_receive.txt +++ /dev/null @@ -1,42 +0,0 @@ -modbus_receive(3) -================= - - -NAME ----- -modbus_receive - receive an indication request - - -SYNOPSIS --------- -*int modbus_receive(modbus_t *'ctx', uint8_t *'req');* - - -DESCRIPTION ------------ -The *modbus_receive()* function shall receive an indication request from the -socket of the context _ctx_. This function is used by Modbus slave/server to -receive and analyze indication request sent by the masters/clients. - -If you need to use another socket or file descriptor than the one defined in the -context _ctx_, see the function linkmb:modbus_set_socket[3]. - - -RETURN VALUE ------------- -The function shall store the indication request in _req_ and return the request -length if successful. The returned request length can be zero if the indication -request is ignored (eg. a query for another slave in RTU mode). Otherwise it -shall return -1 and set errno. - - -SEE ALSO --------- -linkmb:modbus_set_socket[3] -linkmb:modbus_reply[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_receive_confirmation.txt b/doc/modbus_receive_confirmation.txt deleted file mode 100644 index 290d1f6..0000000 --- a/doc/modbus_receive_confirmation.txt +++ /dev/null @@ -1,53 +0,0 @@ -modbus_receive_confirmation(3) -============================== - - -NAME ----- -modbus_receive_confirmation - receive a confirmation request - - -SYNOPSIS --------- -*int modbus_receive_confirmation(modbus_t *'ctx', uint8_t *'rsp');* - - -DESCRIPTION ------------ -The *modbus_receive_confirmation()* function shall receive a request via the -socket of the context _ctx_. This function must be used for debugging purposes -because the received response isn't checked against the initial request. This -function can be used to receive request not handled by the library. - -The maximum size of the response depends on the used backend, in RTU the _rsp_ -array must be _MODBUS_RTU_MAX_ADU_LENGTH_ bytes and in TCP it must be -_MODBUS_TCP_MAX_ADU_LENGTH_ bytes. If you want to write code compatible with -both, you can use the constant _MODBUS_MAX_ADU_LENGTH_ (maximum value of all -libmodbus backends). Take care to allocate enough memory to store responses to -avoid crashes of your server. - - -RETURN VALUE ------------- -The function shall store the confirmation request in _rsp_ and return the -response length if successful. The returned request length can be zero if the -indication request is ignored (eg. a query for another slave in RTU -mode). Otherwise it shall return -1 and set errno. - -EXAMPLE -------- -[source,c] -------------------- -uint8_t rsp[MODBUS_MAX_ADU_LENGTH]; -rc = modbus_receive_confirmation(ctx, rsp); -------------------- - -SEE ALSO --------- -linkmb:modbus_send_raw_request[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_reply.txt b/doc/modbus_reply.txt deleted file mode 100644 index 6b71d11..0000000 --- a/doc/modbus_reply.txt +++ /dev/null @@ -1,52 +0,0 @@ -modbus_reply(3) -=============== - -NAME ----- -modbus_reply - send a response to the received request - - -SYNOPSIS --------- -*int modbus_reply(modbus_t *'ctx', const uint8_t *'req', int 'req_length', modbus_mapping_t *'mb_mapping'); - - -DESCRIPTION ------------ -The *modbus_reply()* function shall send a response to received request. The -request _req_ given in argument is analyzed, a response is then built and sent -by using the information of the modbus context _ctx_. - -If the request indicates to read or write a value the operation will done in the -modbus mapping _mb_mapping_ according to the type of the manipulated data. - -If an error occurs, an exception response will be sent. - -This function is designed for Modbus server. - - -RETURN VALUE ------------- -The function shall return the length of the response sent if -successful. Otherwise it shall return -1 and set errno. - - -ERRORS ------- -*EMBMDATA*:: -Sending has failed - -See also the errors returned by the syscall used to send the response (eg. send -or write). - - -SEE ALSO --------- -linkmb:modbus_reply_exception[3] -linkmb:libmodbus[7] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_reply_exception.txt b/doc/modbus_reply_exception.txt deleted file mode 100644 index b2170be..0000000 --- a/doc/modbus_reply_exception.txt +++ /dev/null @@ -1,57 +0,0 @@ -modbus_reply_exception(3) -========================= - -NAME ----- -modbus_reply_exception - send an exception response - - -SYNOPSIS --------- -*int modbus_reply_exception(modbus_t *'ctx', const uint8_t *'req', unsigned int 'exception_code'); - - -DESCRIPTION ------------ -The *modbus_reply_exception()* function shall send an exception response based -on the 'exception_code' in argument. - -The libmodbus provides the following exception codes: - -* MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1) -* MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2) -* MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3) -* MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4) -* MODBUS_EXCEPTION_ACKNOWLEDGE (5) -* MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6) -* MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7) -* MODBUS_EXCEPTION_MEMORY_PARITY (8) -* MODBUS_EXCEPTION_NOT_DEFINED (9) -* MODBUS_EXCEPTION_GATEWAY_PATH (10) -* MODBUS_EXCEPTION_GATEWAY_TARGET (11) - -The initial request _req_ is required to build a valid response. - - -RETURN VALUE ------------- -The function shall return the length of the response sent if -successful. Otherwise it shall return -1 and set errno. - - -ERRORS ------- -*EINVAL*:: -The exception code is invalid - - -SEE ALSO --------- -linkmb:modbus_reply[3] -linkmb:libmodbus[7] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_report_slave_id.txt b/doc/modbus_report_slave_id.txt deleted file mode 100644 index 6aedec6..0000000 --- a/doc/modbus_report_slave_id.txt +++ /dev/null @@ -1,61 +0,0 @@ -modbus_report_slave_id(3) -========================= - - -NAME ----- -modbus_report_slave_id - returns a description of the controller - - -SYNOPSIS --------- -*int modbus_report_slave_id(modbus_t *'ctx', int 'max_dest', uint8_t *'dest');* - - -DESCRIPTION ------------ -The *modbus_report_slave_id()* function shall send a request to the controller -to obtain a description of the controller. - -The response stored in _dest_ contains: - -* the slave ID, this unique ID is in reality not unique at all so it's not - possible to depend on it to know how the information are packed in the - response. -* the run indicator status (0x00 = OFF, 0xFF = ON) -* additional data specific to each controller. For example, libmodbus returns - the version of the library as a string. - -The function writes at most _max_dest_ bytes from the response to _dest_ so -you must ensure that _dest_ is large enough. - -RETURN VALUE ------------- -The function shall return the number of read data if successful. - -If the output was truncated due to the _max_dest_ limit then the return value is -the number of bytes which would have been written to _dest_ if enough space had -been available. Thus, a return value greater than _max_dest_ means that the -response data was truncated. - -Otherwise it shall return -1 and set errno. - -EXAMPLE -------- -[source,c] -------------------- -uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH]; - -... - -rc = modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes); -if (rc > 1) { - printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF"); -} -------------------- - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_rtu_get_rts.txt b/doc/modbus_rtu_get_rts.txt deleted file mode 100644 index 559c80b..0000000 --- a/doc/modbus_rtu_get_rts.txt +++ /dev/null @@ -1,47 +0,0 @@ -modbus_rtu_get_rts(3) -===================== - - -NAME ----- -modbus_rtu_get_rts - get the current RTS mode in RTU - - -SYNOPSIS --------- -*int modbus_rtu_get_rts(modbus_t *'ctx');* - - -DESCRIPTION ------------ -The *modbus_rtu_get_rts()* function shall get the current Request To Send mode -of the libmodbus context _ctx_. The possible returned values are: - -* MODBUS_RTU_RTS_NONE -* MODBUS_RTU_RTS_UP -* MODBUS_RTU_RTS_DOWN - -This function can only be used with a context using a RTU backend. - - -RETURN VALUE ------------- -The function shall return the current RTS mode if successful. Otherwise it shall -return -1 and set errno. - - -ERRORS ------- -*EINVAL*:: -The libmodbus backend is not RTU. - - -SEE ALSO --------- -linkmb:modbus_rtu_set_rts[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_rtu_get_rts_delay.txt b/doc/modbus_rtu_get_rts_delay.txt deleted file mode 100644 index 43853d4..0000000 --- a/doc/modbus_rtu_get_rts_delay.txt +++ /dev/null @@ -1,46 +0,0 @@ -modbus_rtu_get_rts_delay(3) -=========================== - - -NAME ----- -modbus_rtu_get_rts_delay - get the current RTS delay in RTU - - -SYNOPSIS --------- -*int modbus_rtu_get_rts_delay(modbus_t *'ctx');* - - -DESCRIPTION ------------ - -The _modbus_rtu_get_rts_delay()_ function shall get the current Request To Send -delay period of the libmodbus context 'ctx'. - -This function can only be used with a context using a RTU backend. - - -RETURN VALUE ------------- -The _modbus_rtu_get_rts_delay()_ function shall return the current RTS delay in -microseconds if successful. Otherwise it shall return -1 and set errno. - - -ERRORS ------- -*EINVAL*:: -The libmodbus backend is not RTU. - - -SEE ALSO --------- -linkmb:modbus_rtu_set_rts_delay[3] - - -AUTHORS -------- -Jimmy Bergström - -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_rtu_get_serial_mode.txt b/doc/modbus_rtu_get_serial_mode.txt deleted file mode 100644 index b580728..0000000 --- a/doc/modbus_rtu_get_serial_mode.txt +++ /dev/null @@ -1,53 +0,0 @@ -modbus_rtu_get_serial_mode(3) -============================= - - -NAME ----- -modbus_rtu_get_serial_mode - get the current serial mode - - -SYNOPSIS --------- -*int modbus_rtu_get_serial_mode(modbus_t *'ctx');* - - -DESCRIPTION ------------ -The *modbus_rtu_get_serial_mode()* function shall return the serial mode -currently used by the libmodbus context: - -*MODBUS_RTU_RS232*:: the serial line is set for RS232 communication. RS-232 - (Recommended Standard 232) is the traditional name for a series of standards - for serial binary single-ended data and control signals connecting between a - DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating - Equipment). It is commonly used in computer serial ports - -*MODBUS_RTU_RS485*:: the serial line is set for RS485 communication. EIA-485, - also known as TIA/EIA-485 or RS-485, is a standard defining the electrical - characteristics of drivers and receivers for use in balanced digital multipoint - systems. This standard is widely used for communications in industrial - automation because it can be used effectively over long distances and in - electrically noisy environments. - -This function is only available on Linux kernels 2.6.28 onwards and can only be -used with a context using a RTU backend. - - -RETURN VALUE ------------- -The function shall return `MODBUS_RTU_RS232` or `MODBUS_RTU_RS485` if -successful. Otherwise it shall return -1 and set errno to one of the values -defined below. - - -ERRORS ------- -*EINVAL*:: -The current libmodbus backend is not RTU. - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_rtu_set_custom_rts.txt b/doc/modbus_rtu_set_custom_rts.txt deleted file mode 100644 index c17bd3d..0000000 --- a/doc/modbus_rtu_set_custom_rts.txt +++ /dev/null @@ -1,45 +0,0 @@ -modbus_rtu_set_custom_rts(3) -============================ - - -NAME ----- -modbus_rtu_set_custom_rts - set a function to be used for custom RTS implementation - - -SYNOPSIS --------- -*int modbus_rtu_set_custom_rts(modbus_t *'ctx', void (*'set_rts') (modbus_t *ctx, int on))* - - -DESCRIPTION ------------ -The _modbus_rtu_set_custom_rts()_ function shall set a custom function to be -called when the RTS pin is to be set before and after a transmission. By default -this is set to an internal function that toggles the RTS pin using an ioctl -call. - -Note that this function adheres to the RTS mode, the values MODBUS_RTU_RTS_UP or -MODBUS_RTU_RTS_DOWN must be used for the function to be called. - -This function can only be used with a context using a RTU backend. - - -RETURN VALUE ------------- -The _modbus_rtu_set_custom_rts()_ function shall return 0 if successful. -Otherwise it shall return -1 and set errno to one of the values defined below. - - -ERRORS ------- -*EINVAL*:: -The libmodbus backend is not RTU. - - -AUTHORS -------- -Jimmy Bergström - -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_rtu_set_rts_delay.txt b/doc/modbus_rtu_set_rts_delay.txt deleted file mode 100644 index 39af7df..0000000 --- a/doc/modbus_rtu_set_rts_delay.txt +++ /dev/null @@ -1,46 +0,0 @@ -modbus_rtu_set_rts_delay(3) -=========================== - - -NAME ----- -modbus_rtu_set_rts_delay - set the RTS delay in RTU - - -SYNOPSIS --------- -*int modbus_rtu_set_rts_delay(modbus_t *'ctx', int 'us');* - - -DESCRIPTION ------------ - -The _modbus_rtu_set_rts_delay()_ function shall set the Request To Send delay -period of the libmodbus context 'ctx'. - -This function can only be used with a context using a RTU backend. - - -RETURN VALUE ------------- -The _modbus_rtu_set_rts_delay()_ function shall return 0 if successful. -Otherwise it shall return -1 and set errno. - - -ERRORS ------- -*EINVAL*:: -The libmodbus backend is not RTU or a negative delay was specified. - - -SEE ALSO --------- -linkmb:modbus_rtu_get_rts_delay[3] - - -AUTHORS -------- -Jimmy Bergström - -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_rtu_set_serial_mode.txt b/doc/modbus_rtu_set_serial_mode.txt deleted file mode 100644 index 7086dc4..0000000 --- a/doc/modbus_rtu_set_serial_mode.txt +++ /dev/null @@ -1,56 +0,0 @@ -modbus_rtu_set_serial_mode(3) -============================= - - -NAME ----- -modbus_rtu_set_serial_mode - set the serial mode - - -SYNOPSIS --------- -*int modbus_rtu_set_serial_mode(modbus_t *'ctx', int 'mode');* - - -DESCRIPTION ------------ -The *modbus_rtu_set_serial_mode()* function shall set the selected serial -mode: - -*MODBUS_RTU_RS232*:: the serial line is set for RS232 communication. RS-232 - (Recommended Standard 232) is the traditional name for a series of standards - for serial binary single-ended data and control signals connecting between a - DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating - Equipment). It is commonly used in computer serial ports - -*MODBUS_RTU_RS485*:: the serial line is set for RS485 communication. EIA-485, - also known as TIA/EIA-485 or RS-485, is a standard defining the electrical - characteristics of drivers and receivers for use in balanced digital multipoint - systems. This standard is widely used for communications in industrial - automation because it can be used effectively over long distances and in - electrically noisy environments. - -This function is only supported on Linux kernels 2.6.28 onwards. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno to one of the values defined below. - - -ERRORS ------- -*EINVAL*:: -The current libmodbus backend is not RTU. - -*ENOTSUP*:: -The function is not supported on your platform. - -If the call to ioctl() fails, the error code of ioctl will be returned. - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_bits_from_byte.txt b/doc/modbus_set_bits_from_byte.txt deleted file mode 100644 index 72b2949..0000000 --- a/doc/modbus_set_bits_from_byte.txt +++ /dev/null @@ -1,36 +0,0 @@ -modbus_set_bits_from_byte(3) -============================ - - -NAME ----- -modbus_set_bits_from_byte - set many bits from a single byte value - - -SYNOPSIS --------- -*void modbus_set_bits_from_byte(uint8_t *'dest', int 'index', const uint8_t 'value');* - - -DESCRIPTION ------------ -The *modbus_set_bits_from_byte()* function shall set many bits from a single byte. -All 8 bits from the byte _value_ will be written to _dest_ array starting at -_index_ position. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_set_bits_from_byte[3] -linkmb:modbus_set_bits_from_bytes[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_bits_from_bytes.txt b/doc/modbus_set_bits_from_bytes.txt deleted file mode 100644 index cfbb8ed..0000000 --- a/doc/modbus_set_bits_from_bytes.txt +++ /dev/null @@ -1,36 +0,0 @@ -modbus_set_bits_from_bytes(3) -============================ - - -NAME ----- -modbus_set_bits_from_bytes - set many bits from an array of bytes - - -SYNOPSIS --------- -*void modbus_set_bits_from_bytes(uint8_t *'dest', int 'index', unsigned int 'nb_bits', const uint8_t *'tab_byte');* - - -DESCRIPTION ------------ -The *modbus_set_bits_from_bytes* function shall set bits by reading an array of -bytes. All the bits of the bytes read from the first position of the array -_tab_byte_ are written as bits in the _dest_ array starting at position _index_. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_set_bits_from_byte[3] -linkmb:modbus_get_byte_from_bits[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_byte_timeout.txt b/doc/modbus_set_byte_timeout.txt deleted file mode 100644 index 86c644c..0000000 --- a/doc/modbus_set_byte_timeout.txt +++ /dev/null @@ -1,54 +0,0 @@ -modbus_set_byte_timeout(3) -========================== - - -NAME ----- -modbus_set_byte_timeout - set timeout between bytes - - -SYNOPSIS --------- -*void modbus_set_byte_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* - - -DESCRIPTION ------------ -The *modbus_set_byte_timeout()* function shall set the timeout interval between -two consecutive bytes of the same message. The timeout is an upper bound on the -amount of time elapsed before *select()* returns, if the time elapsed is longer -than the defined timeout, an `ETIMEDOUT` error will be raised by the -function waiting for a response. - -The value of _to_usec_ argument must be in the range 0 to 999999. - -If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. -In this case, *modbus_set_response_timeout()* governs the entire handling of the -response, the full confirmation response must be received before expiration of -the response timeout. When a byte timeout is set, the response timeout is only -used to wait for until the first byte of the response. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno. - - -ERRORS ------- -*EINVAL*:: -The argument _ctx_ is NULL or _to_usec_ is larger than 999999. - - -SEE ALSO --------- -linkmb:modbus_get_byte_timeout[3] -linkmb:modbus_get_response_timeout[3] -linkmb:modbus_set_response_timeout[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 deleted file mode 100644 index 3154c21..0000000 --- a/doc/modbus_set_debug.txt +++ /dev/null @@ -1,38 +0,0 @@ -modbus_set_debug(3) -=================== - -NAME ----- -modbus_set_debug - set debug flag of the context - - -SYNOPSIS --------- -*int modbus_set_debug(modbus_t *'ctx', int 'flag');* - - -DESCRIPTION ------------ -The *modbus_set_debug()* function shall set the debug flag of the *modbus_t* -context by using the argument _flag_. By default, the boolean flag is set to -`FALSE`. When the _flag_ 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 ------------- -The function shall return 0 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_set_float.txt b/doc/modbus_set_float.txt deleted file mode 100644 index f124022..0000000 --- a/doc/modbus_set_float.txt +++ /dev/null @@ -1,36 +0,0 @@ -modbus_set_float(3) -=================== - -NAME ----- -modbus_set_float - set a float value from 2 registers - - -SYNOPSIS --------- -*void modbus_set_float(float 'f', uint16_t *'dest');* - -Warning, this function is *deprecated* since libmodbus v3.2.0 and has been -replaced by *modbus_set_float_dcba()*. - -DESCRIPTION ------------ -The *modbus_set_float()* function shall set a float to 4 bytes in Modbus format -(ABCD). The _dest_ array must be pointer on two 16 bits values to be able to -store the full result of the conversion. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_get_float[3] -linkmb:modbus_set_float_dcba[3] - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_float_abcd.txt b/doc/modbus_set_float_abcd.txt deleted file mode 100644 index 386cbef..0000000 --- a/doc/modbus_set_float_abcd.txt +++ /dev/null @@ -1,38 +0,0 @@ -modbus_set_float_abcd(3) -======================== - - -NAME ----- -modbus_set_float_abcd - set a float value in 2 registers using ABCD byte order - - -SYNOPSIS --------- -*void modbus_set_float_abcd(float 'f', uint16_t *'dest');* - - -DESCRIPTION ------------ -The *modbus_set_float_abcd()* function shall set a float to 4 bytes in usual -Modbus format. The _dest_ array must be pointer on two 16 bits values to be able -to store the full result of the conversion. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_get_float_abcd[3] -linkmb:modbus_set_float_badc[3] -linkmb:modbus_set_float_cdab[3] -linkmb:modbus_set_float_dcba[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_float_badc.txt b/doc/modbus_set_float_badc.txt deleted file mode 100644 index d41d777..0000000 --- a/doc/modbus_set_float_badc.txt +++ /dev/null @@ -1,38 +0,0 @@ -modbus_set_float_badc(3) -======================== - - -NAME ----- -modbus_set_float_badc - set a float value in 2 registers using BADC byte order - - -SYNOPSIS --------- -*void modbus_set_float_badc(float 'f', uint16_t *'dest');* - - -DESCRIPTION ------------ -The *modbus_set_float_badc()* function shall set a float to 4 bytes in swapped -bytes Modbus format (BADC instead of ABCD). The _dest_ array must be pointer on -two 16 bits values to be able to store the full result of the conversion. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_get_float_badc[3] -linkmb:modbus_set_float_abcd[3] -linkmb:modbus_set_float_cdab[3] -linkmb:modbus_set_float_dcba[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_float_cdab.txt b/doc/modbus_set_float_cdab.txt deleted file mode 100644 index 3a03725..0000000 --- a/doc/modbus_set_float_cdab.txt +++ /dev/null @@ -1,39 +0,0 @@ -modbus_set_float_cdab(3) -======================== - - -NAME ----- -modbus_set_float_cdab - set a float value in 2 registers using CDAB byte order - - -SYNOPSIS --------- -*void modbus_set_float_cdab(float 'f', uint16_t *'dest');* - - -DESCRIPTION ------------ -The *modbus_set_float_cdab()* function shall set a float to 4 bytes in swapped -words Modbus format (CDAB order instead of ABCD). The _dest_ array must be -pointer on two 16 bits values to be able to store the full result of the -conversion. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_get_float_cdab[3] -linkmb:modbus_set_float_abcd[3] -linkmb:modbus_set_float_badc[3] -linkmb:modbus_set_float_dcba[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_float_dcba.txt b/doc/modbus_set_float_dcba.txt deleted file mode 100644 index 578ae6f..0000000 --- a/doc/modbus_set_float_dcba.txt +++ /dev/null @@ -1,37 +0,0 @@ -modbus_set_float_dcba(3) -======================== - - -NAME ----- -modbus_set_float_dcba - set a float value in 2 registers using DCBA byte order - - -SYNOPSIS --------- -*void modbus_set_float_dcba(float 'f', uint16_t *'dest');* - - -DESCRIPTION ------------ -The *modbus_set_float_dcba()* function shall set a float to 4 bytes in inverted -Modbus format (DCBA order). The _dest_ array must be pointer on two 16 bits -values to be able to store the full result of the conversion. - - -RETURN VALUE ------------- -There is no return values. - - -SEE ALSO --------- -linkmb:modbus_get_float_dcba[3] -linkmb:modbus_set_float[3] -linkmb:modbus_get_float[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_indication_timeout.txt b/doc/modbus_set_indication_timeout.txt deleted file mode 100644 index 6524bdc..0000000 --- a/doc/modbus_set_indication_timeout.txt +++ /dev/null @@ -1,48 +0,0 @@ -modbus_set_indication_timeout(3) -================================ - - -NAME ----- -modbus_set_indication_timeout - set timeout between indications - - -SYNOPSIS --------- -*void modbus_set_indication_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* - - -DESCRIPTION ------------ -The *modbus_set_indication_timeout()* function shall set the timeout interval used by -a server to wait for a request from a client. - -The value of _to_usec_ argument must be in the range 0 to 999999. - -If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. -In this case, the server will wait forever. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno. - - -ERRORS ------- -*EINVAL*:: -The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. - - -SEE ALSO --------- -linkmb:modbus_get_indication_timeout[3] -linkmb:modbus_get_response_timeout[3] -linkmb:modbus_set_response_timeout[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_set_response_timeout.txt b/doc/modbus_set_response_timeout.txt deleted file mode 100644 index e99e38c..0000000 --- a/doc/modbus_set_response_timeout.txt +++ /dev/null @@ -1,65 +0,0 @@ -modbus_set_response_timeout(3) -============================== - - -NAME ----- -modbus_set_response_timeout - set timeout for response - - -SYNOPSIS --------- -*int modbus_set_response_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* - - -DESCRIPTION ------------ -The *modbus_set_response_timeout()* function shall set the timeout interval used -to wait for a response. When a byte timeout is set, if elapsed time for the -first byte of response is longer than the given timeout, an `ETIMEDOUT` error -will be raised by the function waiting for a response. When byte timeout is -disabled, the full confirmation response must be received before expiration of -the response timeout. - -The value of _to_usec_ argument must be in the range 0 to 999999. - - -RETURN VALUE ------------- -The function shall return 0 if successful. Otherwise it shall return -1 and set -errno. - - -ERRORS ------- -*EINVAL*:: -The argument _ctx_ is NULL, or both _to_sec_ and _to_usec_ are zero, or _to_usec_ -is larger than 999999. - - -EXAMPLE -------- -[source,c] -------------------- -uint32_t old_response_to_sec; -uint32_t old_response_to_usec; - -/* Save original timeout */ -modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); - -/* Define a new timeout of 200ms */ -modbus_set_response_timeout(ctx, 0, 200000); -------------------- - - -SEE ALSO --------- -linkmb:modbus_get_response_timeout[3] -linkmb:modbus_get_byte_timeout[3] -linkmb:modbus_set_byte_timeout[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_strerror.txt b/doc/modbus_strerror.txt deleted file mode 100644 index 9cc355f..0000000 --- a/doc/modbus_strerror.txt +++ /dev/null @@ -1,54 +0,0 @@ -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 -------- -.Display 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_tcp_accept.txt b/doc/modbus_tcp_accept.txt deleted file mode 100644 index 4c46d90..0000000 --- a/doc/modbus_tcp_accept.txt +++ /dev/null @@ -1,56 +0,0 @@ -modbus_tcp_accept(3) -==================== - - -NAME ----- -modbus_tcp_accept - accept a new connection on a TCP Modbus socket (IPv4) - - -SYNOPSIS --------- -*int modbus_tcp_accept(modbus_t *'ctx', int *'s);* - - -DESCRIPTION ------------ -The *modbus_tcp_accept()* function shall extract the first connection on the -queue of pending connections, create a new socket and store it in libmodbus -context given in argument. If available, _accept4()_ with `SOCK_CLOEXEC` will be -called instead of *accept()*. - - -RETURN VALUE ------------- -The function shall return a new socket if successful. -Otherwise it shall return -1 and set errno. - - -EXAMPLE -------- -For detailed example, see unit-test-server.c source file in tests directory. - -[source,c] -------------------- -... - -ctx = modbus_new_tcp("127.0.0.1", 502); -s = modbus_tcp_listen(ctx, 1); -modbus_tcp_accept(ctx, &s); - -... - -close(s) -modbus_free(ctx); -------------------- - -SEE ALSO --------- -linkmb:modbus_tcp_pi_accept[3] -linkmb:modbus_tcp_listen[3] -linkmb:modbus_tcp_pi_listen[3] - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_tcp_pi_accept.txt b/doc/modbus_tcp_pi_accept.txt deleted file mode 100644 index a84dc43..0000000 --- a/doc/modbus_tcp_pi_accept.txt +++ /dev/null @@ -1,56 +0,0 @@ -modbus_tcp_pi_accept(3) -======================= - - -NAME ----- -modbus_tcp_pi_accept - accept a new connection on a TCP PI Modbus socket (IPv6) - - -SYNOPSIS --------- -*int modbus_tcp_pi_accept(modbus_t *'ctx', int *'s);* - - -DESCRIPTION ------------ -The *modbus_tcp_pi_accept()* function shall extract the first connection on the -queue of pending connections, create a new socket and store it in libmodbus -context given in argument. If available, _accept4()_ with `SOCK_CLOEXEC` will be -called instead of *accept()*. - - -RETURN VALUE ------------- -The function shall return a new socket if successful. -Otherwise it shall return -1 and set errno. - - -EXAMPLE -------- -For detailed example, see unit-test-server.c source file in tests directory. - -[source,c] -------------------- -... - -ctx = modbus_new_tcp_pi("::0", 502); -s = modbus_tcp_pi_listen(ctx, 1); -modbus_tcp_pi_accept(ctx, &s); - -... - -close(s) -modbus_free(ctx); -------------------- - -SEE ALSO --------- -linkmb:modbus_tcp_pi_accept[3] -linkmb:modbus_tcp_listen[3] -linkmb:modbus_tcp_pi_listen[3] - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_tcp_pi_listen.txt b/doc/modbus_tcp_pi_listen.txt deleted file mode 100644 index 2a501ee..0000000 --- a/doc/modbus_tcp_pi_listen.txt +++ /dev/null @@ -1,67 +0,0 @@ -modbus_tcp_pi_listen(3) -======================= - - -NAME ----- -modbus_tcp_pi_listen - create and listen a TCP PI Modbus socket (IPv6) - - -SYNOPSIS --------- -*int modbus_tcp_pi_listen(modbus_t *'ctx', int 'nb_connection');* - - -DESCRIPTION ------------ -The *modbus_tcp_pi_listen()* function shall create a socket and listen to -maximum _nb_connection_ incoming connections on the specified nodes. The -context *ctx* must be allocated and initialized with linkmb:modbus_new_tcp_pi[3] -before to set the node to listen, if node is set to NULL or '0.0.0.0', any addresses will be -listen. - - -RETURN VALUE ------------- -The function shall return a new socket if successful. Otherwise it shall return --1 and set errno. - - -EXAMPLE -------- - -For detailed examples, see source files in tests directory: - -- unit-test-server.c, simple but handle only one connection - -[source,c] -------------------- -... - -ctx = modbus_new_tcp_pi("::0", "502"); -s = modbus_tcp_pi_listen(ctx, 1); -modbus_tcp_pi_accept(ctx, &s); - -for (;;) { - rc = modbus_receive(ctx, query); - modbus_replay(ctx, query, rc, mb_mapping); -} -... - -mclose(s); -modbus_free(ctx); -------------------- - -- bandwidth-server-many-up.c, handles several connections at once - - -SEE ALSO --------- -linkmb:modbus_new_tcp_pi[3] -linkmb:modbus_tcp_pi_accept[3] -linkmb:modbus_tcp_listen[3] - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/doc/modbus_write_and_read_registers.txt b/doc/modbus_write_and_read_registers.txt deleted file mode 100644 index e9b14bd..0000000 --- a/doc/modbus_write_and_read_registers.txt +++ /dev/null @@ -1,51 +0,0 @@ -modbus_write_and_read_registers(3) -================================== - - -NAME ----- -modbus_write_and_read_registers - write and read many registers in a single transaction - - -SYNOPSIS --------- -*int modbus_write_and_read_registers(modbus_t *'ctx', int 'write_addr', int 'write_nb', const uint16_t *'src', int 'read_addr', int 'read_nb', const uint16_t *'dest');* - - -DESCRIPTION ------------ -The *modbus_write_and_read_registers()* function shall write the content of the -_write_nb_ holding registers from the array 'src' to the address _write_addr_ of -the remote device then shall read the content of the _read_nb_ holding registers -to the address _read_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 0x17 (write/read registers). - - -RETURN VALUE ------------- -The function shall return the number of read registers if successful. Otherwise -it shall return -1 and set errno. - - -ERRORS ------- -*EMBMDATA*:: -Too many registers requested, Too many registers to write - - -SEE ALSO --------- -linkmb:modbus_read_registers[3] -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_write_bit.txt b/doc/modbus_write_bit.txt deleted file mode 100644 index 3b4df9e..0000000 --- a/doc/modbus_write_bit.txt +++ /dev/null @@ -1,38 +0,0 @@ -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 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 deleted file mode 100644 index 7f1af84..0000000 --- a/doc/modbus_write_bits.txt +++ /dev/null @@ -1,45 +0,0 @@ -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 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 deleted file mode 100644 index 781b3af..0000000 --- a/doc/modbus_write_register.txt +++ /dev/null @@ -1,38 +0,0 @@ -modbus_write_register(3) -======================== - - -NAME ----- -modbus_write_register - write a single register - - -SYNOPSIS --------- -*int modbus_write_register(modbus_t *'ctx', int 'addr', const uint16_t '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 function shall return 1 if successful. Otherwise it shall return -1 and set -errno. - - -SEE ALSO --------- -linkmb:modbus_read_registers[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 deleted file mode 100644 index a5654fb..0000000 --- a/doc/modbus_write_registers.txt +++ /dev/null @@ -1,38 +0,0 @@ -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 function shall return the number of written registers if -successful. Otherwise it shall return -1 and set errno. - - -SEE ALSO --------- -linkmb:modbus_write_register[3] -linkmb:modbus_read_registers[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - diff --git a/docs/assets/client-sensors.excalidraw b/docs/assets/client-sensors.excalidraw new file mode 100644 index 0000000..bb8eba6 --- /dev/null +++ b/docs/assets/client-sensors.excalidraw @@ -0,0 +1,606 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 473, + "versionNonce": 1256506895, + "isDeleted": false, + "id": "ox1Blt2bzl0onmQfB7ZAN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 827.69921875, + "y": 210.68359375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 251.7109375, + "height": 259.47265625, + "seed": 1508024704, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "sE5xq9Fz5VDTWcJGhJizg", + "type": "arrow" + }, + { + "id": "HZoAI_wR8CyRR9fVaFwSl", + "type": "arrow" + } + ], + "updated": 1660298248381, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 585, + "versionNonce": 720617423, + "isDeleted": false, + "id": "rjHz2X8U0ZDEyckj_tTSw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 854.0546875, + "y": 287.16015625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 199, + "height": 160, + "seed": 2100367744, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "vJNRjoY0dZcqOBw5RzuHn", + "type": "arrow" + } + ], + "updated": 1660298281789, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Reads temperatures\nfrom various\nModbus sensors (servers)\n\nS1: read index 0 -> 28\nS2: read index 0 -> 26\n...\n", + "baseline": 154, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Reads temperatures\nfrom various\nModbus sensors (servers)\n\nS1: read index 0 -> 28\nS2: read index 0 -> 26\n...\n" + }, + { + "type": "rectangle", + "version": 534, + "versionNonce": 2127380463, + "isDeleted": false, + "id": "mDgu1gSg34HbU-NAHPB30", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 420.2109375, + "y": 212.580078125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 216.16406250000006, + "height": 172.06640624999997, + "seed": 1336837760, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "sE5xq9Fz5VDTWcJGhJizg", + "type": "arrow" + } + ], + "updated": 1660298020282, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 653, + "versionNonce": 2127484513, + "isDeleted": false, + "id": "UxvTnld8qh188IzV4uJ2q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 443.79296875, + "y": 286.3515625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 80, + "seed": 759374208, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660298185311, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Measures temperature\nand hygrometry:\n0: 28°C\n1: 32% ", + "baseline": 74, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Measures temperature\nand hygrometry:\n0: 28°C\n1: 32% " + }, + { + "type": "text", + "version": 349, + "versionNonce": 1469666511, + "isDeleted": false, + "id": "F6UUk6_B6uALmjxcHLYw4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 488.19921875, + "y": 237.921875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 79, + "height": 25, + "seed": 354006656, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660298032950, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Sensor 1", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Sensor 1" + }, + { + "type": "text", + "version": 224, + "versionNonce": 864770191, + "isDeleted": false, + "id": "v7q2uvVFHZBvjr-y_ZJKl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 884.5546875, + "y": 238.328125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 150, + "height": 25, + "seed": 2108436864, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660299132232, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "libmodbus client", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "libmodbus client" + }, + { + "type": "arrow", + "version": 925, + "versionNonce": 27208751, + "isDeleted": false, + "id": "sE5xq9Fz5VDTWcJGhJizg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 656.03125, + "y": 313.29799967005374, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 154.05078125, + "height": 8.294130761394001, + "seed": 455209344, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1660298248381, + "link": null, + "locked": false, + "startBinding": { + "elementId": "mDgu1gSg34HbU-NAHPB30", + "focus": 0.08648410639065775, + "gap": 19.65625 + }, + "endBinding": { + "elementId": "ox1Blt2bzl0onmQfB7ZAN", + "focus": 0.08133464876815498, + "gap": 17.6171875 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 154.05078125, + 8.294130761394001 + ] + ] + }, + { + "type": "text", + "version": 709, + "versionNonce": 650449167, + "isDeleted": false, + "id": "Q6P32mRyop5JlKGPB3tei", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 5.552321937284518, + "x": 679.345703125, + "y": 433.1444738051471, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 79, + "height": 15, + "seed": 1091054019, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660298261423, + "link": null, + "locked": false, + "fontSize": 11.542968749999993, + "fontFamily": 1, + "text": "TCP or serial", + "baseline": 10, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "TCP or serial" + }, + { + "type": "text", + "version": 707, + "versionNonce": 1999616833, + "isDeleted": false, + "id": "vETmEnYJoC4MKv7ysqjAv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.06779103263247777, + "x": 683.3417968749999, + "y": 281.21582031250006, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 79, + "height": 15, + "seed": 1043479501, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660298255264, + "link": null, + "locked": false, + "fontSize": 11.542968749999993, + "fontFamily": 1, + "text": "TCP or serial", + "baseline": 10, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "TCP or serial" + }, + { + "type": "rectangle", + "version": 587, + "versionNonce": 85990017, + "isDeleted": false, + "id": "pHhCP3DIU5fE4v3yi3obG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 426.513671875, + "y": 424.2646484375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 216.16406250000006, + "height": 172.06640624999997, + "seed": 1733016847, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "sE5xq9Fz5VDTWcJGhJizg", + "type": "arrow" + }, + { + "id": "HZoAI_wR8CyRR9fVaFwSl", + "type": "arrow" + } + ], + "updated": 1660298157321, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 708, + "versionNonce": 1824105825, + "isDeleted": false, + "id": "3oXICnKHoOzNPyb-PxNbt", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 450.095703125, + "y": 498.0361328125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 80, + "seed": 1378197345, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660298208836, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Measures temperature\nand hygrometry:\n0: 26°C\n1: 40% ", + "baseline": 74, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Measures temperature\nand hygrometry:\n0: 26°C\n1: 40% " + }, + { + "type": "text", + "version": 400, + "versionNonce": 747588289, + "isDeleted": false, + "id": "rD_cbOE0Mwz-sfB0YqcaJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 494.501953125, + "y": 449.6064453125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 88, + "height": 25, + "seed": 68109103, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660298172011, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Sensor 2", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Sensor 2" + }, + { + "type": "arrow", + "version": 1150, + "versionNonce": 1550306895, + "isDeleted": false, + "id": "HZoAI_wR8CyRR9fVaFwSl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 666.49609375, + "y": 532.2655116636315, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 145.8515625, + "height": 133.46442554799017, + "seed": 1409289601, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1660298248381, + "link": null, + "locked": false, + "startBinding": { + "elementId": "pHhCP3DIU5fE4v3yi3obG", + "focus": 0.7718436212944663, + "gap": 23.818359375 + }, + "endBinding": { + "elementId": "ox1Blt2bzl0onmQfB7ZAN", + "focus": 0.28922965891088237, + "gap": 15.3515625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 145.8515625, + -133.46442554799017 + ] + ] + }, + { + "id": "feq5Rn2_gEHIfIzRPvNu6", + "type": "rectangle", + "x": 832.283203125, + "y": 515.0556640625, + "width": 255, + "height": 76.1171875, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 826152751, + "version": 65, + "versionNonce": 19459567, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "n4_rv3VhjyMXLSFrP52Vw" + }, + { + "id": "vJNRjoY0dZcqOBw5RzuHn", + "type": "arrow" + } + ], + "updated": 1660298281790, + "link": null, + "locked": false + }, + { + "id": "n4_rv3VhjyMXLSFrP52Vw", + "type": "text", + "x": 837.283203125, + "y": 540.6142578125, + "width": 245, + "height": 25, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 555916079, + "version": 20, + "versionNonce": 1538604143, + "isDeleted": false, + "boundElements": null, + "updated": 1660298276528, + "link": null, + "locked": false, + "text": "Database or logs", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 18, + "containerId": "feq5Rn2_gEHIfIzRPvNu6", + "originalText": "Database or logs" + }, + { + "id": "vJNRjoY0dZcqOBw5RzuHn", + "type": "arrow", + "x": 958.509765625, + "y": 472.4150390625, + "width": 0, + "height": 39.33984375, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "round", + "seed": 1036508641, + "version": 20, + "versionNonce": 2130978977, + "isDeleted": false, + "boundElements": null, + "updated": 1660298281790, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 39.33984375 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "rjHz2X8U0ZDEyckj_tTSw", + "focus": -0.04979978015075378, + "gap": 25.2548828125 + }, + "endBinding": { + "elementId": "feq5Rn2_gEHIfIzRPvNu6", + "focus": -0.009987745098039217, + "gap": 3.30078125 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/assets/client-sensors.webp b/docs/assets/client-sensors.webp new file mode 100644 index 0000000..c827fb5 --- /dev/null +++ b/docs/assets/client-sensors.webp diff --git a/docs/assets/server-grafana.excalidraw b/docs/assets/server-grafana.excalidraw new file mode 100644 index 0000000..96e48b7 --- /dev/null +++ b/docs/assets/server-grafana.excalidraw @@ -0,0 +1,488 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 938, + "versionNonce": 1589965569, + "isDeleted": false, + "id": "ox1Blt2bzl0onmQfB7ZAN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 471.66796875, + "y": 61.640625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 251.7109375, + "height": 346.86328125, + "seed": 1508024704, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "sE5xq9Fz5VDTWcJGhJizg", + "type": "arrow" + }, + { + "id": "RdDFVItfRo8k8NarDHSp-", + "type": "arrow" + } + ], + "updated": 1660300922199, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1153, + "versionNonce": 977576399, + "isDeleted": false, + "id": "rjHz2X8U0ZDEyckj_tTSw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 498.0234375, + "y": 138.1171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 187, + "height": 240, + "seed": 2100367744, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660300922199, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Collect data from CPU,\nIO and memory with\ntimestamp\n\n0: 0.1 %\n1: 1456 b/s\n2: 4567 b\n3: 1660190233 (time)\n...\n\n100: false (alert)\n", + "baseline": 234, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Collect data from CPU,\nIO and memory with\ntimestamp\n\n0: 0.1 %\n1: 1456 b/s\n2: 4567 b\n3: 1660190233 (time)\n...\n\n100: false (alert)\n" + }, + { + "type": "rectangle", + "version": 772, + "versionNonce": 1558709263, + "isDeleted": false, + "id": "mDgu1gSg34HbU-NAHPB30", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 896.8984375, + "y": 44.853515625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 216.16406250000006, + "height": 172.06640624999997, + "seed": 1336837760, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "sE5xq9Fz5VDTWcJGhJizg", + "type": "arrow" + } + ], + "updated": 1660300917063, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 607, + "versionNonce": 747285039, + "isDeleted": false, + "id": "F6UUk6_B6uALmjxcHLYw4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 964.88671875, + "y": 70.1953125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 84, + "height": 25, + "seed": 354006656, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660300917063, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Grafana", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Grafana" + }, + { + "type": "text", + "version": 556, + "versionNonce": 1932158625, + "isDeleted": false, + "id": "v7q2uvVFHZBvjr-y_ZJKl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 528.5234375, + "y": 89.28515625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 159, + "height": 25, + "seed": 2108436864, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660300922199, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "libmodbus server", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "libmodbus server" + }, + { + "type": "arrow", + "version": 2401, + "versionNonce": 1251011297, + "isDeleted": false, + "id": "sE5xq9Fz5VDTWcJGhJizg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 748.0898437500001, + "y": 161.19331310212854, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 134.5039062499999, + "height": 30.970574872077407, + "seed": 455209344, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1660300922199, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ox1Blt2bzl0onmQfB7ZAN", + "gap": 24.710937500000114, + "focus": -0.19349510698149744 + }, + "endBinding": { + "elementId": "mDgu1gSg34HbU-NAHPB30", + "gap": 14.3046875, + "focus": 0.2600477394392373 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 134.5039062499999, + -30.970574872077407 + ] + ] + }, + { + "type": "text", + "version": 1184, + "versionNonce": 1589324399, + "isDeleted": false, + "id": "Q6P32mRyop5JlKGPB3tei", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 6.077759617018872, + "x": 746.0369822154072, + "y": 102.90361683493032, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 111, + "height": 29, + "seed": 1091054019, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660300917063, + "link": null, + "locked": false, + "fontSize": 11.542968749999993, + "fontFamily": 1, + "text": "TCP read requests\n(polling)", + "baseline": 25, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "TCP read requests\n(polling)" + }, + { + "id": "ViVqW_nxoEJO1DpluuMzF", + "type": "image", + "x": 923.3162172379032, + "y": 116.828369140625, + "width": 163.32850302419354, + "height": 63.289794921875, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "round", + "seed": 953641007, + "version": 332, + "versionNonce": 1122873217, + "isDeleted": false, + "boundElements": null, + "updated": 1660300917064, + "link": null, + "locked": false, + "status": "saved", + "fileId": "fe56123c11422301d020f581b74d4397ab49e99c", + "scale": [ + 1, + 1 + ] + }, + { + "id": "RdDFVItfRo8k8NarDHSp-", + "type": "arrow", + "x": 898.5878906250001, + "y": 340.31123325850484, + "width": 158.6875000000001, + "height": 28.44727928318008, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "round", + "seed": 595270337, + "version": 1096, + "versionNonce": 1842538177, + "isDeleted": false, + "boundElements": null, + "updated": 1660300922199, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -158.6875000000001, + -28.44727928318008 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ro1CNQcmtpkib2r-uhEJo", + "gap": 10.179687499999886, + "focus": -0.37043558235421187 + }, + "endBinding": { + "elementId": "ox1Blt2bzl0onmQfB7ZAN", + "gap": 16.521484375, + "focus": 0.2615821499314503 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "ro1CNQcmtpkib2r-uhEJo", + "type": "rectangle", + "x": 908.767578125, + "y": 248.8369140625, + "width": 216.01953125, + "height": 154, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1261656367, + "version": 298, + "versionNonce": 866798383, + "isDeleted": false, + "boundElements": [ + { + "id": "RdDFVItfRo8k8NarDHSp-", + "type": "arrow" + }, + { + "type": "text", + "id": "zWdPKja_yF9g4yVY1kvXH" + } + ], + "updated": 1660300917064, + "link": null, + "locked": false + }, + { + "id": "zWdPKja_yF9g4yVY1kvXH", + "type": "text", + "x": 913.767578125, + "y": 253.8369140625, + "width": 206, + "height": 75, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 76196961, + "version": 380, + "versionNonce": 1800831809, + "isDeleted": false, + "boundElements": null, + "updated": 1660300917064, + "link": null, + "locked": false, + "text": "\nTriggers alert when\nservice is down", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "baseline": 68, + "containerId": "ro1CNQcmtpkib2r-uhEJo", + "originalText": "\nTriggers alert when\nservice is down" + }, + { + "type": "text", + "version": 1386, + "versionNonce": 2109148495, + "isDeleted": false, + "id": "DZ2rUAdMymO7ajB4Xr_Kf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.17070993938211565, + "x": 774.3998831194928, + "y": 298.59613347989244, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 107, + "height": 15, + "seed": 109244929, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1660300917064, + "link": null, + "locked": false, + "fontSize": 11.542968749999993, + "fontFamily": 1, + "text": "TCP write request", + "baseline": 10, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "TCP write request" + }, + { + "id": "Os6j9M5Ipt4Ay74nFj29L", + "type": "text", + "x": 937.599609375, + "y": 348.8330078125, + "width": 163, + "height": 30, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 577132609, + "version": 307, + "versionNonce": 654734113, + "isDeleted": false, + "boundElements": null, + "updated": 1660300917064, + "link": null, + "locked": false, + "text": "Write True to address 100\non issue", + "fontSize": 12.1, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 26, + "containerId": null, + "originalText": "Write True to address 100\non issue" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": { + "fe56123c11422301d020f581b74d4397ab49e99c": { + "mimeType": "image/jpeg", + "id": "fe56123c11422301d020f581b74d4397ab49e99c", + "dataURL": "data:image/jpeg;base64,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", + "created": 1660300358240 + } + } +} \ No newline at end of file diff --git a/docs/assets/server-grafana.webp b/docs/assets/server-grafana.webp new file mode 100644 index 0000000..636dc3a --- /dev/null +++ b/docs/assets/server-grafana.webp diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..9601cc8 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,263 @@ +# libmodbus + +A featureful and portable Open Source Modbus library. + +## 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 IPv4/IPv6). The + site provides documentation about the [Modbus +Specifications and Implementation Guides](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. + +## Use cases + +The library can be used to write a: + +- **client**, the application reads/writes data from various devices. +- **server**, the application provides data to several clients. + +
+ +
A libmodbus client that reads only the temperatures from sensors.
+
+ +
+ +
A libmodbus server that exposes data to a Grafana service.
+
+ +## Contexts + +The Modbus protocol supports several transport protocols (eg. serial RTU, +Ethernet TCP) called backends in *libmodbus*. + +The first step is to allocate and set a `modbus_t` context according to the +required backend (RTU or TCP) with a dedicated function, such as +[modbus_new_rtu](modbus_new_rtu). +The function will return an opaque structure called `modbus_t` containing all +necessary information to establish a connection with other Modbus devices +according to the selected backend. + +Once this context has been created, you can use use the common API provided by +*libmodbus* to read/write or set the various timeouts. With this common API, +it's easy to switch the backend of your application from RTU to TCP IPv6 for +example. + +### 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). + +The Modbus RTU framing calls a slave, a device/service which handle Modbus +requests, and a master, a client which send requests. The communication is +always initiated by the master. + +Many Modbus devices can be connected together on the same physical link so +before sending a message, you must set the slave (receiver) with +[modbus_set_slave](mobus_set_slave). If you're running a slave, its slave number +will be used to filter received messages. + +The libmodbus implementation of RTU isn't time based as stated in original +Modbus specification, instead all bytes are sent as fast as possible and a +response or an indication is considered complete when all expected characters +have been received. This implementation offers very fast communication but you +must take care to set a response timeout of slaves less than response timeout of +master (ortherwise other slaves may ignore master requests when one of the slave +is not responding). + +To create a Modbus RTU context, you should use [modbus_new_rtu](modbus_new_rtu). + +You can tweak the serial mode with the following functions: + +- [modbus_rtu_get_serial_mode](modbus_rtu_get_serial_mode) +- [modbus_rtu_set_serial_mode](modbus_rtu_set_serial_mode) +- [modbus_rtu_get_rts](modbus_rtu_get_rts) +- [modbus_rtu_set_rts](modbus_rtu_set_rts) +- [modbus_rtu_set_custom_rts](modbus_rtu_set_custom_rts) +- [modbus_rtu_get_rts_delay](modbus_rtu_get_rts_delay) +- [modbus_rtu_set_rts_delay](modbus_rtu_set_rts_delay) + +### 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. + +To create a Modbus TCP context, you should use [modbus_new_tcp](modbus_new_tcp). + +### TCP PI (IPv4 and IPv6) Context + +The TCP PI (Protocol Independent) 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 PI context, you should use [modbus_new_tcp_pi](modbus_new_tcp_pi). + +## Connection + +The following functions are provided to establish and close a connection with +Modbus devices: + +- [modbus_connect](modbus_connect) establishes a connection. +- [modbus_close](modbus_close) closes a connection. +- [modbus_flush](modbus_flush) flushed a connection. + +In RTU, you should define the slave ID of your client with +[modbus_set_slave](modbus_set_slave). + +To analyse the exchanged data, you can enable the debug mode with +[modbus_set_debug](modbus_set_debug). + +Once you have completed the communication or at the end of your program, you +should free the resources with the common function, [modbus_free](modbus_free) + +## Reads and writes from the client + +The Modbus protocol defines different data types and functions to read and write +them from/to remote devices. The following functions are used by the clients to +send Modbus requests: + +To read data: + +- [modbus_read_bits](modbus_read_bits) +- [modbus_read_input_bits](modbus_read_input_bits) +- [modbus_read_registers](modbus_read_registers) +- [modbus_read_input_registers](modbus_read_input_registers) +- [modbus_report_slave_id](modbus_report_slave_id) + +To write data: + +- [modbus_write_bit](modbus_write_bit) +- [modbus_write_register](modbus_write_register) +- [modbus_write_bits](modbus_write_bits) +- [modbus_write_registers](modbus_write_registers) + +To write and read data in a single operation: + +- [modbus_write_and_read_registers](modbus_write_and_read_registers) + +To send and receive low-level requests: + +- [modbus_send_raw_request](modbus_send_raw_request) +- [modbus_receive_confirmation](modbus_receive_confirmation) + +To reply to an exception: + +- [modbus_reply_exception](modbus_reply_exception) + +## Handling requests from server + +The server is waiting for request from clients and must answer when it is +concerned by the request. The libmodbus offers the following functions to +handle requests: + +Data mapping: + +- [modbus_mapping_new](modbus_mapping_new) +- [modbus_mapping_free](modbus_mapping_free) + +Receive: + +- [modbus_receive](modbus_receive) + +Reply: + +- [modbus_reply](modbus_reply) +- [modbus_reply_exception](modbus_reply_exception) + +## Advanced functions + +Timeout settings: + +- [modbus_get_byte_timeout](modbus_get_byte_timeout) +- [modbus_set_byte_timeout](modbus_set_byte_timeout) +- [modbus_get_response_timeout](modbus_get_response_timeout) +- [modbus_set_response_timeout](modbus_set_response_timeout) + +Error recovery mode: + +- [modbus_set_error_recovery](modbus_set_error_recovery) + +Setter/getter of internal socket: + +- [modbus_set_socket](modbus_set_socket) +- [modbus_get_socket](modbus_get_socket) + +Information about header: + +- [modbus_get_header_length](modbus_get_header_length) + +## Data handling + +Macros for data manipulation: + +- `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] + +Handling of bits and bytes: + +- [modbus_set_bits_from_byte](modbus_set_bits_from_byte) +- [modbus_set_bits_from_bytes](modbus_set_bits_from_bytes) +- [modbus_get_byte_from_bits](modbus_get_byte_from_bits) + +Set or get float numbers: + +- [modbus_get_float_abcd](modbus_get_float_abcd) +- [modbus_set_float_abcd](modbus_set_float_abcd) +- [modbus_get_float_badc](modbus_get_float_badc) +- [modbus_set_float_badc](modbus_set_float_badc) +- [modbus_get_float_cdab](modbus_get_float_cdab) +- [modbus_set_float_cdab](modbus_set_float_cdab) +- [modbus_get_float_dcba](modbus_get_float_dcba) +- [modbus_set_float_dcba](modbus_set_float_dcba) +- [modbus_get_float](modbus_get_float) **deprecated** +- [modbus_set_float](modbus_set_float) **deprecated** + +## 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 +[modbus_strerror](modbus_strerror). + +## 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. + +## Copying + +Free use of this software is granted under the terms of the GNU Lesser General +Public License (LGPL v2.1+). For details see the file `COPYING.LESSER` included +with the libmodbus distribution. diff --git a/docs/modbus_close.md b/docs/modbus_close.md new file mode 100644 index 0000000..6fe7606 --- /dev/null +++ b/docs/modbus_close.md @@ -0,0 +1,40 @@ +# modbus_close + +## Name + +modbus_close - close a Modbus connection + +## Synopsis + +```c +void modbus_close(modbus_t *ctx); +``` + +## Description + +The *modbus_close()* function shall close the connection established with the +backend set in the context. + +## Return value + +There is no return value. + +## Example + +```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 + +- [modbus_connect](modbus_connect) diff --git a/docs/modbus_connect.md b/docs/modbus_connect.md new file mode 100644 index 0000000..f3bf5e3 --- /dev/null +++ b/docs/modbus_connect.md @@ -0,0 +1,40 @@ +# modbus_connect + +## Name + +modbus_connect - establish a Modbus connection + +## Synopsis + +```c +int modbus_connect(modbus_t *ctx); +``` + +## Description + +The *modbus_connect()* function shall establish a connection to a Modbus server, +a network or a bus using the context information of libmodbus context given in +argument. + +## Return value + +The 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 + +```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 + +- [modbus_close](modbus_close) diff --git a/docs/modbus_flush.md b/docs/modbus_flush.md new file mode 100644 index 0000000..5a9f09b --- /dev/null +++ b/docs/modbus_flush.md @@ -0,0 +1,21 @@ +# modbus_flush + +## Name + +modbus_flush - flush non-transmitted data + +## Synopsis + +```c +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 function shall return 0 or the number of flushed bytes if +successful. Otherwise it shall return -1 and set errno. diff --git a/docs/modbus_free.md b/docs/modbus_free.md new file mode 100644 index 0000000..816f8d3 --- /dev/null +++ b/docs/modbus_free.md @@ -0,0 +1,19 @@ +# modbus_free + +## Name + +modbus_free - free a libmodbus context + +## Synopsis + +```c +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. diff --git a/docs/modbus_get_byte_from_bits.md b/docs/modbus_get_byte_from_bits.md new file mode 100644 index 0000000..84b4b65 --- /dev/null +++ b/docs/modbus_get_byte_from_bits.md @@ -0,0 +1,26 @@ +# modbus_get_byte_from_bits + +## Name + +modbus_get_byte_from_bits - get the value from many bits + +## Synopsis + +```c +uint8_t modbus_get_byte_from_bits(const uint8_t *src, int index, unsigned int nb_bits); +``` + +## Description + +The *modbus_get_byte_from_bits()* function shall extract a value from many +bits. All `nb_bits` bits from `src` at position `index` will be read as a +single value. To obtain a full byte, set nb_bits to 8. + +## Return value + +The function shall return a byte containing the bits read. + +## See also + +- [modbus_set_bits_from_byte](modbus_set_bits_from_byte) +- [modbus_set_bits_from_bytes](modbus_set_bits_from_bytes) diff --git a/docs/modbus_get_byte_timeout.md b/docs/modbus_get_byte_timeout.md new file mode 100644 index 0000000..04a5732 --- /dev/null +++ b/docs/modbus_get_byte_timeout.md @@ -0,0 +1,38 @@ +# modbus_get_byte_timeout + +## Name + +modbus_get_byte_timeout - get timeout between bytes + +## Synopsis + +```c +int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); +``` + +## Description + +The *modbus_get_byte_timeout()* function shall store the timeout interval +between two consecutive bytes of the same message in the `to_sec` and `to_usec` +arguments. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + +## Example + +```c +uint32_t to_sec; +uint32_t to_usec; + +/* Save original timeout */ +modbus_get_byte_timeout(ctx, &to_sec, &to_usec); +``` + +## See also + +- [modbus_set_byte_timeout](modbus_set_byte_timeout) +- [modbus_get_response_timeout](modbus_get_response_timeout) +- [modbus_set_response_timeout](modbus_set_response_timeout) diff --git a/docs/modbus_get_float.md b/docs/modbus_get_float.md new file mode 100644 index 0000000..8eec560 --- /dev/null +++ b/docs/modbus_get_float.md @@ -0,0 +1,31 @@ +# modbus_get_float + +## Name + +modbus_get_float - get a float value from 2 registers + +## Synopsis + +```c +float modbus_get_float(const uint16_t *src); +``` + +Warning, this function is *deprecated* since libmodbus v3.2.0 and has been +replaced by *modbus_get_float_dcba()*. + +## Description + +The *modbus_get_float()* function shall get a float from 4 bytes in Modbus +format (DCBA byte order). The `src` array must be a pointer on two 16 bits +values, for example, if the first word is set to 0x4465 and the second to +0x229a, the float value will be 916.540649. + +## Return value + +The function shall return a float. + +## See also + +- [modbus_set_float](modbus_set_float) +- [modbus_set_float_dcba](modbus_set_float_dcba) +- [modbus_get_float_dcba](modbus_get_float_dcba) diff --git a/docs/modbus_get_float_abcd.md b/docs/modbus_get_float_abcd.md new file mode 100644 index 0000000..2f21271 --- /dev/null +++ b/docs/modbus_get_float_abcd.md @@ -0,0 +1,29 @@ +# modbus_get_float_abcd + +## Name + +modbus_get_float_abcd - get a float value from 2 registers in ABCD byte order + +## Synopsis + +```c +float modbus_get_float_abcd(const uint16_t *src); +``` + +## Description + +The *modbus_get_float_abcd()* function shall get a float from 4 bytes in usual +Modbus format. The `src` array must be a pointer on two 16 bits values, for +example, if the first word is set to 0x0020 and the second to 0xF147, the float +value will be read as 123456.0. + +## Return value + +The function shall return a float. + +## See also + +- [modbus_set_float_abcd](modbus_set_float_abcd) +- [modbus_get_float_badc](modbus_get_float_badc) +- [modbus_get_float_cdab](modbus_get_float_cdab) +- [modbus_get_float_dcba](modbus_get_float_dcba) diff --git a/docs/modbus_get_float_badc.md b/docs/modbus_get_float_badc.md new file mode 100644 index 0000000..a730e8c --- /dev/null +++ b/docs/modbus_get_float_badc.md @@ -0,0 +1,29 @@ +# modbus_get_float_badc + +## Name + +modbus_get_float_badc - get a float value from 2 registers in BADC byte order + +## Synopsis + +```c +float modbus_get_float_badc(const uint16_t *src); +``` + +## Description + +The *modbus_get_float_badc()* function shall get a float from 4 bytes with +swapped bytes (BADC instead of ABCD). The `src` array must be a pointer on two +16 bits values, for example, if the first word is set to 0x2000 and the second +to 0x47F1, the float value will be read as 123456.0. + +## Return value + +The function shall return a float. + +## See also + +- [modbus_set_float_badc](modbus_set_float_badc) +- [modbus_get_float_abcd](modbus_get_float_abcd) +- [modbus_get_float_cdab](modbus_get_float_cdab) +- [modbus_get_float_dcba](modbus_get_float_dcba) diff --git a/docs/modbus_get_float_cdab.md b/docs/modbus_get_float_cdab.md new file mode 100644 index 0000000..fb4ba35 --- /dev/null +++ b/docs/modbus_get_float_cdab.md @@ -0,0 +1,29 @@ +# modbus_get_float_cdab + +## Name + +modbus_get_float_cdab - get a float value from 2 registers in CDAB byte order + +## Synopsis + +```c +float modbus_get_float_cdab(const uint16_t *src); +``` + +## Description + +The *modbus_get_float_cdab()* function shall get a float from 4 bytes with +swapped words (CDAB order instead of ABCD). The `src` array must be a pointer on +two 16 bits values, for example, if the first word is set to F147 and the second +to 0x0020, the float value will be read as 123456.0. + +## Return value + +The function shall return a float. + +## See also + +- [modbus_set_float_cdab](modbus_set_float_cdab) +- [modbus_get_float_abcd](modbus_get_float_abcd) +- [modbus_get_float_badc](modbus_get_float_badc) +- [modbus_get_float_dcba](modbus_get_float_dcba) diff --git a/docs/modbus_get_float_dcba.md b/docs/modbus_get_float_dcba.md new file mode 100644 index 0000000..0d22c35 --- /dev/null +++ b/docs/modbus_get_float_dcba.md @@ -0,0 +1,29 @@ +# modbus_get_float_dcba + +## Name + +modbus_get_float_dcba - get a float value from 2 registers in DCBA byte order + +## Synopsis + +```c +float modbus_get_float_dcba(const uint16_t *src); +``` + +## Description + +The *modbus_get_float_dcba()* function shall get a float from 4 bytes in +inverted Modbus format (DCBA order instead of ABCD). The `src` array must be a +pointer on two 16 bits values, for example, if the first word is set to 0x47F1 +and the second to 0x2000, the float value will be read as 123456.0. + +## Return value + +The function shall return a float. + +## See also + +- [modbus_set_float_dcba](modbus_set_float_dcba) +- [modbus_get_float_abcd](modbus_get_float_abcd) +- [modbus_get_float_badc](modbus_get_float_badc) +- [modbus_get_float_cdab](modbus_get_float_cdab) diff --git a/docs/modbus_get_header_length.md b/docs/modbus_get_header_length.md new file mode 100644 index 0000000..df1ed66 --- /dev/null +++ b/docs/modbus_get_header_length.md @@ -0,0 +1,21 @@ +# modbus_get_header_length + +## Name + +modbus_get_header_length - retrieve the current header length + +## Synopsis + +```c +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 function is convenient to manipulate a message and +so its limited to low-level operations. + +## Return value + +The header length as integer value. diff --git a/docs/modbus_get_indication_timeout.md b/docs/modbus_get_indication_timeout.md new file mode 100644 index 0000000..11a9f86 --- /dev/null +++ b/docs/modbus_get_indication_timeout.md @@ -0,0 +1,39 @@ +# modbus_get_indication_timeout + +## Name + +modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). + +## Synopsis + +```c +int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); +``` + +## Description + +The *modbus_get_indication_timeout()* function shall store the timeout interval +used to wait for an indication in the `to_sec` and `to_usec` arguments. +Indication is the term used by the Modbus protocol to designate a request +received by the server. + +The default value is zero, it means the server will wait forever. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + +```c +uint32_t to_sec; +uint32_t to_usec; + +/* Save original timeout */ +modbus_get_indication_timeout(ctx, &to_sec, &to_usec); +``` + +## See also + +- [modbus_set_indication_timeout](modbus_set_indication_timeout) +- [modbus_get_response_timeout](modbus_get_response_timeout) +- [modbus_set_response_timeout](modbus_set_response_timeout) diff --git a/docs/modbus_get_response_timeout.md b/docs/modbus_get_response_timeout.md new file mode 100644 index 0000000..93464c2 --- /dev/null +++ b/docs/modbus_get_response_timeout.md @@ -0,0 +1,40 @@ +# modbus_get_response_timeout + +## Name + +modbus_get_response_timeout - get timeout for response + +## Synopsis + +```c +int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); +``` + +## Description + +The *modbus_get_response_timeout()* function shall return the timeout interval +used to wait for a response in the `to_sec` and `to_usec` arguments. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + +Example: + +```c +uint32_t old_response_to_sec; +uint32_t old_response_to_usec; + +/* Save original timeout */ +modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); + +/* Define a new and too short timeout! */ +modbus_set_response_timeout(ctx, 0, 0); +``` + +## See also + +- [modbus_set_response_timeout](modbus_set_response_timeout) +- [modbus_get_byte_timeout](modbus_get_byte_timeout) +- [modbus_set_byte_timeout](modbus_set_byte_timeout) diff --git a/docs/modbus_get_slave.md b/docs/modbus_get_slave.md new file mode 100644 index 0000000..7a5496e --- /dev/null +++ b/docs/modbus_get_slave.md @@ -0,0 +1,29 @@ +# modbus_get_slave + +## Name + +modbus_get_slave - get slave number in the context + +## Synopsis + +```c +int modbus_get_slave(modbus_t *ctx); +``` + +## Description + +The *modbus_get_slave()* function shall get the slave number in the libmodbus +context. + +## Return value + +The function shall return the slave number if successful. Otherwise it shall +return -1 and set errno to one of the values defined below. + +## Errors + +- *EINVAL*, the libmodbus context is undefined. + +## See also + +- [modbus_set_slave](modbus_set_slave) diff --git a/docs/modbus_get_socket.md b/docs/modbus_get_socket.md new file mode 100644 index 0000000..086cff5 --- /dev/null +++ b/docs/modbus_get_socket.md @@ -0,0 +1,25 @@ +# modbus_get_socket + +## Name + +modbus_get_socket - get the current socket of the context + +## Synopsis + +```c +int modbus_get_socket(modbus_t *'ctx'); +``` + +## Description + +The *modbus_get_socket()* function shall return the current socket or file +descriptor of the libmodbus context. + +## Return value + +The function returns the current socket or file descriptor of the context if +successful. Otherwise it shall return -1 and set errno. + +## See also + +- [modbus_set_socket](modbus_set_socket) diff --git a/docs/modbus_mapping_free.md b/docs/modbus_mapping_free.md new file mode 100644 index 0000000..380f618 --- /dev/null +++ b/docs/modbus_mapping_free.md @@ -0,0 +1,24 @@ +# modbus_mapping_free + +## Name + +modbus_mapping_free - free a modbus_mapping_t structure + +## Synopsis + +```c +void modbus_mapping_free(modbus_mapping_t *mb_mapping); +``` + +## Description + +The function shall free the four arrays of mb_mapping_t structure and finally +the mb_mapping_t referenced by `mb_mapping`. + +## Return value + +There is no return values. + +## See also + +- [modbus_mapping_new](modbus_mapping_new) diff --git a/docs/modbus_mapping_new.md b/docs/modbus_mapping_new.md new file mode 100644 index 0000000..fdc11c5 --- /dev/null +++ b/docs/modbus_mapping_new.md @@ -0,0 +1,60 @@ +# modbus_mapping_new + +## Name + +modbus_mapping_new - allocate four arrays of bits and registers + +## Synopsis + +```c +modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits, int nb_registers, int nb_input_registers); +``` + +## Description + +The *modbus_mapping_new()* function shall allocate four arrays to store bits, +input bits, registers and inputs registers. The pointers are stored in +modbus_mapping_t structure. All values of the arrays are initialized to zero. + +This function is equivalent to a call of the +[modbus_mapping_new_start_address](modbus_mapping_new_start_address) function +with all start addresses to `0`. + +If it isn't necessary to allocate an array for a specific type of data, you can +pass the zero value in argument, the associated pointer will be NULL. + +This function is convenient to handle requests in a Modbus server/slave. + +## Return value + +The function shall return the new allocated structure if successful. Otherwise +it shall return NULL and set errno. + +## Errors + +- *ENOMEM*, not enough memory. + +## Example + +```c +/* The first value of each array is accessible from the 0 address. */ +mb_mapping = modbus_mapping_new( + BITS_ADDRESS + BITS_NB, + INPUT_BITS_ADDRESS + INPUT_BITS_NB, + REGISTERS_ADDRESS + REGISTERS_NB, + INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB +); +if (mb_mapping == NULL) { + fprintf( + stderr, "Failed to allocate the mapping: %s\n", + modbus_strerror(errno) + ); + modbus_free(ctx); + return -1; +} +``` + +## See also + +- [modbus_mapping_free](modbus_mapping_free) +- [modbus_mapping_new_start_address](modbus_mapping_new_start_address) diff --git a/docs/modbus_mapping_new_start_address.md b/docs/modbus_mapping_new_start_address.md new file mode 100644 index 0000000..edc267b --- /dev/null +++ b/docs/modbus_mapping_new_start_address.md @@ -0,0 +1,85 @@ +# modbus_mapping_new_start_address + +## Name + +modbus_mapping_new_start_address - allocate four arrays of bits and registers accessible from their starting addresses + +## Synopsis + +```c +modbus_mapping_t* modbus_mapping_new_start_address( + int start_bits, int nb_bits, + int start_input_bits, int nb_input_bits, + int start_registers, int nb_registers, + int start_input_registers, int nb_input_registers); +``` + +## Description + +The `modbus_mapping_new_start_address()` function shall allocate four arrays to +store bits, input bits, registers and inputs registers. The pointers are stored +in modbus_mapping_t structure. All values of the arrays are initialized to zero. + +The different starting addresses make it possible to place the mapping at any +address in each address space. This way, you can give access to the clients at +values stored at high addresses without allocating memory from the address zero, +for eg. to make available registers from 340 to 349, you can use: + +```c +mb_mapping = modbus_mapping_new_start_address(0, 0, 0, 0, 340, 10, 0, 0); +``` + +The newly created `mb_mapping` will have the following arrays: + +- `tab_bits` set to NULL +- `tab_input_bits` set to NULL +- `tab_input_registers` allocated to store 10 registers (`uint16_t`) +- `tab_registers` set to NULL. + +The clients can read the first register by using the address 340 in its request. +On the server side, you should use the first index of the array to set the value +at this client address: + +```c +mb_mapping->tab_registers[0] = 42; +``` + +If it isn't necessary to allocate an array for a specific type of data, you can +pass the zero value in argument, the associated pointer will be NULL. + +This function is convenient to handle requests in a Modbus server/slave. + +## Return value + +The `modbus_mapping_new_start_address()` function shall return the new allocated structure if +successful. Otherwise it shall return NULL and set errno. + +## Errors + +- *ENOMEM*, not enough memory. + +## Example + +```c +/* The first value of each array is accessible at the defined address. +The end address is ADDRESS + NB - 1. */ +mb_mapping = modbus_mapping_new_start_address( + BITS_ADDRESS, BITS_NB, + INPUT_BITS_ADDRESS, INPUT_BITS_NB, + REGISTERS_ADDRESS, REGISTERS_NB, + INPUT_REGISTERS_ADDRESS, INPUT_REGISTERS_NB +); +if (mb_mapping == NULL) { + fprintf( + stderr, "Failed to allocate the mapping: %s\n", + modbus_strerror(errno) + ); + modbus_free(ctx); + return -1; +} +``` + +## See also + +- [modbus_mapping_new](modbus_mapping_new) +- [modbus_mapping_free](modbus_mapping_free) diff --git a/docs/modbus_mask_write_register.md b/docs/modbus_mask_write_register.md new file mode 100644 index 0000000..c6eb60e --- /dev/null +++ b/docs/modbus_mask_write_register.md @@ -0,0 +1,30 @@ +# modbus_mask_write_register + +## Name + +modbus_mask_write_register - mask a single register + +## Synopsis + +```c +int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and, uint16_t or); +``` + +## Description + +The *modbus_mask_write_register()* function shall modify the value of the +holding register at the address 'addr' of the remote device using the algorithm: + + new value = (current value AND 'and') OR ('or' AND (NOT 'and')) + +The function uses the Modbus function code 0x16 (mask single register). + +## Return value + +The function shall return 1 if successful. Otherwise it shall return -1 and set +errno. + +## See also + +- [modbus_read_registers](modbus_read_registers) +- [modbus_write_registers](modbus_write_registers) diff --git a/docs/modbus_new_rtu.md b/docs/modbus_new_rtu.md new file mode 100644 index 0000000..33fd5ec --- /dev/null +++ b/docs/modbus_new_rtu.md @@ -0,0 +1,77 @@ +# modbus_new_rtu + +## Name + +modbus_new_rtu - create a libmodbus context for RTU + +## Synopsis + +```c +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 Windows, 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. + +Once the `modbus_t` structure is initialized, you must set the slave of your +device with [modbus_set_slave](modbus_set_slave) and connect to the serial bus with +[modbus_connect](modbus_connect). + +## Return value + +The 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. +- *ENOMEM*, out of memory. Possibly, the application hits its memory limit + and/or whole system is running out of memory. + +## Example + +```c +modbus_t *ctx; + +ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1); +if (ctx == NULL) { + fprintf(stderr, "Unable to create the libmodbus context\n"); + return -1; +} + +modbus_set_slave(ctx, YOUR_DEVICE_ID); + +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(ctx); + return -1; +} +``` + +## See also + +- [modbus_new_tcp](modbus_new_tcp) +- [modbus_free](modbus_free) diff --git a/docs/modbus_new_tcp.md b/docs/modbus_new_tcp.md new file mode 100644 index 0000000..30ab07f --- /dev/null +++ b/docs/modbus_new_tcp.md @@ -0,0 +1,60 @@ +# modbus_new_tcp + +## Name + +modbus_new_tcp - create a libmodbus context for TCP/IPv4 + +## Synopsis + +```c +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 to establish a connection. A NULL value can be used to listen any addresses in +server mode. + +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 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. +- *ENOMEM*, out of memory. Possibly, the application hits its memory limit + and/or whole system is running out of memory. + +## Example + +```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 + +- [modbus_tcp_listen](modbus_tcp_listen) +- [modbus_free](modbus_free) diff --git a/docs/modbus_new_tcp_pi.md b/docs/modbus_new_tcp_pi.md new file mode 100644 index 0000000..90d4308 --- /dev/null +++ b/docs/modbus_new_tcp_pi.md @@ -0,0 +1,62 @@ +# modbus_new_tcp_pi + +## Name + +modbus_new_tcp_pi - create a libmodbus context for TCP Protocol Independent + +## Synopsis + +```c +*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". A NULL value can be used to +listen any addresses in server mode. + +The `service` argument is the service name/port number to connect to. To use the +default Modbus port, you can provide an NULL value or 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. + +:octicons-tag-24: v3.1.8 handles NULL value for `service` (no *EINVAL* error). + +## Return value + +The 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 + +- *ENOMEM*, out of memory. Possibly, the application hits its memory limit + and/or whole system is running out of memory. + +## Example + +```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 + +- [modbus_new_tcp](modbus_new_tcp) +- [modbus_tcp_pi_listen](modbus_tcp_pi_listen) +- [modbus_free](modbus_free) diff --git a/docs/modbus_read_bits.md b/docs/modbus_read_bits.md new file mode 100644 index 0000000..9e30976 --- /dev/null +++ b/docs/modbus_read_bits.md @@ -0,0 +1,36 @@ +# modbus_read_bits + +## Name + +modbus_read_bits - read many bits + +## Synopsis + +```c +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 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 + +- [modbus_write_bit](modbus_write_bit) +- [modbus_write_bits](modbus_write_bits) diff --git a/docs/modbus_read_input_bits.md b/docs/modbus_read_input_bits.md new file mode 100644 index 0000000..2991cfb --- /dev/null +++ b/docs/modbus_read_input_bits.md @@ -0,0 +1,35 @@ +# modbus_read_input_bits + +## Name + +modbus_read_input_bits - read many input bits + +## Synopsis + +```c +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 0x02 (read input status). + +## Return value + +The 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 + +- [modbus_read_input_registers](modbus_read_input_registers) diff --git a/docs/modbus_read_input_registers.md b/docs/modbus_read_input_registers.md new file mode 100644 index 0000000..3e74a5f --- /dev/null +++ b/docs/modbus_read_input_registers.md @@ -0,0 +1,39 @@ +# modbus_read_input_registers + +## Name + +modbus_read_input_registers - read many input registers + +## Synopsis + +```c +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 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 + +- [modbus_read_input_bits](modbus_read_input_bits) +- [modbus_write_register](modbus_write_register) +- [modbus_write_registers](modbus_write_registers) diff --git a/docs/modbus_read_registers.md b/docs/modbus_read_registers.md new file mode 100644 index 0000000..6150da9 --- /dev/null +++ b/docs/modbus_read_registers.md @@ -0,0 +1,65 @@ +# modbus_read_registers + +## Name + +modbus_read_registers - read many registers + +## Synopsis + +```c +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 function shall return the number of read registers +if successful. Otherwise it shall return -1 and set errno. + +## Errors + +- *EMBMDATA*, too many registers requested. + +## Example + +```c +modbus_t *ctx; +uint16_t tab_reg[64]; +int rc; +int i; + +ctx = modbus_new_tcp("127.0.0.1", 1502); +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(ctx); + return -1; +} + +rc = modbus_read_registers(ctx, 0, 10, tab_reg); +if (rc == -1) { + fprintf(stderr, "%s\n", modbus_strerror(errno)); + return -1; +} + +for (i=0; i < rc; i++) { + printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); +} + +modbus_close(ctx); +modbus_free(ctx); +``` + +## See also + +- [modbus_write_register](modbus_write_register) +- [modbus_write_registers](modbus_write_registers) diff --git a/docs/modbus_receive.md b/docs/modbus_receive.md new file mode 100644 index 0000000..fa3c548 --- /dev/null +++ b/docs/modbus_receive.md @@ -0,0 +1,32 @@ +# modbus_receive + +## Name + +modbus_receive - receive an indication request + +## Synopsis + +```c +int modbus_receive(modbus_t *'ctx', uint8_t *'req'); +``` + +## Description + +The *modbus_receive()* function shall receive an indication request from the +socket of the context `ctx`. This function is used by Modbus slave/server to +receive and analyze indication request sent by the masters/clients. + +If you need to use another socket or file descriptor than the one defined in the +context `ctx`, see the function [modbus_set_socket](modbus_set_socket). + +## Return value + +The function shall store the indication request in `req` and return the request +length if successful. The returned request length can be zero if the indication +request is ignored (eg. a query for another slave in RTU mode). Otherwise it +shall return -1 and set errno. + +## See also + +- [modbus_set_socket](modbus_set_socket) +- [modbus_reply](modbus_reply) diff --git a/docs/modbus_receive_confirmation.md b/docs/modbus_receive_confirmation.md new file mode 100644 index 0000000..700e6c4 --- /dev/null +++ b/docs/modbus_receive_confirmation.md @@ -0,0 +1,43 @@ +# modbus_receive_confirmation + +## Name + +modbus_receive_confirmation - receive a confirmation request + +## Synopsis + +```c +int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp); +``` + +## Description + +The *modbus_receive_confirmation()* function shall receive a request via the +socket of the context `ctx`. This function must be used for debugging purposes +because the received response isn't checked against the initial request. This +function can be used to receive request not handled by the library. + +The maximum size of the response depends on the used backend, in RTU the `rsp` +array must be `MODBUS_RTU_MAX_ADU_LENGTH` bytes and in TCP it must be +`MODBUS_TCP_MAX_ADU_LENGTH` bytes. If you want to write code compatible with +both, you can use the constant `MODBUS_MAX_ADU_LENGTH` (maximum value of all +libmodbus backends). Take care to allocate enough memory to store responses to +avoid crashes of your server. + +## Return value + +The function shall store the confirmation request in `rsp` and return the +response length if successful. The returned request length can be zero if the +indication request is ignored (eg. a query for another slave in RTU +mode). Otherwise it shall return -1 and set errno. + +## Example + +```c +uint8_t rsp[MODBUS_MAX_ADU_LENGTH]; +rc = modbus_receive_confirmation(ctx, rsp); +``` + +## See also + +- [modbus_send_raw_request](modbus_send_raw_request) diff --git a/docs/modbus_reply.md b/docs/modbus_reply.md new file mode 100644 index 0000000..2ca3090 --- /dev/null +++ b/docs/modbus_reply.md @@ -0,0 +1,39 @@ +# modbus_reply + +## Name + +modbus_reply - send a response to the received request + +## Synopsis + +```c +int modbus_reply(modbus_t *ctx, const uint8_t *req, int req_length, modbus_mapping_t *mb_mapping); +``` + +## Description + +The *modbus_reply()* function shall send a response to received request. The +request `req` given in argument is analyzed, a response is then built and sent +by using the information of the modbus context `ctx`. + +If the request indicates to read or write a value the operation will done in the +modbus mapping `mb_mapping` according to the type of the manipulated data. + +If an error occurs, an exception response will be sent. + +This function is designed for Modbus server. + +## Return value + +The function shall return the length of the response sent if +successful. Otherwise it shall return -1 and set errno. + +## Errors + +- *EMBMDATA*, sending has failed + +See also the errors returned by the syscall used to send the response (eg. send or write). + +## See also + +- [modbus_reply_exception](modbus_reply_exception) diff --git a/docs/modbus_reply_exception.md b/docs/modbus_reply_exception.md new file mode 100644 index 0000000..bba24a5 --- /dev/null +++ b/docs/modbus_reply_exception.md @@ -0,0 +1,45 @@ +# modbus_reply_exception + +## Name + +modbus_reply_exception - send an exception response + +## Synopsis + +```c +int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code); +``` + +## Description + +The *modbus_reply_exception()* function shall send an exception response based +on the 'exception_code' in argument. + +The libmodbus provides the following exception codes: + +- MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1) +- MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2) +- MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3) +- MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4) +- MODBUS_EXCEPTION_ACKNOWLEDGE (5) +- MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6) +- MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7) +- MODBUS_EXCEPTION_MEMORY_PARITY (8) +- MODBUS_EXCEPTION_NOT_DEFINED (9) +- MODBUS_EXCEPTION_GATEWAY_PATH (10) +- MODBUS_EXCEPTION_GATEWAY_TARGET (11) + +The initial request `req` is required to build a valid response. + +## Return value + +The function shall return the length of the response sent if +successful. Otherwise it shall return -1 and set errno. + +## Errors + +- *EINVAL*, the exception code is invalid + +## See also + +- [modbus_reply](modbus_reply) diff --git a/docs/modbus_report_slave_id.md b/docs/modbus_report_slave_id.md new file mode 100644 index 0000000..d02c576 --- /dev/null +++ b/docs/modbus_report_slave_id.md @@ -0,0 +1,52 @@ +# modbus_report_slave_id + +## Name + +modbus_report_slave_id - returns a description of the controller + +## Synopsis + +```c +int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest); +``` + +## Description + +The *modbus_report_slave_id()* function shall send a request to the controller +to obtain a description of the controller. + +The response stored in `dest` contains: + +- the slave ID, this unique ID is in reality not unique at all so it's not + possible to depend on it to know how the information are packed in the + response. +- the run indicator status (0x00 = OFF, 0xFF = ON) +- additional data specific to each controller. For example, libmodbus returns + the version of the library as a string. + +The function writes at most `max_dest` bytes from the response to `dest` so +you must ensure that `dest` is large enough. + +## Return value + +The function shall return the number of read data if successful. + +If the output was truncated due to the `max_dest` limit then the return value is +the number of bytes which would have been written to `dest` if enough space had +been available. Thus, a return value greater than `max_dest` means that the +response data was truncated. + +Otherwise it shall return -1 and set errno. + +## Example + +```c +uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH]; + +... + +rc = modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes); +if (rc > 1) { + printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF"); +} +``` diff --git a/docs/modbus_rtu_get_rts.md b/docs/modbus_rtu_get_rts.md new file mode 100644 index 0000000..16b2d53 --- /dev/null +++ b/docs/modbus_rtu_get_rts.md @@ -0,0 +1,35 @@ +# modbus_rtu_get_rts + +## Name + +modbus_rtu_get_rts - get the current RTS mode in RTU + +## Synopsis + +```c +int modbus_rtu_get_rts(modbus_t *ctx); +``` + +## Description + +The *modbus_rtu_get_rts()* function shall get the current Request To Send mode +of the libmodbus context `ctx`. The possible returned values are: + +- `MODBUS_RTU_RTS_NONE` +- `MODBUS_RTU_RTS_UP` +- `MODBUS_RTU_RTS_DOWN` + +This function can only be used with a context using a RTU backend. + +## Return value + +The function shall return the current RTS mode if successful. Otherwise it shall +return -1 and set errno. + +## Errors + +- *EINVAL*, the libmodbus backend is not RTU. + +## See also + +- [modbus_rtu_set_rts](modbus_rtu_set_rts) diff --git a/docs/modbus_rtu_get_rts_delay.md b/docs/modbus_rtu_get_rts_delay.md new file mode 100644 index 0000000..236fecf --- /dev/null +++ b/docs/modbus_rtu_get_rts_delay.md @@ -0,0 +1,31 @@ +# modbus_rtu_get_rts_delay + +## Name + +modbus_rtu_get_rts_delay - get the current RTS delay in RTU + +## Synopsis + +```c +int modbus_rtu_get_rts_delay(modbus_t *ctx); +``` + +## Description + +The `modbus_rtu_get_rts_delay()` function shall get the current Request To Send +delay period of the libmodbus context 'ctx'. + +This function can only be used with a context using a RTU backend. + +## Return value + +The `modbus_rtu_get_rts_delay()` function shall return the current RTS delay in +microseconds if successful. Otherwise it shall return -1 and set errno. + +## Errors + +- *EINVAL*, the libmodbus backend is not RTU. + +## See also + +- [modbus_rtu_set_rts_delay](modbus_rtu_set_rts_delay) diff --git a/docs/modbus_rtu_get_serial_mode.md b/docs/modbus_rtu_get_serial_mode.md new file mode 100644 index 0000000..0715694 --- /dev/null +++ b/docs/modbus_rtu_get_serial_mode.md @@ -0,0 +1,41 @@ +# modbus_rtu_get_serial_mode + +## Name + +modbus_rtu_get_serial_mode - get the current serial mode + +## Synopsis + +```c +int modbus_rtu_get_serial_mode(modbus_t *ctx); +``` + +## Description + +The *modbus_rtu_get_serial_mode()* function shall return the serial mode +currently used by the libmodbus context: + +- **MODBUS_RTU_RS232**, the serial line is set for RS232 communication. RS-232 + (Recommended Standard 232) is the traditional name for a series of standards + for serial binary single-ended data and control signals connecting between a + DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating Equipment). + It is commonly used in computer serial ports + +- **MODBUS_RTU_RS485**, the serial line is set for RS485 communication. EIA-485, + also known as TIA/EIA-485 or RS-485, is a standard defining the electrical + characteristics of drivers and receivers for use in balanced digital + multipoint systems. This standard is widely used for communications in + industrial automation because it can be used effectively over long distances + and in electrically noisy environments. This function is only available on + Linux kernels 2.6.28 onwards and can only be used with a context using a RTU + backend. + +## Return value + +The function shall return `MODBUS_RTU_RS232` or `MODBUS_RTU_RS485` if +successful. Otherwise it shall return -1 and set errno to one of the values +defined below. + +## Errors + +- *EINVAL*, the current libmodbus backend is not RTU. diff --git a/docs/modbus_rtu_set_custom_rts.md b/docs/modbus_rtu_set_custom_rts.md new file mode 100644 index 0000000..9b3230b --- /dev/null +++ b/docs/modbus_rtu_set_custom_rts.md @@ -0,0 +1,32 @@ +# modbus_rtu_set_custom_rts + +## Name + +modbus_rtu_set_custom_rts - set a function to be used for custom RTS implementation + +## Synopsis + +```c +int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)) +``` + +## Description + +The `modbus_rtu_set_custom_rts()` function shall set a custom function to be +called when the RTS pin is to be set before and after a transmission. By default +this is set to an internal function that toggles the RTS pin using an ioctl +call. + +Note that this function adheres to the RTS mode, the values `MODBUS_RTU_RTS_UP` or +`MODBUS_RTU_RTS_DOWN` must be used for the function to be called. + +This function can only be used with a context using a RTU backend. + +## Return value + +The `modbus_rtu_set_custom_rts()` function shall return 0 if successful. +Otherwise it shall return -1 and set errno to one of the values defined below. + +## Errors + +- *EINVAL*, the libmodbus backend is not RTU. diff --git a/doc/modbus_rtu_set_rts.txt b/docs/modbus_rtu_set_rts.md index f746ba4..d903e31 100644 --- a/doc/modbus_rtu_set_rts.txt +++ b/docs/modbus_rtu_set_rts.md @@ -1,19 +1,17 @@ -modbus_rtu_set_rts(3) -===================== +# modbus_rtu_set_rts +## Name -NAME ----- modbus_rtu_set_rts - set the RTS mode in RTU +## Synopsis -SYNOPSIS --------- -*int modbus_rtu_set_rts(modbus_t *'ctx', int 'mode')* +```c +int modbus_rtu_set_rts(modbus_t *ctx, int mode) +``` +## Description -DESCRIPTION ------------ The *modbus_rtu_set_rts()* function shall set the Request To Send mode to communicate on a RS485 serial bus. By default, the mode is set to `MODBUS_RTU_RTS_NONE` and no signal is issued before writing data on the wire. @@ -28,24 +26,20 @@ RTS flag. This function can only be used with a context using a RTU backend. +## Return value -RETURN VALUE ------------- The function shall return 0 if successful. Otherwise it shall return -1 and set errno to one of the values defined below. +## Errors -ERRORS ------- -*EINVAL*:: -The libmodbus backend isn't RTU or the mode given in argument is invalid. +- *EINVAL*, the libmodbus backend isn't RTU or the mode given in argument is invalid. +## Example -EXAMPLE -------- -.Enable the RTS mode with positive polarity -[source,c] -------------------- +Enable the RTS mode with positive polarity: + +```c modbus_t *ctx; uint16_t tab_reg[10]; @@ -68,14 +62,8 @@ if (rc == -1) { modbus_close(ctx); modbus_free(ctx); -------------------- - -SEE ALSO --------- -linkmb:modbus_rtu_get_rts[3] +``` +## See also -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [modbus_rtu_get_rts](modbus_rtu_get_rts) diff --git a/docs/modbus_rtu_set_rts_delay.md b/docs/modbus_rtu_set_rts_delay.md new file mode 100644 index 0000000..3c0cc97 --- /dev/null +++ b/docs/modbus_rtu_set_rts_delay.md @@ -0,0 +1,31 @@ +# modbus_rtu_set_rts_delay + +## Name + +modbus_rtu_set_rts_delay - set the RTS delay in RTU + +## Synopsis + +```c +int modbus_rtu_set_rts_delay(modbus_t *ctx, int us); +``` + +## Description + +The `modbus_rtu_set_rts_delay()` function shall set the Request To Send delay +period of the libmodbus context 'ctx'. + +This function can only be used with a context using a RTU backend. + +## Return value + +The `modbus_rtu_set_rts_delay()` function shall return 0 if successful. +Otherwise it shall return -1 and set errno. + +## Errors + +- *EINVAL*, the libmodbus backend is not RTU or a negative delay was specified. + +## See also + +- [modbus_rtu_get_rts_delay](modbus_rtu_get_rts_delay) diff --git a/docs/modbus_rtu_set_serial_mode.md b/docs/modbus_rtu_set_serial_mode.md new file mode 100644 index 0000000..d20aabd --- /dev/null +++ b/docs/modbus_rtu_set_serial_mode.md @@ -0,0 +1,43 @@ +# modbus_rtu_set_serial_mode + +## Name + +modbus_rtu_set_serial_mode - set the serial mode + +## Synopsis + +```c +int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode); +``` + +## Description + +The *modbus_rtu_set_serial_mode()* function shall set the selected serial +mode: + +- **MODBUS_RTU_RS232**, the serial line is set for RS232 communication. RS-232 + (Recommended Standard 232) is the traditional name for a series of standards + for serial binary single-ended data and control signals connecting between a + DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating Equipment). + It is commonly used in computer serial ports. + +- **MODBUS_RTU_RS485**, the serial line is set for RS485 communication. +EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the +electrical characteristics of drivers and receivers for use in balanced +digital multipoint systems. This standard is widely used for communications +in industrial automation because it can be used effectively over long +distances and in electrically noisy environments. + +This function is only supported on Linux kernels 2.6.28 onwards. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno to one of the values defined below. + +## Errors + +- *EINVAL*, the current libmodbus backend is not RTU. +- *ENOTSUP*, the function is not supported on your platform. + +If the call to `ioctl()` fails, the error code of ioctl will be returned. diff --git a/doc/modbus_send_raw_request.txt b/docs/modbus_send_raw_request.md index 39f836d..99b65b8 100644 --- a/doc/modbus_send_raw_request.txt +++ b/docs/modbus_send_raw_request.md @@ -1,23 +1,21 @@ -modbus_send_raw_request(3) -========================== +# modbus_send_raw_request +## Name -NAME ----- modbus_send_raw_request - send a raw request +## Synopsis -SYNOPSIS --------- -*int modbus_send_raw_request(modbus_t *'ctx', const uint8_t *'raw_req', int 'raw_req_length');* +```c +int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length); +``` +## Description -DESCRIPTION ------------ The *modbus_send_raw_request()* function shall send a request via the socket of -the context _ctx_. This function must be used for debugging purposes because you +the context `ctx`. This function must be used for debugging purposes because you have to take care to make a valid request by hand. The function only adds to the -message, the header or CRC of the selected backend, so _raw_req_ must start and +message, the header or CRC of the selected backend, so `raw_req` must start and contain at least a slave/unit identifier and a function code. This function can be used to send request not handled by the library. @@ -25,18 +23,15 @@ The public header of libmodbus provides a list of supported Modbus functions codes, prefixed by `MODBUS_FC_` (eg. `MODBUS_FC_READ_HOLDING_REGISTERS`), to help build of raw requests. +## Return value -RETURN VALUE ------------- The function shall return the full message length, counting the extra data relating to the backend, if successful. Otherwise it shall return -1 and set errno. +## Example -EXAMPLE -------- -[source,c] -------------------- +```c modbus_t *ctx; /* Read 5 holding registers from address 1 */ uint8_t raw_req[] = { 0xFF, MODBUS_FC_READ_HOLDING_REGISTERS, 0x00, 0x01, 0x0, 0x05 }; @@ -55,14 +50,8 @@ modbus_receive_confirmation(ctx, rsp); modbus_close(ctx); modbus_free(ctx); -------------------- +``` -SEE ALSO --------- -linkmb:modbus_receive_confirmation[3] +## See also - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [modbus_receive_confirmation](modbus_receive_confirmation) diff --git a/docs/modbus_set_bits_from_byte.md b/docs/modbus_set_bits_from_byte.md new file mode 100644 index 0000000..702b9ba --- /dev/null +++ b/docs/modbus_set_bits_from_byte.md @@ -0,0 +1,27 @@ +# modbus_set_bits_from_byte + +## Name + +modbus_set_bits_from_byte - set many bits from a single byte value + + +## Synopsis + +```c +void modbus_set_bits_from_byte(uint8_t *dest, int index, const uint8_t value); +``` + +## Description + +The *modbus_set_bits_from_byte()* function shall set many bits from a single +byte. All 8 bits from the byte `value` will be written to `dest` array starting +at `index` position. + +## Return value + +There is no return values. + +## See also + +- [modbus_set_bits_from_byte](modbus_set_bits_from_byte) +- [modbus_set_bits_from_bytes](modbus_set_bits_from_bytes) diff --git a/docs/modbus_set_bits_from_bytes.md b/docs/modbus_set_bits_from_bytes.md new file mode 100644 index 0000000..2dd0dbd --- /dev/null +++ b/docs/modbus_set_bits_from_bytes.md @@ -0,0 +1,26 @@ +# modbus_set_bits_from_bytes + +## Name + +modbus_set_bits_from_bytes - set many bits from an array of bytes + +## Synopsis + +```c +void modbus_set_bits_from_bytes(uint8_t *dest, int index, unsigned int nb_bits, const uint8_t *tab_byte); +``` + +## Description + +The *modbus_set_bits_from_bytes* function shall set bits by reading an array of +bytes. All the bits of the bytes read from the first position of the array +`tab_byte` are written as bits in the `dest` array starting at position `index`. + +## Return value + +There is no return values. + +## See also + +- [modbus_set_bits_from_byte](modbus_set_bits_from_byte) +- [modbus_get_byte_from_bits](modbus_get_byte_from_bits) diff --git a/docs/modbus_set_byte_timeout.md b/docs/modbus_set_byte_timeout.md new file mode 100644 index 0000000..5bed59d --- /dev/null +++ b/docs/modbus_set_byte_timeout.md @@ -0,0 +1,43 @@ +# modbus_set_byte_timeout + +## Name + +modbus_set_byte_timeout - set timeout between bytes + +## Synopsis + +```c +void modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); +``` + +## Description + +The *modbus_set_byte_timeout()* function shall set the timeout interval between +two consecutive bytes of the same message. The timeout is an upper bound on the +amount of time elapsed before *select()* returns, if the time elapsed is longer +than the defined timeout, an `ETIMEDOUT` error will be raised by the +function waiting for a response. + +The value of `to_usec` argument must be in the range 0 to 999999. + +If both `to_sec` and `to_usec` are zero, this timeout will not be used at all. +In this case, *modbus_set_response_timeout()* governs the entire handling of the +response, the full confirmation response must be received before expiration of +the response timeout. When a byte timeout is set, the response timeout is only +used to wait for until the first byte of the response. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + +## Errors + +- *EINVAL*, The argument `ctx` is NULL or `to_usec` is larger than 999999. + +## See also + +- [modbus_get_byte_timeout](modbus_get_byte_timeout) +- [modbus_get_response_timeout](modbus_get_response_timeout) +- [modbus_set_response_timeout](modbus_set_response_timeout) +w diff --git a/docs/modbus_set_debug.md b/docs/modbus_set_debug.md new file mode 100644 index 0000000..b68a173 --- /dev/null +++ b/docs/modbus_set_debug.md @@ -0,0 +1,29 @@ +# modbus_set_debug + +## Name + +modbus_set_debug - set debug flag of the context + +## Synopsis + +```c +int modbus_set_debug(modbus_t *ctx, int flag); +``` + +## Description + +The *modbus_set_debug()* function shall set the debug flag of the *modbus_t* +context by using the argument `flag`. By default, the boolean flag is set to +`FALSE`. When the `flag` 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. + +```text +[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 + +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. diff --git a/doc/modbus_set_error_recovery.txt b/docs/modbus_set_error_recovery.md index b5fc521..f4e634f 100644 --- a/doc/modbus_set_error_recovery.txt +++ b/docs/modbus_set_error_recovery.md @@ -1,22 +1,20 @@ -modbus_set_error_recovery(3) -============================ +# modbus_set_error_recovery +## Name -NAME ----- modbus_set_error_recovery - set the error recovery mode +## Synopsis -SYNOPSIS --------- -*int modbus_set_error_recovery(modbus_t *'ctx', modbus_error_recovery_mode 'error_recovery');* +```c +int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery); +``` +## Description -DESCRIPTION ------------ The *modbus_set_error_recovery()* function shall set the error recovery mode to apply when the connection fails or the byte received is not expected. The -argument _error_recovery_ may be bitwise-or'ed with zero or more of the +argument `error_recovery` may be bitwise-or'ed with zero or more of the following constants. By default there is no error recovery (`MODBUS_ERROR_RECOVERY_NONE`) so the @@ -42,29 +40,20 @@ The modes are mask values and so they are complementary. It's not recommended to enable error recovery for slave/server. +## Return value -RETURN VALUE ------------- The function shall return 0 if successful. Otherwise it shall return -1 and set errno to one of the values defined below. +## Errors -ERRORS ------- -*EINVAL*:: -The value of the argument _error_recovery_ is not positive. +- *EINVAL*, the value of the argument `error_recovery` is not positive. +## Example -EXAMPLE -------- -[source,c] -------------------- -modbus_set_error_recovery(ctx, - MODBUS_ERROR_RECOVERY_LINK | - MODBUS_ERROR_RECOVERY_PROTOCOL); -------------------- - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +```c +modbus_set_error_recovery( + ctx, + MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL +); +``` diff --git a/docs/modbus_set_float.md b/docs/modbus_set_float.md new file mode 100644 index 0000000..6d5a524 --- /dev/null +++ b/docs/modbus_set_float.md @@ -0,0 +1,29 @@ +# modbus_set_float + +## Name + +modbus_set_float - set a float value from 2 registers + +## Synopsis + +```c +void modbus_set_float(float f, uint16_t *dest); +``` + +Warning, this function is *deprecated* since libmodbus v3.2.0 and has been +replaced by *modbus_set_float_dcba()*. + +## Description + +The *modbus_set_float()* function shall set a float to 4 bytes in Modbus format +(ABCD). The `dest` array must be pointer on two 16 bits values to be able to +store the full result of the conversion. + +## Return value + +There is no return values. + +## See also + +- [modbus_get_float](modbus_get_float) +- [modbus_set_float_dcba](modbus_set_float_dcba) diff --git a/docs/modbus_set_float_abcd.md b/docs/modbus_set_float_abcd.md new file mode 100644 index 0000000..8a3c65a --- /dev/null +++ b/docs/modbus_set_float_abcd.md @@ -0,0 +1,28 @@ +# modbus_set_float_abcd + +## Name + +modbus_set_float_abcd - set a float value in 2 registers using ABCD byte order + +## Synopsis + +```c +void modbus_set_float_abcd(float f, uint16_t *dest); +``` + +## Description + +The *modbus_set_float_abcd()* function shall set a float to 4 bytes in usual +Modbus format. The `dest` array must be pointer on two 16 bits values to be able +to store the full result of the conversion. + +## Return value + +There is no return values. + +## See also + +- [modbus_get_float_abcd](modbus_get_float_abcd) +- [modbus_set_float_badc](modbus_set_float_badc) +- [modbus_set_float_cdab](modbus_set_float_cdab) +- [modbus_set_float_dcba](modbus_set_float_dcba) diff --git a/docs/modbus_set_float_badc.md b/docs/modbus_set_float_badc.md new file mode 100644 index 0000000..e763eec --- /dev/null +++ b/docs/modbus_set_float_badc.md @@ -0,0 +1,28 @@ +# modbus_set_float_badc + +## Name + +modbus_set_float_badc - set a float value in 2 registers using BADC byte order + +## Synopsis + +```c +void modbus_set_float_badc(float f, uint16_t *dest); +``` + +## Description + +The *modbus_set_float_badc()* function shall set a float to 4 bytes in swapped +bytes Modbus format (BADC instead of ABCD). The `dest` array must be pointer on +two 16 bits values to be able to store the full result of the conversion. + +## Return value + +There is no return values. + +## See also + +- [modbus_get_float_badc](modbus_get_float_badc) +- [modbus_set_float_abcd](modbus_set_float_abcd) +- [modbus_set_float_cdab](modbus_set_float_cdab) +- [modbus_set_float_dcba](modbus_set_float_dcba) diff --git a/docs/modbus_set_float_cdab.md b/docs/modbus_set_float_cdab.md new file mode 100644 index 0000000..588dbbf --- /dev/null +++ b/docs/modbus_set_float_cdab.md @@ -0,0 +1,29 @@ +# modbus_set_float_cdab + +## Name + +modbus_set_float_cdab - set a float value in 2 registers using CDAB byte order + +## Synopsis + +```c +void modbus_set_float_cdab(float f, uint16_t *dest); +``` + +## Description + +The *modbus_set_float_cdab()* function shall set a float to 4 bytes in swapped +words Modbus format (CDAB order instead of ABCD). The `dest` array must be +pointer on two 16 bits values to be able to store the full result of the +conversion. + +## Return value + +There is no return values. + +## See also + +- [modbus_get_float_cdab](modbus_get_float_cdab) +- [modbus_set_float_abcd](modbus_set_float_abcd) +- [modbus_set_float_badc](modbus_set_float_badc) +- [modbus_set_float_dcba](modbus_set_float_dcba) diff --git a/docs/modbus_set_float_dcba.md b/docs/modbus_set_float_dcba.md new file mode 100644 index 0000000..04f0d98 --- /dev/null +++ b/docs/modbus_set_float_dcba.md @@ -0,0 +1,27 @@ +# modbus_set_float_dcba + +## Name + +modbus_set_float_dcba - set a float value in 2 registers using DCBA byte order + +## Synopsis + +```c +void modbus_set_float_dcba(float f, uint16_t *dest); +``` + +## Description + +The *modbus_set_float_dcba()* function shall set a float to 4 bytes in inverted +Modbus format (DCBA order). The `dest` array must be pointer on two 16 bits +values to be able to store the full result of the conversion. + +## Return value + +There is no return values. + +## See also + +- [modbus_get_float_dcba](modbus_get_float_dcba) +- [modbus_set_float](modbus_set_float) +- [modbus_get_float](modbus_get_float) diff --git a/docs/modbus_set_indication_timeout.md b/docs/modbus_set_indication_timeout.md new file mode 100644 index 0000000..2fc5c59 --- /dev/null +++ b/docs/modbus_set_indication_timeout.md @@ -0,0 +1,36 @@ +# modbus_set_indication_timeout + +## Name + +modbus_set_indication_timeout - set timeout between indications + +## Synopsis + +```c +void modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); +``` + +## Description + +The *modbus_set_indication_timeout()* function shall set the timeout interval used by +a server to wait for a request from a client. + +The value of `to_usec` argument must be in the range 0 to 999999. + +If both `to_sec` and `to_usec` are zero, this timeout will not be used at all. +In this case, the server will wait forever. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + +## Errors + +- *EINVAL*, the argument `ctx` is NULL or `to_usec` is larger than 1000000. + +## See also + +- [modbus_get_indication_timeout](modbus_get_indication_timeout) +- [modbus_get_response_timeout](modbus_get_response_timeout) +- [modbus_set_response_timeout](modbus_set_response_timeout) diff --git a/docs/modbus_set_response_timeout.md b/docs/modbus_set_response_timeout.md new file mode 100644 index 0000000..8378692 --- /dev/null +++ b/docs/modbus_set_response_timeout.md @@ -0,0 +1,51 @@ +# modbus_set_response_timeout + +## Name + +modbus_set_response_timeout - set timeout for response + +## Synopsis + +```c +int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); +``` + +## Description + +The *modbus_set_response_timeout()* function shall set the timeout interval used +to wait for a response. When a byte timeout is set, if elapsed time for the +first byte of response is longer than the given timeout, an `ETIMEDOUT` error +will be raised by the function waiting for a response. When byte timeout is +disabled, the full confirmation response must be received before expiration of +the response timeout. + +The value of `to_usec` argument must be in the range 0 to 999999. + +## Return value + +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + +## Errors + +- *EINVAL*, the argument `ctx` is NULL, or both `to_sec` and `to_usec` are zero, + or `to_usec` is larger than 999999. + +## Example + +```c +uint32_t old_response_to_sec; +uint32_t old_response_to_usec; + +/* Save original timeout */ +modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); + +/* Define a new timeout of 200ms */ +modbus_set_response_timeout(ctx, 0, 200000); +``` + +## See also + +- [modbus_get_response_timeout](modbus_get_response_timeout) +- [modbus_get_byte_timeout](modbus_get_byte_timeout) +- [modbus_set_byte_timeout](modbus_set_byte_timeout) diff --git a/doc/modbus_set_slave.txt b/docs/modbus_set_slave.md index 7f9ecb0..c79d215 100644 --- a/doc/modbus_set_slave.txt +++ b/docs/modbus_set_slave.md @@ -1,19 +1,17 @@ -modbus_set_slave(3) -=================== +# modbus_set_slave +## Name -NAME ----- modbus_set_slave - set slave number in the context +## Synopsis -SYNOPSIS --------- -*int modbus_set_slave(modbus_t *'ctx', int 'slave');* +```c +int modbus_set_slave(modbus_t *ctx, int slave); +``` +## Description -DESCRIPTION ------------ The *modbus_set_slave()* function shall set the slave number in the libmodbus context. @@ -35,23 +33,18 @@ remote device or software drops the requests! The special 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 -RETURN VALUE ------------- The function shall return 0 if successful. Otherwise it shall return -1 and set errno to one of the values defined below. +## Errors -ERRORS ------- -*EINVAL*:: -The slave number is invalid. +- *EINVAL*, the slave number is invalid. +## Example -EXAMPLE -------- -[source,c] -------------------- +```c modbus_t *ctx; ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1); @@ -72,13 +65,8 @@ if (modbus_connect(ctx) == -1) { modbus_free(ctx); return -1; } -------------------- +``` -SEE ALSO --------- -linkmb:modbus_get_slave[3] +## See also -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [modbus_get_slave](modbus_get_slave) diff --git a/doc/modbus_set_socket.txt b/docs/modbus_set_socket.md index 49e5d1f..8df91a0 100644 --- a/doc/modbus_set_socket.txt +++ b/docs/modbus_set_socket.md @@ -1,33 +1,28 @@ -modbus_set_socket(3) -==================== +# modbus_set_socket +## Name -NAME ----- modbus_set_socket - set socket of the context +## Synopsis -SYNOPSIS --------- -*int modbus_set_socket(modbus_t *'ctx', int 's');* +```c +int modbus_set_socket(modbus_t *ctx, int s); +``` +## Description -DESCRIPTION ------------ The *modbus_set_socket()* function shall set the socket or file descriptor in the libmodbus context. This function is useful for managing multiple client connections to the same server. +## Return value -RETURN VALUE ------------- The function shall return 0 if successful. Otherwise it shall return -1 and set errno. +## Example -EXAMPLE -------- -[source,c] -------------------- +```c ctx = modbus_new_tcp("127.0.0.1", 1502); server_socket = modbus_tcp_listen(ctx, NB_CONNECTION); @@ -43,14 +38,8 @@ if (FD_ISSET(master_socket, &rdset)) { modbus_reply(ctx, query, rc, mb_mapping); } } -------------------- +``` -SEE ALSO --------- -linkmb:modbus_get_socket[3] +## See also - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [modbus_get_socket](modbus_get_socket) diff --git a/docs/modbus_strerror.md b/docs/modbus_strerror.md new file mode 100644 index 0000000..3c65a36 --- /dev/null +++ b/docs/modbus_strerror.md @@ -0,0 +1,39 @@ +# modbus_strerror + +## Name + +modbus_strerror - return the error message + +## Synopsis + +```c +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 + +Display an error message when a Modbus connection cannot be established + +```c +if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + abort(); +} +``` diff --git a/docs/modbus_tcp_accept.md b/docs/modbus_tcp_accept.md new file mode 100644 index 0000000..16f75c8 --- /dev/null +++ b/docs/modbus_tcp_accept.md @@ -0,0 +1,46 @@ +# modbus_tcp_accept + +## Name + +modbus_tcp_accept - accept a new connection on a TCP Modbus socket (IPv4) + +## Synopsis + +```c +int modbus_tcp_accept(modbus_t *ctx, int *s); +``` + +## Description + +The *modbus_tcp_accept()* function shall extract the first connection on the +queue of pending connections, create a new socket and store it in libmodbus +context given in argument. If available, `accept4()` with `SOCK_CLOEXEC` will be +called instead of `accept()`. + +## Return value + +The function shall return a new socket if successful. +Otherwise it shall return -1 and set errno. + +## Example + +For detailed example, see unit-test-server.c source file in tests directory. + +```c +... + +ctx = modbus_new_tcp("127.0.0.1", 502); +s = modbus_tcp_listen(ctx, 1); +modbus_tcp_accept(ctx, &s); + +... + +close(s) +modbus_free(ctx); +``` + +## See also + +- [modbus_tcp_pi_accept](modbus_tcp_pi_accept) +- [modbus_tcp_listen](modbus_tcp_listen) +- [modbus_tcp_pi_listen](modbus_tcp_pi_listen) diff --git a/doc/modbus_tcp_listen.txt b/docs/modbus_tcp_listen.md index 640bbbb..bf090c5 100644 --- a/doc/modbus_tcp_listen.txt +++ b/docs/modbus_tcp_listen.md @@ -1,42 +1,37 @@ -modbus_tcp_listen(3) -==================== +# modbus_tcp_listen +## Name -NAME ----- modbus_tcp_listen - create and listen a TCP Modbus socket (IPv4) -SYNOPSIS --------- -*int modbus_tcp_listen(modbus_t *'ctx', int 'nb_connection');* +## Synopsis +```c +int modbus_tcp_listen(modbus_t *ctx, int nb_connection); +``` + +## Description -DESCRIPTION ------------ The *modbus_tcp_listen()* function shall create a socket and listen to maximum -_nb_connection_ incoming connections on the specified IP address. The context -_ctx _must be allocated and initialized with linkmb:modbus_new_tcp[3] before to +`nb_connection` incoming connections on the specified IP address. The context +`ctx` must be allocated and initialized with [modbus_new_tcp](modbus_new_tcp) before to set the IP address to listen, if IP address is set to NULL or '0.0.0.0', any addresses will be listen. +## Return value -RETURN VALUE ------------- The function shall return a new socket if successful. Otherwise it shall return -1 and set errno. +## Example -EXAMPLE -------- For detailed examples, see source files in tests directory: - unit-test-server.c, simple but handle only one connection - bandwidth-server-many-up.c, handles several connections at once - -[source,c] -------------------- +```c ... /* To listen any addresses on port 502 */ @@ -58,15 +53,10 @@ if (select(server_socket + 1, &refset, NULL, NULL, NULL) == -1) { close(server_socket); modbus_free(ctx); -------------------- - -SEE ALSO --------- -linkmb:modbus_new_tcp[3] -linkmb:modbus_tcp_accept[3] -linkmb:modbus_tcp_pi_listen[3] - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +``` + +## See also + +- [modbus_new_tcp](modbus_new_tcp) +- [modbus_tcp_accept](modbus_tcp_accept) +- [modbus_tcp_pi_listen](modbus_tcp_pi_listen) diff --git a/docs/modbus_tcp_pi_accept.md b/docs/modbus_tcp_pi_accept.md new file mode 100644 index 0000000..6ee0ccb --- /dev/null +++ b/docs/modbus_tcp_pi_accept.md @@ -0,0 +1,46 @@ +# modbus_tcp_pi_accept + +## Name + +modbus_tcp_pi_accept - accept a new connection on a TCP PI Modbus socket (IPv6) + +## Synopsis + +```c +int modbus_tcp_pi_accept(modbus_t *ctx, int *s); +``` + +## Description + +The *modbus_tcp_pi_accept()* function shall extract the first connection on the +queue of pending connections, create a new socket and store it in libmodbus +context given in argument. If available, `accept4()` with `SOCK_CLOEXEC` will be +called instead of `accept()`. + +## Return value + +The function shall return a new socket if successful. +Otherwise it shall return -1 and set errno. + +## Example + +For detailed example, see unit-test-server.c source file in tests directory. + +```c +... + +ctx = modbus_new_tcp_pi("::0", 502); +s = modbus_tcp_pi_listen(ctx, 1); +modbus_tcp_pi_accept(ctx, &s); + +... + +close(s) +modbus_free(ctx); +``` + +## See also + +- [modbus_tcp_pi_accept](modbus_tcp_pi_accept) +- [modbus_tcp_listen](modbus_tcp_listen) +- [modbus_tcp_pi_listen](modbus_tcp_pi_listen) diff --git a/docs/modbus_tcp_pi_listen.md b/docs/modbus_tcp_pi_listen.md new file mode 100644 index 0000000..d832808 --- /dev/null +++ b/docs/modbus_tcp_pi_listen.md @@ -0,0 +1,55 @@ +# modbus_tcp_pi_listen + +## Name + +modbus_tcp_pi_listen - create and listen a TCP PI Modbus socket (IPv6) + +## Synopsis + +```c +int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection); +``` + +## Description + +The *modbus_tcp_pi_listen()* function shall create a socket and listen to +maximum `nb_connection` incoming connections on the specified nodes. The +context *ctx* must be allocated and initialized with [modbus_new_tcp_pi](modbus_new_tcp_pi) +before to set the node to listen, if node is set to NULL or '0.0.0.0', any addresses will be +listen. + +## Return value + +The function shall return a new socket if successful. Otherwise it shall return +-1 and set errno. + +## Example + +For detailed examples, see source files in tests directory: + +- unit-test-server.c, simple but handle only one connection + +```c +... + +ctx = modbus_new_tcp_pi("::0", "502"); +s = modbus_tcp_pi_listen(ctx, 1); +modbus_tcp_pi_accept(ctx, &s); + +for (;;) { + rc = modbus_receive(ctx, query); + modbus_replay(ctx, query, rc, mb_mapping); +} +... + +modbus_close(s); +modbus_free(ctx); +``` + +- bandwidth-server-many-up.c, handles several connections at once + +## See also + +- [modbus_new_tcp_pi](modbus_new_tcp_pi) +- [modbus_tcp_pi_accept](modbus_tcp_pi_accept) +- [modbus_tcp_listen](modbus_tcp_listen) diff --git a/docs/modbus_write_and_read_registers.md b/docs/modbus_write_and_read_registers.md new file mode 100644 index 0000000..143cd54 --- /dev/null +++ b/docs/modbus_write_and_read_registers.md @@ -0,0 +1,43 @@ +# modbus_write_and_read_registers + +## Name + +modbus_write_and_read_registers - write and read many registers in a single transaction + +## Synopsis + +```c +int modbus_write_and_read_registers( + modbus_t *ctx, + int write_addr, int write_nb, const uint16_t *src, + int read_addr, int read_nb, const uint16_t *dest +); +``` + +## Description + +The *modbus_write_and_read_registers()* function shall write the content of the +`write_nb` holding registers from the array 'src' to the address `write_addr` of +the remote device then shall read the content of the `read_nb` holding registers +to the address `read_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 0x17 (write/read registers). + +## Return value + +The function shall return the number of read registers if successful. Otherwise +it shall return -1 and set errno. + +## Errors + +- *EMBMDATA*, too many registers requested, Too many registers to write + +## See also + +- [modbus_read_registers](modbus_read_registers) +- [modbus_write_register](modbus_write_register) +- [modbus_write_registers](modbus_write_registers) diff --git a/docs/modbus_write_bit.md b/docs/modbus_write_bit.md new file mode 100644 index 0000000..232534a --- /dev/null +++ b/docs/modbus_write_bit.md @@ -0,0 +1,28 @@ +# modbus_write_bit + +## Name + +modbus_write_bit - write a single bit + +## Synopsis + +```c +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 function shall return 1 if successful. Otherwise it shall return -1 and set +errno. + +## See also + +- [modbus_read_bits](modbus_read_bits) +- [modbus_write_bits](modbus_write_bits) diff --git a/docs/modbus_write_bits.md b/docs/modbus_write_bits.md new file mode 100644 index 0000000..34beb98 --- /dev/null +++ b/docs/modbus_write_bits.md @@ -0,0 +1,33 @@ +# modbus_write_bits + +## Name + +modbus_write_bits - write many bits + +## Synopsis + +```c +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 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 + +- [modbus_read_bits](modbus_read_bits) +- [modbus_write_bit](modbus_write_bit) diff --git a/docs/modbus_write_register.md b/docs/modbus_write_register.md new file mode 100644 index 0000000..bf66c8e --- /dev/null +++ b/docs/modbus_write_register.md @@ -0,0 +1,28 @@ +# modbus_write_register + +## Name + +modbus_write_register - write a single register + +## Synopsis + +```c +int modbus_write_register(modbus_t *ctx, int addr, const uint16_t 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 function shall return 1 if successful. Otherwise it shall return -1 and set +errno. + +## See also + +- [modbus_read_registers](modbus_read_registers) +- [modbus_write_registers](modbus_write_registers) diff --git a/docs/modbus_write_registers.md b/docs/modbus_write_registers.md new file mode 100644 index 0000000..a89f22c --- /dev/null +++ b/docs/modbus_write_registers.md @@ -0,0 +1,28 @@ +# modbus_write_registers + +## Name + +modbus_write_registers - write many registers + +## Synopsis + +```c +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 function shall return the number of written registers if +successful. Otherwise it shall return -1 and set errno. + +## See also + +- [modbus_write_register](modbus_write_register) +- [modbus_read_registers](modbus_read_registers) diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..61358fd --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,17 @@ +site_name: libmodbus + +theme: + name: material + font: false + +markdown_extensions: + - md_in_html + - attr_list + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg