Skip to content

Commit 6acf2b2

Browse files
Merge pull request #19 from NikolasK-source/main
update to 1.5.0
2 parents cb2dd77 + f61effd commit 6acf2b2

File tree

5 files changed

+52
-70
lines changed

5 files changed

+52
-70
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,5 @@ modules.order
466466
Module.symvers
467467
Mkfile.old
468468
dkms.conf
469+
src/generated/version_info.cpp
470+
src/generated/version_info.hpp

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.22.0 FATAL_ERROR)
99
# ======================================================================================================================
1010

1111
# project
12-
project(stdin-to-modbus-shm LANGUAGES CXX VERSION 1.4.0)
12+
project(stdin-to-modbus-shm LANGUAGES CXX VERSION 1.5.0)
1313

1414
# settings
1515
set(Target "stdin-to-modbus-shm") # Executable name (without file extension!)

src/generated/version_info.cpp

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/generated/version_info.hpp

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/main.cpp

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ constexpr std::array<int, 10> TERM_SIGNALS = {SIGINT,
6262
*/
6363
int main(int argc, char **argv) {
6464
const std::string exe_name = std::filesystem::path(*argv).filename().string();
65-
cxxopts::Options options(exe_name, "Read instructions from stdin and write them to a modbus shared memory");
65+
cxxopts::Options options(exe_name, "Read instructions from stdin and write them to a Modbus shared memory");
6666

6767
auto exit_usage = [&exe_name]() {
6868
std::cerr << "Use '" << exe_name << " --help' for more information.\n";
@@ -115,6 +115,11 @@ int main(int argc, char **argv) {
115115
options.add_options("shared memory")("semaphore-timeout",
116116
"maximum time (in seconds) to wait for semaphore (default: 0.1)",
117117
cxxopts::value<double>()->default_value("0.1"));
118+
options.add_options("shared_memory")(
119+
"pid",
120+
"terminate application if application with given pid is terminated. Provide "
121+
"the pid of the Modbus client to terminate when the Modbus client is terminated.",
122+
cxxopts::value<pid_t>());
118123

119124
// parse arguments
120125
cxxopts::ParseResult args;
@@ -129,7 +134,7 @@ int main(int argc, char **argv) {
129134
std::cout << "Data input format: reg_type:address:value[:data_type]" << '\n';
130135
std::cout << " reg_type : modbus register type: [do|di|ao|ai]" << '\n';
131136
std::cout << " address : address of the target register: [0-" << MAX_MODBUS_REGS - 1 << "]" << '\n';
132-
std::cout << " The actual maximum register depends on the size of the modbus shared memory."
137+
std::cout << " The actual maximum register depends on the size of the Modbus shared memory."
133138
<< '\n';
134139
std::cout << " value : value that is written to the target register" << '\n';
135140
std::cout << " Some string constants are available. The input format depends on the type of "
@@ -364,25 +369,25 @@ int main(int argc, char **argv) {
364369

365370
// check shared mem
366371
if (shm_do->get_size() > MAX_MODBUS_REGS) {
367-
std::cerr << "shared memory '" << shm_do->get_name() << "is to large to be a valid modbus shared memory."
372+
std::cerr << "shared memory '" << shm_do->get_name() << "is to large to be a valid Modbus shared memory."
368373
<< '\n';
369374
return EX_SOFTWARE;
370375
}
371376

372377
if (shm_di->get_size() > MAX_MODBUS_REGS) {
373-
std::cerr << "shared memory '" << shm_di->get_name() << "' is to large to be a valid modbus shared memory."
378+
std::cerr << "shared memory '" << shm_di->get_name() << "' is to large to be a valid Modbus shared memory."
374379
<< '\n';
375380
return EX_SOFTWARE;
376381
}
377382

378383
if (shm_ao->get_size() / 2 > MAX_MODBUS_REGS) {
379-
std::cerr << "shared memory '" << shm_ao->get_name() << "' is to large to be a valid modbus shared memory."
384+
std::cerr << "shared memory '" << shm_ao->get_name() << "' is to large to be a valid Modbus shared memory."
380385
<< '\n';
381386
return EX_SOFTWARE;
382387
}
383388

384389
if (shm_ai->get_size() / 2 > MAX_MODBUS_REGS) {
385-
std::cerr << "shared memory '" << shm_ai->get_name() << "' is to large to be a valid modbus shared memory."
390+
std::cerr << "shared memory '" << shm_ai->get_name() << "' is to large to be a valid Modbus shared memory."
386391
<< '\n';
387392
return EX_SOFTWARE;
388393
}
@@ -395,13 +400,13 @@ int main(int argc, char **argv) {
395400
}
396401

397402
if (shm_ao->get_size() % 2) {
398-
std::cerr << "the size of shared memory '" << shm_ao->get_name() << "' is odd. It is not a valid modbus shm."
403+
std::cerr << "the size of shared memory '" << shm_ao->get_name() << "' is odd. It is not a valid Modbus shm."
399404
<< '\n';
400405
return EX_SOFTWARE;
401406
}
402407

403408
if (shm_ai->get_size() % 2) {
404-
std::cerr << "the size of shared memory '" << shm_ai->get_name() << "' is odd. It is not a valid modbus shm."
409+
std::cerr << "the size of shared memory '" << shm_ai->get_name() << "' is odd. It is not a valid Modbus shm."
405410
<< '\n';
406411
return EX_SOFTWARE;
407412
}
@@ -425,6 +430,12 @@ int main(int argc, char **argv) {
425430
std::cerr << e.what() << '\n';
426431
return EX_SOFTWARE;
427432
}
433+
} else {
434+
std::cerr << "WARNING: No semaphore specified.\n"
435+
" Concurrent access to the shared memory is possible.\n"
436+
" This can result in CORRUPTED DATA.\n"
437+
" Use --semaphore to specify a semaphore that is provided by the Modbus client.\n";
438+
std::cerr << std::flush;
428439
}
429440

430441
const double SEMAPHORE_TIMEOUT_S = args["semaphore-timeout"].as<double>();
@@ -439,6 +450,22 @@ int main(int argc, char **argv) {
439450
static_cast<suseconds_t>(std::modf(SEMAPHORE_TIMEOUT_S, &modf_dummy) * 1'000'000),
440451
};
441452

453+
// modbus client pid
454+
pid_t mb_client_pid = 0;
455+
bool use_mb_client_pid = false;
456+
if (args.count("pid")) {
457+
mb_client_pid = args["pid"].as<pid_t>();
458+
use_mb_client_pid = true;
459+
} else {
460+
std::cerr << "WARNING: No Modbus client pid provided.\n"
461+
" Terminating the Modbus client application WILL NOT result in the termination of this "
462+
"application.\n"
463+
" This application WILL NOT connect to the shared memory of a restarted Modbus client.\n"
464+
" Use --pid to specify the pid of the Modbus client.\n"
465+
" Command line example: --pid $(pidof modbus-tcp-client-shm)\n"
466+
<< std::flush;
467+
}
468+
442469
std::cout << std::fixed;
443470

444471
auto last_time = std::chrono::steady_clock::now();
@@ -648,6 +675,20 @@ int main(int argc, char **argv) {
648675
input_thread.detach();
649676

650677
while (!terminate) {
678+
if (use_mb_client_pid) {
679+
// check if modbus client is still alive
680+
int tmp = kill(mb_client_pid, 0);
681+
if (tmp == -1) {
682+
if (errno == ESRCH) {
683+
std::cerr << "Modbus client (pid=" << mb_client_pid << ") no longer alive.\n" << std::flush;
684+
} else {
685+
perror("failed to send signal to the Modbus client");
686+
}
687+
terminate = true;
688+
break;
689+
}
690+
}
691+
651692
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // NOLINT
652693
}
653694

0 commit comments

Comments
 (0)