Commit d87350fb56e904d3a0eb67e4011dcb42b9ece8bc

Authored by Peter M. Groen
Committed by GitHub
2 parents 1bd935fb 40c6b751

Merge pull request #2 from pgroen/feat/pgroen/modbus-rtu-implementation

Feat/pgroen/modbus rtu implementation
CMakeLists.txt
@@ -8,4 +8,6 @@ include(projectheader) @@ -8,4 +8,6 @@ include(projectheader)
8 project_header(modbus-cpp) 8 project_header(modbus-cpp)
9 9
10 add_subdirectory(src) 10 add_subdirectory(src)
  11 +add_subdirectory(tests)
  12 +# add_subdirectory(tools)
11 13
src/connectionconfig.h
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 #pragma once 7 #pragma once
8 8
9 #include <string> 9 #include <string>
  10 +#include <termios.h>
10 11
11 namespace osdev { 12 namespace osdev {
12 namespace components { 13 namespace components {
@@ -29,27 +30,17 @@ public: @@ -29,27 +30,17 @@ public:
29 NONE 30 NONE
30 }; 31 };
31 32
32 - enum class E_BAUDRATE  
33 - {  
34 - R1200 = 1200,  
35 - R2400 = 2400,  
36 - R4800 = 4800,  
37 - R9600 = 9600,  
38 - R19200 = 19200,  
39 - R38400 = 38400,  
40 - R57600 = 57600,  
41 - R76800 = 76800,  
42 - R115200 = 115200  
43 - };  
44 -  
45 ConnectionConfig(); 33 ConnectionConfig();
46 34
47 // Getters and Setters 35 // Getters and Setters
48 void setConnectionType( E_CONNECTIONTYPE type ) { m_conType = type; } 36 void setConnectionType( E_CONNECTIONTYPE type ) { m_conType = type; }
49 E_CONNECTIONTYPE getConnectionType() const { return m_conType; } 37 E_CONNECTIONTYPE getConnectionType() const { return m_conType; }
50 38
51 - void setBaudRate( E_BAUDRATE baud_rate ) { m_baudRate = baud_rate; }  
52 - E_BAUDRATE getBaudRate() const { return m_baudRate; } 39 + void setPortName(const std::string &port_name) { m_portName = port_name; }
  40 + std::string getPortName() { return m_portName; }
  41 +
  42 + void setBaudRate( speed_t baud_rate ) { m_baudRate = baud_rate; }
  43 + speed_t getBaudRate() const { return m_baudRate; }
53 44
54 void setParity(E_PARITY parity) { m_parity = parity; } 45 void setParity(E_PARITY parity) { m_parity = parity; }
55 E_PARITY getParity() const { return m_parity; } 46 E_PARITY getParity() const { return m_parity; }
@@ -70,14 +61,15 @@ public: @@ -70,14 +61,15 @@ public:
70 int getFrameTimeout() const { return m_frameTimeOut; } 61 int getFrameTimeout() const { return m_frameTimeOut; }
71 62
72 private: 63 private:
73 - E_CONNECTIONTYPE m_conType = E_CONNECTIONTYPE::UNKNOWN;  
74 - E_BAUDRATE m_baudRate = E_BAUDRATE::R9600;  
75 - E_PARITY m_parity = E_PARITY::NONE;  
76 - int m_dataBits = 8;  
77 - int m_stopBits = 1;  
78 - std::string m_ipAddress{};  
79 - unsigned int m_portNumber = 502;  
80 - int m_frameTimeOut = -1; 64 + E_CONNECTIONTYPE m_conType = E_CONNECTIONTYPE::UNKNOWN;
  65 + std::string m_portName = "/dev/ttyUSB0";
  66 + speed_t m_baudRate = B9600;
  67 + E_PARITY m_parity = E_PARITY::NONE;
  68 + int m_dataBits = 8;
  69 + int m_stopBits = 1;
  70 + std::string m_ipAddress{};
  71 + unsigned int m_portNumber = 502;
  72 + int m_frameTimeOut = -1;
81 73
82 }; 74 };
83 75
src/modbusbase.h
@@ -57,8 +57,8 @@ namespace modbus { @@ -57,8 +57,8 @@ namespace modbus {
57 class ModbusBase 57 class ModbusBase
58 { 58 {
59 public: 59 public:
60 - ModbusBase();  
61 - virtual ~ModbusBase(); 60 + ModbusBase() {}
  61 + virtual ~ModbusBase() {}
62 62
63 // Pure virtuals. Override when inherited. 63 // Pure virtuals. Override when inherited.
64 virtual bool Connect() = 0; 64 virtual bool Connect() = 0;
src/modbusrtu.cpp
@@ -4,3 +4,96 @@ @@ -4,3 +4,96 @@
4 * This source code is licensed under the MIT license found in the 4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree. 5 * LICENSE file in the root directory of this source tree.
6 */ 6 */
  7 +
  8 +#include "modbusrtu.h"
  9 +
  10 +#include <stdio.h>
  11 +
  12 +// Linux headers
  13 +#include <fcntl.h> // Contains file controls like O_RDWR
  14 +#include <errno.h> // Error integer and strerror() function
  15 +#include <termios.h> // Contains POSIX terminal control definitions
  16 +#include <unistd.h> // write(), read(), close()
  17 +
  18 +using namespace osdev::components::modbus;
  19 +
  20 +ModbusRtu::ModbusRtu( const ConnectionConfig &conf )
  21 + : m_conConfig( conf )
  22 + , m_socket( -1 )
  23 +{
  24 +}
  25 +
  26 +bool ModbusRtu::Connect()
  27 +{
  28 + m_socket = open( m_conConfig.getPortName().c_str(), O_RDWR);
  29 + if(m_socket == -1)
  30 + {
  31 + return false;
  32 + }
  33 +
  34 + struct termios l_tty;
  35 +
  36 + // Read in existing settings, and handle any error
  37 + if( tcgetattr(m_socket, &l_tty) != 0 )
  38 + {
  39 + // Replace later on with a logger line.
  40 + return false;
  41 + }
  42 +
  43 + /* Control modes */
  44 + l_tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
  45 + l_tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
  46 + l_tty.c_cflag &= ~CSIZE; // Clear all bits that set the data field
  47 + l_tty.c_cflag |= CS8; // 8 bits per byte (most common)
  48 + l_tty.c_cflag &= ~CRTSCTS; // Disable RTS / CTS hardware flow control (most common)
  49 + l_tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
  50 +
  51 + /* local modes */
  52 + l_tty.c_lflag &= ~ICANON; // Something, something CANONICAL.. Something, something Dark Side....
  53 + l_tty.c_lflag &= ~ECHO; // Disable echo
  54 + l_tty.c_lflag &= ~ECHOE; // Disable Erasure
  55 + l_tty.c_lflag &= ~ECHONL; // Diasble new-line echo
  56 + l_tty.c_lflag &= ~ISIG; // Disable interpretation of INTS, QUIT and SUSP
  57 + l_tty.c_lflag &= ~(IXON | IXOFF | IXANY ); // Turn off s/w flow control
  58 +
  59 + /* Ouput modes */
  60 + l_tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
  61 + l_tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
  62 +
  63 + // Wait for up to 1 seconds ( 10 deciseconds), returning as soon as any data is received.
  64 + l_tty.c_cc[VTIME] = 10;
  65 + l_tty.c_cc[VMIN] = 0;
  66 +
  67 + // Set the read and write baudrate.
  68 + cfsetispeed(&l_tty, m_conConfig.getBaudRate());
  69 + cfsetospeed(&l_tty, m_conConfig.getBaudRate());
  70 +
  71 + // Save the tty settings.
  72 + if( tcsetattr(m_socket, TCSANOW, &l_tty) != 0 )
  73 + {
  74 + Close();
  75 + return false;
  76 + }
  77 +
  78 + return true;
  79 +}
  80 +
  81 +bool ModbusRtu::Close()
  82 +{
  83 + if( close(m_socket) != 0 )
  84 + {
  85 + return false;
  86 + }
  87 + return true;
  88 +}
  89 +
  90 +int ModbusRtu::modbusSend(uint8_t *to_send, size_t length)
  91 +{
  92 + return write(m_socket, to_send, length);
  93 +
  94 +}
  95 +
  96 +int ModbusRtu::modbusReceive(uint8_t *buffer)
  97 +{
  98 + return read(m_socket, buffer, sizeof(*buffer));
  99 +}
src/modbusrtu.h
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 */ 6 */
7 7
8 #include "modbusbase.h" 8 #include "modbusbase.h"
  9 +#include "connectionconfig.h"
9 10
10 namespace osdev { 11 namespace osdev {
11 namespace components { 12 namespace components {
@@ -13,7 +14,31 @@ namespace modbus { @@ -13,7 +14,31 @@ namespace modbus {
13 14
14 class ModbusRtu : public ModbusBase 15 class ModbusRtu : public ModbusBase
15 { 16 {
  17 +public:
  18 + explicit ModbusRtu( const ConnectionConfig &conf );
  19 + virtual ~ModbusRtu() {}
16 20
  21 + virtual bool Connect() override;
  22 + virtual bool Close() override;
  23 +
  24 + /*!
  25 + * \brief modbusSend
  26 + * \param to_send
  27 + * \param length
  28 + * \return
  29 + */
  30 + virtual int modbusSend(uint8_t *to_send, size_t length) override;
  31 +
  32 + /*!
  33 + * \brief modbusReceive
  34 + * \param buffer
  35 + * \return
  36 + */
  37 + virtual int modbusReceive(uint8_t *buffer) override;
  38 +
  39 +private:
  40 + ConnectionConfig m_conConfig;
  41 + int m_socket;
17 }; 42 };
18 43
19 } /* End namespace modbus */ 44 } /* End namespace modbus */
tests/CMakeLists.txt 0 → 100644
  1 +# ****************************************************************
  2 +# Copyright (c)2022 Peter M. Groen
  3 +# This file is licensed under the MIT license found in the
  4 +# LICENSE file in the root directory of this source tree.
  5 +# ****************************************************************
  6 +add_executable(modbustest
  7 + connectionconfigtest.cpp
  8 +)
  9 +
  10 +target_include_directories(modbustest PRIVATE
  11 + ${CMAKE_CURRENT_SOURCE_DIR}
  12 + ${CMAKE_SOURCE_DIR}/include
  13 + ${CMAKE_SOURCE_DIR}/src
  14 + ${CMAKE_BINARY_DIR}
  15 +)
  16 +
  17 +target_link_libraries(modbustest PRIVATE
  18 + gmock_main
  19 + gmock
  20 + gtest
  21 + modbus-cpp
  22 +)
  23 +
  24 +add_test(NAME modbustest COMMAND modbustest)
  25 +
  26 +set_tests_properties(modbustest PROPERTIES
  27 + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
  28 +)
tests/connectionconfigtest.cpp 0 → 100644
  1 +/****************************************************************
  2 + * Copyright (c)2022 Peter M. Groen
  3 + * This file is licensed under the MIT license found in the
  4 + * LICENSE file in the root directory of this source tree.
  5 + ****************************************************************/
  6 +
  7 +#include <gmock/gmock.h>
  8 +#include <gtest/gtest.h>
  9 +
  10 +#include "connectionconfig.h"
  11 +
  12 +using namespace osdev::components::modbus;
  13 +
  14 +TEST(ConnectionConfigTest, SerialPortConfig)
  15 +{
  16 + ConnectionConfig oConfig;
  17 + oConfig.setBaudRate( B9600 );
  18 + oConfig.setConnectionType( ConnectionConfig::E_CONNECTIONTYPE::SERIAL );
  19 + oConfig.setDataBits( 8 );
  20 + oConfig.setStopBits( 1 );
  21 + oConfig.setFrameTimeout( 10 );
  22 + oConfig.setParity( ConnectionConfig::E_PARITY::NONE );
  23 + oConfig.setPortName( "/dev/ttyUSB0" );
  24 +
  25 + // Test all parameters
  26 +
  27 +}
tools/CMakeLists.txt 0 → 100644
  1 +cmake_minimum_required(VERSION 3.0)
  2 +project(modbus-cpp)
  3 +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
  4 +
  5 +# ==============================================================================
  6 +# = Include build information
  7 +include(projectheader)
  8 +project_header(modbus-cpp)
  9 +
  10 +add_subdirectory(modbus-master)
  11 +# add_subdirectory(modbus-slave)
tools/README.md 0 → 100644
tools/modbus-master/CMakeLists.txt 0 → 100644
  1 +cmake_minimum_required(VERSION 3.16)
  2 +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
  3 +
  4 +include(projectheader)
  5 +project_header(modbus-master)
  6 +
  7 +include(compiler)
  8 +
  9 +include_directories(
  10 + ${CMAKE_SOURCE_DIR}/include
  11 +)
  12 +
  13 +set(SRC_LIST
  14 +)
  15 +
tools/modbus-slave/CMakeLists.txt 0 → 100644
  1 +cmake_minimum_required(VERSION 3.16)
  2 +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
  3 +
  4 +include(projectheader)
  5 +project_header(modbus-cpp)
  6 +
  7 +include(compiler)
  8 +
  9 +include_directories(
  10 + ${CMAKE_SOURCE_DIR}/include
  11 +)
  12 +
  13 +set(SRC_LIST
  14 + ${CMAKE_CURRENT_SOURCE_DIR}/modbusbase.h
  15 + ${CMAKE_CURRENT_SOURCE_DIR}/modbusbase.cpp
  16 + ${CMAKE_CURRENT_SOURCE_DIR}/modbustcp.h
  17 + ${CMAKE_CURRENT_SOURCE_DIR}/modbustcp.cpp
  18 + ${CMAKE_CURRENT_SOURCE_DIR}/modbusrtu.h
  19 + ${CMAKE_CURRENT_SOURCE_DIR}/modbusrtu.cpp
  20 + ${CMAKE_CURRENT_SOURCE_DIR}/connectionconfig.h
  21 + ${CMAKE_CURRENT_SOURCE_DIR}/connectionconfig.cpp
  22 +)
  23 +
  24 +include(library)
  25 +add_libraries(PUBLIC
  26 +)
  27 +
  28 +include(installation)
  29 +install_component()
  30 +