Commit 58942988 authored by Marco Bartolini's avatar Marco Bartolini
Browse files

removed ModbusChannel from MedicinaMinorServo

parent f6c3f224
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4,9 +4,9 @@
#include <boost/shared_ptr.hpp>
#include <boost/timer.hpp>

#include "IRA"
#include <IRA>
#include <ModbusChannel.h>

#include "ModbusChannel.hpp"
#include "MedMinorServoProtocol.hpp"

#define PROTOCOLTIMEOUT 2 * 10000000
+0 −117
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
+14 −14
Original line number Diff line number Diff line
@@ -16,16 +16,16 @@ LIBRARIES_L =
# <brief description of lllll library>
MedMinorServoControl_OBJECTS   = MedMinorServoControl MedMinorServoGeometry \
                                 MedMinorServoTime MedMinorServoModbus \
                                 ModbusChannel PositionQueue
                                 PositionQueue

MedMinorServoControl_LIBS   = baci acsnc IRALibrary ManagmentDefinitionsStubs \
MedMinorServoControl_LIBS   = baci acsnc IRALibrary ModbusChannel ManagmentDefinitionsStubs \
                              ManagementErrors \
                              ComponentErrors modbus boost_thread

MinorServoBossImpl_OBJECTS = MedMinorServoControl MedMinorServoGeometry \
                             MedMinorServoStatus MedMinorServoParameters \
                             MedMinorServoTime MedMinorServoModbus \
                             MedMinorServoScan ModbusChannel PositionQueue \
                             MedMinorServoScan PositionQueue \
                             PositionMonitoringThread MSBossPublisher \
                             SetupThread ScanThread \
                             MSBossTracker MedMinorServoOffset MinorServoBossImpl
@@ -33,7 +33,7 @@ MinorServoBossImpl_OBJECTS = MedMinorServoControl MedMinorServoGeometry \
MinorServoBossImpl_LIBS = MedMinorServoBossStubs MinorServoBossStubs \
                          ManagmentDefinitionsStubs MinorServoDefinitionsStubs \
                          ManagementErrors \
                          IRALibrary ComponentErrors MinorServoErrors \
                          IRALibrary ModbusChannel ComponentErrors MinorServoErrors \
                          acsnc ParserErrors AntennaDefinitionsStubs \
                          MountStubs AntennaBossStubs AntennaErrors \
                          ActiveSurfaceBossStubs boost_thread acstime modbus \
@@ -42,20 +42,20 @@ MinorServoBossImpl_LIBS = MedMinorServoBossStubs MinorServoBossStubs \
EXECUTABLES_L     = testclient testgeometry testprimary testsecondary testpassive real_to_virtual
real_to_virtual_OBJECTS = real_to_virtual testutils MedMinorServoGeometry MedMinorServoTime
real_to_virtual_LIBS = IRALibrary
testclient_OBJECTS = testclient testutils MedMinorServoModbus ModbusChannel MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testclient_LIBS = IRALibrary boost_thread modbus 
testprimary_OBJECTS = testprimary testutils MedMinorServoModbus ModbusChannel MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testprimary_LIBS = IRALibrary boost_thread modbus 
testsecondary_OBJECTS = testsecondary testutils MedMinorServoModbus ModbusChannel MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testsecondary_LIBS = IRALibrary boost_thread modbus 
testpassive_OBJECTS = testpassive testutils MedMinorServoModbus ModbusChannel MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testpassive_LIBS = IRALibrary boost_thread modbus 
testclient_OBJECTS = testclient testutils MedMinorServoModbus MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testclient_LIBS = IRALibrary boost_thread modbus ModbusChannel
testprimary_OBJECTS = testprimary testutils MedMinorServoModbus MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testprimary_LIBS = IRALibrary boost_thread modbus ModbusChannel
testsecondary_OBJECTS = testsecondary testutils MedMinorServoModbus MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testsecondary_LIBS = IRALibrary boost_thread modbus ModbusChannel
testpassive_OBJECTS = testpassive testutils MedMinorServoModbus MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
testpassive_LIBS = IRALibrary boost_thread modbus ModbusChannel
testgeometry_OBJECTS = testgeometry testutils MedMinorServoGeometry MedMinorServoTime PositionQueue
testgeometry_LIBS = IRALibrary boost_unit_test_framework boost_thread modbus 

EXECUTABLES = scudisconnect
scudisconnect_OBJECTS = scudisconnect MedMinorServoModbus ModbusChannel MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
scudisconnect_LIBS = IRALibrary modbus boost_thread
scudisconnect_OBJECTS = scudisconnect MedMinorServoModbus MedMinorServoGeometry MedMinorServoTime MedMinorServoControl PositionQueue
scudisconnect_LIBS = IRALibrary modbus ModbusChannel boost_thread

#
# Configuration Database Files
+0 −113
Original line number Diff line number Diff line
#include "ModbusChannel.hpp"

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);
};