3
3
* This program is free software. You can redistribute it and/or modify it under the terms of the GPLv3 License.
4
4
*/
5
5
6
+ #include " Modbus_TCP_Client_poll.hpp"
7
+ #include " Print_Time.hpp"
8
+ #include " generated/version_info.hpp"
9
+ #include " license.hpp"
10
+ #include " modbus_shm.hpp"
11
+
6
12
#include < atomic>
7
13
#include < condition_variable>
8
14
#include < csignal>
33
39
# pragma GCC diagnostic pop
34
40
#endif
35
41
36
- #include " Modbus_TCP_Client_poll.hpp"
37
- #include " Print_Time.hpp"
38
- #include " license.hpp"
39
- #include " modbus_shm.hpp"
40
-
41
-
42
42
// ! Maximum number of registers per type
43
43
static constexpr size_t MODBUS_MAX_REGS = 0x10000 ;
44
44
@@ -111,74 +111,82 @@ int main(int argc, char **argv) {
111
111
#endif
112
112
113
113
// all command line arguments
114
- options.add_options ()(
114
+ options.add_options (" network " )(
115
115
" i,host" , " host to listen for incoming connections" , cxxopts::value<std::string>()->default_value (" any" ));
116
- options.add_options ()(" p,service" ,
117
- " service or port to listen for incoming connections" ,
118
- cxxopts::value<std::string>()->default_value (" 502" ));
119
- options.add_options ()(
116
+ options.add_options (" network " )(" p,service" ,
117
+ " service or port to listen for incoming connections" ,
118
+ cxxopts::value<std::string>()->default_value (" 502" ));
119
+ options.add_options (" shared memory " )(
120
120
" n,name-prefix" , " shared memory name prefix" , cxxopts::value<std::string>()->default_value (" modbus_" ));
121
- options.add_options ()(" do-registers" ,
122
- " number of digital output registers" ,
123
- cxxopts::value<std::size_t >()->default_value (" 65536" ));
124
- options.add_options ()(
121
+ options.add_options (" modbus " )(" do-registers" ,
122
+ " number of digital output registers" ,
123
+ cxxopts::value<std::size_t >()->default_value (" 65536" ));
124
+ options.add_options (" modbus " )(
125
125
" di-registers" , " number of digital input registers" , cxxopts::value<std::size_t >()->default_value (" 65536" ));
126
- options.add_options ()(
126
+ options.add_options (" modbus " )(
127
127
" ao-registers" , " number of analog output registers" , cxxopts::value<std::size_t >()->default_value (" 65536" ));
128
- options.add_options ()(
128
+ options.add_options (" modbus " )(
129
129
" ai-registers" , " number of analog input registers" , cxxopts::value<std::size_t >()->default_value (" 65536" ));
130
- options.add_options ()(" m,monitor" , " output all incoming and outgoing packets to stdout" );
131
- options.add_options ()(" c,connections" ,
132
- " number of allowed simultaneous Modbus Server connections." ,
133
- cxxopts::value<std::size_t >()->default_value (" 1" ));
134
- options.add_options ()(" r,reconnect" , " do not terminate if no Modbus Server is connected anymore." );
135
- options.add_options ()(" byte-timeout" ,
136
- " timeout interval in seconds between two consecutive bytes of the same message. "
137
- " In most cases it is sufficient to set the response timeout. "
138
- " Fractional values are possible." ,
139
- cxxopts::value<double >());
140
- options.add_options ()(" response-timeout" ,
141
- " set the timeout interval in seconds used to wait for a response. "
142
- " When a byte timeout is set, if the elapsed time for the first byte of response is longer "
143
- " than the given timeout, a timeout is detected. "
144
- " When byte timeout is disabled, the full confirmation response must be received before "
145
- " expiration of the response timeout. "
146
- " Fractional values are possible." ,
147
- cxxopts::value<double >());
130
+ options.add_options (" modbus" )(" m,monitor" , " output all incoming and outgoing packets to stdout" );
131
+ options.add_options (" network" )(" c,connections" ,
132
+ " number of allowed simultaneous Modbus Server connections." ,
133
+ cxxopts::value<std::size_t >()->default_value (" 1" ));
134
+ options.add_options (" network" )(" r,reconnect" , " do not terminate if no Modbus Server is connected anymore." );
135
+ options.add_options (" modbus" )(" byte-timeout" ,
136
+ " timeout interval in seconds between two consecutive bytes of the same message. "
137
+ " In most cases it is sufficient to set the response timeout. "
138
+ " Fractional values are possible." ,
139
+ cxxopts::value<double >());
140
+ options.add_options (" modbus" )(
141
+ " response-timeout" ,
142
+ " set the timeout interval in seconds used to wait for a response. "
143
+ " When a byte timeout is set, if the elapsed time for the first byte of response is longer "
144
+ " than the given timeout, a timeout is detected. "
145
+ " When byte timeout is disabled, the full confirmation response must be received before "
146
+ " expiration of the response timeout. "
147
+ " Fractional values are possible." ,
148
+ cxxopts::value<double >());
148
149
#ifdef OS_LINUX
149
- options.add_options ()(" t,tcp-timeout" ,
150
- " tcp timeout in seconds. Set to 0 to use the system defaults (not recommended)." ,
151
- cxxopts::value<std::size_t >()->default_value (" 5" ));
150
+ options.add_options (" network " )(" t,tcp-timeout" ,
151
+ " tcp timeout in seconds. Set to 0 to use the system defaults (not recommended)." ,
152
+ cxxopts::value<std::size_t >()->default_value (" 5" ));
152
153
#endif
153
- options.add_options ()(" force" ,
154
- " Force the use of the shared memory even if it already exists. "
155
- " Do not use this option per default! "
156
- " It should only be used if the shared memory of an improperly terminated instance continues "
157
- " to exist as an orphan and is no longer used." );
158
- options.add_options ()(" s,separate" ,
159
- " Use a separate shared memory for requests with the specified client id. "
160
- " The client id (as hex value) is appended to the shared memory prefix (e.g. modbus_fc_DO)"
161
- " . You can specify multiple client ids by separating them with ','. "
162
- " Use --separate-all to generate separate shared memories for all possible client ids." ,
163
- cxxopts::value<std::vector<std::uint8_t >>());
164
- options.add_options ()(" separate-all" ,
165
- " like --separate, but for all client ids (creates 1028 shared memory files! "
166
- " check/set 'ulimit -n' before using this option.)" );
167
- options.add_options ()(" semaphore" ,
168
- " protect the shared memory with a named semaphore against simultaneous access" ,
169
- cxxopts::value<std::string>());
170
- options.add_options ()(" semaphore-force" ,
171
- " Force the use of the semaphore even if it already exists. "
172
- " Do not use this option per default! "
173
- " It should only be used if the semaphore of an improperly terminated instance continues "
174
- " to exist as an orphan and is no longer used." );
175
- options.add_options ()(" b,permissions" ,
176
- " permission bits that are applied when creating a shared memory." ,
177
- cxxopts::value<std::string>()->default_value (" 0640" ));
178
- options.add_options ()(" h,help" , " print usage" );
179
- options.add_options ()(" version" , " print version information" );
180
- options.add_options ()(" license" , " show licences (short)" );
181
- options.add_options ()(" license-full" , " show licences (full license text)" );
154
+ options.add_options (" shared memory" )(
155
+ " force" ,
156
+ " Force the use of the shared memory even if it already exists. "
157
+ " Do not use this option per default! "
158
+ " It should only be used if the shared memory of an improperly terminated instance continues "
159
+ " to exist as an orphan and is no longer used." );
160
+ options.add_options (" shared memory" )(
161
+ " s,separate" ,
162
+ " Use a separate shared memory for requests with the specified client id. "
163
+ " The client id (as hex value) is appended to the shared memory prefix (e.g. modbus_fc_DO)"
164
+ " . You can specify multiple client ids by separating them with ','. "
165
+ " Use --separate-all to generate separate shared memories for all possible client ids." ,
166
+ cxxopts::value<std::vector<std::uint8_t >>());
167
+ options.add_options (" shared memory" )(" separate-all" ,
168
+ " like --separate, but for all client ids (creates 1028 shared memory files! "
169
+ " check/set 'ulimit -n' before using this option.)" );
170
+ options.add_options (" shared memory" )(" semaphore" ,
171
+ " protect the shared memory with a named semaphore against simultaneous access" ,
172
+ cxxopts::value<std::string>());
173
+ options.add_options (" shared memory" )(
174
+ " semaphore-force" ,
175
+ " Force the use of the semaphore even if it already exists. "
176
+ " Do not use this option per default! "
177
+ " It should only be used if the semaphore of an improperly terminated instance continues "
178
+ " to exist as an orphan and is no longer used." );
179
+ options.add_options (" shared memory" )(" b,permissions" ,
180
+ " permission bits that are applied when creating a shared memory." ,
181
+ cxxopts::value<std::string>()->default_value (" 0640" ));
182
+ options.add_options (" other" )(" h,help" , " print usage" );
183
+ options.add_options (" version information" )(" version" , " print version and exit" );
184
+ options.add_options (" version information" )(" longversion" ,
185
+ " print version (including compiler and system info) and exit" );
186
+ options.add_options (" version information" )(" shortversion" , " print version (only version string) and exit" );
187
+ options.add_options (" version information" )(" git-hash" , " print git hash" );
188
+ options.add_options (" other" )(" license" , " show licences (short)" );
189
+ options.add_options (" other" )(" license-full" , " show licences (full license text)" );
182
190
183
191
// parse arguments
184
192
cxxopts::ParseResult args;
@@ -210,8 +218,8 @@ int main(int argc, char **argv) {
210
218
return EX_OK;
211
219
}
212
220
213
- // print usage
214
- if (args.count (" version " )) {
221
+ // print version
222
+ if (args.count (" longversion " )) {
215
223
std::cout << PROJECT_NAME << ' ' << PROJECT_VERSION << " (compiled with " << COMPILER_INFO << " on "
216
224
<< SYSTEM_INFO << ' )'
217
225
#ifndef OS_LINUX
@@ -221,6 +229,33 @@ int main(int argc, char **argv) {
221
229
return EX_OK;
222
230
}
223
231
232
+ if (args.count (" shortversion" )) {
233
+ std::cout << PROJECT_VERSION << ' \n ' ;
234
+ return EX_OK;
235
+ }
236
+
237
+ if (args.count (" version" )) {
238
+ std::cout << PROJECT_NAME << ' ' << PROJECT_VERSION << ' \n ' ;
239
+ return EX_OK;
240
+ }
241
+
242
+ if (args.count (" longversion" )) {
243
+ std::cout << PROJECT_NAME << ' ' << PROJECT_VERSION << ' \n ' ;
244
+ std::cout << " compiled with " << COMPILER_INFO << ' \n ' ;
245
+ std::cout << " on system " << SYSTEM_INFO
246
+ #ifndef OS_LINUX
247
+ << " -nonlinux"
248
+ #endif
249
+ << ' \n ' ;
250
+ std::cout << " from git commit " << RCS_HASH << ' \n ' ;
251
+ return EX_OK;
252
+ }
253
+
254
+ if (args.count (" git-hash" )) {
255
+ std::cout << RCS_HASH << ' \n ' ;
256
+ return EX_OK;
257
+ }
258
+
224
259
// print licenses
225
260
if (args.count (" license" )) {
226
261
print_licenses (std::cout, false );
0 commit comments