Skip to content

Commit 5a1d7f6

Browse files
Merge pull request #18 from NikolasK-source/main
Release 1.2.3
2 parents a9ac422 + 666170d commit 5a1d7f6

File tree

7 files changed

+104
-79
lines changed

7 files changed

+104
-79
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR)
44
# ======================================================================================================================
55

66
# project
7-
project(Modbus_TCP_client_shm LANGUAGES CXX VERSION 1.2.2)
7+
project(Modbus_TCP_client_shm LANGUAGES CXX VERSION 1.2.3)
88

99
# settings
1010
set(Target "modbus-tcp-client-shm") # Executable name (without file extension!)

README.md

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,46 @@ As an alternative to the ```git submodule``` commands, the ```--recursive``` opt
1616

1717
## Use
1818
```
19-
Modbus_TCP_client_shm [OPTION...]
19+
modbus-tcp-client-shm [OPTION...]
2020
21-
-i, --ip arg ip to listen for incoming connections (default: 0.0.0.0)
22-
-p, --port arg port to listen for incoming connections (default: 502)
23-
-n, --name-prefix arg shared memory name prefix (default: modbus_)
24-
--do-registers arg number of digital output registers (default: 65536)
25-
--di-registers arg number of digital input registers (default: 65536)
26-
--ao-registers arg number of analog output registers (default: 65536)
27-
--ai-registers arg number of analog input registers (default: 65536)
28-
-m, --monitor output all incoming and outgoing packets to stdout
29-
-r, --reconnect do not terminate if Master disconnects.
30-
-h, --help print usage
21+
-i, --ip arg ip to listen for incoming connections (default: 0.0.0.0)
22+
-p, --port arg port to listen for incoming connections (default: 502)
23+
-n, --name-prefix arg shared memory name prefix (default: modbus_)
24+
--do-registers arg number of digital output registers (default: 65536)
25+
--di-registers arg number of digital input registers (default: 65536)
26+
--ao-registers arg number of analog output registers (default: 65536)
27+
--ai-registers arg number of analog input registers (default: 65536)
28+
-m, --monitor output all incoming and outgoing packets to stdout
29+
-r, --reconnect do not terminate if the Modbus Server disconnects.
30+
--byte-timeout arg timeout interval in seconds between two consecutive bytes of the same message. In most
31+
cases it is sufficient to set the response timeout. Fractional values are possible.
32+
--response-timeout arg set the timeout interval in seconds used to wait for a response. When a byte timeout is
33+
set, if the elapsed time for the first byte of response is longer than the given timeout,
34+
a timeout is detected. When byte timeout is disabled, the full confirmation response must
35+
be received before expiration of the response timeout. Fractional values are possible.
36+
-t, --tcp-timeout arg tcp timeout in seconds. Set to 0 to use the system defaults (not recommended). (default:
37+
5)
38+
--force Force the use of the shared memory even if it already exists. Do not use this option per
39+
default! It should only be used if the shared memory of an improperly terminated instance
40+
continues to exist as an orphan and is no longer used.
41+
-s, --separate arg Use a separate shared memory for requests with the specified client id. The the client id
42+
(as hex value) is appended to the shared memory prefix (e.g. modbus_fc_DO). You can
43+
specify multiple client ids by separating them with ','. Use --separate-all to generate
44+
separate shared memories for all possible client ids.
45+
--separate-all like --separate, but for all client ids (creates 1028 shared memory files! check/set
46+
'ulimit -n' before using this option.)
47+
-h, --help print usage
48+
--version print version information
49+
--license show licences
3150
3251
3352
The modbus registers are mapped to shared memory objects:
34-
type | name | master-access | shm name
35-
-----|---------------------------|-----------------|----------------
36-
DO | Discrete Output Coils | read-write | <name-prefix>DO
37-
DI | Discrete Input Coils | read-only | <name-prefix>DI
38-
AO | Discrete Output Registers | read-write | <name-prefix>AO
39-
AI | Discrete Input Registers | read-only | <name-prefix>AI
53+
type | name | mb-server-access | shm name
54+
-----|---------------------------|------------------|----------------
55+
DO | Discrete Output Coils | read-write | <name-prefix>DO
56+
DI | Discrete Input Coils | read-only | <name-prefix>DI
57+
AO | Discrete Output Registers | read-write | <name-prefix>AO
58+
AI | Discrete Input Registers | read-only | <name-prefix>AI
4059
```
4160

