Skip to content

Commit 1c1715c

Browse files
Merge pull request #10 from NikolasK-source/main
Release 0.2.1
2 parents 5aa8418 + 26d537d commit 1c1715c

File tree

7 files changed

+49
-75
lines changed

7 files changed

+49
-75
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
[submodule "libs/libmodbus"]
55
path = libs/libmodbus
66
url = https://github.com/stephane/libmodbus
7+
[submodule "libs/cxxshm"]
8+
path = libs/cxxshm
9+
url = https://github.com/NikolasK-source/cxxshm.git

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_RTU_client_shm LANGUAGES CXX VERSION 0.2.0)
7+
project(Modbus_RTU_client_shm LANGUAGES CXX VERSION 0.2.1)
88

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

libs/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ target_link_libraries(${Target} PRIVATE rt)
1010

1111
add_subdirectory(cxxopts EXCLUDE_FROM_ALL)
1212
target_link_libraries(${Target} PRIVATE cxxopts)
13+
14+
add_subdirectory(cxxshm EXCLUDE_FROM_ALL)
15+
target_link_libraries(${Target} PRIVATE cxxshm)

libs/cxxshm

Submodule cxxshm added at dfed3b0

src/main.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ static void sig_term_handler(int) {
2929
terminate = true;
3030
}
3131

