modbusrtu.cpp
3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
* Copyright (c) 2022 Peter M. Groen
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "modbusrtu.h"
#include <stdio.h>
// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
using namespace osdev::components::modbus;
ModbusRtu::ModbusRtu( const ConnectionConfig &conf )
: m_conConfig( conf )
, m_socket( -1 )
{
}
bool ModbusRtu::Connect()
{
m_socket = open( m_conConfig.getPortName().c_str(), O_RDWR);
if(m_socket == -1)
{
return false;
}
struct termios l_tty;
// Read in existing settings, and handle any error
if( tcgetattr(m_socket, &l_tty) != 0 )
{
// Replace later on with a logger line.
return false;
}
/* Control modes */
l_tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
l_tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
l_tty.c_cflag &= ~CSIZE; // Clear all bits that set the data field
l_tty.c_cflag |= CS8; // 8 bits per byte (most common)
l_tty.c_cflag &= ~CRTSCTS; // Disable RTS / CTS hardware flow control (most common)
l_tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
/* local modes */
l_tty.c_lflag &= ~ICANON; // Something, something CANONICAL.. Something, something Dark Side....
l_tty.c_lflag &= ~ECHO; // Disable echo
l_tty.c_lflag &= ~ECHOE; // Disable Erasure
l_tty.c_lflag &= ~ECHONL; // Diasble new-line echo
l_tty.c_lflag &= ~ISIG; // Disable interpretation of INTS, QUIT and SUSP
l_tty.c_lflag &= ~(IXON | IXOFF | IXANY ); // Turn off s/w flow control
/* Ouput modes */
l_tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
l_tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
// Wait for up to 1 seconds ( 10 deciseconds), returning as soon as any data is received.
l_tty.c_cc[VTIME] = 10;
l_tty.c_cc[VMIN] = 0;
// Set the read and write baudrate.
cfsetispeed(&l_tty, m_conConfig.getBaudRate());
cfsetospeed(&l_tty, m_conConfig.getBaudRate());
// Save the tty settings.
if( tcsetattr(m_socket, TCSANOW, &l_tty) != 0 )
{
Close();
return false;
}
return true;
}
bool ModbusRtu::Close()
{
if( close(m_socket) != 0 )
{
return false;
}
return true;
}
int ModbusRtu::modbusSend(uint8_t *to_send, size_t length)
{
return write(m_socket, to_send, length);
}
int ModbusRtu::modbusReceive(uint8_t *buffer)
{
return read(m_socket, buffer, sizeof(*buffer));
}