4261
### Use privileged ports

docs/index.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@ One for each register type:
1313
- Discrete Input Registers (AI)
1414

1515
All registers are initialized with 0 at the beginning.
16-
The Modbus master reads and writes directly the values from these shared memories.
16+
The Modbus server reads and writes directly the values from these shared memories.
1717

1818
The actual functionality of the client is realized by applications that read data from or write data to the shared memory.
1919

2020

2121
## Use the Application
2222
The application can be started completely without command line arguments.
2323
In this case the client listens for connections on all IPs on port 502 (the default modbus port).
24-
The application terminates if the master disconnects.
24+
The application terminates if the Modbus server disconnects.
2525

2626
The arguments ```--port``` and ```--ip``` can be used to specify port and ip to listen to.
2727

2828
By using the command line argument ```--monitor``` all incoming and outgoing packets are printed on stdout.
29-
This option should be used carefully, as it generates large amounts of output depending on the masters polling cycle and the number of used registers.
29+
This option should be used carefully, as it generates large amounts of output depending on the Modbus servers polling cycle and the number of used registers.
3030

31-
The ```--reconnect``` option can be used to specify that the application is not terminated when the master disconnects, but waits for a new connection.
31+
The ```--reconnect``` option can be used to specify that the application is not terminated when the Modbus Server disconnects, but waits for a new connection.
3232

