From c626b947bdbec76f50c2ef18d4a3fa69284ac794 Mon Sep 17 00:00:00 2001 From: Nikolas Koesling Date: Sat, 13 Apr 2024 17:50:33 +0200 Subject: [PATCH 1/5] update gitignore --- .gitignore | 2 ++ src/generated/version_info.cpp | 14 ---------- src/generated/version_info.hpp | 47 ---------------------------------- 3 files changed, 2 insertions(+), 61 deletions(-) delete mode 100644 src/generated/version_info.cpp delete mode 100644 src/generated/version_info.hpp diff --git a/.gitignore b/.gitignore index 4cfb858..2a9f16f 100644 --- a/.gitignore +++ b/.gitignore @@ -466,3 +466,5 @@ modules.order Module.symvers Mkfile.old dkms.conf +src/generated/version_info.cpp +src/generated/version_info.hpp diff --git a/src/generated/version_info.cpp b/src/generated/version_info.cpp deleted file mode 100644 index 8cda9f1..0000000 --- a/src/generated/version_info.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2024 Nikolas Koesling . - * This program is free software. You can redistribute it and/or modify it under the terms of the MIT License. - */ - -// This file is automatically generated. DO NOT CHANGE! - -#include "version_info.hpp" - -const std::string stdin_to_modbus_shm_version_info::VERSION_STR(PROJECT_VERSION); -const std::string stdin_to_modbus_shm_version_info::NAME(PROJECT_NAME); -const std::string stdin_to_modbus_shm_version_info::COMPILER(COMPILER_INFO); -const std::string stdin_to_modbus_shm_version_info::SYSTEM(SYSTEM_INFO); -const std::string stdin_to_modbus_shm_version_info::GIT_HASH("920708ae1f4add3ee443228eb0ca0966a059ab8b-dirty"); diff --git a/src/generated/version_info.hpp b/src/generated/version_info.hpp deleted file mode 100644 index 8c57c82..0000000 --- a/src/generated/version_info.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2024 Nikolas Koesling . - * This program is free software. You can redistribute it and/or modify it under the terms of the MIT License. - */ - -// This file is automatically generated. DO NOT CHANGE! - -#include - -/** - * @brief struct that contains version information - * @details contains only static members --> no instance can be created - */ -struct stdin_to_modbus_shm_version_info { - //* Mayor version number - static constexpr int MAYOR = PROJECT_VERSION_MAJOR; - - //* Minor version number - static constexpr int MINOR = PROJECT_VERSION_MINOR; - - //* Patchlevel - static constexpr int PATCH = PROJECT_VERSION_PATCH; - - //* Complete version as string - static const std::string VERSION_STR; - - //* cmake project name - static const std::string NAME; - - //* compiler info - static const std::string COMPILER; - - //* host system info - static const std::string SYSTEM; - - /** - * @brief git hash - * @details - * Contains the complete git hash. - * If there are uncommitted changes in the repository, - * the suffix '-dirty' is appended - */ - static const std::string GIT_HASH; - -private: - stdin_to_modbus_shm_version_info() = default; -}; From 8bd6fd9d2d56a2f98e6cceee12100b3db5deb846 Mon Sep 17 00:00:00 2001 From: Nikolas Koesling Date: Sat, 13 Apr 2024 18:23:22 +0200 Subject: [PATCH 2/5] option to check if modbus client is still alive --- src/main.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 71df39c..e00f033 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,6 +115,11 @@ int main(int argc, char **argv) { options.add_options("shared memory")("semaphore-timeout", "maximum time (in seconds) to wait for semaphore (default: 0.1)", cxxopts::value()->default_value("0.1")); + options.add_options("shared_memory")( + "pid", + "terminate application if application with given pid is terminated. Provide " + "the pid of the modbus client to terminate when the mosbus client is terminated.", + cxxopts::value()); // parse arguments cxxopts::ParseResult args; @@ -425,6 +430,11 @@ int main(int argc, char **argv) { std::cerr << e.what() << '\n'; return EX_SOFTWARE; } + } else { + std::cerr << "WARNING: No semaphore specified.\n" + " Concurrent access to the shared memory is possible that can result in CORRUPTED DATA.\n" + " Use --semaphore to specify a semaphore that is provided by the Modbus client.\n"; + std::cerr << std::flush; } const double SEMAPHORE_TIMEOUT_S = args["semaphore-timeout"].as(); @@ -439,6 +449,22 @@ int main(int argc, char **argv) { static_cast(std::modf(SEMAPHORE_TIMEOUT_S, &modf_dummy) * 1'000'000), }; + // modbus client pid + pid_t mb_client_pid = 0; + bool use_mb_client_pid = false; + if (args.count("pid")) { + mb_client_pid = args["pid"].as(); + use_mb_client_pid = true; + } else { + std::cerr << "WARNING: No Modbus client pid provided.\n" + " Terminating the Modbus client application WILL NOT result in the termination of this " + "application.\n" + " This application WILL NOT connect to the shared memory of a restarted Modbus client.\n" + " Use --pid to specify the pid of the modbus client.\n" + " Command line example: --pid $(pidof modbus-tcp-client-shm)\n" + << std::flush; + } + std::cout << std::fixed; auto last_time = std::chrono::steady_clock::now(); @@ -648,6 +674,20 @@ int main(int argc, char **argv) { input_thread.detach(); while (!terminate) { + if (use_mb_client_pid) { + // check if modbus client is still alive + int tmp = kill(mb_client_pid, 0); + if (tmp == -1) { + if (errno == ESRCH) { + std::cerr << "Modbus client (pid=" << mb_client_pid << ") no longer alive.\n" << std::flush; + } else { + perror("failed to send signal to modbus client"); + } + terminate = true; + break; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // NOLINT } From ac3ff24ff0e3bcbf832a8297494d3262e1b21975 Mon Sep 17 00:00:00 2001 From: Nikolas Koesling Date: Sat, 13 Apr 2024 19:53:57 +0200 Subject: [PATCH 3/5] fix typo --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index e00f033..ed18299 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -118,7 +118,7 @@ int main(int argc, char **argv) { options.add_options("shared_memory")( "pid", "terminate application if application with given pid is terminated. Provide " - "the pid of the modbus client to terminate when the mosbus client is terminated.", + "the pid of the Modbus client to terminate when the Modbus client is terminated.", cxxopts::value()); // parse arguments From df7fc3723bb31d5e1b7390e6b34618b4c1f85ca4 Mon Sep 17 00:00:00 2001 From: Nikolas Koesling Date: Sat, 13 Apr 2024 20:17:00 +0200 Subject: [PATCH 4/5] fix typos --- src/main.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ed18299..b83dfd3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -62,7 +62,7 @@ constexpr std::array TERM_SIGNALS = {SIGINT, */ int main(int argc, char **argv) { const std::string exe_name = std::filesystem::path(*argv).filename().string(); - cxxopts::Options options(exe_name, "Read instructions from stdin and write them to a modbus shared memory"); + cxxopts::Options options(exe_name, "Read instructions from stdin and write them to a Modbus shared memory"); auto exit_usage = [&exe_name]() { std::cerr << "Use '" << exe_name << " --help' for more information.\n"; @@ -134,7 +134,7 @@ int main(int argc, char **argv) { std::cout << "Data input format: reg_type:address:value[:data_type]" << '\n'; std::cout << " reg_type : modbus register type: [do|di|ao|ai]" << '\n'; std::cout << " address : address of the target register: [0-" << MAX_MODBUS_REGS - 1 << "]" << '\n'; - std::cout << " The actual maximum register depends on the size of the modbus shared memory." + std::cout << " The actual maximum register depends on the size of the Modbus shared memory." << '\n'; std::cout << " value : value that is written to the target register" << '\n'; std::cout << " Some string constants are available. The input format depends on the type of " @@ -369,25 +369,25 @@ int main(int argc, char **argv) { // check shared mem if (shm_do->get_size() > MAX_MODBUS_REGS) { - std::cerr << "shared memory '" << shm_do->get_name() << "is to large to be a valid modbus shared memory." + std::cerr << "shared memory '" << shm_do->get_name() << "is to large to be a valid Modbus shared memory." << '\n'; return EX_SOFTWARE; } if (shm_di->get_size() > MAX_MODBUS_REGS) { - std::cerr << "shared memory '" << shm_di->get_name() << "' is to large to be a valid modbus shared memory." + std::cerr << "shared memory '" << shm_di->get_name() << "' is to large to be a valid Modbus shared memory." << '\n'; return EX_SOFTWARE; } if (shm_ao->get_size() / 2 > MAX_MODBUS_REGS) { - std::cerr << "shared memory '" << shm_ao->get_name() << "' is to large to be a valid modbus shared memory." + std::cerr << "shared memory '" << shm_ao->get_name() << "' is to large to be a valid Modbus shared memory." << '\n'; return EX_SOFTWARE; } if (shm_ai->get_size() / 2 > MAX_MODBUS_REGS) { - std::cerr << "shared memory '" << shm_ai->get_name() << "' is to large to be a valid modbus shared memory." + std::cerr << "shared memory '" << shm_ai->get_name() << "' is to large to be a valid Modbus shared memory." << '\n'; return EX_SOFTWARE; } @@ -400,13 +400,13 @@ int main(int argc, char **argv) { } if (shm_ao->get_size() % 2) { - std::cerr << "the size of shared memory '" << shm_ao->get_name() << "' is odd. It is not a valid modbus shm." + std::cerr << "the size of shared memory '" << shm_ao->get_name() << "' is odd. It is not a valid Modbus shm." << '\n'; return EX_SOFTWARE; } if (shm_ai->get_size() % 2) { - std::cerr << "the size of shared memory '" << shm_ai->get_name() << "' is odd. It is not a valid modbus shm." + std::cerr << "the size of shared memory '" << shm_ai->get_name() << "' is odd. It is not a valid Modbus shm." << '\n'; return EX_SOFTWARE; } @@ -432,7 +432,8 @@ int main(int argc, char **argv) { } } else { std::cerr << "WARNING: No semaphore specified.\n" - " Concurrent access to the shared memory is possible that can result in CORRUPTED DATA.\n" + " Concurrent access to the shared memory is possible.\n" + " This can result in CORRUPTED DATA.\n" " Use --semaphore to specify a semaphore that is provided by the Modbus client.\n"; std::cerr << std::flush; } @@ -460,7 +461,7 @@ int main(int argc, char **argv) { " Terminating the Modbus client application WILL NOT result in the termination of this " "application.\n" " This application WILL NOT connect to the shared memory of a restarted Modbus client.\n" - " Use --pid to specify the pid of the modbus client.\n" + " Use --pid to specify the pid of the Modbus client.\n" " Command line example: --pid $(pidof modbus-tcp-client-shm)\n" << std::flush; } @@ -681,7 +682,7 @@ int main(int argc, char **argv) { if (errno == ESRCH) { std::cerr << "Modbus client (pid=" << mb_client_pid << ") no longer alive.\n" << std::flush; } else { - perror("failed to send signal to modbus client"); + perror("failed to send signal to the Modbus client"); } terminate = true; break; From f61effd5ff7bd6186467844b12a29cda11c6a6e6 Mon Sep 17 00:00:00 2001 From: Nikolas Koesling Date: Sat, 13 Apr 2024 20:20:05 +0200 Subject: [PATCH 5/5] increment version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 483cfaf..a921c89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.22.0 FATAL_ERROR) # ====================================================================================================================== # project -project(stdin-to-modbus-shm LANGUAGES CXX VERSION 1.4.0) +project(stdin-to-modbus-shm LANGUAGES CXX VERSION 1.5.0) # settings set(Target "stdin-to-modbus-shm") # Executable name (without file extension!)