Skip to content

Commit

Permalink
Merge branch 'main' into release
Browse files Browse the repository at this point in the history
Release 1.0.3
  • Loading branch information
NikolasK-source committed Aug 2, 2022
2 parents c8f288d + b8ba536 commit 2077f47
Show file tree
Hide file tree
Showing 15 changed files with 739 additions and 31 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# general
build*
docs/
docs/*

!docs/index.md
!docs/_config.yml

# editor files

Expand Down Expand Up @@ -462,3 +465,5 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf

!network.koesling.modbus_tcp_client_shm.yml
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR)
# ======================================================================================================================

# project
project(Modbus_TCP_client_shm LANGUAGES CXX VERSION 1.0.2)
project(Modbus_TCP_client_shm LANGUAGES CXX VERSION 1.0.3)

# settings
set(Target "Modbus_TCP_client_shm") # Executable name (without file extension!)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Nikolas Koesling
Copyright (c) 2021-2022 Nikolas Koesling

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ The modbus registers are mapped to shared memory objects:
AI | Discrete Input Registers | read-only | <name-prefix>AI
```

### Use privileged ports
The standard modbus port (502) can be used only by the root user under linux by default.
To circumvent this, you can create an entry in the iptables that redirects packets on the standard modbus port to a higher port.
The following example redirects packets from port 502 (standard modbus port) to port 5020
```
iptables -A PREROUTING -t nat -p tcp --dport 502 -j REDIRECT --to-port 5020
```
The modbus client must be called with the option ```-p 5020```

## Libraries
This application uses the following libraries:
- cxxopts by jarro2783 (https://github.com/jarro2783/cxxopts)
Expand Down
1 change: 1 addition & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
theme: jekyll-theme-cayman
78 changes: 78 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Shared Memory Modbus TCP Client

This project is a simple command line based Modbus TCP client for POXIX compatible operating systems that stores the contents of its registers in shared memory.

## Basic operating principle

The client creates four shared memories.
One for each register type:
- Discrete Output Coils (DO)
- Discrete Input Coils (DI)
- Discrete Output Registers (AO)
- Discrete Input Registers (AI)

All registers are initialized with 0 at the beginning.
The Modbus master reads and writes directly the values from these shared memories.

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


## Use the Application
The application can be started completely without command line arguments.
In this case the client listens for connections on all IPs on port 502 (the default modbus port).
The application terminates if the master disconnects.

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

By using the command line argument ```--monitor``` all incoming and outgoing packets are printed on stdout.
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.

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

### Use privileged ports
Ports below 1024 cannot be used by standard users.
Therefore, the default modbus port (502) cannot be used without further action.

Here are two ways to use the port anyway:
#### iptables (recommended)
An entry can be added to the iptables that forwards the packets on the actual port to a higher port.

The following example redirects all tcp packets on port 502 to port 5020:
```
iptables -A PREROUTING -t nat -p tcp --dport 502 -j REDIRECT --to-port 5020
```

#### setcap
The command ```setcap``` can be used to allow the application to access privileged ports.
However, this option gives the application significantly more rights than it actually needs and should therefore be avoided.

This option cannot be used with flatpaks.

```
setcap 'cap_net_bind_service=+ep' /path/to/binary
```



## Build from Source

The following packages are required for building the application:
- cmake
- clang or gcc

Additionally, the following packages are required to build the modbus library:
- autoconf
- automake
- libtool


Use the following commands to build the application:
```
git clone --recursive https://github.com/NikolasK-source/modbus_tcp_client_shm.git
cd modbus_tcp_client_shm
mkdir build
cmake -B build . -DCMAKE_BUILD_TYPE=Release -DCLANG_FORMAT=OFF -DCOMPILER_WARNINGS=OFF
cmake --build build
```

The binary is located in the build directory.
26 changes: 26 additions & 0 deletions network.koesling.modbus_tcp_client_shm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
id: network.koesling.modbus_tcp_client_shm
runtime: org.freedesktop.Platform
runtime-version: '21.08'
sdk: org.freedesktop.Sdk
command: Modbus_TCP_client_shm
finish-args:
- --device=shm
- --share=network
modules:
- name: Modbus_TCP_client_shm
buildsystem: simple
build-commands:
# build
- mkdir build
- cmake -B build . -DCMAKE_BUILD_TYPE=Release -DCLANG_FORMAT=OFF -DCOMPILER_WARNINGS=OFF
- cmake --build build

# install
- mkdir -p "${FLATPAK_DEST}/bin"
- cp build/Modbus_TCP_client_shm ${FLATPAK_DEST}/bin
- ls -lah ${FLATPAK_DEST}
sources:
- type: git
branch: release
url: https://github.com/NikolasK-source/modbus_tcp_client_shm.git

2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
target_sources(${Target} PRIVATE main.cpp)
target_sources(${Target} PRIVATE modbus_shm.cpp)
target_sources(${Target} PRIVATE Modbus_TCP_Slave.cpp)
target_sources(${Target} PRIVATE license.cpp)


# ---------------------------------------- header files (*.jpp, *.h, ...) ----------------------------------------------
# ======================================================================================================================
target_sources(${Target} PRIVATE modbus_shm.hpp)
target_sources(${Target} PRIVATE Modbus_TCP_Slave.hpp)
target_sources(${Target} PRIVATE license.hpp)



Expand Down
5 changes: 5 additions & 0 deletions src/Modbus_TCP_Slave.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
* Copyright (C) 2021-2022 Nikolas Koesling <[email protected]>.
* This program is free software. You can redistribute it and/or modify it under the terms of the MIT License.
*/

#include "Modbus_TCP_Slave.hpp"

#include <stdexcept>
Expand Down
9 changes: 7 additions & 2 deletions src/Modbus_TCP_Slave.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
* Copyright (C) 2021-2022 Nikolas Koesling <[email protected]>.
* This program is free software. You can redistribute it and/or modify it under the terms of the MIT License.
*/

#pragma once

#include <modbus/modbus.h>
Expand All @@ -9,7 +14,7 @@ namespace TCP {
//! Modbus TCP slave
class Slave {
private:
modbus_t * modbus; //!< modbus object (see libmodbus library)
modbus_t *modbus; //!< modbus object (see libmodbus library)
modbus_mapping_t *mapping; //!< modbus data object (see libmodbus library)
bool delete_mapping; //!< indicates whether the mapping object was created by this instance
int socket = -1; //!< socket of the modbus connection
Expand All @@ -23,7 +28,7 @@ class Slave {
*/
explicit Slave(const std::string &ip = "0.0.0.0",
short unsigned int port = 502,
modbus_mapping_t * mapping = nullptr);
modbus_mapping_t *mapping = nullptr);

/*! \brief destroy the modbus slave
*
Expand Down
Loading

0 comments on commit 2077f47

Please sign in to comment.