3333
The client creates four shared memories and names them ```modbus_DO```, ```modbus_DI```, ```modbus_AO``` and ```modbus_AI``` by default.
3434
The prefix modbus_ can be changed via the argument ```--name-prefix```.
@@ -76,8 +76,14 @@ This option cannot be used with flatpaks.
7676
setcap 'cap_net_bind_service=+ep' /path/to/binary
7777
```
7878

79+
## Install
7980

80-
## Using the Flatpak package
81+
### Using the Modbus Collection Flapak Package: Shared Memory Modbus (recommended)
82+
[SHM-Modbus](https://nikolask-source.github.io/SHM_Modbus/) is a collection of the shared memory modbus tools.
83+
It is available as flatpak and published on flathub as ```network.koesling.shm-modbs```.
84+
85+
86+
### Using the Standalone Flatpak Package
8187
The flatpak package can be installed via the .flatpak file.
8288
This can be downloaded from the GitHub [projects release page](https://github.com/NikolasK-source/modbus_tcp_client_shm/releases):
8389

@@ -94,7 +100,7 @@ To enable calling with ```modbus-tcp-client-shm``` [this script](https://gist.gi
94100
In order to be executable everywhere, the path in which the script is placed must be in the ```PATH``` environment variable.
95101

96102

97-
## Build from Source
103+
### Build from Source
98104

99105
The following packages are required for building the application:
100106
- cmake

src/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
target_sources(${Target} PRIVATE main.cpp)
55
target_sources(${Target} PRIVATE modbus_shm.cpp)
6-
target_sources(${Target} PRIVATE Modbus_TCP_Slave.cpp)
6+
target_sources(${Target} PRIVATE Modbus_TCP_Client.cpp)
77
target_sources(${Target} PRIVATE license.cpp)
88

99

1010
# ---------------------------------------- header files (*.jpp, *.h, ...) ----------------------------------------------
1111
# ======================================================================================================================
1212
target_sources(${Target} PRIVATE modbus_shm.hpp)
13-
target_sources(${Target} PRIVATE Modbus_TCP_Slave.hpp)
13+
target_sources(${Target} PRIVATE Modbus_TCP_Client.hpp)
1414
target_sources(${Target} PRIVATE license.hpp)
1515

1616

src/Modbus_TCP_Slave.cpp renamed to src/Modbus_TCP_Client.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* This program is free software. You can redistribute it and/or modify it under the terms of the MIT License.
44
*/
55

6-
#include "Modbus_TCP_Slave.hpp"
6+
#include "Modbus_TCP_Client.hpp"
77

88
#include <algorithm>
99
#include <arpa/inet.h>
@@ -23,7 +23,7 @@ namespace TCP {
2323

2424
static constexpr int MAX_REGS = 0x10000;
2525

26-
Slave::Slave(const std::string &ip, unsigned short port, modbus_mapping_t *mapping, std::size_t tcp_timeout) {
26+
Client::Client(const std::string &ip, unsigned short port, modbus_mapping_t *mapping, std::size_t tcp_timeout) {
2727
// create modbus object
2828
modbus = modbus_new_tcp(ip.c_str(), static_cast<int>(port));
2929
if (modbus == nullptr) {
@@ -62,7 +62,7 @@ Slave::Slave(const std::string &ip, unsigned short port, modbus_mapping_t *mappi
6262
#endif
6363
}
6464

65-
Slave::Slave(const std::string &ip, unsigned short port, modbus_mapping_t **mappings, std::size_t tcp_timeout) {
65+
Client::Client(const std::string &ip, unsigned short port, modbus_mapping_t **mappings, std::size_t tcp_timeout) {
6666
// create modbus object
6767
modbus = modbus_new_tcp(ip.c_str(), static_cast<int>(port));
6868
if (modbus == nullptr) {
@@ -98,7 +98,7 @@ Slave::Slave(const std::string &ip, unsigned short port, modbus_mapping_t **mapp
9898
#endif
9999
}
100100

101-
void Slave::listen() {
101+
void Client::listen() {
102102
// create tcp socket
103103
socket = modbus_tcp_listen(modbus, 1);
104104
if (socket == -1) {
@@ -116,7 +116,7 @@ void Slave::listen() {
116116
}
117117

118118
#ifdef OS_LINUX
119-
void Slave::set_tcp_timeout(std::size_t tcp_timeout) {
119+
void Client::set_tcp_timeout(std::size_t tcp_timeout) {
120120
// set user timeout (~= timeout for tcp connection)
121121
unsigned user_timeout = static_cast<unsigned>(tcp_timeout) * 1000;
122122
int tmp = setsockopt(socket, IPPROTO_TCP, TCP_USER_TIMEOUT, &user_timeout, sizeof(tcp_timeout));
@@ -148,7 +148,7 @@ void Slave::set_tcp_timeout(std::size_t tcp_timeout) {
148148
#endif
149149

150150

151-
Slave::~Slave() {
151+
Client::~Client() {
152152
if (modbus != nullptr) {
153153
modbus_close(modbus);
154154
modbus_free(modbus);
@@ -157,14 +157,14 @@ Slave::~Slave() {
157157
if (socket != -1) { close(socket); }
158158
}
159159

160-
void Slave::set_debug(bool debug) {
160+
void Client::set_debug(bool debug) {
161161
if (modbus_set_debug(modbus, debug)) {
162162
const std::string error_msg = modbus_strerror(errno);
163163
throw std::runtime_error("failed to enable modbus debugging mode: " + error_msg);
164164
}
165165
}
166166

167-
std::string Slave::connect_client() {
167+
std::string Client::connect_client() {
168168
int tmp = modbus_tcp_accept(modbus, &socket);
169169
if (tmp < 0) {
170170
const std::string error_msg = modbus_strerror(errno);
@@ -189,7 +189,7 @@ std::string Slave::connect_client() {
189189
return sstr.str();
190190
}
191191

192-
bool Slave::handle_request() {
192+
bool Client::handle_request() {
193193
// receive modbus request
194194
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
195195
int rc = modbus_receive(modbus, query);
@@ -232,7 +232,7 @@ static inline timeout_t double_to_timeout_t(double timeout) {
232232
return ret;
233233
}
234234

235-
void Slave::set_byte_timeout(double timeout) {
235+
void Client::set_byte_timeout(double timeout) {
236236
const auto T = double_to_timeout_t(timeout);
237237
auto ret = modbus_set_byte_timeout(modbus, T.sec, T.usec);
238238

@@ -242,7 +242,7 @@ void Slave::set_byte_timeout(double timeout) {
242242
}
243243
}
244244

245-
void Slave::set_response_timeout(double timeout) {
245+
void Client::set_response_timeout(double timeout) {
246246
const auto T = double_to_timeout_t(timeout);
247247
auto ret = modbus_set_response_timeout(modbus, T.sec, T.usec);
248248

@@ -252,7 +252,7 @@ void Slave::set_response_timeout(double timeout) {
252252
}
253253
}
254254

255-
double Slave::get_byte_timeout() {
255+
double Client::get_byte_timeout() {
256256
timeout_t timeout {};
257257

258258
auto ret = modbus_get_byte_timeout(modbus, &timeout.sec, &timeout.usec);
@@ -265,7 +265,7 @@ double Slave::get_byte_timeout() {
265265
return static_cast<double>(timeout.sec) + (static_cast<double>(timeout.usec) / (1000.0 * 1000.0));
266266
}
267267

268-
double Slave::get_response_timeout() {
268+
double Client::get_response_timeout() {
269269
timeout_t timeout {};
270270

271271
auto ret = modbus_get_response_timeout(modbus, &timeout.sec, &timeout.usec);

src/Modbus_TCP_Slave.hpp renamed to src/Modbus_TCP_Client.hpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ namespace TCP {
1414

1515
constexpr std::size_t MAX_CLIENT_IDS = 256;
1616

17-
//! Modbus TCP slave
18-
class Slave {
17+
//! Modbus TCP client
18+
class Client {
1919
private:
2020
modbus_t *modbus; //!< modbus object (see libmodbus library)
2121
modbus_mapping_t
@@ -24,36 +24,36 @@ class Slave {
2424
int socket = -1; //!< socket of the modbus connection
2525

2626
public:
27-
/*! \brief create modbus slave (TCP server)
27+
/*! \brief create modbus client (TCP server)
2828
*
2929
* @param ip ip to listen for incoming connections (default 0.0.0.0 (any))
3030
* @param port port to listen for incoming connections (default 502)
3131
* @param mapping modbus mapping object for all client ids
3232
* nullptr: an mapping object with maximum size is generated
3333
* @param tcp_timeout tcp timeout (currently only available on linux systems)
3434
*/
35-
explicit Slave(const std::string &ip = "0.0.0.0",
36-
short unsigned int port = 502,
37-
modbus_mapping_t *mapping = nullptr,
38-
std::size_t tcp_timeout = 5);
35+
explicit Client(const std::string &ip = "0.0.0.0",
36+
short unsigned int port = 502,
37+
modbus_mapping_t *mapping = nullptr,
38+
std::size_t tcp_timeout = 5);
3939

4040
/**
41-
* @brief create modbus slave (TCP server) with dedicated mappings per client id
41+
* @brief create modbus client (TCP server) with dedicated mappings per client id
4242
*
4343
* @param ip ip to listen for incoming connections
4444
* @param port port to listen for incoming connections
4545
* @param mappings modbus mappings (one for each possible id)
4646
* @param tcp_timeout tcp timeout (currently only available on linux systems)
4747
*/
48-
Slave(const std::string &ip,
49-
short unsigned int port,
50-
modbus_mapping_t *mappings[MAX_CLIENT_IDS],
51-
std::size_t tcp_timeout = 5);
48+
Client(const std::string &ip,
49+
short unsigned int port,
50+
modbus_mapping_t *mappings[MAX_CLIENT_IDS],
51+
std::size_t tcp_timeout = 5);
5252

53-
/*! \brief destroy the modbus slave
53+
/*! \brief destroy the modbus client
5454
*
5555
*/
56-
~Slave();
56+
~Client();
5757

5858
/*! \brief enable/disable debugging output
5959
*
@@ -67,7 +67,7 @@ class Slave {
6767
*/
6868
std::string connect_client();
6969

70-
/*! \brief wait for request from Master and generate reply
70+
/*! \brief wait for request from Modbus Server and generate reply
7171
*
7272
* @return true: connection closed
7373
*/

0 commit comments

Comments
 (0)