diff --git a/.gitignore b/.gitignore index b3c7d9632..8c04291ec 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 b46f2e44d..7495eadaf 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 905288921..ad341470b 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 cc1482d4f..202135e53 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 56bbf1ab3..89f0c19db 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 47c797135..000000000 --- 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 a90a75e6b..ad26abd24 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 08eba6d6d..000000000 --- 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 39e67e441..000000000 --- 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 716c684aa..000000000 --- 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_free.txt b/doc/modbus_free.txt deleted file mode 100644 index f7b12f070..000000000 --- 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 e0828f1a6..000000000 --- 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 d7ba0704e..000000000 --- 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 023c0bb50..000000000 --- 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 6a491b29f..000000000 --- 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 317770d47..000000000 --- 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 82261b726..000000000 --- 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 cd98a048c..000000000 --- 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 79f7cd96d..000000000 --- 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 3af39d9cd..000000000 --- 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 33558022c..000000000 --- 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 89e2ac019..000000000 --- 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 8645fa4e2..000000000 --- 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 0a99f6233..000000000 --- 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 71cde1d63..000000000 --- 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 0eaaa8ee2..000000000 --- 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 7365503ca..000000000 --- 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 7a8eaacf3..000000000 --- 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_pi.txt b/doc/modbus_new_tcp_pi.txt deleted file mode 100644 index 494c49382..000000000 --- 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 1e7fd1e0f..000000000 --- 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 d7fd3e0a7..000000000 --- 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 20a537672..000000000 --- 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_receive.txt b/doc/modbus_receive.txt deleted file mode 100644 index 460d19b75..000000000 --- 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_reply.txt b/doc/modbus_reply.txt deleted file mode 100644 index 6b71d11c2..000000000 --- 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 b2170be3b..000000000 --- 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 6aedec679..000000000 --- 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 559c80b6e..000000000 --- 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 43853d453..000000000 --- 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 b58072836..000000000 --- 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 c17bd3d1f..000000000 --- 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 39af7df3e..000000000 --- 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 7086dc4a8..000000000 --- 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 72b2949cb..000000000 --- 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 cfbb8ed46..000000000 --- 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_float.txt b/doc/modbus_set_float.txt deleted file mode 100644 index f12402283..000000000 --- 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 386cbef54..000000000 --- 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 d41d777d7..000000000 --- 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 3a0372570..000000000 --- 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 578ae6f64..000000000 --- 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 6524bdc57..000000000 --- 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_write_and_read_registers.txt b/doc/modbus_write_and_read_registers.txt deleted file mode 100644 index e9b14bd4a..000000000 --- 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 3b4df9e30..000000000 --- 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 7f1af8488..000000000 --- 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 781b3af47..000000000 --- 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 a5654fb98..000000000 --- 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 000000000..bb8eba605 --- /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 000000000..c827fb51b Binary files /dev/null and b/docs/assets/client-sensors.webp differ diff --git a/docs/assets/server-grafana.excalidraw b/docs/assets/server-grafana.excalidraw new file mode 100644 index 000000000..96e48b7ca --- /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 000000000..636dc3a6f Binary files /dev/null and b/docs/assets/server-grafana.webp differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..9601cc826 --- /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/doc/modbus_close.txt b/docs/modbus_close.md similarity index 53% rename from doc/modbus_close.txt rename to docs/modbus_close.md index 5a0afc0fd..6fe760666 100644 --- a/doc/modbus_close.txt +++ b/docs/modbus_close.md @@ -1,32 +1,27 @@ -modbus_close(3) -=============== +# modbus_close +## Name -NAME ----- modbus_close - close a Modbus connection +## Synopsis -SYNOPSIS --------- -*void modbus_close(modbus_t *'ctx');* +```c +void modbus_close(modbus_t *ctx); +``` +## Description -DESCRIPTION ------------ The *modbus_close()* function shall close the connection established with the backend set in the context. +## Return value -RETURN VALUE ------------- There is no return value. +## Example -EXAMPLE -------- -[source,c] -------------------- +```c modbus_t *ctx; ctx = modbus_new_tcp("127.0.0.1", 502); @@ -38,14 +33,8 @@ if (modbus_connect(ctx) == -1) { modbus_close(ctx); modbus_free(ctx); -------------------- +``` -SEE ALSO --------- -linkmb:modbus_connect[3] +## See also - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [modbus_connect](modbus_connect) diff --git a/doc/modbus_connect.txt b/docs/modbus_connect.md similarity index 61% rename from doc/modbus_connect.txt rename to docs/modbus_connect.md index a4437ec96..f3bf5e3f1 100644 --- a/doc/modbus_connect.txt +++ b/docs/modbus_connect.md @@ -1,35 +1,30 @@ -modbus_connect(3) -================= +# modbus_connect +## Name -NAME ----- modbus_connect - establish a Modbus connection +## Synopsis -SYNOPSIS --------- -*int modbus_connect(modbus_t *'ctx');* +```c +int modbus_connect(modbus_t *ctx); +``` +## Description -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 -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 -EXAMPLE -------- -[source,c] -------------------- +```c modbus_t *ctx; ctx = modbus_new_tcp("127.0.0.1", 502); @@ -38,15 +33,8 @@ if (modbus_connect(ctx) == -1) { modbus_free(ctx); return -1; } -------------------- +``` +## See also -SEE ALSO --------- -linkmb:modbus_close[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [modbus_close](modbus_close) diff --git a/doc/modbus_flush.txt b/docs/modbus_flush.md similarity index 54% rename from doc/modbus_flush.txt rename to docs/modbus_flush.md index f4f9b166c..5a9f09be6 100644 --- a/doc/modbus_flush.txt +++ b/docs/modbus_flush.md @@ -1,30 +1,21 @@ -modbus_flush(3) -=============== +# modbus_flush +## Name -NAME ----- modbus_flush - flush non-transmitted data +## Synopsis -SYNOPSIS --------- -*int modbus_flush(modbus_t *'ctx');* +```c +int modbus_flush(modbus_t *ctx); +``` +## Description -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 -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/docs/modbus_free.md b/docs/modbus_free.md new file mode 100644 index 000000000..816f8d306 --- /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 000000000..84b4b6500 --- /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 000000000..04a5732cb --- /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 000000000..8eec56043 --- /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 000000000..2f21271ce --- /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 000000000..a730e8cfd --- /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 000000000..fb4ba3550 --- /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 000000000..0d22c352c --- /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 000000000..df1ed6669 --- /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 000000000..11a9f866c --- /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 000000000..93464c221 --- /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 000000000..7a5496e0f --- /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 000000000..086cff5c0 --- /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 000000000..380f618be --- /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 000000000..fdc11c560 --- /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 000000000..edc267bc4 --- /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 000000000..c6eb60e9f --- /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 000000000..33fd5ec67 --- /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/doc/modbus_new_tcp.txt b/docs/modbus_new_tcp.md similarity index 57% rename from doc/modbus_new_tcp.txt rename to docs/modbus_new_tcp.md index 5447aa63a..30ab07f52 100644 --- a/doc/modbus_new_tcp.txt +++ b/docs/modbus_new_tcp.md @@ -1,53 +1,44 @@ -modbus_new_tcp(3) -================= +# modbus_new_tcp +## Name -NAME ----- modbus_new_tcp - create a libmodbus context for TCP/IPv4 +## Synopsis -SYNOPSIS --------- -*modbus_t *modbus_new_tcp(const char *'ip', int 'port');* +```c +modbus_t *modbus_new_tcp(const char *ip, int port); +``` +## Description -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 +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 +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 -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 -ERRORS ------- -*EINVAL*:: -An invalid IP address was given. +- *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. -*ENOMEM*:: -Out of memory. Possibly, the application hits its memory limit and/or whole -system is running out of memory. +## Example - -EXAMPLE -------- -[source,c] -------------------- +```c modbus_t *ctx; ctx = modbus_new_tcp("127.0.0.1", 1502); @@ -61,15 +52,9 @@ if (modbus_connect(ctx) == -1) { modbus_free(ctx); return -1; } -------------------- - -SEE ALSO --------- -linkmb:modbus_tcp_listen[3] -linkmb:modbus_free[3] +``` +## See also -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [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 000000000..90d430872 --- /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 000000000..9e30976c5 --- /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 000000000..2991cfb0e --- /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 000000000..3e74a5fb9 --- /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/doc/modbus_read_registers.txt b/docs/modbus_read_registers.md similarity index 55% rename from doc/modbus_read_registers.txt rename to docs/modbus_read_registers.md index dd29fdcd7..6150da924 100644 --- a/doc/modbus_read_registers.txt +++ b/docs/modbus_read_registers.md @@ -1,45 +1,38 @@ -modbus_read_registers(3) -======================== +# modbus_read_registers +## Name -NAME ----- modbus_read_registers - read many registers +## Synopsis -SYNOPSIS --------- -*int modbus_read_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest');* +```c +int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); +``` +## Description -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). +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)). +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 -RETURN VALUE ------------- The function shall return the number of read registers if successful. Otherwise it shall return -1 and set errno. +## Errors -ERRORS ------- -*EMBMDATA*:: -Too many registers requested +- *EMBMDATA*, too many registers requested. +## Example -EXAMPLE -------- -[source,c] -------------------- +```c modbus_t *ctx; uint16_t tab_reg[64]; int rc; @@ -64,16 +57,9 @@ for (i=0; i < rc; i++) { modbus_close(ctx); modbus_free(ctx); -------------------- +``` +## See also -SEE ALSO --------- -linkmb:modbus_write_register[3] -linkmb:modbus_write_registers[3] - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [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 000000000..fa3c54846 --- /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/doc/modbus_receive_confirmation.txt b/docs/modbus_receive_confirmation.md similarity index 51% rename from doc/modbus_receive_confirmation.txt rename to docs/modbus_receive_confirmation.md index 290d1f6ac..700e6c40b 100644 --- a/doc/modbus_receive_confirmation.txt +++ b/docs/modbus_receive_confirmation.md @@ -1,53 +1,43 @@ -modbus_receive_confirmation(3) -============================== +# modbus_receive_confirmation +## Name -NAME ----- modbus_receive_confirmation - receive a confirmation request +## Synopsis -SYNOPSIS --------- -*int modbus_receive_confirmation(modbus_t *'ctx', uint8_t *'rsp');* +```c +int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp); +``` +## Description -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 +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 +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 -RETURN VALUE ------------- -The function shall store the confirmation request in _rsp_ and return the +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] -------------------- +## Example + +```c uint8_t rsp[MODBUS_MAX_ADU_LENGTH]; rc = modbus_receive_confirmation(ctx, rsp); -------------------- - -SEE ALSO --------- -linkmb:modbus_send_raw_request[3] +``` +## See also -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +- [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 000000000..2ca3090b7 --- /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 000000000..bba24a5c0 --- /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 000000000..d02c57648 --- /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 000000000..16b2d5374 --- /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 000000000..236fecf81 --- /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 000000000..0715694fa --- /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 000000000..9b3230b54 --- /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 similarity index 73% rename from doc/modbus_rtu_set_rts.txt rename to docs/modbus_rtu_set_rts.md index f746ba457..d903e31fb 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 000000000..3c0cc9736 --- /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 000000000..d20aabd2c --- /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 similarity index 68% rename from doc/modbus_send_raw_request.txt rename to docs/modbus_send_raw_request.md index 39f836d28..99b65b8ff 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 000000000..702b9ba76 --- /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 000000000..2dd0dbde7 --- /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/doc/modbus_set_byte_timeout.txt b/docs/modbus_set_byte_timeout.md similarity index 54% rename from doc/modbus_set_byte_timeout.txt rename to docs/modbus_set_byte_timeout.md index 86c644c1e..5bed59d97 100644 --- a/doc/modbus_set_byte_timeout.txt +++ b/docs/modbus_set_byte_timeout.md @@ -1,54 +1,43 @@ -modbus_set_byte_timeout(3) -========================== +# modbus_set_byte_timeout +## Name -NAME ----- modbus_set_byte_timeout - set timeout between bytes +## Synopsis -SYNOPSIS --------- -*void modbus_set_byte_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* +```c +void modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); +``` +## Description -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. +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. +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 -RETURN VALUE ------------- The function shall return 0 if successful. Otherwise it shall return -1 and set errno. +## Errors -ERRORS ------- -*EINVAL*:: -The argument _ctx_ is NULL or _to_usec_ is larger than 999999. +- *EINVAL*, The argument `ctx` is NULL or `to_usec` is larger than 999999. +## See also -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 - +- [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/doc/modbus_set_debug.txt b/docs/modbus_set_debug.md similarity index 51% rename from doc/modbus_set_debug.txt rename to docs/modbus_set_debug.md index 3154c2199..b68a17377 100644 --- a/doc/modbus_set_debug.txt +++ b/docs/modbus_set_debug.md @@ -1,38 +1,29 @@ -modbus_set_debug(3) -=================== +# modbus_set_debug + +## Name -NAME ----- modbus_set_debug - set debug flag of the context +## Synopsis -SYNOPSIS --------- -*int modbus_set_debug(modbus_t *'ctx', int 'flag');* +```c +int modbus_set_debug(modbus_t *ctx, int flag); +``` +## Description -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 +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] -___________________ +```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 -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_error_recovery.txt b/docs/modbus_set_error_recovery.md similarity index 70% rename from doc/modbus_set_error_recovery.txt rename to docs/modbus_set_error_recovery.md index b5fc521c2..f4e634f41 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 000000000..6d5a52437 --- /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 000000000..8a3c65af7 --- /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 000000000..e763eecc0 --- /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 000000000..588dbbfdb --- /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 000000000..04f0d98ef --- /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 000000000..2fc5c591b --- /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/doc/modbus_set_response_timeout.txt b/docs/modbus_set_response_timeout.md similarity index 53% rename from doc/modbus_set_response_timeout.txt rename to docs/modbus_set_response_timeout.md index e99e38c14..8378692fd 100644 --- a/doc/modbus_set_response_timeout.txt +++ b/docs/modbus_set_response_timeout.md @@ -1,19 +1,17 @@ -modbus_set_response_timeout(3) -============================== +# modbus_set_response_timeout +## Name -NAME ----- modbus_set_response_timeout - set timeout for response +## Synopsis -SYNOPSIS --------- -*int modbus_set_response_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* +```c +int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); +``` +## Description -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 @@ -21,26 +19,21 @@ 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. +The value of `to_usec` argument must be in the range 0 to 999999. +## Return value -RETURN VALUE ------------- The function shall return 0 if successful. Otherwise it shall return -1 and set errno. +## Errors -ERRORS ------- -*EINVAL*:: -The argument _ctx_ is NULL, or both _to_sec_ and _to_usec_ are zero, or _to_usec_ -is larger than 999999. +- *EINVAL*, the argument `ctx` is NULL, or both `to_sec` and `to_usec` are zero, + or `to_usec` is larger than 999999. +## Example -EXAMPLE -------- -[source,c] -------------------- +```c uint32_t old_response_to_sec; uint32_t old_response_to_usec; @@ -49,17 +42,10 @@ 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 -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 - +- [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 similarity index 78% rename from doc/modbus_set_slave.txt rename to docs/modbus_set_slave.md index 7f9ecb099..c79d21502 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 similarity index 63% rename from doc/modbus_set_socket.txt rename to docs/modbus_set_socket.md index 49e5d1ff0..8df91a015 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/doc/modbus_strerror.txt b/docs/modbus_strerror.md similarity index 50% rename from doc/modbus_strerror.txt rename to docs/modbus_strerror.md index 9cc355f1a..3c65a366e 100644 --- a/doc/modbus_strerror.txt +++ b/docs/modbus_strerror.md @@ -1,54 +1,39 @@ -modbus_strerror(3) -================= +# modbus_strerror +## Name -NAME ----- modbus_strerror - return the error message +## Synopsis -SYNOPSIS --------- -*const char *modbus_strerror(int 'errnum');* +```c +const char *modbus_strerror(int errnum); +``` +## Description -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 +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 -RETURN VALUE ------------- The *modbus_strerror()* function shall return a pointer to an error message string. +## Errors -ERRORS ------- No errors are defined. +## Example -EXAMPLE -------- -.Display an error message when a Modbus connection cannot be established -[source,c] -------------------- +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(); } -------------------- - -SEE ALSO --------- -linkmb:libmodbus - - -AUTHORS -------- -The libmodbus documentation was written by Stéphane Raimbault - +``` diff --git a/doc/modbus_tcp_accept.txt b/docs/modbus_tcp_accept.md similarity index 50% rename from doc/modbus_tcp_accept.txt rename to docs/modbus_tcp_accept.md index 4c46d9079..16f75c857 100644 --- a/doc/modbus_tcp_accept.txt +++ b/docs/modbus_tcp_accept.md @@ -1,37 +1,32 @@ -modbus_tcp_accept(3) -==================== +# modbus_tcp_accept +## Name -NAME ----- modbus_tcp_accept - accept a new connection on a TCP Modbus socket (IPv4) +## Synopsis -SYNOPSIS --------- -*int modbus_tcp_accept(modbus_t *'ctx', int *'s);* +```c +int modbus_tcp_accept(modbus_t *ctx, int *s); +``` +## Description -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()*. +context given in argument. If available, `accept4()` with `SOCK_CLOEXEC` will be +called instead of `accept()`. +## 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 example, see unit-test-server.c source file in tests directory. -[source,c] -------------------- +```c ... ctx = modbus_new_tcp("127.0.0.1", 502); @@ -42,15 +37,10 @@ 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 - +``` + +## 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 similarity index 61% rename from doc/modbus_tcp_listen.txt rename to docs/modbus_tcp_listen.md index 640bbbbfe..bf090c5cd 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/doc/modbus_tcp_pi_accept.txt b/docs/modbus_tcp_pi_accept.md similarity index 50% rename from doc/modbus_tcp_pi_accept.txt rename to docs/modbus_tcp_pi_accept.md index a84dc43df..6ee0ccb95 100644 --- a/doc/modbus_tcp_pi_accept.txt +++ b/docs/modbus_tcp_pi_accept.md @@ -1,37 +1,32 @@ -modbus_tcp_pi_accept(3) -======================= +# modbus_tcp_pi_accept +## Name -NAME ----- modbus_tcp_pi_accept - accept a new connection on a TCP PI Modbus socket (IPv6) +## Synopsis -SYNOPSIS --------- -*int modbus_tcp_pi_accept(modbus_t *'ctx', int *'s);* +```c +int modbus_tcp_pi_accept(modbus_t *ctx, int *s); +``` +## Description -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()*. +context given in argument. If available, `accept4()` with `SOCK_CLOEXEC` will be +called instead of `accept()`. +## 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 example, see unit-test-server.c source file in tests directory. -[source,c] -------------------- +```c ... ctx = modbus_new_tcp_pi("::0", 502); @@ -42,15 +37,10 @@ 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 - +``` + +## 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_pi_listen.txt b/docs/modbus_tcp_pi_listen.md similarity index 55% rename from doc/modbus_tcp_pi_listen.txt rename to docs/modbus_tcp_pi_listen.md index 2a501ee6c..d83280805 100644 --- a/doc/modbus_tcp_pi_listen.txt +++ b/docs/modbus_tcp_pi_listen.md @@ -1,41 +1,35 @@ -modbus_tcp_pi_listen(3) -======================= +# modbus_tcp_pi_listen +## Name -NAME ----- modbus_tcp_pi_listen - create and listen a TCP PI Modbus socket (IPv6) +## Synopsis -SYNOPSIS --------- -*int modbus_tcp_pi_listen(modbus_t *'ctx', int 'nb_connection');* +```c +int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection); +``` +## Description -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] +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 -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 -[source,c] -------------------- +```c ... ctx = modbus_new_tcp_pi("::0", "502"); @@ -48,20 +42,14 @@ for (;;) { } ... -mclose(s); +modbus_close(s); modbus_free(ctx); -------------------- +``` - bandwidth-server-many-up.c, handles several connections at once +## See also -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 - +- [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 000000000..143cd54b0 --- /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 000000000..232534a98 --- /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 000000000..34beb98ae --- /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 000000000..bf66c8e08 --- /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 000000000..a89f22c3f --- /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 000000000..61358fda1 --- /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