Loading Common/Libraries/ModbusChannel/include/ModbusChannel.h 0 → 100755 +117 −0 Original line number Diff line number Diff line #ifndef MODBUSCHANNEL_HPP #define MODBUSCHANNEL_HPP #include <modbus/modbus.h> #include <sys/time.h> #include <string> #include <cerrno> #include <stdexcept> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #define MODBUS_DEFAULT_PORT MODBUS_TCP_DEFAULT_PORT #define MODBUS_TIMEOUT 2 class ModbusChannel; //fwd declaration typedef boost::shared_ptr<ModbusChannel> ModbusChannel_sp; ModbusChannel_sp get_modbus_channel(const char* server_ip, int server_port=MODBUS_DEFAULT_PORT); class ModbusError: public std::runtime_error { public: ModbusError(const char *msg): std::runtime_error(std::string(msg)){}; }; class ModbusTimeout : public ModbusError { public: ModbusTimeout(const char *msg): ModbusError(msg){}; }; /** * utility called for raising the proper errors during execution of * modbus methods */ void modbus_check_error(int rc); class ModbusChannel { public: /** * Ctor * @param ip: the ip of the modbus server * @param port: the modbus server port, defaults to 502 as specified by * modbus refence documentation */ ModbusChannel(const char* server_ip, int server_port = MODBUS_DEFAULT_PORT); /** * destructor */ virtual ~ModbusChannel(); /** * Synchronized */ void connect(); //throw ModbusError /** * Synchronized */ void disconnect(); inline bool is_connected() {return _is_connected;}; /** * Read from the server the specified bytes into the dest_buffer. * It verifies that the specified address is even and also * size is even so that it can use 16 bit words addressing as specified * by modbus library. If something goes wrong raises a ModbusError. * @param address: the address in bytes of the registers to be read * @param size: the size in bytes of the buffer to be read * @param dest_buffer: the binary content where data will be copied */ void read(int address, int size, unsigned char *dest_buffer); //throw ModbusError /** * Write the content of source_buffer at the specified address in the * server. It verifies that the destination address is even and also * size is even so that it can use 16 bit words addressing as specified * by modbus library. If something goes wrong raises a ModbusError. * @param address: the address in bytes of the registers to be written * @param size: the size in bytes of the buffer to be written * @param source_buffer: the binary content to be copied into the server */ void write(int address, int size, const unsigned char *source_buffer); //throw ModbusError /** * Template method used for directly unpacking the read value at * specified address, into the return type */ template<typename T> T get(int address); //throw ModbusError private: /* class members */ boost::mutex _connection_guard; std::string _server_ip; int _server_port; bool _is_connected; modbus_t *_modbus_context; /* We do not want this object to be copied so we prohibit copying * operations by definition , the _modbus_context is thread safe * so the ModbusChannel can be shared among many threads */ ModbusChannel(const ModbusChannel&); ModbusChannel& operator=(const ModbusChannel&); }; template <typename T> T ModbusChannel::get(int address) { T return_value; this->read(address, sizeof(T), (unsigned char*)(&return_value)); return return_value; } #endif Common/Libraries/ModbusChannel/src/Makefile 0 → 100644 +208 −0 Original line number Diff line number Diff line #******************************************************************************* # PPPPPPPP # # "@(#) $Id$" # # Makefile of ........ # # who when what # -------- -------- ---------------------------------------------- # mbartolini 03/03/15 created # #******************************************************************************* # This Makefile follows VLT Standards (see Makefile(5) for more). #******************************************************************************* # REMARKS # None #------------------------------------------------------------------------ # # user definable C-compilation flags #USER_CFLAGS = # # additional include and library search paths #USER_INC = #USER_LIB = # # MODULE CODE DESCRIPTION: # ------------------------ # As a general rule: public file are "cleaned" and "installed" # local (_L) are not "installed". # # C programs (public and local) # ----------------------------- EXECUTABLES = EXECUTABLES_L = # # <brief description of xxxxx program> xxxxx_OBJECTS = xxxxx_LDFLAGS = xxxxx_LIBS = # # special compilation flags for single c sources #yyyyy_CFLAGS = # # Includes (.h) files (public only) # --------------------------------- INCLUDES = ModbusChannel.h # # Libraries (public and local) # ---------------------------- LIBRARIES = ModbusChannel LIBRARIES_L = # # <brief description of lllll library> ModbusChannel_OBJECTS = ModbusChannel ModbusChannel_LIBS = modbus boost_thread # # Scripts (public and local) # ---------------------------- SCRIPTS = SCRIPTS_L = # # TCL scripts (public and local) # ------------------------------ TCL_SCRIPTS = TCL_SCRIPTS_L = # # Python stuff (public and local) # ---------------------------- PY_SCRIPTS = PY_SCRIPTS_L = PY_MODULES = PY_MODULES_L = PY_PACKAGES = PY_PACKAGES_L = pppppp_MODULES = # # <brief description of tttttt tcl-script> tttttt_OBJECTS = tttttt_TCLSH = tttttt_LIBS = # # TCL libraries (public and local) # ------------------------------ TCL_LIBRARIES = TCL_LIBRARIES_L = # # <brief description of tttlll library> tttlll_OBJECTS = # # Configuration Database Files # ---------------------------- CDB_SCHEMAS = # # IDL Files and flags # IDL_FILES = TAO_IDLFLAGS = USER_IDL = # # Jarfiles and their directories # JARFILES= jjj_DIRS= jjj_EXTRAS= # # java sources in Jarfile on/off DEBUG= # # ACS XmlIdl generation on/off # XML_IDL= # # Java Component Helper Classes generation on/off # COMPONENT_HELPERS= # # Java Entity Classes generation on/off # XSDBIND= # # Schema Config files for the above # XSDBIND_INCLUDE= # man pages to be done # -------------------- MANSECTIONS = MAN1 = MAN3 = MAN5 = MAN7 = MAN8 = # # local man pages # --------------- MANl = # # ASCII file to be converted into Framemaker-MIF # -------------------- ASCII_TO_MIF = # # other files to be installed #---------------------------- INSTALL_FILES = # # list of all possible C-sources (used to create automatic dependencies) # ------------------------------ CSOURCENAMES = \ $(foreach exe, $(EXECUTABLES) $(EXECUTABLES_L), $($(exe)_OBJECTS)) \ $(foreach rtos, $(RTAI_MODULES) , $($(rtos)_OBJECTS)) \ $(foreach lib, $(LIBRARIES) $(LIBRARIES_L), $($(lib)_OBJECTS)) # #>>>>> END OF standard rules # # INCLUDE STANDARDS # ----------------- MAKEDIRTMP := $(shell searchFile include/acsMakefile) ifneq ($(MAKEDIRTMP),\#error\#) MAKEDIR := $(MAKEDIRTMP)/include include $(MAKEDIR)/acsMakefile endif # # TARGETS # ------- all: do_all @echo " . . . 'all' done" clean : clean_all @echo " . . . clean done" clean_dist : clean_all clean_dist_all @echo " . . . clean_dist done" man : do_man @echo " . . . man page(s) done" install : install_all @echo " . . . installation done" #___oOo___ Common/Libraries/ModbusChannel/src/ModbusChannel.cpp 0 → 100755 +113 −0 Original line number Diff line number Diff line #include "ModbusChannel.h" ModbusChannel_sp get_modbus_channel(const char *server_ip, int server_port) { ModbusChannel_sp _modbus_channel(new ModbusChannel(server_ip, server_port)); _modbus_channel->connect(); return _modbus_channel; }; void modbus_check_error(int rc) { if( rc == -1) { if(errno == ETIMEDOUT){ throw ModbusTimeout(modbus_strerror(errno)); }else{ throw ModbusError(modbus_strerror(errno)); } } }; ModbusChannel::ModbusChannel(const char* server_ip, int server_port) : _server_ip(std::string(server_ip)), _server_port(server_port), _is_connected(false), _modbus_context(NULL) { int rc; this->_modbus_context = modbus_new_tcp(this->_server_ip.c_str(), this->_server_port); if(this->_modbus_context == NULL) { throw ModbusError(modbus_strerror(errno)); } rc = modbus_set_error_recovery(this->_modbus_context, (modbus_error_recovery_mode) (MODBUS_ERROR_RECOVERY_PROTOCOL | MODBUS_ERROR_RECOVERY_LINK) ); modbus_check_error(rc); timeval _response_timeout; _response_timeout.tv_sec = MODBUS_TIMEOUT; _response_timeout.tv_usec = 0; modbus_set_response_timeout(this->_modbus_context, &_response_timeout); }; ModbusChannel::~ModbusChannel() { this->disconnect(); modbus_free(this->_modbus_context); }; void ModbusChannel::connect() { boost::mutex::scoped_lock lock(_connection_guard); int rc; if(!(this->_is_connected)) { rc = modbus_connect(this->_modbus_context); modbus_check_error(rc); this->_is_connected = true; } }; void ModbusChannel::disconnect() { boost::mutex::scoped_lock lock(_connection_guard); if(this->_is_connected){ modbus_close(this->_modbus_context); this->_is_connected = false; } }; void ModbusChannel::read(int address, int size, unsigned char *dest) { int rc; if(!(size % 2 == 0)) { throw ModbusError("data transfer size must be even"); } int _size = size / 2; if(!(address % 2 == 0)) { throw ModbusError("destination address must be even"); } int _address = address / 2; rc = modbus_read_registers(this->_modbus_context, _address, _size, (uint16_t *)dest); modbus_check_error(rc); }; void ModbusChannel::write(int address, int size, const unsigned char *source_buffer) { int rc; if(!(size % 2 == 0)) { throw ModbusError("data transfer size must be even"); } int _size = size / 2; if(!(address % 2 == 0)) { throw ModbusError("destination address must be even"); } int _address = address / 2; rc = modbus_write_registers(this->_modbus_context, _address, _size, (uint16_t *)source_buffer); modbus_check_error(rc); }; Loading
Common/Libraries/ModbusChannel/include/ModbusChannel.h 0 → 100755 +117 −0 Original line number Diff line number Diff line #ifndef MODBUSCHANNEL_HPP #define MODBUSCHANNEL_HPP #include <modbus/modbus.h> #include <sys/time.h> #include <string> #include <cerrno> #include <stdexcept> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #define MODBUS_DEFAULT_PORT MODBUS_TCP_DEFAULT_PORT #define MODBUS_TIMEOUT 2 class ModbusChannel; //fwd declaration typedef boost::shared_ptr<ModbusChannel> ModbusChannel_sp; ModbusChannel_sp get_modbus_channel(const char* server_ip, int server_port=MODBUS_DEFAULT_PORT); class ModbusError: public std::runtime_error { public: ModbusError(const char *msg): std::runtime_error(std::string(msg)){}; }; class ModbusTimeout : public ModbusError { public: ModbusTimeout(const char *msg): ModbusError(msg){}; }; /** * utility called for raising the proper errors during execution of * modbus methods */ void modbus_check_error(int rc); class ModbusChannel { public: /** * Ctor * @param ip: the ip of the modbus server * @param port: the modbus server port, defaults to 502 as specified by * modbus refence documentation */ ModbusChannel(const char* server_ip, int server_port = MODBUS_DEFAULT_PORT); /** * destructor */ virtual ~ModbusChannel(); /** * Synchronized */ void connect(); //throw ModbusError /** * Synchronized */ void disconnect(); inline bool is_connected() {return _is_connected;}; /** * Read from the server the specified bytes into the dest_buffer. * It verifies that the specified address is even and also * size is even so that it can use 16 bit words addressing as specified * by modbus library. If something goes wrong raises a ModbusError. * @param address: the address in bytes of the registers to be read * @param size: the size in bytes of the buffer to be read * @param dest_buffer: the binary content where data will be copied */ void read(int address, int size, unsigned char *dest_buffer); //throw ModbusError /** * Write the content of source_buffer at the specified address in the * server. It verifies that the destination address is even and also * size is even so that it can use 16 bit words addressing as specified * by modbus library. If something goes wrong raises a ModbusError. * @param address: the address in bytes of the registers to be written * @param size: the size in bytes of the buffer to be written * @param source_buffer: the binary content to be copied into the server */ void write(int address, int size, const unsigned char *source_buffer); //throw ModbusError /** * Template method used for directly unpacking the read value at * specified address, into the return type */ template<typename T> T get(int address); //throw ModbusError private: /* class members */ boost::mutex _connection_guard; std::string _server_ip; int _server_port; bool _is_connected; modbus_t *_modbus_context; /* We do not want this object to be copied so we prohibit copying * operations by definition , the _modbus_context is thread safe * so the ModbusChannel can be shared among many threads */ ModbusChannel(const ModbusChannel&); ModbusChannel& operator=(const ModbusChannel&); }; template <typename T> T ModbusChannel::get(int address) { T return_value; this->read(address, sizeof(T), (unsigned char*)(&return_value)); return return_value; } #endif
Common/Libraries/ModbusChannel/src/Makefile 0 → 100644 +208 −0 Original line number Diff line number Diff line #******************************************************************************* # PPPPPPPP # # "@(#) $Id$" # # Makefile of ........ # # who when what # -------- -------- ---------------------------------------------- # mbartolini 03/03/15 created # #******************************************************************************* # This Makefile follows VLT Standards (see Makefile(5) for more). #******************************************************************************* # REMARKS # None #------------------------------------------------------------------------ # # user definable C-compilation flags #USER_CFLAGS = # # additional include and library search paths #USER_INC = #USER_LIB = # # MODULE CODE DESCRIPTION: # ------------------------ # As a general rule: public file are "cleaned" and "installed" # local (_L) are not "installed". # # C programs (public and local) # ----------------------------- EXECUTABLES = EXECUTABLES_L = # # <brief description of xxxxx program> xxxxx_OBJECTS = xxxxx_LDFLAGS = xxxxx_LIBS = # # special compilation flags for single c sources #yyyyy_CFLAGS = # # Includes (.h) files (public only) # --------------------------------- INCLUDES = ModbusChannel.h # # Libraries (public and local) # ---------------------------- LIBRARIES = ModbusChannel LIBRARIES_L = # # <brief description of lllll library> ModbusChannel_OBJECTS = ModbusChannel ModbusChannel_LIBS = modbus boost_thread # # Scripts (public and local) # ---------------------------- SCRIPTS = SCRIPTS_L = # # TCL scripts (public and local) # ------------------------------ TCL_SCRIPTS = TCL_SCRIPTS_L = # # Python stuff (public and local) # ---------------------------- PY_SCRIPTS = PY_SCRIPTS_L = PY_MODULES = PY_MODULES_L = PY_PACKAGES = PY_PACKAGES_L = pppppp_MODULES = # # <brief description of tttttt tcl-script> tttttt_OBJECTS = tttttt_TCLSH = tttttt_LIBS = # # TCL libraries (public and local) # ------------------------------ TCL_LIBRARIES = TCL_LIBRARIES_L = # # <brief description of tttlll library> tttlll_OBJECTS = # # Configuration Database Files # ---------------------------- CDB_SCHEMAS = # # IDL Files and flags # IDL_FILES = TAO_IDLFLAGS = USER_IDL = # # Jarfiles and their directories # JARFILES= jjj_DIRS= jjj_EXTRAS= # # java sources in Jarfile on/off DEBUG= # # ACS XmlIdl generation on/off # XML_IDL= # # Java Component Helper Classes generation on/off # COMPONENT_HELPERS= # # Java Entity Classes generation on/off # XSDBIND= # # Schema Config files for the above # XSDBIND_INCLUDE= # man pages to be done # -------------------- MANSECTIONS = MAN1 = MAN3 = MAN5 = MAN7 = MAN8 = # # local man pages # --------------- MANl = # # ASCII file to be converted into Framemaker-MIF # -------------------- ASCII_TO_MIF = # # other files to be installed #---------------------------- INSTALL_FILES = # # list of all possible C-sources (used to create automatic dependencies) # ------------------------------ CSOURCENAMES = \ $(foreach exe, $(EXECUTABLES) $(EXECUTABLES_L), $($(exe)_OBJECTS)) \ $(foreach rtos, $(RTAI_MODULES) , $($(rtos)_OBJECTS)) \ $(foreach lib, $(LIBRARIES) $(LIBRARIES_L), $($(lib)_OBJECTS)) # #>>>>> END OF standard rules # # INCLUDE STANDARDS # ----------------- MAKEDIRTMP := $(shell searchFile include/acsMakefile) ifneq ($(MAKEDIRTMP),\#error\#) MAKEDIR := $(MAKEDIRTMP)/include include $(MAKEDIR)/acsMakefile endif # # TARGETS # ------- all: do_all @echo " . . . 'all' done" clean : clean_all @echo " . . . clean done" clean_dist : clean_all clean_dist_all @echo " . . . clean_dist done" man : do_man @echo " . . . man page(s) done" install : install_all @echo " . . . installation done" #___oOo___
Common/Libraries/ModbusChannel/src/ModbusChannel.cpp 0 → 100755 +113 −0 Original line number Diff line number Diff line #include "ModbusChannel.h" ModbusChannel_sp get_modbus_channel(const char *server_ip, int server_port) { ModbusChannel_sp _modbus_channel(new ModbusChannel(server_ip, server_port)); _modbus_channel->connect(); return _modbus_channel; }; void modbus_check_error(int rc) { if( rc == -1) { if(errno == ETIMEDOUT){ throw ModbusTimeout(modbus_strerror(errno)); }else{ throw ModbusError(modbus_strerror(errno)); } } }; ModbusChannel::ModbusChannel(const char* server_ip, int server_port) : _server_ip(std::string(server_ip)), _server_port(server_port), _is_connected(false), _modbus_context(NULL) { int rc; this->_modbus_context = modbus_new_tcp(this->_server_ip.c_str(), this->_server_port); if(this->_modbus_context == NULL) { throw ModbusError(modbus_strerror(errno)); } rc = modbus_set_error_recovery(this->_modbus_context, (modbus_error_recovery_mode) (MODBUS_ERROR_RECOVERY_PROTOCOL | MODBUS_ERROR_RECOVERY_LINK) ); modbus_check_error(rc); timeval _response_timeout; _response_timeout.tv_sec = MODBUS_TIMEOUT; _response_timeout.tv_usec = 0; modbus_set_response_timeout(this->_modbus_context, &_response_timeout); }; ModbusChannel::~ModbusChannel() { this->disconnect(); modbus_free(this->_modbus_context); }; void ModbusChannel::connect() { boost::mutex::scoped_lock lock(_connection_guard); int rc; if(!(this->_is_connected)) { rc = modbus_connect(this->_modbus_context); modbus_check_error(rc); this->_is_connected = true; } }; void ModbusChannel::disconnect() { boost::mutex::scoped_lock lock(_connection_guard); if(this->_is_connected){ modbus_close(this->_modbus_context); this->_is_connected = false; } }; void ModbusChannel::read(int address, int size, unsigned char *dest) { int rc; if(!(size % 2 == 0)) { throw ModbusError("data transfer size must be even"); } int _size = size / 2; if(!(address % 2 == 0)) { throw ModbusError("destination address must be even"); } int _address = address / 2; rc = modbus_read_registers(this->_modbus_context, _address, _size, (uint16_t *)dest); modbus_check_error(rc); }; void ModbusChannel::write(int address, int size, const unsigned char *source_buffer) { int rc; if(!(size % 2 == 0)) { throw ModbusError("data transfer size must be even"); } int _size = size / 2; if(!(address % 2 == 0)) { throw ModbusError("destination address must be even"); } int _address = address / 2; rc = modbus_write_registers(this->_modbus_context, _address, _size, (uint16_t *)source_buffer); modbus_check_error(rc); };