├── .gitignore ├── BUILD ├── Doxyfile ├── INSTALL ├── README.md ├── WORKSPACE ├── __init__.py ├── boost.BUILD ├── contrib ├── __init__.py ├── emulation_driver.py ├── libmodbus │ ├── .dir-locals.el │ ├── .gitignore │ ├── .travis.yml │ ├── AUTHORS │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── COPYING.LESSER │ ├── ISSUE_TEMPLATE.md │ ├── MIGRATION │ ├── Makefile.am │ ├── NEWS │ ├── README.md │ ├── acinclude.m4 │ ├── autogen.sh │ ├── configure.ac │ ├── doc │ │ ├── Makefile.am │ │ ├── asciidoc.conf │ │ ├── libmodbus.txt │ │ ├── modbus_close.txt │ │ ├── modbus_connect.txt │ │ ├── modbus_flush.txt │ │ ├── modbus_free.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_indication_timeout.txt │ │ ├── modbus_get_response_timeout.txt │ │ ├── modbus_get_slave.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.txt │ │ ├── modbus_new_tcp_pi.txt │ │ ├── modbus_read_bits.txt │ │ ├── modbus_read_input_bits.txt │ │ ├── modbus_read_input_registers.txt │ │ ├── modbus_read_registers.txt │ │ ├── modbus_receive.txt │ │ ├── modbus_receive_confirmation.txt │ │ ├── modbus_reply.txt │ │ ├── modbus_reply_exception.txt │ │ ├── modbus_report_slave_id.txt │ │ ├── modbus_rtu_get_rts.txt │ │ ├── modbus_rtu_get_rts_delay.txt │ │ ├── modbus_rtu_get_serial_mode.txt │ │ ├── modbus_rtu_set_custom_rts.txt │ │ ├── modbus_rtu_set_rts.txt │ │ ├── modbus_rtu_set_rts_delay.txt │ │ ├── modbus_rtu_set_serial_mode.txt │ │ ├── modbus_send_raw_request.txt │ │ ├── modbus_set_bits_from_byte.txt │ │ ├── modbus_set_bits_from_bytes.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_listen.txt │ │ ├── modbus_tcp_pi_accept.txt │ │ ├── modbus_tcp_pi_listen.txt │ │ ├── modbus_write_and_read_registers.txt │ │ ├── modbus_write_bit.txt │ │ ├── modbus_write_bits.txt │ │ ├── modbus_write_register.txt │ │ └── modbus_write_registers.txt │ ├── libmodbus.pc.in │ ├── m4 │ │ └── .gitignore │ ├── src │ │ ├── Makefile.am │ │ ├── modbus-data.c │ │ ├── modbus-private.h │ │ ├── modbus-rtu-private.h │ │ ├── modbus-rtu.c │ │ ├── modbus-rtu.h │ │ ├── modbus-tcp-private.h │ │ ├── modbus-tcp.c │ │ ├── modbus-tcp.h │ │ ├── modbus-version.h.in │ │ ├── modbus.c │ │ ├── modbus.h │ │ └── win32 │ │ │ ├── Make-tests │ │ │ ├── README.win32 │ │ │ ├── config.h.win32 │ │ │ ├── configure.js │ │ │ ├── modbus-9.sln │ │ │ ├── modbus.dll.manifest.in │ │ │ ├── modbus.rc │ │ │ └── modbus.vcproj │ └── tests │ │ ├── LICENSE │ │ ├── Makefile.am │ │ ├── README.md │ │ ├── bandwidth-client.c │ │ ├── bandwidth-server-many-up.c │ │ ├── bandwidth-server-one.c │ │ ├── random-test-client.c │ │ ├── random-test-server.c │ │ ├── unit-test-client.c │ │ ├── unit-test-server.c │ │ ├── unit-test.h.in │ │ ├── unit-tests.sh │ │ └── version.c ├── modbus_comm_module.cc ├── physical_system_sim.py └── plc_runner.cc ├── docs ├── Makefile ├── about.rst ├── access_variables.rst ├── advanced_topics.rst ├── building_physical_simulations.rst ├── co_simulation.rst ├── conf.py ├── contact.rst ├── doxygen_reference.rst ├── ext_comm_modules.rst ├── il_programming.rst ├── images │ └── pendulum_control.png ├── index.rst ├── installation.rst ├── mainpage.dox ├── make.bat ├── plc_communication.rst ├── plc_io.rst ├── prerequisites.rst ├── project_configuration.rst ├── quickstart.rst ├── reference │ └── 2010_Book_IEC61131-3ProgrammingIndustrialAutomationSystems.pdf ├── resource_specification.rst ├── running_plc.rst ├── system_specification.rst └── user_guide.rst ├── examples ├── __init__.py ├── common │ ├── __init__.py │ ├── example_hmi.cc │ ├── single_pendulum_sim.py │ └── two_pendulums_2_plcs_sim.py ├── core_examples │ └── inverted_pendulum │ │ ├── CPU_001.prototxt │ │ ├── plc1_system_specification.prototxt │ │ ├── plc2_system_specification.prototxt │ │ └── simulation.py ├── idle_plc │ ├── CPU_001.prototxt │ ├── README │ ├── comm_module.cc │ └── system_specification.prototxt └── inverted_pendulum │ ├── CPU_001.prototxt │ ├── plc_system_specification.prototxt │ └── simulation.py ├── gmock.BUILD ├── open_scada_workspace.bzl ├── setup.sh └── src ├── __init__.py └── pc_emulator ├── __init__.py ├── core ├── executor.cc ├── functions_registry.cc ├── insn_registry.cc ├── insns │ ├── add_insn.cc │ ├── and_insn.cc │ ├── div_insn.cc │ ├── eq_insn.cc │ ├── ge_insn.cc │ ├── gt_insn.cc │ ├── ld_insn.cc │ ├── le_insn.cc │ ├── lt_insn.cc │ ├── mod_insn.cc │ ├── mul_insn.cc │ ├── ne_insn.cc │ ├── not_insn.cc │ ├── or_insn.cc │ ├── shl_insn.cc │ ├── shr_insn.cc │ ├── st_insn.cc │ ├── sub_insn.cc │ └── xor_insn.cc ├── kronos_api.cc ├── pc_clock.cc ├── pc_configuration.cc ├── pc_datatype.cc ├── pc_datatype_registry.cc ├── pc_logger.cc ├── pc_mem_unit.cc ├── pc_pou_code_container.cc ├── pc_resource.cc ├── pc_resource_registry.cc ├── pc_variable.cc ├── resource_manager.cc ├── sfb │ ├── tof.cc │ ├── ton.cc │ └── tp.cc ├── sfb_registry.cc ├── sfc │ ├── abs.cc │ ├── acos.cc │ ├── any_to_any.cc │ ├── asin.cc │ ├── atan.cc │ ├── cos.cc │ ├── exp.cc │ ├── gtod.cc │ ├── limit.cc │ ├── ln.cc │ ├── log.cc │ ├── max.cc │ ├── min.cc │ ├── mux.cc │ ├── sel.cc │ ├── sin.cc │ ├── sqrt.cc │ └── tan.cc ├── sfc_registry.cc ├── task.cc └── utils.cc ├── ext_modules ├── actuator_module.cc ├── comm_module.cc ├── include │ ├── actuator_module.h │ ├── comm_module.h │ ├── ext_module_intf.h │ ├── pc_config_interface.h │ ├── pc_resource_interface.h │ └── sensor_module.h ├── pc_config_interface.cc ├── pc_resource_interface.cc └── sensor_module.cc ├── grpc_ext ├── access_service_impl.cc ├── ext_interface_grpc_api.cc ├── grpc_server_main.cc └── include │ ├── access_service_impl.h │ └── ext_interface_grpc_api.h ├── include ├── configuration.h ├── elementary_datatypes.h ├── executor.h ├── functions_registry.h ├── insn_registry.h ├── insns │ ├── add_insn.h │ ├── and_insn.h │ ├── div_insn.h │ ├── eq_insn.h │ ├── ge_insn.h │ ├── gt_insn.h │ ├── insn.h │ ├── ld_insn.h │ ├── le_insn.h │ ├── lt_insn.h │ ├── mod_insn.h │ ├── mul_insn.h │ ├── ne_insn.h │ ├── not_insn.h │ ├── or_insn.h │ ├── shl_insn.h │ ├── shr_insn.h │ ├── st_insn.h │ ├── sub_insn.h │ └── xor_insn.h ├── kronos_api.h ├── pc_clock.h ├── pc_configuration.h ├── pc_datatype.h ├── pc_datatype_registry.h ├── pc_logger.h ├── pc_mem_unit.h ├── pc_pou_code_container.h ├── pc_resource.h ├── pc_resource_registry.h ├── pc_variable.h ├── resource.h ├── resource_manager.h ├── sfb │ ├── sfb.h │ ├── tof.h │ ├── ton.h │ └── tp.h ├── sfb_registry.h ├── sfc │ ├── abs.h │ ├── acos.h │ ├── any_to_any.h │ ├── asin.h │ ├── atan.h │ ├── cos.h │ ├── exp.h │ ├── gtod.h │ ├── limit.h │ ├── ln.h │ ├── log.h │ ├── max.h │ ├── min.h │ ├── mux.h │ ├── sel.h │ ├── sfc.h │ ├── sin.h │ ├── sqrt.h │ └── tan.h ├── sfc_registry.h ├── synchronized_queue.h ├── task.h └── utils.h ├── proto ├── configuration.proto ├── mem_access.proto ├── mem_access_pb2.py ├── mem_access_pb2_grpc.py ├── system_pous.prototxt └── system_specification.proto └── tests ├── access_variable_tests ├── CPU_001.prototxt ├── access_variable_test.cc └── input.prototxt ├── datatype_tests ├── datatype_test.cc └── input.prototxt ├── execution_tests ├── CPU_001.prototxt ├── execution_test.cc └── input.prototxt ├── insn_tests ├── CPU_001.prototxt ├── input.prototxt └── insn_test.cc ├── sfc_tests ├── CPU_001.prototxt ├── input.prototxt └── sfc_test.cc └── variable_tests ├── CPU_001.prototxt ├── input.prototxt └── variable_test.cc /.gitignore: -------------------------------------------------------------------------------- 1 | SCADA_on_CORE.code-workspace 2 | .vscode/ipch 3 | .vscode/settings.json 4 | .vscode/tasks.json 5 | .vscode/launch.json 6 | .vscode 7 | *.pyc 8 | bazel-bin 9 | bazel-OpenSCADA 10 | bazel-out 11 | bazel-testlogs 12 | bazel-genfiles 13 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Dependencies: 2 | - libboost 3 | Download from https://www.boost.org/users/history/version_1_61_0.html 4 | Extract to folder /src/boost 5 | cd /src/boost/boost_1_61_0 6 | ./bootstrap.sh --prefix=release 7 | sudo ./b2 install -j4 8 | - bazel 9 | sudo apt-get install openjdk-8-jdk 10 | echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list 11 | curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - 12 | sudo apt-get update && sudo apt-get install bazel 13 | sudo apt-get install --only-upgrade bazel 14 | 15 | Make sure the version of bazel is atleast 0.21.0 or greater (run command: bazel version) 16 | 17 | -protobuf 18 | -install v3.6.1 from https://github.com/protocolbuffers/protobuf/releases 19 | -download https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-all-3.6.1.tar.gz 20 | -cd ~/protobuf-3.6.1 21 | ./configure && sudo make -j8 && sudo make install -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Full documentation can be found [here](https://openscada.readthedocs.io/en/latest/index.html). 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, absolute_import, print_function, unicode_literals 2 | -------------------------------------------------------------------------------- /boost.BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "boost", 3 | srcs = glob(["lib/*.so*"]), 4 | hdrs = glob(["include/**/*.hpp", "include/**/*.h"]), 5 | includes = ["include"], 6 | visibility = ["//visibility:public"], 7 | #linkopts = ["-lpython3"], 8 | linkstatic = 1, 9 | ) -------------------------------------------------------------------------------- /contrib/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, absolute_import, print_function, unicode_literals 2 | -------------------------------------------------------------------------------- /contrib/libmodbus/.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((nil . ((indent-tabs-mode . nil) 2 | (c-basic-offset . 4) 3 | (fill-column . 80)))) 4 | 5 | -------------------------------------------------------------------------------- /contrib/libmodbus/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | *.o 4 | *.la 5 | *.lo 6 | *.log 7 | *.trs 8 | .deps 9 | .libs 10 | GPATH 11 | GRTAGS 12 | GSYMS 13 | GTAGS 14 | INSTALL 15 | Makefile 16 | Makefile.in 17 | /aclocal.m4 18 | /autom4te.cache 19 | /build-aux 20 | /config.* 21 | /configure 22 | /configure.scan 23 | /depcomp 24 | /install-sh 25 | /libtool 26 | /ltmain.sh 27 | /missing 28 | /libmodbus.pc 29 | /stamp-h1 30 | /*.sublime-* 31 | /.vscode 32 | src/modbus-version.h 33 | src/win32/modbus.dll.manifest 34 | tests/bandwidth-client 35 | tests/bandwidth-server-many-up 36 | tests/bandwidth-server-one 37 | tests/random-test-client 38 | tests/random-test-server 39 | tests/unit-test-client 40 | tests/unit-test.h 41 | tests/unit-test-server 42 | tests/version 43 | tests/stamp-h2 44 | doc/*.html 45 | doc/*.3 46 | doc/*.7 47 | -------------------------------------------------------------------------------- /contrib/libmodbus/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | compiler: 4 | - gcc 5 | - clang 6 | 7 | script: ./autogen.sh && ./configure && make && make check 8 | -------------------------------------------------------------------------------- /contrib/libmodbus/AUTHORS: -------------------------------------------------------------------------------- 1 | Stéphane Raimbault 2 | Tobias Doerffel - CLA 3 | Florian Forster 4 | oldfaber 5 | Hannu Vuolasaho - CLA 6 | Michael Heimpold - CLA 7 | Jimmy Bergström - CLA 8 | Jakob Bysewski - CLA -------------------------------------------------------------------------------- /contrib/libmodbus/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | How Do I Submit A Good Bug Report? 2 | ---------------------------------- 3 | 4 | Please, don't send direct emails to Stéphane Raimbault unless you want 5 | commercial support. 6 | 7 | Take care to read the documentation at http://libmodbus.org/documentation/. 8 | 9 | - *Be sure it's a bug before creating an issue*, in doubt, post a message on 10 | https://groups.google.com/forum/#!forum/libmodbus or send an email to 11 | libmodbus@googlegroups.com 12 | 13 | - *Use a clear and decriptive title* for the issue to identify 14 | 15 | - *Which version of libmodbus are you using?* you can obtain this information 16 | from your package manager or by running `pkg-config --modversion libmodbus`. 17 | You can provide the sha1 of the commit if you have fetched the code with `git`. 18 | 19 | - *Which operating system are you using?* 20 | 21 | - *Describe the exact steps which reproduce the problem* in as many details as 22 | possible. For example, the software/equipement which runs the Modbus server, how 23 | the clients are connected (TCP, RTU, ASCII) and the source code you are using. 24 | 25 | - *Enable the debug mode*, libmodbus provides a function to display the content 26 | of the Modbus messages and it's very convenient to analyze issues 27 | (http://libmodbus.org/docs/latest/modbus_set_debug.html). 28 | 29 | Good bug reports provide right and quick fixes! 30 | -------------------------------------------------------------------------------- /contrib/libmodbus/Makefile.am: -------------------------------------------------------------------------------- 1 | CLEANFILES = 2 | ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} 3 | AM_MAKEFLAGS = --no-print-directory 4 | 5 | pkgconfigdir = $(libdir)/pkgconfig 6 | pkgconfig_DATA = libmodbus.pc 7 | EXTRA_DIST = libmodbus.pc.in 8 | CLEANFILES += libmodbus.pc 9 | 10 | dist_doc_DATA = MIGRATION README.md 11 | 12 | SUBDIRS = src doc 13 | 14 | if BUILD_TESTS 15 | SUBDIRS += tests 16 | endif 17 | -------------------------------------------------------------------------------- /contrib/libmodbus/acinclude.m4: -------------------------------------------------------------------------------- 1 | dnl ############################################################################## 2 | dnl # AC_LIBMODBUS_CHECK_BUILD_DOC # 3 | dnl # Check whether to build documentation and install man-pages # 4 | dnl ############################################################################## 5 | AC_DEFUN([AC_LIBMODBUS_CHECK_BUILD_DOC], [{ 6 | # Allow user to disable doc build 7 | AC_ARG_WITH([documentation], [AS_HELP_STRING([--without-documentation], 8 | [disable documentation build even if asciidoc and xmlto are present [default=no]])]) 9 | 10 | if test "x$with_documentation" = "xno"; then 11 | ac_libmodbus_build_doc="no" 12 | else 13 | # Determine whether or not documentation should be built and installed. 14 | ac_libmodbus_build_doc="yes" 15 | # Check for asciidoc and xmlto and don't build the docs if these are not installed. 16 | AC_CHECK_PROG(ac_libmodbus_have_asciidoc, asciidoc, yes, no) 17 | AC_CHECK_PROG(ac_libmodbus_have_xmlto, xmlto, yes, no) 18 | if test "x$ac_libmodbus_have_asciidoc" = "xno" -o "x$ac_libmodbus_have_xmlto" = "xno"; then 19 | ac_libmodbus_build_doc="no" 20 | fi 21 | fi 22 | 23 | AC_MSG_CHECKING([whether to build documentation]) 24 | AC_MSG_RESULT([$ac_libmodbus_build_doc]) 25 | if test "x$ac_libmodbus_build_doc" = "xno"; then 26 | AC_MSG_WARN([The tools to build the documentation aren't installed]) 27 | fi 28 | AM_CONDITIONAL(BUILD_DOC, test "x$ac_libmodbus_build_doc" = "xyes") 29 | }]) 30 | -------------------------------------------------------------------------------- /contrib/libmodbus/autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | if autoreconf --install --symlink --force; then 3 | echo 4 | echo "------------------------------------------------------" 5 | echo "Initialized build system. You can now run ./configure " 6 | echo "------------------------------------------------------" 7 | echo 8 | else 9 | echo 10 | echo "--------------------------" 11 | echo "Running autoreconf failed." 12 | echo "--------------------------" 13 | echo 14 | fi 15 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/asciidoc.conf: -------------------------------------------------------------------------------- 1 | [paradef-default] 2 | literal-style=template="literalparagraph" 3 | 4 | [macros] 5 | (?su)[\\]?(?Plinkmb):(?P\S*?)\[(?P.*?)\]= 6 | 7 | ifdef::backend-docbook[] 8 | [linkmb-inlinemacro] 9 | {0%{target}} 10 | {0#} 11 | {0#{target}{0}} 12 | {0#} 13 | endif::backend-docbook[] 14 | 15 | ifdef::backend-xhtml11[] 16 | [linkmb-inlinemacro] 17 | {target}{0?({0})} 18 | endif::backend-xhtml11[] 19 | 20 | ifdef::doctype-manpage[] 21 | ifdef::backend-docbook[] 22 | [header] 23 | template::[header-declarations] 24 | 25 | 26 | {mantitle} 27 | {manvolnum} 28 | libmodbus 29 | v{libmodbus_version} 30 | libmodbus Manual 31 | 32 | 33 | {manname} 34 | {manpurpose} 35 | 36 | endif::backend-docbook[] 37 | endif::doctype-manpage[] 38 | 39 | ifdef::backend-xhtml11[] 40 | [footer] 41 | 42 | {disable-javascript%

} 43 | 49 | 50 | 51 | endif::backend-xhtml11[] 52 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_close.txt: -------------------------------------------------------------------------------- 1 | modbus_close(3) 2 | =============== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_close - close a Modbus connection 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_close(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_close()* function shall close the connection established with the 18 | backend set in the context. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | There is no return value. 24 | 25 | 26 | EXAMPLE 27 | ------- 28 | [source,c] 29 | ------------------- 30 | modbus_t *ctx; 31 | 32 | ctx = modbus_new_tcp("127.0.0.1", 502); 33 | if (modbus_connect(ctx) == -1) { 34 | fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); 35 | modbus_free(ctx); 36 | return -1; 37 | } 38 | 39 | modbus_close(ctx); 40 | modbus_free(ctx); 41 | ------------------- 42 | 43 | SEE ALSO 44 | -------- 45 | linkmb:modbus_connect[3] 46 | 47 | 48 | AUTHORS 49 | ------- 50 | The libmodbus documentation was written by Stéphane Raimbault 51 | 52 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_connect.txt: -------------------------------------------------------------------------------- 1 | modbus_connect(3) 2 | ================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_connect - establish a Modbus connection 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_connect(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_connect()* function shall establish a connection to a Modbus server, 18 | a network or a bus using the context information of libmodbus context given in 19 | argument. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | The function shall return 0 if successful. Otherwise it shall return -1 and set 25 | errno to one of the values defined by the system calls of the underlying 26 | platform. 27 | 28 | 29 | EXAMPLE 30 | ------- 31 | [source,c] 32 | ------------------- 33 | modbus_t *ctx; 34 | 35 | ctx = modbus_new_tcp("127.0.0.1", 502); 36 | if (modbus_connect(ctx) == -1) { 37 | fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); 38 | modbus_free(ctx); 39 | return -1; 40 | } 41 | ------------------- 42 | 43 | 44 | SEE ALSO 45 | -------- 46 | linkmb:modbus_close[3] 47 | 48 | 49 | AUTHORS 50 | ------- 51 | The libmodbus documentation was written by Stéphane Raimbault 52 | 53 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_flush.txt: -------------------------------------------------------------------------------- 1 | modbus_flush(3) 2 | =============== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_flush - flush non-transmitted data 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_flush(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_flush()* function shall discard data received but not read to the 18 | socket or file descriptor associated to the context 'ctx'. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | The function shall return 0 or the number of flushed bytes if 24 | successful. Otherwise it shall return -1 and set errno. 25 | 26 | 27 | AUTHORS 28 | ------- 29 | The libmodbus documentation was written by Stéphane Raimbault 30 | 31 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_free.txt: -------------------------------------------------------------------------------- 1 | modbus_free(3) 2 | ============== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_free - free a libmodbus context 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_free(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_free()* function shall free an allocated modbus_t structure. 18 | 19 | 20 | RETURN VALUE 21 | ------------ 22 | There is no return values. 23 | 24 | 25 | SEE ALSO 26 | -------- 27 | linkmb:libmodbus[3] 28 | 29 | 30 | AUTHORS 31 | ------- 32 | The libmodbus documentation was written by Stéphane Raimbault 33 | 34 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_byte_from_bits.txt: -------------------------------------------------------------------------------- 1 | modbus_get_byte_from_bits(3) 2 | ============================ 3 | 4 | NAME 5 | ---- 6 | modbus_get_byte_from_bits - get the value from many bits 7 | 8 | 9 | SYNOPSIS 10 | -------- 11 | *uint8_t modbus_get_byte_from_bits(const uint8_t *'src', int 'index', unsigned int 'nb_bits');* 12 | 13 | 14 | DESCRIPTION 15 | ----------- 16 | The *modbus_get_byte_from_bits()* function shall extract a value from many 17 | bits. All _nb_bits_ bits from _src_ at position _index_ will be read as a 18 | single value. To obtain a full byte, set nb_bits to 8. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | The function shall return a byte containing the bits read. 24 | 25 | 26 | SEE ALSO 27 | -------- 28 | linkmb:modbus_set_bits_from_byte[3] 29 | linkmb:modbus_set_bits_from_bytes[3] 30 | 31 | 32 | AUTHORS 33 | ------- 34 | The libmodbus documentation was written by Stéphane Raimbault 35 | 36 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_byte_timeout.txt: -------------------------------------------------------------------------------- 1 | modbus_get_byte_timeout(3) 2 | ========================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_byte_timeout - get timeout between bytes 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_get_byte_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_byte_timeout()* function shall store the timeout interval 18 | between two consecutive bytes of the same message in the _to_sec_ and _to_usec_ 19 | arguments. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | The function shall return 0 if successful. Otherwise it shall return -1 and set 25 | errno. 26 | 27 | 28 | EXAMPLE 29 | ------- 30 | [source,c] 31 | ------------------- 32 | uint32_t to_sec; 33 | uint32_t to_usec; 34 | 35 | /* Save original timeout */ 36 | modbus_get_byte_timeout(ctx, &to_sec, &to_usec); 37 | ------------------- 38 | 39 | 40 | SEE ALSO 41 | -------- 42 | linkmb:modbus_set_byte_timeout[3] 43 | linkmb:modbus_get_response_timeout[3] 44 | linkmb:modbus_set_response_timeout[3] 45 | 46 | 47 | AUTHORS 48 | ------- 49 | The libmodbus documentation was written by Stéphane Raimbault 50 | 51 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_float.txt: -------------------------------------------------------------------------------- 1 | modbus_get_float(3) 2 | =================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_float - get a float value from 2 registers 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *float modbus_get_float(const uint16_t *'src');* 13 | 14 | Warning, this function is *deprecated* since libmodbus v3.2.0 and has been 15 | replaced by *modbus_get_float_dcba()*. 16 | 17 | DESCRIPTION 18 | ----------- 19 | The *modbus_get_float()* function shall get a float from 4 bytes in Modbus 20 | format (DCBA byte order). The _src_ array must be a pointer on two 16 bits 21 | values, for example, if the first word is set to 0x4465 and the second to 22 | 0x229a, the float value will be 916.540649. 23 | 24 | 25 | RETURN VALUE 26 | ------------ 27 | The function shall return a float. 28 | 29 | 30 | SEE ALSO 31 | -------- 32 | linkmb:modbus_set_float[3] 33 | linkmb:modbus_set_float_dcba[3] 34 | linkmb:modbus_get_float_dcba[3] 35 | 36 | AUTHORS 37 | ------- 38 | The libmodbus documentation was written by Stéphane Raimbault 39 | 40 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_float_abcd.txt: -------------------------------------------------------------------------------- 1 | modbus_get_float_abcd(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_float_abcd - get a float value from 2 registers in ABCD byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *float modbus_get_float_abcd(const uint16_t *'src');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_float_abcd()* function shall get a float from 4 bytes in usual 18 | Modbus format. The _src_ array must be a pointer on two 16 bits values, for 19 | example, if the first word is set to 0x0020 and the second to 0xF147, the float 20 | value will be read as 123456.0. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return a float. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | linkmb:modbus_set_float_abcd[3] 31 | linkmb:modbus_get_float_badc[3] 32 | linkmb:modbus_get_float_cdab[3] 33 | linkmb:modbus_get_float_dcba[3] 34 | 35 | 36 | AUTHORS 37 | ------- 38 | The libmodbus documentation was written by Stéphane Raimbault 39 | 40 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_float_badc.txt: -------------------------------------------------------------------------------- 1 | modbus_get_float_badc(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_float_badc - get a float value from 2 registers in BADC byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *float modbus_get_float_badc(const uint16_t *'src');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_float_badc()* function shall get a float from 4 bytes with 18 | swapped bytes (BADC instead of ABCD). The _src_ array must be a pointer on two 19 | 16 bits values, for example, if the first word is set to 0x2000 and the second 20 | to 0x47F1, the float value will be read as 123456.0. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return a float. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | linkmb:modbus_set_float_badc[3] 31 | linkmb:modbus_get_float_abcd[3] 32 | linkmb:modbus_get_float_cdab[3] 33 | linkmb:modbus_get_float_dcba[3] 34 | 35 | 36 | AUTHORS 37 | ------- 38 | The libmodbus documentation was written by Stéphane Raimbault 39 | 40 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_float_cdab.txt: -------------------------------------------------------------------------------- 1 | modbus_get_float_cdab(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_float_cdab - get a float value from 2 registers in CDAB byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *float modbus_get_float_cdab(const uint16_t *'src');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_float_cdab()* function shall get a float from 4 bytes with 18 | swapped words (CDAB order instead of ABCD). The _src_ array must be a pointer on 19 | two 16 bits values, for example, if the first word is set to F147 and the second 20 | to 0x0020, the float value will be read as 123456.0. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return a float. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | linkmb:modbus_set_float_cdab[3] 31 | linkmb:modbus_get_float_abcd[3] 32 | linkmb:modbus_get_float_badc[3] 33 | linkmb:modbus_get_float_dcba[3] 34 | 35 | 36 | AUTHORS 37 | ------- 38 | The libmodbus documentation was written by Stéphane Raimbault 39 | 40 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_float_dcba.txt: -------------------------------------------------------------------------------- 1 | modbus_get_float_dcba(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_float_dcba - get a float value from 2 registers in DCBA byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *float modbus_get_float_dcba(const uint16_t *'src');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_float_dcba()* function shall get a float from 4 bytes in 18 | inversed Modbus format (DCBA order instead of ABCD). The _src_ array must be a 19 | pointer on two 16 bits values, for example, if the first word is set to 0x47F1 20 | and the second to 0x2000, the float value will be read as 123456.0. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return a float. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | linkmb:modbus_set_float_dcba[3] 31 | linkmb:modbus_get_float_abcd[3] 32 | linkmb:modbus_get_float_badc[3] 33 | linkmb:modbus_get_float_cdab[3] 34 | 35 | 36 | AUTHORS 37 | ------- 38 | The libmodbus documentation was written by Stéphane Raimbault 39 | 40 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_header_length.txt: -------------------------------------------------------------------------------- 1 | modbus_get_header_length(3) 2 | =========================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_header_length - retrieve the current header length 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_get_header_length(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_header_length()* function shall retrieve the current header 18 | length from the backend. This function is convenient to manipulate a message and 19 | so its limited to low-level operations. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | The header length as integer value. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:libmodbus[7] 30 | 31 | 32 | AUTHORS 33 | ------- 34 | The libmodbus documentation was written by Stéphane Raimbault 35 | 36 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_indication_timeout.txt: -------------------------------------------------------------------------------- 1 | modbus_get_indication_timeout(3) 2 | ================================ 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). 8 | 9 | SYNOPSIS 10 | -------- 11 | *int modbus_get_indication_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* 12 | 13 | 14 | DESCRIPTION 15 | ----------- 16 | 17 | The *modbus_get_indication_timeout()* function shall store the timeout interval 18 | used to wait for an indication in the _to_sec_ and _to_usec_ arguments. 19 | Indication is the term used by the Modbus protocol to designate a request 20 | received by the server. 21 | 22 | The default value is zero, it means the server will wait forever. 23 | 24 | 25 | RETURN VALUE 26 | ------------ 27 | The function shall return 0 if successful. Otherwise it shall return -1 and set 28 | errno. 29 | 30 | 31 | EXAMPLE 32 | ------- 33 | [source,c] 34 | ------------------- 35 | uint32_t to_sec; 36 | uint32_t to_usec; 37 | 38 | /* Save original timeout */ 39 | modbus_get_indication_timeout(ctx, &to_sec, &to_usec); 40 | ------------------- 41 | 42 | 43 | SEE ALSO 44 | -------- 45 | linkmb:modbus_set_indication_timeout[3] 46 | linkmb:modbus_get_response_timeout[3] 47 | linkmb:modbus_set_response_timeout[3] 48 | 49 | 50 | AUTHORS 51 | ------- 52 | The libmodbus documentation was written by Stéphane Raimbault 53 | 54 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_response_timeout.txt: -------------------------------------------------------------------------------- 1 | modbus_get_response_timeout(3) 2 | ============================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_response_timeout - get timeout for response 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_get_response_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_response_timeout()* function shall return the timeout interval 18 | used to wait for a response in the _to_sec_ and _to_usec_ arguments. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | The function shall return 0 if successful. Otherwise it shall return -1 and set 24 | errno. 25 | 26 | 27 | EXAMPLE 28 | ------- 29 | [source,c] 30 | ------------------- 31 | uint32_t old_response_to_sec; 32 | uint32_t old_response_to_usec; 33 | 34 | /* Save original timeout */ 35 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); 36 | 37 | /* Define a new and too short timeout! */ 38 | modbus_set_response_timeout(ctx, 0, 0); 39 | ------------------- 40 | 41 | 42 | SEE ALSO 43 | -------- 44 | linkmb:modbus_set_response_timeout[3] 45 | linkmb:modbus_get_byte_timeout[3] 46 | linkmb:modbus_set_byte_timeout[3] 47 | 48 | 49 | AUTHORS 50 | ------- 51 | The libmodbus documentation was written by Stéphane Raimbault 52 | 53 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_slave.txt: -------------------------------------------------------------------------------- 1 | modbus_get_slave(3) 2 | =================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_slave - get slave number in the context 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_get_slave(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_slave()* function shall get the slave number in the libmodbus 18 | context. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | The function shall return the slave number if successful. Otherwise it shall return -1 24 | and set errno to one of the values defined below. 25 | 26 | 27 | ERRORS 28 | ------ 29 | *EINVAL*:: 30 | The libmodbus context is undefined. 31 | 32 | 33 | SEE ALSO 34 | -------- 35 | linkmb:modbus_set_slave[3] 36 | 37 | 38 | AUTHORS 39 | ------- 40 | The libmodbus documentation was written by Stéphane Raimbault 41 | 42 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_get_socket.txt: -------------------------------------------------------------------------------- 1 | modbus_get_socket(3) 2 | ==================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_get_socket - get the current socket of the context 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_get_socket(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_get_socket()* function shall return the current socket or file 18 | descriptor of the libmodbus context. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | The function returns the current socket or file descriptor of the context if 24 | successful. Otherwise it shall return -1 and set errno. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:modbus_set_socket[3] 30 | 31 | 32 | AUTHORS 33 | ------- 34 | The libmodbus documentation was written by Stéphane Raimbault 35 | 36 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_mapping_free.txt: -------------------------------------------------------------------------------- 1 | modbus_mapping_free(3) 2 | ===================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_mapping_free - free a modbus_mapping_t structure 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_mapping_free(modbus_mapping_t *'mb_mapping');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The function shall free the four arrays of mb_mapping_t structure and finally 18 | the mb_mapping_t referenced by _mb_mapping_. 19 | 20 | 21 | RETURN VALUE 22 | ------------ 23 | There is no return values. 24 | 25 | 26 | SEE ALSO 27 | -------- 28 | linkmb:modbus_mapping_new[3] 29 | 30 | 31 | AUTHORS 32 | ------- 33 | The libmodbus documentation was written by Stéphane Raimbault 34 | 35 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_mask_write_register.txt: -------------------------------------------------------------------------------- 1 | modbus_mask_write_register(3) 2 | ============================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_mask_write_register - mask a single register 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_mask_write_register(modbus_t *'ctx', int 'addr', uint16_t 'and', uint16_t 'or');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_mask_write_register()* function shall modify the value of the 18 | holding register at the address 'addr' of the remote device using the algorithm: 19 | 20 | new value = (current value AND 'and') OR ('or' AND (NOT 'and')) 21 | 22 | The function uses the Modbus function code 0x16 (mask single register). 23 | 24 | 25 | RETURN VALUE 26 | ------------ 27 | The function shall return 1 if successful. Otherwise it shall return -1 and set 28 | errno. 29 | 30 | 31 | SEE ALSO 32 | -------- 33 | linkmb:modbus_read_registers[3] 34 | linkmb:modbus_write_registers[3] 35 | 36 | 37 | AUTHORS 38 | ------- 39 | Martijn de Gouw 40 | The libmodbus documentation was written by Stéphane Raimbault 41 | 42 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_read_bits.txt: -------------------------------------------------------------------------------- 1 | modbus_read_bits(3) 2 | =================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_read_bits - read many bits 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_read_bits(modbus_t *'ctx', int 'addr', int 'nb', uint8_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_read_bits()* function shall read the status of the _nb_ bits (coils) 18 | to the address _addr_ of the remote device. The result of reading is stored in 19 | _dest_ array as unsigned bytes (8 bits) set to `TRUE` or `FALSE`. 20 | 21 | You must take care to allocate enough memory to store the results in _dest_ 22 | (at least _nb_ * sizeof(uint8_t)). 23 | 24 | The function uses the Modbus function code 0x01 (read coil status). 25 | 26 | 27 | RETURN VALUE 28 | ------------ 29 | The function shall return the number of read bits if successful. Otherwise it 30 | shall return -1 and set errno. 31 | 32 | 33 | ERRORS 34 | ------ 35 | *EMBMDATA*:: 36 | Too many bits requested 37 | 38 | 39 | SEE ALSO 40 | -------- 41 | linkmb:modbus_write_bit[3] 42 | linkmb:modbus_write_bits[3] 43 | 44 | 45 | AUTHORS 46 | ------- 47 | The libmodbus documentation was written by Stéphane Raimbault 48 | 49 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_read_input_bits.txt: -------------------------------------------------------------------------------- 1 | modbus_read_input_bits(3) 2 | ========================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_read_input_bits - read many input bits 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_read_input_bits(modbus_t *'ctx', int 'addr', int 'nb', uint8_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_read_input_bits()* function shall read the content of the _nb_ input 18 | bits to the address _addr_ of the remote device. The result of reading is stored 19 | in _dest_ array as unsigned bytes (8 bits) set to _TRUE_ or _FALSE_. 20 | 21 | You must take care to allocate enough memory to store the results in _dest_ 22 | (at least _nb_ * sizeof(uint8_t)). 23 | 24 | The function uses the Modbus function code 0x02 (read input status). 25 | 26 | 27 | RETURN VALUE 28 | ------------ 29 | The function shall return the number of read input status if 30 | successful. Otherwise it shall return -1 and set errno. 31 | 32 | 33 | ERRORS 34 | ------ 35 | *EMBMDATA*:: 36 | Too many discrete inputs requested 37 | 38 | 39 | SEE ALSO 40 | -------- 41 | linkmb:modbus_read_input_registers[3] 42 | 43 | 44 | AUTHORS 45 | ------- 46 | The libmodbus documentation was written by Stéphane Raimbault 47 | 48 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_read_input_registers.txt: -------------------------------------------------------------------------------- 1 | modbus_read_input_registers(3) 2 | ============================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_read_input_registers - read many input registers 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_read_input_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_read_input_registers()* function shall read the content of the _nb_ 18 | input registers to address _addr_ of the remote device. The result of the 19 | reading is stored in _dest_ array as word values (16 bits). 20 | 21 | You must take care to allocate enough memory to store the results in _dest_ (at 22 | least _nb_ * sizeof(uint16_t)). 23 | 24 | The function uses the Modbus function code 0x04 (read input registers). The 25 | holding registers and input registers have different historical meaning, but 26 | nowadays it's more common to use holding registers only. 27 | 28 | 29 | RETURN VALUE 30 | ------------ 31 | The function shall return the number of read input registers if 32 | successful. Otherwise it shall return -1 and set errno. 33 | 34 | 35 | ERRORS 36 | ------ 37 | *EMBMDATA*:: 38 | Too many bits requested 39 | 40 | 41 | SEE ALSO 42 | -------- 43 | linkmb:modbus_read_input_bits[3] 44 | linkmb:modbus_write_register[3] 45 | linkmb:modbus_write_registers[3] 46 | 47 | 48 | AUTHORS 49 | ------- 50 | The libmodbus documentation was written by Stéphane Raimbault 51 | 52 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_read_registers.txt: -------------------------------------------------------------------------------- 1 | modbus_read_registers(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_read_registers - read many registers 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_read_registers(modbus_t *'ctx', int 'addr', int 'nb', uint16_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_read_registers()* function shall read the content of the _nb_ 18 | holding registers to the address _addr_ of the remote device. The result of 19 | reading is stored in _dest_ array as word values (16 bits). 20 | 21 | You must take care to allocate enough memory to store the results in _dest_ 22 | (at least _nb_ * sizeof(uint16_t)). 23 | 24 | The function uses the Modbus function code 0x03 (read holding registers). 25 | 26 | 27 | RETURN VALUE 28 | ------------ 29 | The function shall return the number of read registers 30 | if successful. Otherwise it shall return -1 and set errno. 31 | 32 | 33 | ERRORS 34 | ------ 35 | *EMBMDATA*:: 36 | Too many registers requested 37 | 38 | 39 | EXAMPLE 40 | ------- 41 | [source,c] 42 | ------------------- 43 | modbus_t *ctx; 44 | uint16_t tab_reg[64]; 45 | int rc; 46 | int i; 47 | 48 | ctx = modbus_new_tcp("127.0.0.1", 1502); 49 | if (modbus_connect(ctx) == -1) { 50 | fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); 51 | modbus_free(ctx); 52 | return -1; 53 | } 54 | 55 | rc = modbus_read_registers(ctx, 0, 10, tab_reg); 56 | if (rc == -1) { 57 | fprintf(stderr, "%s\n", modbus_strerror(errno)); 58 | return -1; 59 | } 60 | 61 | for (i=0; i < rc; i++) { 62 | printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); 63 | } 64 | 65 | modbus_close(ctx); 66 | modbus_free(ctx); 67 | ------------------- 68 | 69 | 70 | SEE ALSO 71 | -------- 72 | linkmb:modbus_write_register[3] 73 | linkmb:modbus_write_registers[3] 74 | 75 | 76 | AUTHORS 77 | ------- 78 | The libmodbus documentation was written by Stéphane Raimbault 79 | 80 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_receive.txt: -------------------------------------------------------------------------------- 1 | modbus_receive(3) 2 | ================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_receive - receive an indication request 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_receive(modbus_t *'ctx', uint8_t *'req');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_receive()* function shall receive an indication request from the 18 | socket of the context _ctx_. This function is used by Modbus slave/server to 19 | receive and analyze indication request sent by the masters/clients. 20 | 21 | If you need to use another socket or file descriptor than the one defined in the 22 | context _ctx_, see the function linkmb:modbus_set_socket[3]. 23 | 24 | 25 | RETURN VALUE 26 | ------------ 27 | The function shall store the indication request in _req_ and return the request 28 | length if successful. The returned request length can be zero if the indication 29 | request is ignored (eg. a query for another slave in RTU mode). Otherwise it 30 | shall return -1 and set errno. 31 | 32 | 33 | SEE ALSO 34 | -------- 35 | linkmb:modbus_set_socket[3] 36 | linkmb:modbus_reply[3] 37 | 38 | 39 | AUTHORS 40 | ------- 41 | The libmodbus documentation was written by Stéphane Raimbault 42 | 43 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_receive_confirmation.txt: -------------------------------------------------------------------------------- 1 | modbus_receive_confirmation(3) 2 | ============================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_receive_confirmation - receive a confirmation request 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_receive_confirmation(modbus_t *'ctx', uint8_t *'rsp');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_receive_confirmation()* function shall receive a request via the 18 | socket of the context _ctx_. This function must be used for debugging purposes 19 | because the received response isn't checked against the initial request. This 20 | function can be used to receive request not handled by the library. 21 | 22 | The maximum size of the response depends on the used backend, in RTU the _rsp_ 23 | array must be _MODBUS_RTU_MAX_ADU_LENGTH_ bytes and in TCP it must be 24 | _MODBUS_TCP_MAX_ADU_LENGTH_ bytes. If you want to write code compatible with 25 | both, you can use the constant _MODBUS_MAX_ADU_LENGTH_ (maximum value of all 26 | libmodbus backends). Take care to allocate enough memory to store responses to 27 | avoid crashes of your server. 28 | 29 | 30 | RETURN VALUE 31 | ------------ 32 | The function shall store the confirmation request in _rsp_ and return the 33 | response length if sucessful. The returned request length can be zero if the 34 | indication request is ignored (eg. a query for another slave in RTU 35 | mode). Otherwise it shall return -1 and set errno. 36 | 37 | EXAMPLE 38 | ------- 39 | [source,c] 40 | ------------------- 41 | uint8_t rsp[MODBUS_MAX_ADU_LENGTH]; 42 | rc = modbus_receive_confirmation(ctx, rsp); 43 | ------------------- 44 | 45 | SEE ALSO 46 | -------- 47 | linkmb:modbus_send_raw_request[3] 48 | 49 | 50 | AUTHORS 51 | ------- 52 | The libmodbus documentation was written by Stéphane Raimbault 53 | 54 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_reply.txt: -------------------------------------------------------------------------------- 1 | modbus_reply(3) 2 | =============== 3 | 4 | NAME 5 | ---- 6 | modbus_reply - send a reponse to the received request 7 | 8 | 9 | SYNOPSIS 10 | -------- 11 | *int modbus_reply(modbus_t *'ctx', const uint8_t *'req', int 'req_length', modbus_mapping_t *'mb_mapping'); 12 | 13 | 14 | DESCRIPTION 15 | ----------- 16 | The *modbus_reply()* function shall send a response to received request. The 17 | request _req_ given in argument is analyzed, a response is then built and sent 18 | by using the information of the modbus context _ctx_. 19 | 20 | If the request indicates to read or write a value the operation will done in the 21 | modbus mapping _mb_mapping_ according to the type of the manipulated data. 22 | 23 | If an error occurs, an exception response will be sent. 24 | 25 | This function is designed for Modbus server. 26 | 27 | 28 | RETURN VALUE 29 | ------------ 30 | The function shall return the length of the response sent if 31 | successful. Otherwise it shall return -1 and set errno. 32 | 33 | 34 | ERRORS 35 | ------ 36 | *EMBMDATA*:: 37 | Sending has failed 38 | 39 | See also the errors returned by the syscall used to send the response (eg. send 40 | or write). 41 | 42 | 43 | SEE ALSO 44 | -------- 45 | linkmb:modbus_reply_exception[3] 46 | linkmb:libmodbus[7] 47 | 48 | 49 | AUTHORS 50 | ------- 51 | The libmodbus documentation was written by Stéphane Raimbault 52 | 53 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_reply_exception.txt: -------------------------------------------------------------------------------- 1 | modbus_reply_exception(3) 2 | ========================= 3 | 4 | NAME 5 | ---- 6 | modbus_reply_exception - send an exception reponse 7 | 8 | 9 | SYNOPSIS 10 | -------- 11 | *int modbus_reply_exception(modbus_t *'ctx', const uint8_t *'req', unsigned int 'exception_code'); 12 | 13 | 14 | DESCRIPTION 15 | ----------- 16 | The *modbus_reply_exception()* function shall send an exception response based 17 | on the 'exception_code' in argument. 18 | 19 | The libmodbus provides the following exception codes: 20 | 21 | * MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1) 22 | * MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2) 23 | * MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3) 24 | * MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4) 25 | * MODBUS_EXCEPTION_ACKNOWLEDGE (5) 26 | * MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6) 27 | * MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7) 28 | * MODBUS_EXCEPTION_MEMORY_PARITY (8) 29 | * MODBUS_EXCEPTION_NOT_DEFINED (9) 30 | * MODBUS_EXCEPTION_GATEWAY_PATH (10) 31 | * MODBUS_EXCEPTION_GATEWAY_TARGET (11) 32 | 33 | The initial request _req_ is required to build a valid response. 34 | 35 | 36 | RETURN VALUE 37 | ------------ 38 | The function shall return the length of the response sent if 39 | successful. Otherwise it shall return -1 and set errno. 40 | 41 | 42 | ERRORS 43 | ------ 44 | *EINVAL*:: 45 | The exception code is invalid 46 | 47 | 48 | SEE ALSO 49 | -------- 50 | linkmb:modbus_reply[3] 51 | linkmb:libmodbus[7] 52 | 53 | 54 | AUTHORS 55 | ------- 56 | The libmodbus documentation was written by Stéphane Raimbault 57 | 58 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_report_slave_id.txt: -------------------------------------------------------------------------------- 1 | modbus_report_slave_id(3) 2 | ========================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_report_slave_id - returns a description of the controller 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_report_slave_id(modbus_t *'ctx', int 'max_dest', uint8_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_report_slave_id()* function shall send a request to the controller 18 | to obtain a description of the controller. 19 | 20 | The response stored in _dest_ contains: 21 | 22 | * the slave ID, this unique ID is in reality not unique at all so it's not 23 | possible to depend on it to know how the information are packed in the 24 | response. 25 | * the run indicator status (0x00 = OFF, 0xFF = ON) 26 | * additional data specific to each controller. For example, libmodbus returns 27 | the version of the library as a string. 28 | 29 | The function writes at most _max_dest_ bytes from the response to _dest_ so 30 | you must ensure that _dest_ is large enough. 31 | 32 | RETURN VALUE 33 | ------------ 34 | The function shall return the number of read data if successful. 35 | 36 | If the output was truncated due to the _max_dest_ limit then the return value is 37 | the number of bytes which would have been written to _dest_ if enough space had 38 | been available. Thus, a return value greater than _max_dest_ means that the 39 | response data was truncated. 40 | 41 | Otherwise it shall return -1 and set errno. 42 | 43 | EXAMPLE 44 | ------- 45 | [source,c] 46 | ------------------- 47 | uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH]; 48 | 49 | ... 50 | 51 | rc = modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes); 52 | if (rc > 1) { 53 | printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF"); 54 | } 55 | ------------------- 56 | 57 | 58 | AUTHORS 59 | ------- 60 | The libmodbus documentation was written by Stéphane Raimbault 61 | 62 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_rtu_get_rts.txt: -------------------------------------------------------------------------------- 1 | modbus_rtu_get_rts(3) 2 | ===================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_rtu_get_rts - get the current RTS mode in RTU 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_rtu_get_rts(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_rtu_get_rts()* function shall get the current Request To Send mode 18 | of the libmodbus context _ctx_. The possible returned values are: 19 | 20 | * MODBUS_RTU_RTS_NONE 21 | * MODBUS_RTU_RTS_UP 22 | * MODBUS_RTU_RTS_DOWN 23 | 24 | This function can only be used with a context using a RTU backend. 25 | 26 | 27 | RETURN VALUE 28 | ------------ 29 | The function shall return the current RTS mode if successful. Otherwise it shall 30 | return -1 and set errno. 31 | 32 | 33 | ERRORS 34 | ------ 35 | *EINVAL*:: 36 | The libmodbus backend is not RTU. 37 | 38 | 39 | SEE ALSO 40 | -------- 41 | linkmb:modbus_rtu_set_rts[3] 42 | 43 | 44 | AUTHORS 45 | ------- 46 | The libmodbus documentation was written by Stéphane Raimbault 47 | 48 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_rtu_get_rts_delay.txt: -------------------------------------------------------------------------------- 1 | modbus_rtu_get_rts_delay(3) 2 | =========================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_rtu_get_rts_delay - get the current RTS delay in RTU 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_rtu_get_rts_delay(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | 18 | The _modbus_rtu_get_rts_delay()_ function shall get the current Request To Send 19 | delay period of the libmodbus context 'ctx'. 20 | 21 | This function can only be used with a context using a RTU backend. 22 | 23 | 24 | RETURN VALUE 25 | ------------ 26 | The _modbus_rtu_get_rts_delay()_ function shall return the current RTS delay in 27 | microseconds if successful. Otherwise it shall return -1 and set errno. 28 | 29 | 30 | ERRORS 31 | ------ 32 | *EINVAL*:: 33 | The libmodbus backend is not RTU. 34 | 35 | 36 | SEE ALSO 37 | -------- 38 | linkmb:modbus_rtu_set_rts_delay[3] 39 | 40 | 41 | AUTHORS 42 | ------- 43 | Jimmy Bergström 44 | 45 | The libmodbus documentation was written by Stéphane Raimbault 46 | 47 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_rtu_get_serial_mode.txt: -------------------------------------------------------------------------------- 1 | modbus_rtu_get_serial_mode(3) 2 | ============================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_rtu_get_serial_mode - get the current serial mode 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_rtu_get_serial_mode(modbus_t *'ctx');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_rtu_get_serial_mode()* function shall return the serial mode 18 | currently used by the libmodbus context: 19 | 20 | *MODBUS_RTU_RS232*:: the serial line is set for RS232 communication. RS-232 21 | (Recommended Standard 232) is the traditional name for a series of standards 22 | for serial binary single-ended data and control signals connecting between a 23 | DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating 24 | Equipment). It is commonly used in computer serial ports 25 | 26 | *MODBUS_RTU_RS485*:: the serial line is set for RS485 communication. EIA-485, 27 | also known as TIA/EIA-485 or RS-485, is a standard defining the electrical 28 | characteristics of drivers and receivers for use in balanced digital multipoint 29 | systems. This standard is widely used for communications in industrial 30 | automation because it can be used effectively over long distances and in 31 | electrically noisy environments. 32 | 33 | This function is only available on Linux kernels 2.6.28 onwards and can only be 34 | used with a context using a RTU backend. 35 | 36 | 37 | RETURN VALUE 38 | ------------ 39 | The function shall return `MODBUS_RTU_RS232` or `MODBUS_RTU_RS485` if 40 | successful. Otherwise it shall return -1 and set errno to one of the values 41 | defined below. 42 | 43 | 44 | ERRORS 45 | ------ 46 | *EINVAL*:: 47 | The current libmodbus backend is not RTU. 48 | 49 | 50 | AUTHORS 51 | ------- 52 | The libmodbus documentation was written by Stéphane Raimbault 53 | 54 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_rtu_set_custom_rts.txt: -------------------------------------------------------------------------------- 1 | modbus_rtu_set_custom_rts(3) 2 | ============================ 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_rtu_set_custom_rts - set a function to be used for custom RTS implementation 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_rtu_set_custom_rts(modbus_t *'ctx', void (*'set_rts') (modbus_t *ctx, int on))* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The _modbus_rtu_set_custom_rts()_ function shall set a custom function to be 18 | called when the RTS pin is to be set before and after a transmission. By default 19 | this is set to an internal function that toggles the RTS pin using an ioctl 20 | call. 21 | 22 | Note that this function adheres to the RTS mode, the values MODBUS_RTU_RTS_UP or 23 | MODBUS_RTU_RTS_DOWN must be used for the function to be called. 24 | 25 | This function can only be used with a context using a RTU backend. 26 | 27 | 28 | RETURN VALUE 29 | ------------ 30 | The _modbus_rtu_set_custom_rts()_ function shall return 0 if successful. 31 | Otherwise it shall return -1 and set errno to one of the values defined below. 32 | 33 | 34 | ERRORS 35 | ------ 36 | *EINVAL*:: 37 | The libmodbus backend is not RTU. 38 | 39 | 40 | AUTHORS 41 | ------- 42 | Jimmy Bergström 43 | 44 | The libmodbus documentation was written by Stéphane Raimbault 45 | 46 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_rtu_set_rts_delay.txt: -------------------------------------------------------------------------------- 1 | modbus_rtu_set_rts_delay(3) 2 | =========================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_rtu_set_rts_delay - set the RTS delay in RTU 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_rtu_set_rts_delay(modbus_t *'ctx', int 'us');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | 18 | The _modbus_rtu_set_rts_delay()_ function shall set the Request To Send delay 19 | period of the libmodbus context 'ctx'. 20 | 21 | This function can only be used with a context using a RTU backend. 22 | 23 | 24 | RETURN VALUE 25 | ------------ 26 | The _modbus_rtu_set_rts_delay()_ function shall return 0 if successful. 27 | Otherwise it shall return -1 and set errno. 28 | 29 | 30 | ERRORS 31 | ------ 32 | *EINVAL*:: 33 | The libmodbus backend is not RTU or a negative delay was specified. 34 | 35 | 36 | SEE ALSO 37 | -------- 38 | linkmb:modbus_rtu_get_rts_delay[3] 39 | 40 | 41 | AUTHORS 42 | ------- 43 | Jimmy Bergström 44 | 45 | The libmodbus documentation was written by Stéphane Raimbault 46 | 47 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_rtu_set_serial_mode.txt: -------------------------------------------------------------------------------- 1 | modbus_rtu_set_serial_mode(3) 2 | ============================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_rtu_set_serial_mode - set the serial mode 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_rtu_set_serial_mode(modbus_t *'ctx', int 'mode');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_rtu_set_serial_mode()* function shall set the selected serial 18 | mode: 19 | 20 | *MODBUS_RTU_RS232*:: the serial line is set for RS232 communication. RS-232 21 | (Recommended Standard 232) is the traditional name for a series of standards 22 | for serial binary single-ended data and control signals connecting between a 23 | DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating 24 | Equipment). It is commonly used in computer serial ports 25 | 26 | *MODBUS_RTU_RS485*:: the serial line is set for RS485 communication. EIA-485, 27 | also known as TIA/EIA-485 or RS-485, is a standard defining the electrical 28 | characteristics of drivers and receivers for use in balanced digital multipoint 29 | systems. This standard is widely used for communications in industrial 30 | automation because it can be used effectively over long distances and in 31 | electrically noisy environments. 32 | 33 | This function is only supported on Linux kernels 2.6.28 onwards. 34 | 35 | 36 | RETURN VALUE 37 | ------------ 38 | The function shall return 0 if successful. Otherwise it shall return -1 and set 39 | errno to one of the values defined below. 40 | 41 | 42 | ERRORS 43 | ------ 44 | *EINVAL*:: 45 | The current libmodbus backend is not RTU. 46 | 47 | *ENOTSUP*:: 48 | The function is not supported on your platform. 49 | 50 | If the call to ioctl() fails, the error code of ioctl will be returned. 51 | 52 | 53 | AUTHORS 54 | ------- 55 | The libmodbus documentation was written by Stéphane Raimbault 56 | 57 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_bits_from_byte.txt: -------------------------------------------------------------------------------- 1 | modbus_set_bits_from_byte(3) 2 | ============================ 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_bits_from_byte - set many bits from a single byte value 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_bits_from_byte(uint8_t *'dest', int 'index', const uint8_t 'value');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_bits_from_byte()* function shall set many bits from a single byte. 18 | All 8 bits from the byte _value_ will be written to _dest_ array starting at 19 | _index_ position. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | There is no return values. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:modbus_set_bits_from_byte[3] 30 | linkmb:modbus_set_bits_from_bytes[3] 31 | 32 | 33 | AUTHORS 34 | ------- 35 | The libmodbus documentation was written by Stéphane Raimbault 36 | 37 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_bits_from_bytes.txt: -------------------------------------------------------------------------------- 1 | modbus_set_bits_from_bytes(3) 2 | ============================ 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_bits_from_bytes - set many bits from an array of bytes 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_bits_from_bytes(uint8_t *'dest', int 'index', unsigned int 'nb_bits', const uint8_t *'tab_byte');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_bits_from_bytes* function shall set bits by reading an array of 18 | bytes. All the bits of the bytes read from the first position of the array 19 | _tab_byte_ are written as bits in the _dest_ array starting at position _index_. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | There is no return values. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:modbus_set_bits_from_byte[3] 30 | linkmb:modbus_get_byte_from_bits[3] 31 | 32 | 33 | AUTHORS 34 | ------- 35 | The libmodbus documentation was written by Stéphane Raimbault 36 | 37 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_byte_timeout.txt: -------------------------------------------------------------------------------- 1 | modbus_set_byte_timeout(3) 2 | ========================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_byte_timeout - set timeout between bytes 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_byte_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_byte_timeout()* function shall set the timeout interval between 18 | two consecutive bytes of the same message. The timeout is an upper bound on the 19 | amount of time elapsed before *select()* returns, if the time elapsed is longer 20 | than the defined timeout, an `ETIMEDOUT` error will be raised by the 21 | function waiting for a response. 22 | 23 | The value of _to_usec_ argument must be in the range 0 to 999999. 24 | 25 | If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. 26 | In this case, *modbus_set_response_timeout()* governs the entire handling of the 27 | response, the full confirmation response must be received before expiration of 28 | the response timeout. When a byte timeout is set, the response timeout is only 29 | used to wait for until the first byte of the response. 30 | 31 | 32 | RETURN VALUE 33 | ------------ 34 | The function shall return 0 if successful. Otherwise it shall return -1 and set 35 | errno. 36 | 37 | 38 | ERRORS 39 | ------ 40 | *EINVAL*:: 41 | The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. 42 | 43 | 44 | SEE ALSO 45 | -------- 46 | linkmb:modbus_get_byte_timeout[3] 47 | linkmb:modbus_get_response_timeout[3] 48 | linkmb:modbus_set_response_timeout[3] 49 | 50 | 51 | AUTHORS 52 | ------- 53 | The libmodbus documentation was written by Stéphane Raimbault 54 | 55 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_debug.txt: -------------------------------------------------------------------------------- 1 | modbus_set_debug(3) 2 | =================== 3 | 4 | NAME 5 | ---- 6 | modbus_set_debug - set debug flag of the context 7 | 8 | 9 | SYNOPSIS 10 | -------- 11 | *int modbus_set_debug(modbus_t *'ctx', int 'flag');* 12 | 13 | 14 | DESCRIPTION 15 | ----------- 16 | The *modbus_set_debug()* function shall set the debug flag of the *modbus_t* 17 | context by using the argument _flag_. By default, the boolean flag is set to 18 | `FALSE`. When the _flag_ value is set to `TRUE`, many verbose messages are 19 | displayed on stdout and stderr. For example, this flag is useful to display the 20 | bytes of the Modbus messages. 21 | 22 | [verse] 23 | ___________________ 24 | [00][14][00][00][00][06][12][03][00][6B][00][03] 25 | Waiting for a confirmation... 26 | <00><14><00><00><00><09><12><03><06><02><2B><00><00><00><00> 27 | ___________________ 28 | 29 | 30 | RETURN VALUE 31 | ------------ 32 | The function shall return 0 if successful. Otherwise it shall return -1 and set errno. 33 | 34 | 35 | AUTHORS 36 | ------- 37 | The libmodbus documentation was written by Stéphane Raimbault 38 | 39 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_float.txt: -------------------------------------------------------------------------------- 1 | modbus_set_float(3) 2 | =================== 3 | 4 | NAME 5 | ---- 6 | modbus_set_float - set a float value from 2 registers 7 | 8 | 9 | SYNOPSIS 10 | -------- 11 | *void modbus_set_float(float 'f', uint16_t *'dest');* 12 | 13 | Warning, this function is *deprecated* since libmodbus v3.2.0 and has been 14 | replaced by *modbus_set_float_dcba()*. 15 | 16 | DESCRIPTION 17 | ----------- 18 | The *modbus_set_float()* function shall set a float to 4 bytes in Modbus format 19 | (ABCD). The _dest_ array must be pointer on two 16 bits values to be able to 20 | store the full result of the conversion. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | There is no return values. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | linkmb:modbus_get_float[3] 31 | linkmb:modbus_set_float_dcba[3] 32 | 33 | AUTHORS 34 | ------- 35 | The libmodbus documentation was written by Stéphane Raimbault 36 | 37 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_float_abcd.txt: -------------------------------------------------------------------------------- 1 | modbus_set_float_abcd(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_float_abcd - set a float value in 2 registers using ABCD byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_float_abcd(float 'f', uint16_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_float_abcd()* function shall set a float to 4 bytes in usual 18 | Modbus format. The _dest_ array must be pointer on two 16 bits values to be able 19 | to store the full result of the conversion. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | There is no return values. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:modbus_get_float_abcd[3] 30 | linkmb:modbus_set_float_badc[3] 31 | linkmb:modbus_set_float_cdab[3] 32 | linkmb:modbus_set_float_dcba[3] 33 | 34 | 35 | AUTHORS 36 | ------- 37 | The libmodbus documentation was written by Stéphane Raimbault 38 | 39 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_float_badc.txt: -------------------------------------------------------------------------------- 1 | modbus_set_float_badc(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_float_badc - set a float value in 2 registers using BADC byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_float_badc(float 'f', uint16_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_float_badc()* function shall set a float to 4 bytes in swapped 18 | bytes Modbus format (BADC insted of ABCD). The _dest_ array must be pointer on 19 | two 16 bits values to be able to store the full result of the conversion. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | There is no return values. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:modbus_get_float_badc[3] 30 | linkmb:modbus_set_float_abcd[3] 31 | linkmb:modbus_set_float_cdab[3] 32 | linkmb:modbus_set_float_dcba[3] 33 | 34 | 35 | AUTHORS 36 | ------- 37 | The libmodbus documentation was written by Stéphane Raimbault 38 | 39 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_float_cdab.txt: -------------------------------------------------------------------------------- 1 | modbus_set_float_cdab(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_float_cdab - set a float value in 2 registers using CDAB byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_float_cdab(float 'f', uint16_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_float_cdab()* function shall set a float to 4 bytes in swapped 18 | words Modbus format (CDAB order instead of ABCD). The _dest_ array must be 19 | pointer on two 16 bits values to be able to store the full result of the 20 | conversion. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | There is no return values. 26 | 27 | 28 | SEE ALSO 29 | -------- 30 | linkmb:modbus_get_float_cdab[3] 31 | linkmb:modbus_set_float_abcd[3] 32 | linkmb:modbus_set_float_badc[3] 33 | linkmb:modbus_set_float_dcba[3] 34 | 35 | 36 | AUTHORS 37 | ------- 38 | The libmodbus documentation was written by Stéphane Raimbault 39 | 40 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_float_dcba.txt: -------------------------------------------------------------------------------- 1 | modbus_set_float_dcba(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_float_dcba - set a float value in 2 registers using DCBA byte order 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_float_dcba(float 'f', uint16_t *'dest');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_float_dcba()* function shall set a float to 4 bytes in inverted 18 | Modbus format (DCBA order). The _dest_ array must be pointer on two 16 bits 19 | values to be able to store the full result of the conversion. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | There is no return values. 25 | 26 | 27 | SEE ALSO 28 | -------- 29 | linkmb:modbus_get_float_dcba[3] 30 | linkmb:modbus_set_float[3] 31 | linkmb:modbus_get_float[3] 32 | 33 | 34 | AUTHORS 35 | ------- 36 | The libmodbus documentation was written by Stéphane Raimbault 37 | 38 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_indication_timeout.txt: -------------------------------------------------------------------------------- 1 | modbus_set_indication_timeout(3) 2 | ================================ 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_indication_timeout - set timeout between indications 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *void modbus_set_indication_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_indication_timeout()* function shall set the timeout interval used by 18 | a server to wait for a request from a client. 19 | 20 | The value of _to_usec_ argument must be in the range 0 to 999999. 21 | 22 | If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. 23 | In this case, the server will wait forever. 24 | 25 | 26 | RETURN VALUE 27 | ------------ 28 | The function shall return 0 if successful. Otherwise it shall return -1 and set 29 | errno. 30 | 31 | 32 | ERRORS 33 | ------ 34 | *EINVAL*:: 35 | The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. 36 | 37 | 38 | SEE ALSO 39 | -------- 40 | linkmb:modbus_get_indication_timeout[3] 41 | linkmb:modbus_get_response_timeout[3] 42 | linkmb:modbus_set_response_timeout[3] 43 | 44 | 45 | AUTHORS 46 | ------- 47 | The libmodbus documentation was written by Stéphane Raimbault 48 | 49 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_response_timeout.txt: -------------------------------------------------------------------------------- 1 | modbus_set_response_timeout(3) 2 | ============================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_response_timeout - set timeout for response 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_set_response_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_response_timeout()* function shall set the timeout interval used 18 | to wait for a response. When a byte timeout is set, if elapsed time for the 19 | first byte of response is longer than the given timeout, an `ETIMEDOUT` error 20 | will be raised by the function waiting for a response. When byte timeout is 21 | disabled, the full confirmation response must be received before expiration of 22 | the response timeout. 23 | 24 | The value of _to_usec_ argument must be in the range 0 to 999999. 25 | 26 | 27 | RETURN VALUE 28 | ------------ 29 | The function shall return 0 if successful. Otherwise it shall return -1 and set 30 | errno. 31 | 32 | 33 | ERRORS 34 | ------ 35 | *EINVAL*:: 36 | The argument _ctx_ is NULL, or both _to_sec_ and _to_usec_ are zero, or _to_usec_ 37 | is larger than 1000000. 38 | 39 | 40 | EXAMPLE 41 | ------- 42 | [source,c] 43 | ------------------- 44 | uint32_t old_response_to_sec; 45 | uint32_t old_response_to_usec; 46 | 47 | /* Save original timeout */ 48 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); 49 | 50 | /* Define a new timeout of 200ms */ 51 | modbus_set_response_timeout(ctx, 0, 200000); 52 | ------------------- 53 | 54 | 55 | SEE ALSO 56 | -------- 57 | linkmb:modbus_get_response_timeout[3] 58 | linkmb:modbus_get_byte_timeout[3] 59 | linkmb:modbus_set_byte_timeout[3] 60 | 61 | 62 | AUTHORS 63 | ------- 64 | The libmodbus documentation was written by Stéphane Raimbault 65 | 66 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_set_socket.txt: -------------------------------------------------------------------------------- 1 | modbus_set_socket(3) 2 | ==================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_set_socket - set socket of the context 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_set_socket(modbus_t *'ctx', int 's');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_set_socket()* function shall set the socket or file descriptor in 18 | the libmodbus context. This function is useful for managing multiple client 19 | connections to the same server. 20 | 21 | 22 | RETURN VALUE 23 | ------------ 24 | The function shall return 0 if successful. Otherwise it shall return -1 and set errno. 25 | 26 | 27 | EXAMPLE 28 | ------- 29 | [source,c] 30 | ------------------- 31 | ctx = modbus_new_tcp("127.0.0.1", 1502); 32 | server_socket = modbus_tcp_listen(ctx, NB_CONNECTION); 33 | 34 | FD_ZERO(&rdset); 35 | FD_SET(server_socket, &rdset); 36 | 37 | /* .... */ 38 | 39 | if (FD_ISSET(master_socket, &rdset)) { 40 | modbus_set_socket(ctx, master_socket); 41 | rc = modbus_receive(ctx, query); 42 | if (rc != -1) { 43 | modbus_reply(ctx, query, rc, mb_mapping); 44 | } 45 | } 46 | ------------------- 47 | 48 | SEE ALSO 49 | -------- 50 | linkmb:modbus_get_socket[3] 51 | 52 | 53 | AUTHORS 54 | ------- 55 | The libmodbus documentation was written by Stéphane Raimbault 56 | 57 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_strerror.txt: -------------------------------------------------------------------------------- 1 | modbus_strerror(3) 2 | ================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_strerror - return the error message 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *const char *modbus_strerror(int 'errnum');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_strerror()* function shall return a pointer to an error message 18 | string corresponding to the error number specified by the _errnum_ argument. As 19 | libmodbus defines additional error numbers over and above those defined by the 20 | operating system, applications should use *modbus_strerror()* in preference to 21 | the standard *strerror()* function. 22 | 23 | 24 | RETURN VALUE 25 | ------------ 26 | The *modbus_strerror()* function shall return a pointer to an error message 27 | string. 28 | 29 | 30 | ERRORS 31 | ------ 32 | No errors are defined. 33 | 34 | 35 | EXAMPLE 36 | ------- 37 | .Display an error message when a Modbus connection cannot be established 38 | [source,c] 39 | ------------------- 40 | if (modbus_connect(ctx) == -1) { 41 | fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); 42 | abort(); 43 | } 44 | ------------------- 45 | 46 | SEE ALSO 47 | -------- 48 | linkmb:libmodbus 49 | 50 | 51 | AUTHORS 52 | ------- 53 | The libmodbus documentation was written by Stéphane Raimbault 54 | 55 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_tcp_accept.txt: -------------------------------------------------------------------------------- 1 | modbus_tcp_accept(3) 2 | ==================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_tcp_accept - accept a new connection on a TCP Modbus socket (IPv4) 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_tcp_accept(modbus_t *'ctx', int *'s);* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_tcp_accept()* function shall extract the first connection on the 18 | queue of pending connections, create a new socket and store it in libmodbus 19 | context given in argument. If available, _accept4()_ with `SOCK_CLOEXEC` will be 20 | called instead of *accept()*. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return a new socket if successful. 26 | Otherwise it shall return -1 and set errno. 27 | 28 | 29 | EXAMPLE 30 | ------- 31 | For detailed example, see unit-test-server.c source file in tests directory. 32 | 33 | [source,c] 34 | ------------------- 35 | ... 36 | 37 | ctx = modbus_new_tcp("127.0.0.1", 502); 38 | s = modbus_tcp_listen(ctx, 1); 39 | modbus_tcp_accept(ctx, &s); 40 | 41 | ... 42 | 43 | close(s) 44 | modbus_free(ctx); 45 | ------------------- 46 | 47 | SEE ALSO 48 | -------- 49 | linkmb:modbus_tcp_pi_accept[3] 50 | linkmb:modbus_tcp_listen[3] 51 | linkmb:modbus_tcp_pi_listen[3] 52 | 53 | AUTHORS 54 | ------- 55 | The libmodbus documentation was written by Stéphane Raimbault 56 | 57 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_tcp_listen.txt: -------------------------------------------------------------------------------- 1 | modbus_tcp_listen(3) 2 | ==================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_tcp_listen - create and listen a TCP Modbus socket (IPv4) 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_tcp_listen(modbus_t *'ctx', int 'nb_connection');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_tcp_listen()* function shall create a socket and listen to maximum 18 | _nb_connection_ incoming connections on the specified IP address. The context 19 | _ctx _must be allocated and initialized with linkmb:modbus_new_tcp[3] before to 20 | set the IP address to listen, if IP address is set to NULL or '0.0.0.0', any addresses will be 21 | listen. 22 | 23 | 24 | RETURN VALUE 25 | ------------ 26 | The function shall return a new socket if successful. Otherwise it shall return 27 | -1 and set errno. 28 | 29 | 30 | EXAMPLE 31 | ------- 32 | For detailed examples, see source files in tests directory: 33 | 34 | - unit-test-server.c, simple but handle only one connection 35 | - bandwidth-server-many-up.c, handles several connections at once 36 | 37 | 38 | [source,c] 39 | ------------------- 40 | ... 41 | 42 | /* To listen any addresses on port 502 */ 43 | ctx = modbus_new_tcp(NULL, 502); 44 | 45 | /* Handle until 10 established connections */ 46 | server_socket = modbus_tcp_listen(ctx, 10); 47 | 48 | /* Clear the reference set of socket */ 49 | FD_ZERO(&refset); 50 | 51 | /* Add the server socket */ 52 | FD_SET(server_socket, &refset); 53 | 54 | if (select(server_socket + 1, &refset, NULL, NULL, NULL) == -1) { 55 | } 56 | 57 | ... 58 | 59 | close(server_socket); 60 | modbus_free(ctx); 61 | ------------------- 62 | 63 | SEE ALSO 64 | -------- 65 | linkmb:modbus_new_tcp[3] 66 | linkmb:modbus_tcp_accept[3] 67 | linkmb:modbus_tcp_pi_listen[3] 68 | 69 | AUTHORS 70 | ------- 71 | The libmodbus documentation was written by Stéphane Raimbault 72 | 73 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_tcp_pi_accept.txt: -------------------------------------------------------------------------------- 1 | modbus_tcp_pi_accept(3) 2 | ======================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_tcp_pi_accept - accept a new connection on a TCP PI Modbus socket (IPv6) 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_tcp_pi_accept(modbus_t *'ctx', int *'s);* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_tcp_pi_accept()* function shall extract the first connection on the 18 | queue of pending connections, create a new socket and store it in libmodbus 19 | context given in argument. If available, _accept4()_ with `SOCK_CLOEXEC` will be 20 | called instead of *accept()*. 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return a new socket if successful. 26 | Otherwise it shall return -1 and set errno. 27 | 28 | 29 | EXAMPLE 30 | ------- 31 | For detailed example, see unit-test-server.c source file in tests directory. 32 | 33 | [source,c] 34 | ------------------- 35 | ... 36 | 37 | ctx = modbus_new_tcp_pi("::0", 502); 38 | s = modbus_tcp_pi_listen(ctx, 1); 39 | modbus_tcp_pi_accept(ctx, &s); 40 | 41 | ... 42 | 43 | close(s) 44 | modbus_free(ctx); 45 | ------------------- 46 | 47 | SEE ALSO 48 | -------- 49 | linkmb:modbus_tcp_pi_accept[3] 50 | linkmb:modbus_tcp_listen[3] 51 | linkmb:modbus_tcp_pi_listen[3] 52 | 53 | AUTHORS 54 | ------- 55 | The libmodbus documentation was written by Stéphane Raimbault 56 | 57 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_tcp_pi_listen.txt: -------------------------------------------------------------------------------- 1 | modbus_tcp_pi_listen(3) 2 | ======================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_tcp_pi_listen - create and listen a TCP PI Modbus socket (IPv6) 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_tcp_pi_listen(modbus_t *'ctx', int 'nb_connection');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_tcp_pi_listen()* function shall create a socket and listen to 18 | maximum _nb_connection_ incoming connections on the specified nodes. The 19 | context *ctx* must be allocated and initialized with linkmb:modbus_new_tcp_pi[3] 20 | before to set the node to listen, if node is set to NULL or '0.0.0.0', any addresses will be 21 | listen. 22 | 23 | 24 | RETURN VALUE 25 | ------------ 26 | The function shall return a new socket if successful. Otherwise it shall return 27 | -1 and set errno. 28 | 29 | 30 | EXAMPLE 31 | ------- 32 | 33 | For detailed examples, see source files in tests directory: 34 | 35 | - unit-test-server.c, simple but handle only one connection 36 | 37 | [source,c] 38 | ------------------- 39 | ... 40 | 41 | ctx = modbus_new_tcp_pi("::0", "502"); 42 | s = modbus_tcp_pi_listen(ctx, 1); 43 | modbus_tcp_pi_accept(ctx, &s); 44 | 45 | for (;;) { 46 | rc = modbus_receive(ctx, query); 47 | modbus_replay(ctx, query, rc, mb_mapping); 48 | } 49 | ... 50 | 51 | mclose(s); 52 | modbus_free(ctx); 53 | ------------------- 54 | 55 | - bandwidth-server-many-up.c, handles several connections at once 56 | 57 | 58 | SEE ALSO 59 | -------- 60 | linkmb:modbus_new_tcp_pi[3] 61 | linkmb:modbus_tcp_pi_accept[3] 62 | linkmb:modbus_tcp_listen[3] 63 | 64 | AUTHORS 65 | ------- 66 | The libmodbus documentation was written by Stéphane Raimbault 67 | 68 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_write_and_read_registers.txt: -------------------------------------------------------------------------------- 1 | modbus_write_and_read_registers(3) 2 | ================================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_write_and_read_registers - write and read many registers in a single transaction 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *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');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_write_and_read_registers()* function shall write the content of the 18 | _write_nb_ holding registers from the array 'src' to the address _write_addr_ of 19 | the remote device then shall read the content of the _read_nb_ holding registers 20 | to the address _read_addr_ of the remote device. The result of reading is stored 21 | in _dest_ array as word values (16 bits). 22 | 23 | You must take care to allocate enough memory to store the results in _dest_ 24 | (at least _nb_ * sizeof(uint16_t)). 25 | 26 | The function uses the Modbus function code 0x17 (write/read registers). 27 | 28 | 29 | RETURN VALUE 30 | ------------ 31 | The function shall return the number of read registers if successful. Otherwise 32 | it shall return -1 and set errno. 33 | 34 | 35 | ERRORS 36 | ------ 37 | *EMBMDATA*:: 38 | Too many registers requested, Too many registers to write 39 | 40 | 41 | SEE ALSO 42 | -------- 43 | linkmb:modbus_read_registers[3] 44 | linkmb:modbus_write_register[3] 45 | linkmb:modbus_write_registers[3] 46 | 47 | 48 | AUTHORS 49 | ------- 50 | The libmodbus documentation was written by Stéphane Raimbault 51 | 52 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_write_bit.txt: -------------------------------------------------------------------------------- 1 | modbus_write_bit(3) 2 | =================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_write_bit - write a single bit 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_write_bit(modbus_t *'ctx', int 'addr', int 'status');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_write_bit()* function shall write the status of _status_ at the 18 | address _addr_ of the remote device. The value must be set to `TRUE` or `FALSE`. 19 | 20 | The function uses the Modbus function code 0x05 (force single coil). 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return 1 if successful. Otherwise it shall return -1 and set 26 | errno. 27 | 28 | 29 | SEE ALSO 30 | -------- 31 | linkmb:modbus_read_bits[3] 32 | linkmb:modbus_write_bits[3] 33 | 34 | 35 | AUTHORS 36 | ------- 37 | The libmodbus documentation was written by Stéphane Raimbault 38 | 39 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_write_bits.txt: -------------------------------------------------------------------------------- 1 | modbus_write_bits(3) 2 | ==================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_write_bits - write many bits 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_write_bits(modbus_t *'ctx', int 'addr', int 'nb', const uint8_t *'src');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_write_bits()* function shall write the status of the _nb_ bits 18 | (coils) from _src_ at the address _addr_ of the remote device. The 19 | _src_ array must contains bytes set to `TRUE` or `FALSE`. 20 | 21 | The function uses the Modbus function code 0x0F (force multiple coils). 22 | 23 | 24 | RETURN VALUE 25 | ------------ 26 | The function shall return the number of written bits if successful. Otherwise it 27 | shall return -1 and set errno. 28 | 29 | 30 | ERRORS 31 | ------ 32 | *EMBMDATA*:: 33 | Writing too many bits 34 | 35 | 36 | SEE ALSO 37 | -------- 38 | linkmb:modbus_read_bits[3] 39 | linkmb:modbus_write_bit[3] 40 | 41 | 42 | AUTHORS 43 | ------- 44 | The libmodbus documentation was written by Stéphane Raimbault 45 | 46 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_write_register.txt: -------------------------------------------------------------------------------- 1 | modbus_write_register(3) 2 | ======================== 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_write_register - write a single register 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_write_register(modbus_t *'ctx', int 'addr', int 'value');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_write_register()* function shall write the value of _value_ 18 | holding registers at the address _addr_ of the remote device. 19 | 20 | The function uses the Modbus function code 0x06 (preset single register). 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return 1 if successful. Otherwise it shall return -1 and set 26 | errno. 27 | 28 | 29 | SEE ALSO 30 | -------- 31 | linkmb:modbus_read_registers[3] 32 | linkmb:modbus_write_registers[3] 33 | 34 | 35 | AUTHORS 36 | ------- 37 | The libmodbus documentation was written by Stéphane Raimbault 38 | 39 | -------------------------------------------------------------------------------- /contrib/libmodbus/doc/modbus_write_registers.txt: -------------------------------------------------------------------------------- 1 | modbus_write_registers(3) 2 | ========================= 3 | 4 | 5 | NAME 6 | ---- 7 | modbus_write_registers - write many registers 8 | 9 | 10 | SYNOPSIS 11 | -------- 12 | *int modbus_write_registers(modbus_t *'ctx', int 'addr', int 'nb', const uint16_t *'src');* 13 | 14 | 15 | DESCRIPTION 16 | ----------- 17 | The *modbus_write_registers()* function shall write the content of the _nb_ 18 | holding registers from the array _src_ at address _addr_ of the remote device. 19 | 20 | The function uses the Modbus function code 0x10 (preset multiple registers). 21 | 22 | 23 | RETURN VALUE 24 | ------------ 25 | The function shall return the number of written registers if 26 | successful. Otherwise it shall return -1 and set errno. 27 | 28 | 29 | SEE ALSO 30 | -------- 31 | linkmb:modbus_write_register[3] 32 | linkmb:modbus_read_registers[3] 33 | 34 | 35 | AUTHORS 36 | ------- 37 | The libmodbus documentation was written by Stéphane Raimbault 38 | 39 | -------------------------------------------------------------------------------- /contrib/libmodbus/libmodbus.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: modbus 7 | Description: Modbus library 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lmodbus 10 | Cflags: -I${includedir}/modbus 11 | -------------------------------------------------------------------------------- /contrib/libmodbus/m4/.gitignore: -------------------------------------------------------------------------------- 1 | libtool.m4 2 | ltoptions.m4 3 | ltsugar.m4 4 | ltversion.m4 5 | lt~obsolete.m4 6 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = 2 | lib_LTLIBRARIES = libmodbus.la 3 | 4 | AM_CPPFLAGS = \ 5 | -include $(top_builddir)/config.h \ 6 | -DSYSCONFDIR=\""$(sysconfdir)"\" \ 7 | -DLIBEXECDIR=\""$(libexecdir)"\" \ 8 | -I${top_srcdir}/src 9 | 10 | AM_CFLAGS = ${my_CFLAGS} 11 | 12 | libmodbus_la_SOURCES = \ 13 | modbus.c \ 14 | modbus.h \ 15 | modbus-data.c \ 16 | modbus-private.h \ 17 | modbus-rtu.c \ 18 | modbus-rtu.h \ 19 | modbus-rtu-private.h \ 20 | modbus-tcp.c \ 21 | modbus-tcp.h \ 22 | modbus-tcp-private.h \ 23 | modbus-version.h 24 | 25 | libmodbus_la_LDFLAGS = -no-undefined \ 26 | -version-info $(LIBMODBUS_LT_VERSION_INFO) 27 | 28 | if OS_WIN32 29 | libmodbus_la_LIBADD = -lwsock32 30 | endif 31 | 32 | if OS_QNX 33 | libmodbus_la_LIBADD = -lsocket 34 | endif 35 | 36 | # Header files to install 37 | libmodbusincludedir = $(includedir)/modbus 38 | libmodbusinclude_HEADERS = modbus.h modbus-version.h modbus-rtu.h modbus-tcp.h 39 | 40 | DISTCLEANFILES = modbus-version.h 41 | EXTRA_DIST += modbus-version.h.in 42 | CLEANFILES = *~ 43 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/modbus-rtu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1+ 5 | */ 6 | 7 | #ifndef MODBUS_RTU_H 8 | #define MODBUS_RTU_H 9 | 10 | #include "modbus.h" 11 | 12 | MODBUS_BEGIN_DECLS 13 | 14 | /* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 15 | * RS232 / RS485 ADU = 253 bytes + slave (1 byte) + CRC (2 bytes) = 256 bytes 16 | */ 17 | #define MODBUS_RTU_MAX_ADU_LENGTH 256 18 | 19 | MODBUS_API modbus_t* modbus_new_rtu(const char *device, int baud, char parity, 20 | int data_bit, int stop_bit); 21 | 22 | #define MODBUS_RTU_RS232 0 23 | #define MODBUS_RTU_RS485 1 24 | 25 | MODBUS_API int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode); 26 | MODBUS_API int modbus_rtu_get_serial_mode(modbus_t *ctx); 27 | 28 | #define MODBUS_RTU_RTS_NONE 0 29 | #define MODBUS_RTU_RTS_UP 1 30 | #define MODBUS_RTU_RTS_DOWN 2 31 | 32 | MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode); 33 | MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx); 34 | 35 | MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)); 36 | 37 | MODBUS_API int modbus_rtu_set_rts_delay(modbus_t *ctx, int us); 38 | MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx); 39 | 40 | MODBUS_END_DECLS 41 | 42 | #endif /* MODBUS_RTU_H */ 43 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/modbus-tcp-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1+ 5 | */ 6 | 7 | #ifndef MODBUS_TCP_PRIVATE_H 8 | #define MODBUS_TCP_PRIVATE_H 9 | 10 | #define _MODBUS_TCP_HEADER_LENGTH 7 11 | #define _MODBUS_TCP_PRESET_REQ_LENGTH 12 12 | #define _MODBUS_TCP_PRESET_RSP_LENGTH 8 13 | 14 | #define _MODBUS_TCP_CHECKSUM_LENGTH 0 15 | 16 | /* In both structures, the transaction ID must be placed on first position 17 | to have a quick access not dependant of the TCP backend */ 18 | typedef struct _modbus_tcp { 19 | /* Extract from MODBUS Messaging on TCP/IP Implementation Guide V1.0b 20 | (page 23/46): 21 | The transaction identifier is used to associate the future response 22 | with the request. This identifier is unique on each TCP connection. */ 23 | uint16_t t_id; 24 | /* TCP port */ 25 | int port; 26 | /* IP address */ 27 | char ip[16]; 28 | } modbus_tcp_t; 29 | 30 | #define _MODBUS_TCP_PI_NODE_LENGTH 1025 31 | #define _MODBUS_TCP_PI_SERVICE_LENGTH 32 32 | 33 | typedef struct _modbus_tcp_pi { 34 | /* Transaction ID */ 35 | uint16_t t_id; 36 | /* TCP port */ 37 | int port; 38 | /* Node */ 39 | char node[_MODBUS_TCP_PI_NODE_LENGTH]; 40 | /* Service */ 41 | char service[_MODBUS_TCP_PI_SERVICE_LENGTH]; 42 | } modbus_tcp_pi_t; 43 | 44 | #endif /* MODBUS_TCP_PRIVATE_H */ 45 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/modbus-tcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2010 Stéphane Raimbault 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1+ 5 | */ 6 | 7 | #ifndef MODBUS_TCP_H 8 | #define MODBUS_TCP_H 9 | 10 | #include "modbus.h" 11 | 12 | MODBUS_BEGIN_DECLS 13 | 14 | #if defined(_WIN32) && !defined(__CYGWIN__) 15 | /* Win32 with MinGW, supplement to */ 16 | #include 17 | #if !defined(ECONNRESET) 18 | #define ECONNRESET WSAECONNRESET 19 | #endif 20 | #if !defined(ECONNREFUSED) 21 | #define ECONNREFUSED WSAECONNREFUSED 22 | #endif 23 | #if !defined(ETIMEDOUT) 24 | #define ETIMEDOUT WSAETIMEDOUT 25 | #endif 26 | #if !defined(ENOPROTOOPT) 27 | #define ENOPROTOOPT WSAENOPROTOOPT 28 | #endif 29 | #if !defined(EINPROGRESS) 30 | #define EINPROGRESS WSAEINPROGRESS 31 | #endif 32 | #endif 33 | 34 | #define MODBUS_TCP_DEFAULT_PORT 502 35 | #define MODBUS_TCP_SLAVE 0xFF 36 | 37 | /* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 38 | * TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes 39 | */ 40 | #define MODBUS_TCP_MAX_ADU_LENGTH 260 41 | 42 | MODBUS_API modbus_t* modbus_new_tcp(const char *ip_address, int port); 43 | MODBUS_API int modbus_tcp_listen(modbus_t *ctx, int nb_connection); 44 | MODBUS_API int modbus_tcp_accept(modbus_t *ctx, int *s); 45 | 46 | MODBUS_API modbus_t* modbus_new_tcp_pi(const char *node, const char *service); 47 | MODBUS_API int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection); 48 | MODBUS_API int modbus_tcp_pi_accept(modbus_t *ctx, int *s); 49 | 50 | MODBUS_END_DECLS 51 | 52 | #endif /* MODBUS_TCP_H */ 53 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/win32/Make-tests: -------------------------------------------------------------------------------- 1 | # Windows makefile 2 | # -- 3 | # use mingw make 4 | # Get make-3.82-5-mingw32-bin.tar.lzma from 5 | # http://sourceforge.net/projects/mingw/files/MinGW/Extension/make/make-3.82-mingw32/ 6 | # -- 7 | # Set CC=gcc or CC=cl for the pre-defined compilers 8 | # before using this Makefile 9 | # -- 10 | # Compile and link the bandwidth and random tests. 11 | # Build modbus.dll and the import library before building the tests 12 | # modbus.lib/libmodbus.a (the import library) should be in this directory 13 | # modbus.dll should be in this directory or in path 14 | 15 | INCLUDES:=-I../.. -I.. -I. 16 | 17 | ifeq ($(CC),cl) 18 | DEFS+=-D_CRT_SECURE_NO_DEPRECATE=1 -D_CRT_NONSTDC_NO_DEPRECATE=1 19 | CFLAGS=-Zi -W3 -MT -ID:/include/msvc_std 20 | LDOPTS=-link -incremental:NO 21 | LDLIBS=-Fe$@ ws2_32.lib modbus.lib $(LDOPTS) 22 | RES:=res 23 | RCOUT= 24 | endif 25 | 26 | ifeq ($(CC),gcc) 27 | CFLAGS=-g -Wall -O -static -static-libgcc 28 | LDLIBS=-o$@ -lws2_32 -luser32 -L. -lmodbus 29 | LDOPTS= 30 | RES:=o 31 | RCOUT=-o$@ 32 | endif 33 | 34 | CFLAGS+=-DHAVE_CONFIG_H $(DEFS) $(INCLUDES) 35 | 36 | .SUFFIXES: 37 | .SUFFIXES: .c .rc .$(RES) .$(oo) 38 | 39 | # pattern rule for resources 40 | %.$(RES) : %.rc 41 | $(RC) $< $(RCOUT) 42 | 43 | vpath %.c ../../tests 44 | vpath %.h ../src 45 | 46 | all: random-test-client random-test-server bandwidth-client bandwidth-server-one 47 | 48 | random-test-client: random-test-client.c 49 | $(LINK.c) $^ $(LDLIBS) 50 | 51 | random-test-server: random-test-server.c 52 | $(LINK.c) $^ $(LDLIBS) 53 | 54 | bandwidth-server-one: bandwidth-server-one.c 55 | $(LINK.c) $^ $(LDLIBS) 56 | 57 | bandwidth-client: bandwidth-client.c 58 | $(LINK.c) $^ $(LDLIBS) 59 | 60 | 61 | clean: 62 | -@cmd "/c del /Q /S $(OBJS) *.o *.obj *.exe *.pdb *.ilk *.ncb *.res *.dll *.exp *.lib *.ncb *.a *.map *.asm" > NUL: 2>&1 63 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/win32/README.win32: -------------------------------------------------------------------------------- 1 | Intro 2 | ----- 3 | 4 | This directory contains the project file for Visual Studio 2008 to build 5 | modbus.dll and the import library modbus.lib. 6 | 7 | The project file looks for D:/include/msvc_std to find stdint.h. 8 | See ../../README.md file. 9 | 10 | config.h and ../modbus-version.h are generated using configure.js. 11 | 12 | Run 13 | cscript configure.js 14 | or 15 | wscript configure.js 16 | or 17 | double click configure.js to generate these files. 18 | 19 | To get project file for Visual Studio 2005 open copy of file modbus.vcproj in 20 | editor and change attribute `Version` of `VisualStudioProject` tag to "8,00". -------------------------------------------------------------------------------- /contrib/libmodbus/src/win32/modbus-9.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual C++ Express 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "modbus", "modbus.vcproj", "{498E0845-C7F4-438B-8EDE-EF7FC9A74430}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Debug|Win32.Build.0 = Debug|Win32 14 | {498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Release|Win32.ActiveCfg = Release|Win32 15 | {498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/win32/modbus.dll.manifest.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Zsh shell 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /contrib/libmodbus/src/win32/modbus.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vignesh2208/OpenSCADA/ada8aa8548762954fd7d253c96af830d0313ed16/contrib/libmodbus/src/win32/modbus.rc -------------------------------------------------------------------------------- /contrib/libmodbus/tests/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2014 by Stéphane Raimbault 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * The names of the contributors may not be used to endorse or 17 | promote products derived from this software without specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /contrib/libmodbus/tests/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = README.md unit-tests.sh 2 | 3 | noinst_PROGRAMS = \ 4 | bandwidth-server-one \ 5 | bandwidth-server-many-up \ 6 | bandwidth-client \ 7 | random-test-server \ 8 | random-test-client \ 9 | unit-test-server \ 10 | unit-test-client \ 11 | version 12 | 13 | common_ldflags = \ 14 | $(top_builddir)/src/libmodbus.la 15 | 16 | bandwidth_server_one_SOURCES = bandwidth-server-one.c 17 | bandwidth_server_one_LDADD = $(common_ldflags) 18 | 19 | bandwidth_server_many_up_SOURCES = bandwidth-server-many-up.c 20 | bandwidth_server_many_up_LDADD = $(common_ldflags) 21 | 22 | bandwidth_client_SOURCES = bandwidth-client.c 23 | bandwidth_client_LDADD = $(common_ldflags) 24 | 25 | random_test_server_SOURCES = random-test-server.c 26 | random_test_server_LDADD = $(common_ldflags) 27 | 28 | random_test_client_SOURCES = random-test-client.c 29 | random_test_client_LDADD = $(common_ldflags) 30 | 31 | unit_test_server_SOURCES = unit-test-server.c unit-test.h 32 | unit_test_server_LDADD = $(common_ldflags) 33 | 34 | unit_test_client_SOURCES = unit-test-client.c unit-test.h 35 | unit_test_client_LDADD = $(common_ldflags) 36 | 37 | version_SOURCES = version.c 38 | version_LDADD = $(common_ldflags) 39 | 40 | AM_CPPFLAGS = \ 41 | -include $(top_builddir)/config.h \ 42 | -DSYSCONFDIR=\""$(sysconfdir)"\" \ 43 | -DLIBEXECDIR=\""$(libexecdir)"\" \ 44 | -I${top_srcdir}/src \ 45 | -I${top_builddir}/src 46 | 47 | AM_CFLAGS = ${my_CFLAGS} 48 | 49 | CLEANFILES = *~ *.log 50 | 51 | noinst_SCRIPTS=unit-tests.sh 52 | TESTS=./unit-tests.sh 53 | -------------------------------------------------------------------------------- /contrib/libmodbus/tests/README.md: -------------------------------------------------------------------------------- 1 | # License 2 | Test programs of this directory are provided under BSD license (see associated 3 | LICENSE file). 4 | 5 | # Compilation 6 | After installation, you can use pkg-config to compile these tests. 7 | For example, to compile random-test-server run: 8 | 9 | gcc random-test-server.c -o random-test-server `pkg-config --libs --cflags libmodbus` 10 | 11 | - `random-test-server` is necessary to launch a server before running 12 | random-test-client. By default, it receives and replies to Modbus query on the 13 | localhost and port 1502. 14 | 15 | - `random-test-client` sends many different queries to a large range of 16 | addresses and values to test the communication between the client and the 17 | server. 18 | 19 | - `unit-test-server` and `unit-test-client` run a full unit test suite. These 20 | programs are essential to test the Modbus protocol implementation and libmodbus 21 | behavior. 22 | 23 | - `bandwidth-server-one`, `bandwidth-server-many-up` and `bandwidth-client` 24 | return very useful information about the performance of transfert rate between 25 | the server and the client. `bandwidth-server-one` can only handles one 26 | connection at once with a client whereas `bandwidth-server-many-up` opens a 27 | connection for each new clients (with a limit). 28 | -------------------------------------------------------------------------------- /contrib/libmodbus/tests/random-test-server.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008-2014 Stéphane Raimbault 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include 8 | #ifndef _MSC_VER 9 | #include 10 | #endif 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | int main(void) 17 | { 18 | int s = -1; 19 | modbus_t *ctx; 20 | modbus_mapping_t *mb_mapping; 21 | 22 | ctx = modbus_new_tcp("127.0.0.1", 1502); 23 | /* modbus_set_debug(ctx, TRUE); */ 24 | 25 | mb_mapping = modbus_mapping_new(500, 500, 500, 500); 26 | if (mb_mapping == NULL) { 27 | fprintf(stderr, "Failed to allocate the mapping: %s\n", 28 | modbus_strerror(errno)); 29 | modbus_free(ctx); 30 | return -1; 31 | } 32 | 33 | s = modbus_tcp_listen(ctx, 1); 34 | modbus_tcp_accept(ctx, &s); 35 | 36 | for (;;) { 37 | uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH]; 38 | int rc; 39 | 40 | rc = modbus_receive(ctx, query); 41 | if (rc > 0) { 42 | /* rc is the query size */ 43 | modbus_reply(ctx, query, rc, mb_mapping); 44 | } else if (rc == -1) { 45 | /* Connection closed by the client or error */ 46 | break; 47 | } 48 | } 49 | 50 | printf("Quit the loop: %s\n", modbus_strerror(errno)); 51 | 52 | if (s != -1) { 53 | close(s); 54 | } 55 | modbus_mapping_free(mb_mapping); 56 | modbus_close(ctx); 57 | modbus_free(ctx); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /contrib/libmodbus/tests/unit-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | client_log=unit-test-client.log 4 | server_log=unit-test-server.log 5 | 6 | rm -f $client_log $server_log 7 | 8 | echo "Starting server" 9 | ./unit-test-server > $server_log 2>&1 & 10 | 11 | sleep 1 12 | 13 | echo "Starting client" 14 | ./unit-test-client > $client_log 2>&1 15 | rc=$? 16 | 17 | killall unit-test-server 18 | exit $rc 19 | 20 | -------------------------------------------------------------------------------- /contrib/libmodbus/tests/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008-2014 Stéphane Raimbault 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | printf("Compiled with libmodbus version %s (%06X)\n", LIBMODBUS_VERSION_STRING, LIBMODBUS_VERSION_HEX); 13 | printf("Linked with libmodbus version %d.%d.%d\n", 14 | libmodbus_version_major, libmodbus_version_minor, libmodbus_version_micro); 15 | 16 | if (LIBMODBUS_VERSION_CHECK(2, 1, 0)) { 17 | printf("The functions to read/write float values are available (2.1.0).\n"); 18 | } 19 | 20 | if (LIBMODBUS_VERSION_CHECK(2, 1, 1)) { 21 | printf("Oh gosh, brand new API (2.1.1)!\n"); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /contrib/physical_system_sim.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | from abc import ABCMeta, abstractmethod 3 | 4 | class PhysicalSystemSim: 5 | """Generic Physical system simulation abstract class. 6 | 7 | Any physical system simulator which needs to interact with OpenSCADA PLCs 8 | needs to implement this Class. 9 | """ 10 | __metaclass__ = ABCMeta 11 | 12 | def __init__(self, **kwargs): 13 | pass 14 | 15 | @abstractmethod 16 | def progress(self, timestep_secs): 17 | """This method is called internally to advance the simulation by a step size. 18 | 19 | The OpenSCADA emulation_driver.py invokes this function. A physical system 20 | simulator should implement the logic to advance its simulation by 21 | timestep_secs. During this progress, it may set sensor input's of PLCs 22 | and get Actuator outputs from PLC's and act accordingly. 23 | 24 | Args: 25 | timestep_secs (float): Timestep to advance in secs. 26 | Returns: 27 | None 28 | Raises: 29 | None 30 | """ 31 | pass -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = . 8 | BUILDDIR = _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/advanced_topics.rst: -------------------------------------------------------------------------------- 1 | Advanced Topics 2 | =============== 3 | 4 | .. toctree:: 5 | :maxdepth: 3 6 | 7 | access_variables 8 | ext_comm_modules 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/contact.rst: -------------------------------------------------------------------------------- 1 | Contact 2 | ======= 3 | 4 | OpenSCADA is maintained by Project Moses at University of Illinois at Urbana-Champaign. If you have any questions, feel free to reach out to the team at: projectmoses@illinois.edu 5 | -------------------------------------------------------------------------------- /docs/doxygen_reference.rst: -------------------------------------------------------------------------------- 1 | Doxygen Reference Documentation 2 | =============================== 3 | 4 | Generated doxygen documentation of all implemented C++ classes can be found `here `_. 5 | -------------------------------------------------------------------------------- /docs/images/pendulum_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vignesh2208/OpenSCADA/ada8aa8548762954fd7d253c96af830d0313ed16/docs/images/pendulum_control.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | OpenSCADA: IEC 61131-3 compliant PLC emulator with virtual time support 2 | ======================================================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 10 6 | 7 | about 8 | installation 9 | user_guide 10 | advanced_topics 11 | doxygen_reference 12 | contact 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/mainpage.dox: -------------------------------------------------------------------------------- 1 | /*! \mainpage About 2 | 3 | * 4 | * OpenSCADA is platform which supports high fidelity emulation of IEC 61131-3 compliant PLCs and SCADA protocols. It can be used to build and simulate complex 5 | * environments involving cyber-physical systems. OpenSCADA PLCs can be run inside network emulators like CORE/Mininet and interact with other emulated processes. 6 | * OpenSCADA also provides python interfaces to link the network emulation with a physical system simulator. Using these interfaces OpenSCADA PLCs can interact 7 | * with physical system simulators like Matpower, Simulink, ManPy etc. OpenSCADA also ships with support for virtual time based control which is handled by 8 | * Kronos. This allows tight time-synchronization between the physical system simulation and OpenSCADA 9 | * network emulation. 10 | 11 | * In this webpage, you can find all the documented C++ class header files used in OpenSCADA PLC implementation. 12 | */ 13 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/prerequisites.rst: -------------------------------------------------------------------------------- 1 | Prerequisites 2 | ============= 3 | 4 | The user guide assumes that the reader has working knowledge of Instruction List programming (IL) and its terminologies. Interested readers are encouraged to check out the reference book included in `reference `_. Throughout this guide, we will use IEC 61131-3 specific terminologies like resources, configuration, tasks, functions, function blocks and programs which are described in detail in the referenced book. 5 | 6 | The user guide also assumes that the reader is familar with google protobufs and GRPC and their associated terminology. 7 | 8 | * For additional reference on protocol buffers please refer `here `_. 9 | 10 | * For additional reference on GRPC please refer `here `_. 11 | -------------------------------------------------------------------------------- /docs/project_configuration.rst: -------------------------------------------------------------------------------- 1 | Creating a PLC 2 | ============== 3 | 4 | A PLC in OpenSCADA comprises of a RAM module and one or more CPUs. Each CPU module encompasses an Input and Output Memory module and a description of the program or set of programs to execute on that CPU. Thus a single PLC can define and run multiple Instruction List (IL) programs. To completely describe a PLC, a user would need to provide two types of configuration files: 5 | 6 | * **A system specification**: The system specification file includes hardware specific details about the PLC which includes the number of CPUs, the size of RAM memory and the mean and standard deviation of instruction execution times. The system specification file also declares data-types which are used by all IL programs and global variables which may be used by them. Access variables (described in Advanced Topics) can also be declared and made accesible outside the PLC to communication modules. 7 | 8 | 9 | 10 | * **A resource specification**: A separate resource specification should be defined for each CPU on the PLC. The resource specification includes the size of Input and Output memory attached to the CPU as well as all global variables specific to the CPU. Periodic and interrupt tasks can be defined in the resource specification. Functions, Function blocks and Programs to be run on that CPU are also defined and attached to tasks. 11 | 12 | In subsequent sections, we describe each configuration in detail with examples. 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/reference/2010_Book_IEC61131-3ProgrammingIndustrialAutomationSystems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vignesh2208/OpenSCADA/ada8aa8548762954fd7d253c96af830d0313ed16/docs/reference/2010_Book_IEC61131-3ProgrammingIndustrialAutomationSystems.pdf -------------------------------------------------------------------------------- /docs/running_plc.rst: -------------------------------------------------------------------------------- 1 | Starting the PLC 2 | ================ 3 | 4 | The PLC can be started after the System Specification file and referenced Resource specification files are provided. A PLC can be started in normal mode or in virtual time mode under Kronos's control. The PLC can be started as follows:: 5 | 6 | plc_runner [Options [-ens]] -f 7 | 8 | where the following options are optional: 9 | * -e: 1 or 0 to enable/disable Kronos. Default is 0. 10 | * -n: num_insns_per_round - only valid if Kronos is enabled. Please refer Kronos documentation `here `_. 11 | * -s: relative cpu speed - only valid if Kronos is enabled. Please refer Kronos documentation `here `_. 12 | 13 | The Kronos specific options are used to compute the virtual timestep size for each round. Before starting a PLC in virtual time mode, Kronos needs to be installed and loaded. In a subsequent section titled "Building Co-Simulations", we discuss in detail, the steps involved in starting a PLC in virtual time mode and subsequently advancing the emulation in virtual time. 14 | 15 | Starting a PLC in normal mode would be useful for debugging purposes. The PLC can be stopped at any time in normal mode by pressing Ctrl-C. Otherwise it would run for the specified run_time_secs duration configured in the System specification. 16 | -------------------------------------------------------------------------------- /docs/user_guide.rst: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | .. toctree:: 5 | :maxdepth: 13 6 | 7 | prerequisites 8 | project_configuration 9 | system_specification 10 | resource_specification 11 | il_programming 12 | running_plc 13 | plc_io 14 | plc_communication 15 | building_physical_simulations 16 | co_simulation 17 | quickstart 18 | 19 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, absolute_import, print_function, unicode_literals 2 | -------------------------------------------------------------------------------- /examples/common/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, absolute_import, print_function, unicode_literals 2 | -------------------------------------------------------------------------------- /examples/idle_plc/README: -------------------------------------------------------------------------------- 1 | This example illustrates starting an Idle PLC and a Communications module. 2 | The PLC runs in the background but its RAM and ACCESS PATHS are exposed to 3 | the coomunications module which may read/write to them. 4 | 5 | Running the example 6 | ------------------- 7 | 1.Start the PLC 8 | >> cd ~/OpenSCADA; 9 | >> bazel run :example_idle_plc 10 | 11 | 12 | 2.Start the Communications module in a new terminal 13 | >> cd ~/OpenSCADA 14 | >> bazel run :example_comm_module 15 | 16 | 3.Stopping the PLC when done: 17 | Press Ctrl-C in the terminal 18 | 19 | Description 20 | ----------- 21 | The PLC is first started. It initializes and exposes its RAM and Access paths. 22 | When the communication module is run, it reads/updates some memory locations 23 | and access paths. -------------------------------------------------------------------------------- /gmock.BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "main", 3 | srcs = glob( 4 | ["src/*.cc"], 5 | exclude = ["src/gtest-all.cc"] 6 | ), 7 | hdrs = glob([ 8 | "include/**/*.h", 9 | "src/*.h" 10 | ]), 11 | copts = ["-Iexternal/gtest/include"], 12 | linkopts = ["-pthread"], 13 | visibility = ["//visibility:public"], 14 | ) -------------------------------------------------------------------------------- /open_scada_workspace.bzl: -------------------------------------------------------------------------------- 1 | load("//third_party/com_github_robotlocomotion_drake:tools/workspace/github.bzl", "github_archive") 2 | load("//third_party/com_github_robotlocomotion_drake:tools/workspace/pkg_config.bzl", "pkg_config_repository") 3 | load("//third_party/com_github_tensorflow_tensorflow/py:python_configure.bzl", "python_configure") 4 | 5 | def openscada_workspace(): 6 | pkg_config_repository( 7 | name = "ibex", # LGPL3 8 | modname = "ibex", 9 | pkg_config_paths = [ 10 | # macOS 11 | "/usr/local/opt/ibex@2.7.4/share/pkgconfig", 12 | "/usr/local/opt/clp/lib/pkgconfig", # dep of ibex, EPL 13 | "/usr/local/opt/coinutils/lib/pkgconfig", # dep of clp, EPL 14 | # Linux 15 | "/opt/libibex/2.7.4/share/pkgconfig", 16 | ], 17 | ) 18 | pkg_config_repository( 19 | name = "nlopt", # LGPL2 + MIT 20 | modname = "nlopt", 21 | pkg_config_paths = [ 22 | "/usr/local/opt/nlopt/lib/pkgconfig", 23 | ], 24 | ) 25 | 26 | python_configure(name = "local_config_python") 27 | 28 | github_archive( 29 | name = "pybind11", # BSD 30 | repository = "pybind/pybind11", 31 | commit = "v2.2.4", 32 | sha256 = "b69e83658513215b8d1443544d0549b7d231b9f201f6fc787a2b2218b408181e", 33 | build_file = str(Label("//tools:pybind11.BUILD.bazel")), 34 | ) 35 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | if [ "$1" == "install" ]; then 5 | echo "Build Started with Bazel ..." 6 | 7 | echo "Building Emulator library ..." 8 | bazel build :pc_emulator_lib 9 | 10 | echo "Building Python Proto libs ..." 11 | bazel build :py_access_service_proto 12 | 13 | echo "Building LibModbus extensions ..." 14 | cd contrib/libmodbus && ./autogen.sh && ./configure && make install 15 | cd ../../ 16 | 17 | sudo ldconfig 18 | 19 | echo "Building GRPC extensions ..." 20 | bazel build :grpc_ext_lib 21 | 22 | echo "Building GRPC server ..." 23 | bazel build :pc_grpc_server 24 | sudo cp bazel-bin/pc_grpc_server /usr/bin 25 | 26 | echo "Building Modbus comm module ..." 27 | bazel build :modbus_comm_module 28 | sudo cp bazel-bin/modbus_comm_module /usr/bin 29 | 30 | echo "Building PLC Runnable ..." 31 | bazel build :plc_runner 32 | sudo cp bazel-bin/plc_runner /usr/bin 33 | 34 | echo "Building Example HMI ..." 35 | bazel build :example_hmi 36 | sudo cp bazel-bin/example_hmi /usr/bin 37 | 38 | sudo cp bazel-genfiles/py_access_service_proto_pb/src/pc_emulator/proto/*.py src/pc_emulator/proto 39 | sudo chmod 777 src/pc_emulator/proto/*.py 40 | 41 | echo "Build and Install finished ..." 42 | else 43 | if [ "$1" == "uninstall" ]; then 44 | echo "Cleaning up installation ..." 45 | bazel clean 46 | rm /usr/bin/pc_grpc_server || true 47 | rm /usr/bin/modbus_comm_module || true 48 | rm /usr/bin/plc_runner || true 49 | rm /usr/bin/example_hmi || true 50 | rm src/pc_emulator/proto/*.py 51 | cd contrib/libmodbus && make uninstall 52 | cd ../../ 53 | echo "Cleanup finished ..." 54 | fi 55 | fi 56 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, absolute_import, print_function, unicode_literals 2 | -------------------------------------------------------------------------------- /src/pc_emulator/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, absolute_import, print_function, unicode_literals 2 | -------------------------------------------------------------------------------- /src/pc_emulator/core/functions_registry.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/pc_emulator/include/functions_registry.h" 3 | #include "src/pc_emulator/include/pc_logger.h" 4 | #include "src/pc_emulator/include/pc_configuration.h" 5 | #include "src/pc_emulator/include/pc_resource.h" 6 | 7 | using namespace pc_emulator; 8 | using namespace std; 9 | using namespace pc_specification; 10 | 11 | FunctionsRegistry::FunctionsRegistry(PCResourceImpl * AssociatedResource) { 12 | assert(AssociatedResource != nullptr); 13 | 14 | __AssociatedResource = AssociatedResource; 15 | 16 | for(auto it = __AssociatedResource->__ResourcePoUVars.begin(); 17 | it != __AssociatedResource->__ResourcePoUVars.end(); it++) { 18 | PCVariable * PoU = it->second.get(); 19 | 20 | if (PoU->__VariableDataType->__PoUType 21 | == pc_specification::PoUType::FC) { 22 | auto new_func_var = std::unique_ptr( 23 | new PCVariable(__AssociatedResource->__configuration, 24 | __AssociatedResource, 25 | PoU->__VariableName, 26 | PoU->__VariableDataType->__DataTypeName)); 27 | new_func_var->AllocateAndInitialize(); 28 | __FunctionsRegistry.insert(std::make_pair( 29 | PoU->__VariableDataType->__DataTypeName, 30 | std::move(new_func_var))); 31 | } 32 | } 33 | } 34 | 35 | PCVariable* FunctionsRegistry::GetFunction(string FnName) { 36 | auto got = __FunctionsRegistry.find(FnName); 37 | if (got == __FunctionsRegistry.end()) 38 | return nullptr; 39 | 40 | return got->second.get(); 41 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/insns/ld_insn.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/insns/ld_insn.h" 2 | 3 | 4 | using namespace std; 5 | using namespace pc_emulator; 6 | using namespace pc_specification; 7 | 8 | /* 9 | * Sets the Current result accumulator to the passed operand. 10 | */ 11 | void LD_Insn::Execute(PCVariable * __CurrentResult, 12 | std::vector& Operands) { 13 | auto Logger = __AssociatedResource->__configuration->PCLogger.get(); 14 | 15 | if (Operands.size() != 1) { 16 | Logger->RaiseException("LD can take exactly one argument ! " 17 | " Actual number of arguments provided = " + 18 | std::to_string(Operands.size())); 19 | 20 | } 21 | 22 | PCVariable * Operand = Operands[0]; 23 | assert(Operand != nullptr); 24 | if (Operand->__IsVariableContentTypeAPtr) { 25 | Operand = Operand->GetPtrStoredAtField(""); 26 | assert(Operand != nullptr); 27 | } 28 | 29 | 30 | if (IsNegated) { 31 | assert(Operand->__VariableDataType->__DataTypeCategory 32 | != DataTypeCategory::POU); 33 | 34 | auto tmp = Operand->GetCopy(); 35 | *__CurrentResult = !(*tmp.get()); 36 | } else { 37 | auto CurrentResult = __CurrentResult; 38 | *CurrentResult = *Operand; 39 | } 40 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/insns/mod_insn.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/insns/mod_insn.h" 2 | 3 | 4 | using namespace std; 5 | using namespace pc_emulator; 6 | using namespace pc_specification; 7 | 8 | /* 9 | * Sets the Current result accumulator to the passed operand. 10 | */ 11 | void MOD_Insn::Execute(PCVariable * __CurrentResult, 12 | std::vector& Operands) { 13 | auto Logger = __AssociatedResource->__configuration->PCLogger.get(); 14 | 15 | if (Operands.size() != 1) { 16 | Logger->RaiseException("MOD can take exactly one argument ! " 17 | " Actual number of arguments provided = " + 18 | std::to_string(Operands.size())); 19 | 20 | } 21 | 22 | PCVariable * Operand = Operands[0]; 23 | assert(Operand != nullptr); 24 | if (Operand->__IsVariableContentTypeAPtr) { 25 | Operand = Operand->GetPtrStoredAtField(""); 26 | assert(Operand != nullptr); 27 | } 28 | assert(Operand->__VariableDataType->__DataTypeCategory 29 | != DataTypeCategory::POU); 30 | 31 | assert(Operand->__VariableDataType->__DataTypeCategory 32 | != DataTypeCategory::DERIVED); 33 | 34 | assert(Operand->__VariableDataType->__DataTypeCategory 35 | != DataTypeCategory::ARRAY); 36 | auto CurrentResult = __CurrentResult; 37 | 38 | *CurrentResult = (*CurrentResult) % (*Operand); 39 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/insns/ne_insn.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/insns/ne_insn.h" 2 | 3 | 4 | using namespace std; 5 | using namespace pc_emulator; 6 | using namespace pc_specification; 7 | 8 | /* 9 | * Sets the Current result accumulator to the passed operand. 10 | */ 11 | void NE_Insn::Execute(PCVariable * __CurrentResult, 12 | std::vector& Operands) { 13 | auto Logger = __AssociatedResource->__configuration->PCLogger.get(); 14 | 15 | if (Operands.size() != 1) { 16 | Logger->RaiseException("NE can take exactly one argument ! " 17 | " Actual number of arguments provided = " + 18 | std::to_string(Operands.size())); 19 | 20 | } 21 | 22 | PCVariable * Operand = Operands[0]; 23 | assert(Operand != nullptr); 24 | if (Operand->__IsVariableContentTypeAPtr) { 25 | Operand = Operand->GetPtrStoredAtField(""); 26 | assert(Operand != nullptr); 27 | } 28 | assert(Operand->__VariableDataType->__DataTypeCategory 29 | != DataTypeCategory::POU); 30 | 31 | assert(Operand->__VariableDataType->__DataTypeCategory 32 | != DataTypeCategory::DERIVED); 33 | 34 | assert(Operand->__VariableDataType->__DataTypeCategory 35 | != DataTypeCategory::ARRAY); 36 | auto CurrentResult = __CurrentResult; 37 | 38 | 39 | if(*CurrentResult == *Operand) { 40 | *CurrentResult = * __AssociatedResource->GetTmpVariable("BOOL", "0"); 41 | } else { 42 | *CurrentResult = * __AssociatedResource->GetTmpVariable("BOOL", "1"); 43 | } 44 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/insns/not_insn.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/insns/not_insn.h" 2 | 3 | 4 | using namespace std; 5 | using namespace pc_emulator; 6 | using namespace pc_specification; 7 | 8 | /* 9 | * Sets the Current result accumulator to the passed operand. 10 | */ 11 | void NOT_Insn::Execute(PCVariable * __CurrentResult, 12 | std::vector& Operands) { 13 | auto Logger = __AssociatedResource->__configuration->PCLogger.get(); 14 | 15 | if (Operands.size() > 1) { 16 | Logger->RaiseException("NOT can take exactly 0 or 1 arguments ! " 17 | " Actual number of arguments provided = " + 18 | std::to_string(Operands.size())); 19 | 20 | } 21 | 22 | if (Operands.size() == 1) { 23 | PCVariable * Operand = Operands[0]; 24 | assert(Operand != nullptr); 25 | if (Operand->__IsVariableContentTypeAPtr) { 26 | Operand = Operand->GetPtrStoredAtField(""); 27 | assert(Operand != nullptr); 28 | } 29 | 30 | assert(Operand->__VariableDataType->__DataTypeCategory 31 | != DataTypeCategory::POU); 32 | 33 | assert(Operand->__VariableDataType->__DataTypeCategory 34 | != DataTypeCategory::DERIVED); 35 | 36 | assert(Operand->__VariableDataType->__DataTypeCategory 37 | != DataTypeCategory::ARRAY); 38 | auto CurrentResult = __CurrentResult; 39 | if (Operand->__IsVariableContentTypeAPtr) { 40 | Operand = Operand->GetPtrStoredAtField(""); 41 | assert(Operand != nullptr); 42 | } 43 | 44 | auto tmp = Operand->GetCopy(); 45 | *CurrentResult = !(*tmp); 46 | } else { 47 | auto CurrentResult = __CurrentResult; 48 | assert(CurrentResult->__VariableDataType->__DataTypeCategory 49 | == DataTypeCategory::BOOL); 50 | *CurrentResult = !(*CurrentResult); 51 | } 52 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/insns/st_insn.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/insns/st_insn.h" 2 | 3 | 4 | using namespace std; 5 | using namespace pc_emulator; 6 | using namespace pc_specification; 7 | 8 | /* 9 | * Sets the Current result accumulator to the passed operand. 10 | */ 11 | void ST_Insn::Execute(PCVariable * __CurrentResult, 12 | std::vector& Operands) { 13 | auto Logger = __AssociatedResource->__configuration->PCLogger.get(); 14 | 15 | if (Operands.size() != 1) { 16 | Logger->RaiseException("ST can take exactly one argument ! " 17 | " Actual number of arguments provided = " + 18 | std::to_string(Operands.size())); 19 | 20 | } 21 | 22 | PCVariable * Operand = Operands[0]; 23 | assert(Operand != nullptr); 24 | if (Operand->__IsVariableContentTypeAPtr) { 25 | Operand = Operand->GetPtrStoredAtField(""); 26 | assert(Operand != nullptr); 27 | } 28 | 29 | 30 | 31 | if (__CurrentResult 32 | ->__VariableDataType->__DataTypeName != 33 | Operand->__VariableDataType->__DataTypeName) { 34 | Logger->RaiseException("Variable DataTypes of Curr Result and Operand " 35 | " do not match !"); 36 | } 37 | 38 | if (IsNegated) { 39 | assert(Operand->__VariableDataType->__DataTypeCategory 40 | != DataTypeCategory::POU); 41 | std:: cout << "ST Insn Getting Copy\n"; 42 | auto tmp = __CurrentResult->GetCopy(); 43 | *tmp = !(*tmp); 44 | Operand->SetField("", tmp.get()); 45 | } else { 46 | auto CurrentResult = __CurrentResult; 47 | Operand->SetField("", CurrentResult); 48 | } 49 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/kronos_api.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "src/pc_emulator/include/kronos_api.h" 4 | 5 | string GetNxtCommand(int assignedTracerID) { 6 | int ret = writeTracerResults(assignedTracerID, NULL, 0); 7 | if (ret < 0) return "STOP"; 8 | return "CONT"; 9 | } 10 | -------------------------------------------------------------------------------- /src/pc_emulator/core/pc_logger.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/pc_logger.h" 2 | #include "src/pc_emulator/include/pc_configuration.h" 3 | #include "src/pc_emulator/include/task.h" 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | using MemType = pc_specification::MemType; 10 | using DataTypeCategory = pc_specification::DataTypeCategory; 11 | using FieldIntfType = pc_specification::FieldInterfaceType; 12 | using LogLevels = pc_specification::LogLevels; 13 | 14 | 15 | void Logger::LogMessage(int LogLevel, std::string Message) { 16 | string Qualifier = ""; 17 | 18 | if (LogLevel != LogLevels::LOG_NONE && LogLevel <= __LogLevel) { 19 | if (LogLevel == LogLevels::LOG_INFO) { 20 | Qualifier = "INFO"; 21 | } else if (LogLevel == LogLevels::LOG_ERROR) { 22 | Qualifier = "ERROR"; 23 | } else if (LogLevel == LogLevels::LOG_NOTICE) { 24 | Qualifier = "NOTICE"; 25 | } else { 26 | Qualifier = "VERBOSE"; 27 | } 28 | 29 | if (!__LogFile.empty()){ 30 | __ofs << Qualifier << " >> " << Message << std::endl; 31 | } else { 32 | std::cout << Qualifier << " >> " << Message << std::endl; 33 | } 34 | } 35 | 36 | 37 | } 38 | 39 | void Logger::RaiseException(std::string Message) { 40 | if (!__LogFile.empty()){ 41 | __ofs << " EXCEPTION >> " << Message << std::endl; 42 | } else { 43 | std::cout << " EXCEPTION >> " << Message << std::endl; 44 | } 45 | this->ShutDown(); 46 | } 47 | 48 | // this will kill one of the resource threads 49 | void Logger::ShutDown() { 50 | LogMessage(LogLevels::LOG_INFO, "Shutting Down Resource Thread ...."); 51 | exit(-1); 52 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfb_registry.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "src/pc_emulator/include/insn_registry.h" 3 | #include "src/pc_emulator/include/pc_logger.h" 4 | #include "src/pc_emulator/include/pc_configuration.h" 5 | #include "src/pc_emulator/include/pc_resource.h" 6 | #include "src/pc_emulator/include/sfb_registry.h" 7 | 8 | using namespace pc_emulator; 9 | using namespace std; 10 | using namespace pc_specification; 11 | 12 | SFBRegistry::SFBRegistry(PCResourceImpl * AssociatedResource) { 13 | __SFB.insert(std::make_pair("TP", 14 | std::unique_ptr(new TP(AssociatedResource)))); 15 | 16 | __SFB.insert(std::make_pair("TON", 17 | std::unique_ptr(new TON(AssociatedResource)))); 18 | 19 | __SFB.insert(std::make_pair("TOF", 20 | std::unique_ptr(new TOF(AssociatedResource)))); 21 | } 22 | 23 | SFB* SFBRegistry::GetSFB(string SFBName) { 24 | auto got = __SFB.find(SFBName); 25 | 26 | if (got == __SFB.end()) 27 | return nullptr; // Unknown SFB 28 | else { 29 | return got->second.get(); 30 | } 31 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/acos.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/acos.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void ACOS::Execute(PCVariable *CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("ACOS SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = acos(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = acos(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/asin.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/asin.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void ASIN::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("ASIN SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = asin(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = asin(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/atan.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/atan.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void ATAN::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("ATAN SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = atan(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = atan(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/cos.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/cos.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void COS::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("COS SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = cos(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = cos(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/exp.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/exp.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void EXP::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("EXP SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = exp(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = exp(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/gtod.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/gtod.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | #include "src/pc_emulator/include/sfc_registry.h" 4 | #include "src/pc_emulator/include/sfc/any_to_any.h" 5 | 6 | 7 | using namespace std; 8 | using namespace pc_emulator; 9 | using namespace pc_specification; 10 | 11 | void GTOD::Execute(PCVariable * __CurrentResult, 12 | std::vector& MOperands) { 13 | auto configuration = __AssociatedResource->__configuration; 14 | auto CR = __CurrentResult; 15 | auto Tmp = __AssociatedResource->GetTmpVariable("TIME", "t#0s"); 16 | *CR = *Tmp; 17 | auto curr_time = __AssociatedResource->clock->GetCurrentTime(); 18 | CR->SetField("", "t#" + std::to_string(curr_time) + "s"); 19 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/ln.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/ln.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void LN::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("LN SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | if (RealValue < 0) 22 | configuration->PCLogger->RaiseException("LN exception: negative domain"); 23 | RealValue = log(RealValue); 24 | CR->SetField("", &RealValue, sizeof(RealValue)); 25 | } else { 26 | double LRealValue = CR->GetValueStoredAtField("", 27 | DataTypeCategory::LREAL); 28 | if (LRealValue < 0) 29 | configuration->PCLogger->RaiseException("LN exception: negative domain"); 30 | LRealValue = log(LRealValue); 31 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 32 | } 33 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/log.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/log.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void LOG::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("LOG SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | if (RealValue < 0) 22 | configuration->PCLogger->RaiseException("LOG exception: negative domain"); 23 | RealValue = log10(RealValue); 24 | CR->SetField("", &RealValue, sizeof(RealValue)); 25 | } else { 26 | double LRealValue = CR->GetValueStoredAtField("", 27 | DataTypeCategory::LREAL); 28 | if (LRealValue < 0) 29 | configuration->PCLogger->RaiseException("LOG exception: negative domain"); 30 | LRealValue = log10(LRealValue); 31 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 32 | } 33 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/sel.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/sel.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void SEL::Execute(PCVariable * __CurrentResult, 10 | std::vector& MOperands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | 14 | std::vector Operands; 15 | for(int i = 0; i < MOperands.size(); i++) { 16 | if (MOperands[i]->__IsVariableContentTypeAPtr) { 17 | auto Tmp = MOperands[i]->GetPtrStoredAtField(""); 18 | assert(Tmp != nullptr); 19 | Operands.push_back(Tmp); 20 | } else { 21 | Operands.push_back(MOperands[i]); 22 | } 23 | } 24 | if (CR->__VariableDataType->__DataTypeCategory 25 | != DataTypeCategory::BOOL) { 26 | configuration->PCLogger->RaiseException("SEL SFC error: CR is not " 27 | " a boolean"); 28 | } 29 | 30 | if (Operands.size() != 2) { 31 | configuration->PCLogger->RaiseException("SEL SFC error: " 32 | "Exactly 2 operands needed!"); 33 | } 34 | 35 | 36 | bool SelValue = CR->GetValueStoredAtField("", DataTypeCategory::BOOL); 37 | 38 | 39 | if(SelValue == false) { 40 | *CR = *Operands[0]; 41 | } else { 42 | *CR = *Operands[1]; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/sin.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/sin.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void SIN::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("SIN SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = sin(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = sin(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/sqrt.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/sqrt.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void SQRT::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("SQRT SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | if (RealValue < 0) 22 | configuration->PCLogger->RaiseException("SQRT exception: negative domain"); 23 | RealValue = sqrt(RealValue); 24 | CR->SetField("", &RealValue, sizeof(RealValue)); 25 | } else { 26 | double LRealValue = CR->GetValueStoredAtField("", 27 | DataTypeCategory::LREAL); 28 | if (LRealValue < 0) 29 | configuration->PCLogger->RaiseException("SQRT exception: negative domain"); 30 | LRealValue = sqrt(LRealValue); 31 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 32 | } 33 | } -------------------------------------------------------------------------------- /src/pc_emulator/core/sfc/tan.cc: -------------------------------------------------------------------------------- 1 | #include "src/pc_emulator/include/sfc/tan.h" 2 | #include "src/pc_emulator/include/utils.h" 3 | 4 | 5 | using namespace std; 6 | using namespace pc_emulator; 7 | using namespace pc_specification; 8 | 9 | void TAN::Execute(PCVariable * __CurrentResult, 10 | std::vector& Operands) { 11 | auto configuration = __AssociatedResource->__configuration; 12 | auto CR = __CurrentResult; 13 | if (!Utils::IsRealType(CR->__VariableDataType)) { 14 | configuration->PCLogger->RaiseException("TAN SFC error: CR is not " 15 | " a real number"); 16 | } 17 | 18 | if (CR->__VariableDataType->__DataTypeCategory == DataTypeCategory::REAL) { 19 | float RealValue = CR->GetValueStoredAtField("", 20 | DataTypeCategory::REAL); 21 | RealValue = tan(RealValue); 22 | CR->SetField("", &RealValue, sizeof(RealValue)); 23 | } else { 24 | double LRealValue = CR->GetValueStoredAtField("", 25 | DataTypeCategory::LREAL); 26 | LRealValue = tan(LRealValue); 27 | CR->SetField("", &LRealValue, sizeof(LRealValue)); 28 | } 29 | } -------------------------------------------------------------------------------- /src/pc_emulator/ext_modules/actuator_module.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "include/actuator_module.h" 13 | 14 | using namespace std; 15 | using namespace pc_emulator; 16 | using namespace pc_specification; 17 | using MemType = pc_specification::MemType; 18 | using DataTypeCategory = pc_specification::DataTypeCategory; 19 | using FieldIntfType = pc_specification::FieldInterfaceType; 20 | 21 | 22 | 23 | std::unique_ptr ActuatorModule::GetVariableContainer( 24 | string ResourceName, int MemType, int ByteOffset, int BitOffset, 25 | string VariableDataTypeName) { 26 | 27 | 28 | if (MemType != pc_specification::MemType::OUTPUT_MEM) { 29 | std::domain_error("Actuator cannot access INPUT memory!"); 30 | } 31 | auto V = __ConfigInterface.GetVariablePointerToResourceMem( 32 | ResourceName, MemType, ByteOffset, BitOffset, 33 | VariableDataTypeName); 34 | if (V == nullptr) 35 | return nullptr; 36 | return std::unique_ptr(new PCVariableContainer(V)); 37 | }; 38 | -------------------------------------------------------------------------------- /src/pc_emulator/ext_modules/comm_module.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "include/comm_module.h" 13 | 14 | using namespace std; 15 | using namespace pc_emulator; 16 | using namespace pc_specification; 17 | using MemType = pc_specification::MemType; 18 | using DataTypeCategory = pc_specification::DataTypeCategory; 19 | using FieldIntfType = pc_specification::FieldInterfaceType; 20 | 21 | 22 | std::unique_ptr 23 | CommModule::GetVariableContainer(string NestedAccessPath) { 24 | 25 | std::vector results; 26 | 27 | boost::split(results, NestedAccessPath, 28 | boost::is_any_of(".[]"), boost::token_compress_on); 29 | if (NestedAccessPath.empty()) 30 | return nullptr; 31 | 32 | auto V = __ConfigInterface.GetExternVariable(results[0]); 33 | if (V == nullptr) 34 | return nullptr; 35 | string RemField; 36 | if (results.size() > 1) 37 | RemField = NestedAccessPath.substr(NestedAccessPath.find('.') + 1, 38 | string::npos); 39 | 40 | V = V->GetPtrToField(RemField); 41 | return std::unique_ptr(new PCVariableContainer(V)); 42 | }; 43 | 44 | std::unique_ptr CommModule::GetVariableContainer( 45 | int RamByteOffset, int RamBitOffset, 46 | string VariableDataTypeName) { 47 | 48 | auto V = __ConfigInterface.GetVariablePointerToMem( 49 | RamByteOffset, RamBitOffset,VariableDataTypeName); 50 | if (V == nullptr) 51 | return nullptr; 52 | return std::unique_ptr(new PCVariableContainer(V)); 53 | } 54 | -------------------------------------------------------------------------------- /src/pc_emulator/ext_modules/include/actuator_module.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_ACTUATOR_MODULE_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_ACTUATOR_MODULE_H__ 3 | #include "ext_module_intf.h" 4 | 5 | using namespace std; 6 | using namespace pc_specification; 7 | 8 | 9 | namespace pc_emulator { 10 | 11 | // A generic actuator interface 12 | class ActuatorModule: public ExtModule { 13 | public: 14 | 15 | //! Constructor 16 | ActuatorModule(string ConfigurationPath) 17 | : ExtModule(ConfigurationPath) {}; 18 | 19 | //! NOT IMPLEMENTED, Actuator modules cannot query RAM memory. 20 | /*! 21 | Raises an exception. 22 | */ 23 | std::unique_ptr GetVariableContainer( 24 | int RamByteOffset, int RamBitOffset, 25 | string VariableDataTypeName) { 26 | std::domain_error("NOT IMPLEMENTED !"); 27 | return nullptr; 28 | }; 29 | 30 | //! NOT IMPLEMENTED, Actuator modules cannot query access paths. 31 | /*! 32 | Raises an exception. 33 | */ 34 | std::unique_ptr 35 | GetVariableContainer(string AccessPath) { 36 | std::domain_error("NOT IMPLEMENTED !"); 37 | return nullptr; 38 | }; 39 | 40 | //! Returns a variable container for the specified resource mem location 41 | /*! 42 | Raises an exception if MemType is not OUTPUT_MEM 43 | */ 44 | std::unique_ptr GetVariableContainer( 45 | string ResourceName, int MemType, int ByteOffset, int BitOffset, 46 | string VariableDataTypeName); 47 | 48 | }; 49 | 50 | 51 | 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/ext_modules/include/sensor_module.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_SENSOR_MODULE_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_SENSOR_MODULE_H__ 3 | #include "ext_module_intf.h" 4 | 5 | using namespace std; 6 | using namespace pc_specification; 7 | 8 | 9 | namespace pc_emulator { 10 | 11 | // A generic sensor interface 12 | class SensorModule: public ExtModule { 13 | public: 14 | 15 | //! Constructor 16 | SensorModule(string ConfigurationPath) 17 | : ExtModule(ConfigurationPath) {}; 18 | 19 | 20 | //! NOT IMPLEMENTED, Sensor modules cannot query RAM memory. 21 | /*! 22 | Raises an exception. 23 | */ 24 | std::unique_ptr GetVariableContainer( 25 | int RamByteOffset, int RamBitOffset, 26 | string VariableDataTypeName) { 27 | std::domain_error("NOT IMPLEMENTED !"); 28 | return nullptr; 29 | }; 30 | 31 | //! NOT IMPLEMENTED, Sensor modules cannot query access paths. 32 | /*! 33 | Raises an exception. 34 | */ 35 | std::unique_ptr 36 | GetVariableContainer(string AccessPath) { 37 | std::domain_error("NOT IMPLEMENTED !"); 38 | return nullptr; 39 | }; 40 | 41 | 42 | //! Returns a variable container for the specified resource mem location 43 | /*! 44 | Raises an exception if MemType is not INPUT_MEM 45 | */ 46 | std::unique_ptr GetVariableContainer( 47 | string ResourceName, int MemType, int ByteOffset, int BitOffset, 48 | string VariableDataTypeName); 49 | 50 | 51 | 52 | 53 | }; 54 | 55 | 56 | } 57 | 58 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/ext_modules/sensor_module.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "include/sensor_module.h" 13 | 14 | using namespace std; 15 | using namespace pc_emulator; 16 | using namespace pc_specification; 17 | using MemType = pc_specification::MemType; 18 | using DataTypeCategory = pc_specification::DataTypeCategory; 19 | using FieldIntfType = pc_specification::FieldInterfaceType; 20 | 21 | 22 | 23 | std::unique_ptr SensorModule::GetVariableContainer( 24 | string ResourceName, int MemType, int ByteOffset, int BitOffset, 25 | string VariableDataTypeName) { 26 | 27 | 28 | if (MemType != pc_specification::MemType::INPUT_MEM) { 29 | std::domain_error("Sensor cannot access OUTPUT memory!"); 30 | } 31 | auto V = __ConfigInterface.GetVariablePointerToResourceMem( 32 | ResourceName, MemType, ByteOffset, BitOffset, 33 | VariableDataTypeName); 34 | if (V == nullptr) 35 | return nullptr; 36 | return std::unique_ptr(new PCVariableContainer(V)); 37 | }; 38 | -------------------------------------------------------------------------------- /src/pc_emulator/grpc_ext/include/ext_interface_grpc_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_EXT_INTERFACE_GRPC_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_EXT_INTERFACE_GRPC_H__ 3 | #include "src/pc_emulator/ext_modules/include/ext_module_intf.h" 4 | 5 | using namespace std; 6 | using namespace pc_specification; 7 | 8 | 9 | namespace pc_emulator { 10 | 11 | class ExtInterfaceAPI { 12 | public: 13 | 14 | PCConfigurationInterface __ConfigInterface; /*!< Associated Config 15 | Interface */ 16 | 17 | //! Constructor 18 | ExtInterfaceAPI(string ConfigurationPath) 19 | : __ConfigInterface(ConfigurationPath) {}; 20 | 21 | void SetSensorInput( 22 | string ResourceName, int MemType, int ByteOffset, int BitOffset, 23 | string VariableDataTypeName, string Value); 24 | 25 | string GetActuatorOutput( 26 | string ResourceName, int MemType, int ByteOffset, int BitOffset, 27 | string VariableDataTypeName); 28 | }; 29 | 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/functions_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_FUNCTIONS_REGISTRY_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_FUNCTIONS_REGISTRY_H__ 3 | 4 | #include 5 | #include 6 | #include "pc_configuration.h" 7 | #include "pc_resource.h" 8 | #include "pc_variable.h" 9 | #include "pc_datatype.h" 10 | 11 | using namespace std; 12 | 13 | 14 | namespace pc_emulator{ 15 | 16 | //! Class which registers and tracks all valid Functions with a Code Body 17 | class FunctionsRegistry { 18 | private: 19 | 20 | std::unordered_map> 21 | __FunctionsRegistry; /*!< Hash map of function name, variable obj */ 22 | PCResourceImpl * __AssociatedResource; /*!< Resource associated with 23 | this registry */ 24 | public: 25 | 26 | //! Constructor 27 | FunctionsRegistry(PCResourceImpl * AssociatedResource); 28 | 29 | //! Retrieve Function variable object with the specified name 30 | /*! 31 | \param FnName Name of the Function 32 | \return Function variable object 33 | */ 34 | PCVariable* GetFunction(string FnName); 35 | }; 36 | } 37 | 38 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insn_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_INSN_REGISTRY_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_INSN_REGISTRY_H__ 3 | 4 | #include 5 | #include 6 | #include "pc_configuration.h" 7 | #include "pc_resource.h" 8 | #include "insns/insn.h" 9 | #include "insns/ld_insn.h" 10 | #include "insns/st_insn.h" 11 | #include "insns/add_insn.h" 12 | #include "insns/div_insn.h" 13 | #include "insns/eq_insn.h" 14 | #include "insns/ge_insn.h" 15 | #include "insns/gt_insn.h" 16 | #include "insns/le_insn.h" 17 | #include "insns/lt_insn.h" 18 | #include "insns/st_insn.h" 19 | #include "insns/mod_insn.h" 20 | #include "insns/mul_insn.h" 21 | #include "insns/ne_insn.h" 22 | #include "insns/not_insn.h" 23 | #include "insns/or_insn.h" 24 | #include "insns/sub_insn.h" 25 | #include "insns/shl_insn.h" 26 | #include "insns/shr_insn.h" 27 | #include "insns/and_insn.h" 28 | #include "insns/xor_insn.h" 29 | 30 | using namespace std; 31 | 32 | 33 | namespace pc_emulator{ 34 | 35 | //! Class which registers and tracks all valid instructions 36 | class InsnRegistry { 37 | private: 38 | 39 | std::unordered_map> 40 | __InsnRegistry; /*!< Hash map of instruction name, Insn obj */ 41 | public: 42 | 43 | //! Constructor 44 | InsnRegistry(PCResourceImpl * AssociatedResource); 45 | 46 | //! Retrieve Insn object with the specified instruction name 47 | /*! 48 | \param InsnName Name of the instruction 49 | \return Insn object 50 | */ 51 | Insn* GetInsn(string InsnName); 52 | }; 53 | } 54 | 55 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/add_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_ADD_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_ADD_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! ADD instruction 10 | class ADD_Insn: public Insn { 11 | public: 12 | ADD_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "ADD"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/and_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_AND_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_AND_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! AND instruction 10 | class AND_Insn: public Insn { 11 | public: 12 | AND_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "AND"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable * CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/div_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_DIV_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_DIV_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! DIV instruction 10 | class DIV_Insn: public Insn { 11 | public: 12 | DIV_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "DIV"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/eq_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_EQ_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_EQ_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Equality checking instruction 10 | class EQ_Insn: public Insn { 11 | public: 12 | EQ_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "EQ"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/ge_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_GE_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_GE_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Greater than or equal instruction 10 | class GE_Insn: public Insn { 11 | public: 12 | GE_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "GE"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/gt_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_GT_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_GT_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Greater than instruction 10 | class GT_Insn: public Insn { 11 | public: 12 | GT_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "GT"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_INSN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | 12 | using namespace std; 13 | using namespace pc_specification; 14 | 15 | namespace pc_emulator { 16 | 17 | //! Generic abstract class for an IL instruction 18 | class Insn { 19 | public: 20 | 21 | PCResourceImpl * __AssociatedResource; /*!< Associated resource */ 22 | string __InsnName; /*!< Instruction name */ 23 | bool IsNegated; /*!< Should each operand be negated */ 24 | 25 | //! Called to execute the instruction 26 | /*! 27 | \param CurrentResult The CurrentResult register 28 | of the task executing this Insn 29 | \param Operands Operands to the instruction 30 | */ 31 | virtual void Execute(PCVariable *CurrentResult, 32 | std::vector& Operands) = 0; 33 | }; 34 | 35 | } 36 | 37 | 38 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/ld_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_LD_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_LD_INSN_H 3 | 4 | #include "src/pc_emulator/include/insns/insn.h" 5 | 6 | namespace pc_emulator { 7 | 8 | //! Load instruction 9 | class LD_Insn: public Insn { 10 | public: 11 | LD_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 12 | __AssociatedResource = AssociatedResource; 13 | IsNegated = isNegated; 14 | __InsnName = "LD"; 15 | }; 16 | 17 | //! Called to execute the instruction 18 | /*! 19 | \param CurrentResult The CurrentResult register 20 | of the task executing this Insn 21 | \param Operands Operands to the instruction 22 | */ 23 | void Execute(PCVariable *CurrentResult, 24 | std::vector& Operands); 25 | }; 26 | } 27 | 28 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/le_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_LE_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_LE_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Lesser than or equal instruction 10 | class LE_Insn: public Insn { 11 | public: 12 | LE_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "LE"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/lt_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_LT_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_LT_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Lesser than instruction 10 | class LT_Insn: public Insn { 11 | public: 12 | LT_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "LT"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/mod_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_MOD_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_MOD_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! MOD instruction 10 | class MOD_Insn: public Insn { 11 | public: 12 | MOD_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "MOD"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/mul_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_MUL_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_MUL_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Multiply instruction 10 | class MUL_Insn: public Insn { 11 | public: 12 | MUL_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "MUL"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/ne_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_NE_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_NE_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Test for not equal instruction 10 | class NE_Insn: public Insn { 11 | public: 12 | NE_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "NE"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/not_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_NOT_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_NOT_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! NOT instruction 10 | class NOT_Insn: public Insn { 11 | public: 12 | NOT_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "NOT"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/or_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_OR_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_OR_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Bitwise OR instruction 10 | class OR_Insn: public Insn { 11 | public: 12 | OR_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | IsNegated = isNegated; 15 | __InsnName = "OR"; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/shl_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_SHL_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_SHL_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/include/insns/insn.h" 8 | 9 | 10 | using namespace std; 11 | using namespace pc_specification; 12 | 13 | namespace pc_emulator { 14 | 15 | //! Generic abstract class for an Shift left instruction 16 | class SHL_Insn: public Insn { 17 | public: 18 | 19 | SHL_Insn(PCResourceImpl* AssociatedResource, bool isNegated) { 20 | __InsnName = "SHL"; 21 | __AssociatedResource = AssociatedResource; 22 | IsNegated = isNegated; 23 | } 24 | //! Called to execute the instruction 25 | /*! 26 | \param CurrentResult The CurrentResult register 27 | of the task executing this Insn 28 | \param Operands Operands to the instruction 29 | */ 30 | void Execute(PCVariable *CurrentResult, 31 | std::vector& Operands); 32 | }; 33 | 34 | } 35 | 36 | 37 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/shr_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_SHR_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_SHR_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/include/insns/insn.h" 8 | 9 | 10 | using namespace std; 11 | using namespace pc_specification; 12 | 13 | namespace pc_emulator { 14 | 15 | //! Generic abstract class for an Shift right instruction 16 | class SHR_Insn: public Insn { 17 | public: 18 | 19 | SHR_Insn(PCResourceImpl* AssociatedResource, bool isNegated) { 20 | __InsnName = "SHR"; 21 | __AssociatedResource = AssociatedResource; 22 | IsNegated = isNegated; 23 | } 24 | //! Called to execute the instruction 25 | /*! 26 | \param CurrentResult The CurrentResult register 27 | of the task executing this Insn 28 | \param Operands Operands to the instruction 29 | */ 30 | void Execute(PCVariable *CurrentResult, 31 | std::vector& Operands); 32 | }; 33 | 34 | } 35 | 36 | 37 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/st_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_ST_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_ST_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Store instruction 10 | class ST_Insn: public Insn { 11 | public: 12 | ST_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | __InsnName = "ST"; 15 | IsNegated = isNegated; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/sub_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_SUB_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_SUB_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Subtraction instruction 10 | class SUB_Insn: public Insn { 11 | public: 12 | SUB_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | __InsnName = "SUB"; 15 | IsNegated = isNegated; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/insns/xor_insn.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_INSNS_XOR_INSN_H 2 | #define __PC_EMULATOR_INCLUDE_INSNS_XOR_INSN_H 3 | 4 | 5 | #include "src/pc_emulator/include/insns/insn.h" 6 | 7 | namespace pc_emulator { 8 | 9 | //! Bitwise XOR instruction 10 | class XOR_Insn: public Insn { 11 | public: 12 | XOR_Insn(PCResourceImpl * AssociatedResource, bool isNegated) { 13 | __AssociatedResource = AssociatedResource; 14 | __InsnName = "XOR"; 15 | IsNegated = isNegated; 16 | }; 17 | 18 | //! Called to execute the instruction 19 | /*! 20 | \param CurrentResult The CurrentResult register 21 | of the task executing this Insn 22 | \param Operands Operands to the instruction 23 | */ 24 | void Execute(PCVariable *CurrentResult, 25 | std::vector& Operands); 26 | }; 27 | } 28 | 29 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/kronos_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_KRONOS_API_H__ 2 | #define __PC_EMULATOR_INCLUDE_KRONOS_API_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern "C" 12 | { 13 | #include 14 | #include 15 | } 16 | 17 | 18 | using namespace std; 19 | typedef unsigned long u32; 20 | 21 | #define TRACER_RESULTS 'J' 22 | 23 | //! Synchronization Functions 24 | string GetNxtCommand(int assignedTracerID); 25 | 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/pc_emulator/include/pc_clock.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_CLOCK_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_CLOCK_H__ 3 | 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | using namespace std::chrono; 17 | 18 | namespace pc_emulator { 19 | class PCResourceImpl; 20 | 21 | //! Clock associated with a resource 22 | class Clock { 23 | 24 | public: 25 | double __time; /*!< Current time */ 26 | bool __is_virtual; /*!< Is clock virtual ? */ 27 | double __expected_time; 28 | PCResourceImpl * __AssociatedResource; /*!< Associated Resource */ 29 | std::default_random_engine generator; 30 | bool __stop; 31 | 32 | //!Constructor 33 | Clock(bool is_virtual, PCResourceImpl * AssociatedResource); 34 | 35 | //! Returns current time 36 | double GetCurrentTime() { 37 | if (__is_virtual) { 38 | return __time/((double)1000000000.0); 39 | } 40 | 41 | __time = (duration_cast( 42 | system_clock::now() 43 | .time_since_epoch())).count()/1000.0; 44 | return __time; 45 | } 46 | 47 | //!Increments current time by the specified amount 48 | void UpdateCurrentTime(double inc_amount); 49 | 50 | //! Update current time depending on the executed function. 51 | void UpdateCurrentTime(string ExecutedFn); 52 | 53 | //! Sleep for specified duration in microseconds 54 | void SleepFor(int sleep_duration_us) ; 55 | }; 56 | } 57 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/pc_datatype_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_DATATYPE_REGISTRY_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_DATATYPE_REGISTRY_H__ 3 | 4 | #include 5 | #include 6 | 7 | 8 | #include "pc_datatype.h" 9 | 10 | using namespace std; 11 | 12 | 13 | namespace pc_emulator { 14 | class PCDataType; 15 | class PCConfiguration; 16 | 17 | //! Registers and tracks data types 18 | class DataTypeRegistry { 19 | private: 20 | PCConfiguration * __configuration; /*!< Associated configuration */ 21 | std::unordered_map> 22 | __Registry; /*!< A hashmap of resource name, data type obj */ 23 | public: 24 | //!Constructor 25 | DataTypeRegistry(PCConfiguration* configuration) : 26 | __configuration(configuration) {}; 27 | 28 | //!Register new data type 29 | void RegisterDataType(string DataTypeName, 30 | std::unique_ptr DataType); 31 | 32 | //!Retrieves data type with the specified name 33 | PCDataType * GetDataType(string DataTypeName); 34 | 35 | void GetAllRegisteredElementaryDataTypes( 36 | std::vector& ElementaryDataTypes); 37 | 38 | //! Clean's up all registered data types 39 | void Cleanup(); 40 | }; 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/pc_resource_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_RESOURCE_REGISTRY_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_RESOURCE_REGISTRY_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "pc_resource.h" 8 | 9 | 10 | using namespace std; 11 | 12 | 13 | namespace pc_emulator { 14 | class PCResource; 15 | class PCConfiguration; 16 | 17 | //! Registers and tracks resources 18 | class ResourceRegistry { 19 | private: 20 | PCConfiguration * __configuration; /*!< Associated configuration */ 21 | std::unordered_map> 22 | __Registry; /*!< A hashmap of resource name, resource obj */ 23 | public: 24 | //! Constructor 25 | ResourceRegistry(PCConfiguration* configuration) : 26 | __configuration(configuration) {}; 27 | 28 | //!Register new resource 29 | void RegisterResource(string ResourceName, 30 | std::unique_ptr Resource); 31 | 32 | //!Retrieves resource with the specified resource name 33 | PCResource * GetResource(string ResourceName); 34 | 35 | //! Clean's up all registered resources 36 | void Cleanup(); 37 | }; 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/resource_manager.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_RESOURCE_MANAGER_H__ 2 | #define __PC_EMULATOR_INCLUDE_RESOURCE_MANAGER_H__ 3 | 4 | using namespace std; 5 | 6 | #include 7 | #include "pc_datatype.h" 8 | #include "pc_variable.h" 9 | #include "pc_resource.h" 10 | 11 | #ifndef _GNU_SOURCE 12 | #define _GNU_SOURCE /* See feature_test_macros(7) */ 13 | #endif 14 | #include 15 | #include 16 | #define gettid() syscall(SYS_gettid) 17 | 18 | namespace pc_emulator { 19 | class ResourceManager { 20 | public : 21 | PCResourceImpl * __AssociatedResource; 22 | 23 | std::mutex m; 24 | pid_t ResourceThreadPid; 25 | void set_tid() { 26 | std::lock_guard l(m); 27 | ResourceThreadPid = syscall(SYS_gettid); 28 | } 29 | 30 | pid_t get_tid() { 31 | while(true) { 32 | std::lock_guard l(m); 33 | if(ResourceThreadPid != 0) 34 | break; 35 | } 36 | return ResourceThreadPid; 37 | } 38 | 39 | ResourceManager(PCResourceImpl * AssociatedResource) : 40 | __AssociatedResource(AssociatedResource) { 41 | ResourceThreadPid = 0; 42 | }; 43 | 44 | void ExecuteResource(); 45 | void ExecuteResourceManager(); 46 | 47 | std::thread LaunchResource(); 48 | std::thread LaunchResourceManager(); 49 | 50 | }; 51 | } 52 | 53 | 54 | 55 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfb/sfb.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFB_SFB_H 2 | #define __PC_EMULATOR_INCLUDE_SFB_SFB_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "src/pc_emulator/proto/configuration.pb.h" 9 | #include "src/pc_emulator/include/pc_configuration.h" 10 | #include "src/pc_emulator/include/pc_resource.h" 11 | #include "src/pc_emulator/include/pc_logger.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Generic abstract class for an SFB 19 | class SFB { 20 | public: 21 | 22 | PCResourceImpl * __AssociatedResource; /*!< Associated resource */ 23 | string __SFBName; /*!< Name of the system function block */ 24 | 25 | //! Called to execute the sfb 26 | /*! 27 | \param CurrentResult The CurrentResult register 28 | of the task executing this SFB 29 | \param SFB The SFB variable 30 | */ 31 | virtual void Execute(PCVariable *CurrentResult, 32 | PCVariable * SFB) = 0; 33 | }; 34 | 35 | } 36 | 37 | 38 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfb/tof.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFB_TOF_H 2 | #define __PC_EMULATOR_INCLUDE_SFB_TOF_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfb/sfb.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of TOF SFB 19 | class TOF: public SFB { 20 | public: 21 | 22 | TOF(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SFBName = "TOF"; 25 | } 26 | //! Called to execute the sfb 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFB 30 | \param SFB 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | PCVariable * SFB); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfb/ton.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFB_TON_H 2 | #define __PC_EMULATOR_INCLUDE_SFB_TON_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfb/sfb.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of TON SFB 19 | class TON: public SFB { 20 | public: 21 | 22 | TON(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SFBName = "TON"; 25 | } 26 | //! Called to execute the sfb 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFB 30 | \param SFB 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | PCVariable * SFB); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfb/tp.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFB_TP_H 2 | #define __PC_EMULATOR_INCLUDE_SFB_TP_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfb/sfb.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of TP SFB 19 | class TP: public SFB { 20 | public: 21 | 22 | TP(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SFBName = "TP"; 25 | } 26 | //! Called to execute the sfb 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFB 30 | \param SFB 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | PCVariable * SFB); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfb_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_SFB_REGISTRY_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_SFB_REGISTRY_H__ 3 | 4 | #include 5 | #include 6 | #include "pc_configuration.h" 7 | #include "pc_resource.h" 8 | #include "sfb/sfb.h" 9 | #include "sfb/tp.h" 10 | #include "sfb/ton.h" 11 | #include "sfb/tof.h" 12 | 13 | 14 | using namespace std; 15 | 16 | 17 | namespace pc_emulator{ 18 | 19 | //! Class which registers and tracks all valid SFB executors without code body 20 | class SFBRegistry { 21 | private: 22 | 23 | std::unordered_map> 24 | __SFB; /*!< Hash map of SFB name, SFBExec obj */ 25 | public: 26 | 27 | //! Constructor 28 | SFBRegistry(PCResourceImpl * AssociatedResource); 29 | 30 | //! Retrieve SFB object with the specified SFB name 31 | /*! 32 | \param SFBName Name of the instruction 33 | \return SFB object 34 | */ 35 | SFB* GetSFB(string SFBName); 36 | }; 37 | } 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/abs.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_ABS_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_ABS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of ABS SFC 19 | class ABS: public SFC { 20 | public: 21 | 22 | ABS(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "ABS"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/acos.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_ACOS_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_ACOS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of ACOS SFC 19 | class ACOS: public SFC { 20 | public: 21 | 22 | ACOS(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "ACOS"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/asin.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_ASIN_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_ASIN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of ASIN SFC 19 | class ASIN: public SFC { 20 | public: 21 | 22 | ASIN(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "ASIN"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/atan.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_ATAN_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_ATAN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of ATAN SFC 19 | class ATAN: public SFC { 20 | public: 21 | 22 | ATAN(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "ATAN"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/cos.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_COS_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_COS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of COS SFC 19 | class COS: public SFC { 20 | public: 21 | 22 | COS(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "COS"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/exp.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_EXP_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_EXP_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of EXP SFC 19 | class EXP: public SFC { 20 | public: 21 | 22 | EXP(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "EXP"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/gtod.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_GTOD_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_GTOD_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of Get Time of Day SFC 19 | class GTOD: public SFC { 20 | public: 21 | 22 | GTOD(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "GTOD"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/limit.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_LIMIT_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_LIMIT_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of LIMIT SFC 19 | class LIMIT: public SFC { 20 | public: 21 | 22 | LIMIT(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "LIMIT"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/ln.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_LN_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_LN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of LN SFC 19 | class LN: public SFC { 20 | public: 21 | 22 | LN(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "LN"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/log.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_LOG_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_LOG_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of LOG SFC 19 | class LOG: public SFC { 20 | public: 21 | 22 | LOG(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "LOG"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/max.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_MAX_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_MAX_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of MAX SFC 19 | class Max: public SFC { 20 | public: 21 | 22 | Max(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "MAX"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/min.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_MIN_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_MIN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of Min SFC 19 | class Min: public SFC { 20 | public: 21 | 22 | Min(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "MIN"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/mux.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_MUX_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_MUX_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of MUX SFC 19 | class MUX: public SFC { 20 | public: 21 | 22 | MUX(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "MUX"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/sel.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_SEL_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_SEL_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of SEL SFC 19 | class SEL: public SFC { 20 | public: 21 | 22 | SEL(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "SEL"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/sfc.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_SFC_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_SFC_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "src/pc_emulator/proto/configuration.pb.h" 9 | #include "src/pc_emulator/include/pc_configuration.h" 10 | #include "src/pc_emulator/include/pc_resource.h" 11 | #include "src/pc_emulator/include/pc_logger.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Generic abstract class for an IL SFC 19 | class SFC { 20 | public: 21 | 22 | PCResourceImpl * __AssociatedResource; /*!< Associated resource */ 23 | string __SfcName; /*!< Name of the system function */ 24 | 25 | //! Called to execute the sfc 26 | /*! 27 | \param CurrentResult The CurrentResult register 28 | of the task executing this SFC 29 | \param Operands Operands to the sfc 30 | */ 31 | virtual void Execute(PCVariable *CurrentResult, 32 | std::vector& Operands) = 0; 33 | }; 34 | 35 | } 36 | 37 | 38 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/sin.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_SIN_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_SIN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of SIN SFC 19 | class SIN: public SFC { 20 | public: 21 | 22 | SIN(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "SIN"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/sqrt.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_SQRT_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_SQRT_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of SQRT SFC 19 | class SQRT: public SFC { 20 | public: 21 | 22 | SQRT(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "SQRT"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc/tan.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SFC_TAN_H 2 | #define __PC_EMULATOR_INCLUDE_SFC_TAN_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "src/pc_emulator/proto/configuration.pb.h" 8 | #include "src/pc_emulator/include/pc_configuration.h" 9 | #include "src/pc_emulator/include/pc_resource.h" 10 | #include "src/pc_emulator/include/pc_logger.h" 11 | #include "src/pc_emulator/include/sfc/sfc.h" 12 | 13 | using namespace std; 14 | using namespace pc_specification; 15 | 16 | namespace pc_emulator { 17 | 18 | //! Definition of TAN SFC 19 | class TAN: public SFC { 20 | public: 21 | 22 | TAN(PCResourceImpl * AssociatedResource) { 23 | __AssociatedResource = AssociatedResource; 24 | __SfcName = "TAN"; 25 | } 26 | //! Called to execute the sfc 27 | /*! 28 | \param CurrentResult The CurrentResult register 29 | of the task executing this SFC 30 | \param Operands Operands to the sfc 31 | */ 32 | void Execute(PCVariable *CurrentResult, 33 | std::vector& Operands); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/sfc_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_PC_SFC_REGISTRY_H__ 2 | #define __PC_EMULATOR_INCLUDE_PC_SFC_REGISTRY_H__ 3 | 4 | #include 5 | #include 6 | #include "pc_configuration.h" 7 | #include "pc_resource.h" 8 | #include "sfc/sfc.h" 9 | #include "sfc/abs.h" 10 | #include "sfc/acos.h" 11 | #include "sfc/any_to_any.h" 12 | #include "sfc/asin.h" 13 | #include "sfc/atan.h" 14 | #include "sfc/cos.h" 15 | #include "sfc/exp.h" 16 | #include "sfc/gtod.h" 17 | #include "sfc/limit.h" 18 | #include "sfc/ln.h" 19 | #include "sfc/log.h" 20 | #include "sfc/max.h" 21 | #include "sfc/min.h" 22 | #include "sfc/mux.h" 23 | #include "sfc/sel.h" 24 | #include "sfc/sin.h" 25 | #include "sfc/sqrt.h" 26 | #include "sfc/tan.h" 27 | 28 | 29 | using namespace std; 30 | 31 | 32 | namespace pc_emulator{ 33 | 34 | //! Class which registers and tracks all valid SFCs 35 | class SFCRegistry { 36 | private: 37 | 38 | std::unordered_map> 39 | __SFC; /*!< Hash map of SFC name, SFC obj */ 40 | public: 41 | 42 | //! Constructor 43 | SFCRegistry(PCResourceImpl * AssociatedResource); 44 | 45 | //! Retrieve SFC object with the specified SFC name 46 | /*! 47 | \param SFCName Name of the instruction 48 | \return SFC object 49 | */ 50 | SFC* GetSFC(string SFCName); 51 | }; 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /src/pc_emulator/include/synchronized_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef __PC_EMULATOR_INCLUDE_SYNC_QUEUE_H__ 2 | #define __PC_EMULATOR_INCLUDE_SYNC_QUEUE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | template class SynchronizedQueue 11 | { 12 | std::queue queue_; 13 | std::mutex mutex_; 14 | std::condition_variable condvar_; 15 | 16 | typedef std::lock_guard lock; 17 | typedef std::unique_lock ulock; 18 | 19 | public: 20 | void push(T const &val) 21 | { 22 | lock l(mutex_); // prevents multiple pushes corrupting queue_ 23 | bool wake = queue_.empty(); // we may need to wake consumer 24 | queue_.push(val); 25 | if (wake) condvar_.notify_one(); 26 | } 27 | 28 | T pop() 29 | { 30 | ulock u(mutex_); 31 | while (queue_.empty()) 32 | condvar_.wait(u); 33 | // now queue_ is non-empty and we still have the lock 34 | T retval = queue_.front(); 35 | queue_.pop(); 36 | return retval; 37 | } 38 | 39 | bool IsEmpty() { 40 | return queue_.empty(); 41 | } 42 | }; 43 | 44 | #endif --------------------------------------------------------------------------------