32+
constexpr std::array<int, 10> TERM_SIGNALS = {SIGINT,
33+
SIGTERM,
34+
SIGHUP,
35+
SIGIO, // should not happen
36+
SIGPIPE,
37+
SIGPOLL, // should not happen
38+
SIGPROF, // should not happen
39+
SIGUSR1,
40+
SIGUSR2,
41+
SIGVTALRM};
42+
3243
/*! \brief main function
3344
*
3445
* @param argc number of arguments
@@ -47,16 +58,24 @@ int main(int argc, char **argv) {
4758
auto euid = geteuid();
4859
if (!euid) std::cerr << "!!!! WARNING: You should not execute this program with root privileges !!!!" << std::endl;
4960

61+
#ifdef COMPILER_CLANG
62+
# pragma clang diagnostic push
63+
# pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
64+
#endif
5065
// establish signal handler
51-
if (signal(SIGINT, sig_term_handler) || signal(SIGTERM, sig_term_handler)) {
52-
perror("Failed to establish signal handler");
53-
return EX_OSERR;
54-
}
55-
56-
if (signal(SIGALRM, [](int) { exit(EX_OK); })) {
57-
perror("Failed to establish signal handler");
58-
return EX_OSERR;
66+
struct sigaction term_sa;
67+
term_sa.sa_handler = sig_term_handler;
68+
term_sa.sa_flags = SA_RESTART;
69+
sigemptyset(&term_sa.sa_mask);
70+
for (const auto SIGNO : TERM_SIGNALS) {
71+
if (sigaction(SIGNO, &term_sa, nullptr)) {
72+
perror("Failed to establish signal handler");
73+
return EX_OSERR;
74+
}
5975
}
76+
#ifdef COMPILER_CLANG
77+
# pragma clang diagnostic pop
78+
#endif
6079

6180
// all command line arguments
6281
options.add_options()("d,device", "mandatory: serial device", cxxopts::value<std::string>());

src/modbus_shm.cpp

Lines changed: 9 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -35,71 +35,17 @@ Shm_Mapping::Shm_Mapping(std::size_t nb_bits,
3535
mapping.nb_registers = static_cast<int>(nb_registers);
3636
mapping.nb_input_registers = static_cast<int>(nb_input_registers);
3737

38-
// calculate shm object size
39-
shm_data[DO].size = nb_bits;
40-
shm_data[DI].size = nb_input_bits;
41-
shm_data[AO].size = nb_registers * 2;
42-
shm_data[AI].size = nb_input_registers * 2;
43-
44-
// create shm object names
45-
shm_data[DO].name = prefix + "DO";
46-
shm_data[DI].name = prefix + "DI";
47-
shm_data[AO].name = prefix + "AO";
48-
shm_data[AI].name = prefix + "AI";
49-
50-
// create and map shm objects
51-
for (std::size_t i = 0; i < reg_index_t::REG_COUNT; ++i) {
52-
auto &shm = shm_data[i];
53-
54-
int flags = O_RDWR | O_CREAT;
55-
if (!force) flags |= O_EXCL;
56-
57-
// create shm object
58-
shm.fd = shm_open(shm.name.c_str(), flags, 0660);
59-
if (shm.fd < 0) {
60-
throw std::system_error(
61-
errno, std::generic_category(), "Failed to create shared memory '" + shm.name + '\'');
62-
}
63-
64-
// set size of shm object
65-
if (ftruncate(shm.fd, static_cast<__off_t>(shm.size))) {
66-
throw std::system_error(
67-
errno, std::generic_category(), "Failed to resize shared memory '" + shm.name + '\'');
68-
}
69-
70-
// map shm object
71-
shm.addr = mmap(nullptr, shm.size, PROT_WRITE | PROT_READ, MAP_SHARED, shm.fd, 0);
72-
if (shm.addr == nullptr && shm.addr == MAP_FAILED) {
73-
shm.addr = nullptr;
74-
throw std::system_error(errno, std::generic_category(), "Failed to map shared memory '" + shm.name + '\'');
75-
}
76-
}
38+
// create shm objects
39+
shm_data[DO] = std::make_unique<cxxshm::SharedMemory>(prefix + "DO", nb_bits, false, !force);
40+
shm_data[DI] = std::make_unique<cxxshm::SharedMemory>(prefix + "DI", nb_input_bits, false, !force);
41+
shm_data[AO] = std::make_unique<cxxshm::SharedMemory>(prefix + "AO", 2 * nb_registers, false, !force);
42+
shm_data[AI] = std::make_unique<cxxshm::SharedMemory>(prefix + "AI", nb_input_registers, false, !force);
7743

7844
// set shm objects as modbus register storage
79-
mapping.tab_bits = static_cast<uint8_t *>(shm_data[DO].addr);
80-
mapping.tab_input_bits = static_cast<uint8_t *>(shm_data[DI].addr);
81-
mapping.tab_registers = static_cast<uint16_t *>(shm_data[AO].addr);
82-
mapping.tab_input_registers = static_cast<uint16_t *>(shm_data[AI].addr);
83-
}
84-
85-
Shm_Mapping::~Shm_Mapping() {
86-
// unmap and delete shm objects
87-
for (std::size_t i = 0; i < reg_index_t::REG_COUNT; ++i) {
88-
auto &shm = shm_data[i];
89-
if (shm.addr) {
90-
if (munmap(shm.addr, shm.size)) { perror(("Failed to unmap shared memory '" + shm.name + '\'').c_str()); }
91-
}
92-
93-
if (shm.fd != -1) {
94-
if (close(shm.fd)) {
95-
perror(("Failed to close shared memory file descriptor '" + shm.name + '\'').c_str());
96-
}
97-
98-
if (shm_unlink(shm.name.c_str())) {
99-
perror(("Failed to unlink shared memory '" + shm.name + '\'').c_str());
100-
}
101-
}
102-
}
45+
mapping.tab_bits = static_cast<uint8_t *>(shm_data[DO]->get_addr());
46+
mapping.tab_input_bits = static_cast<uint8_t *>(shm_data[DI]->get_addr());
47+
mapping.tab_registers = static_cast<uint16_t *>(shm_data[AO]->get_addr());
48+
mapping.tab_input_registers = static_cast<uint16_t *>(shm_data[AI]->get_addr());
10349
}
10450

10551
} // namespace shm

src/modbus_shm.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
#pragma once
77

8+
#include "cxxshm.hpp"
89
#include "modbus/modbus.h"
910
#include <array>
1011
#include <cstddef>
12+
#include <memory>
1113
#include <string>
1214

1315
namespace Modbus {
@@ -17,7 +19,7 @@ namespace shm {
1719
*
1820
* All required shm objects are created on construction and and deleted on destruction.
1921
*/
20-
class Shm_Mapping {
22+
class Shm_Mapping final {
2123
private:
2224
enum reg_index_t : std::size_t { DO, DI, AO, AI, REG_COUNT };
2325

@@ -33,7 +35,7 @@ class Shm_Mapping {
3335
modbus_mapping_t mapping {};
3436

3537
//! info for all shared memory objects
36-
std::array<shm_data_t, reg_index_t::REG_COUNT> shm_data;
38+
std::array<std::unique_ptr<cxxshm::SharedMemory>, reg_index_t::REG_COUNT> shm_data;
3739

3840
public:
3941
/*! \brief creates a new modbus_mapping_t. Like modbus_mapping_new(), but creates shared memory objects to store its
@@ -59,7 +61,7 @@ class Shm_Mapping {
5961
const std::string &shm_name_prefix = "modbus_",
6062
bool force = false);
6163

62-
~Shm_Mapping();
64+
~Shm_Mapping() = default;
6365

6466
/*! \brief get a pointer to the created modbus_mapping_t object
6567
*

0 commit comments

Comments
 (0)