Skip to content

Commit 05fd4c1

Browse files
committed
updating readme
test updates move requirement
1 parent 1fc0bc7 commit 05fd4c1

File tree

4 files changed

+71
-74
lines changed

4 files changed

+71
-74
lines changed

.github/workflows/cmake.yml

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,40 @@ env:
88

99
jobs:
1010
build:
11-
# The CMake configure and build commands are platform agnostic and should work equally
12-
# well on Windows or Mac. You can convert this to a matrix build if you need
13-
# cross-platform coverage.
14-
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
1511
runs-on: ubuntu-latest
1612

1713
steps:
14+
# Checkout the repository
1815
- uses: actions/checkout@v2
1916

17+
- name: Install requirements
18+
run: apt-get update && apt-get install -y cmake g++ make python3
19+
2020
- name: Checkout Submodules
21-
run: python3 $(pwd)/git_to_https.py .gitmodules && git submodule update --init && git submodule foreach --recursive python3 $(pwd)/git_to_https.py && git submodule update --init
21+
run: |
22+
python3 $(pwd)/git_to_https.py .gitmodules
23+
git submodule update --init
24+
git submodule foreach --recursive python3 $(pwd)/git_to_https.py
25+
git submodule update --init
2226
27+
# Create build directory (out-of-source build)
2328
- name: Create Build Environment
24-
# Some projects don't allow in-source building, so create a separate build directory
25-
# We'll use this as our working directory for all subsequent commands
26-
run: cmake -E make_directory ${{runner.workspace}}/build
27-
28-
- name: SetupLibs
29-
working-directory: ${{runner.workspace}}/build
30-
shell: bash
31-
# Execute the build. You can specify a specific target with "--target <NAME>"
32-
run: sudo apt-get install googletest && cd /usr/src/googletest && sudo cmake ./ && sudo make && sudo make install
29+
run: cmake -E make_directory ${{ runner.workspace }}/build
3330

31+
# Configure the CMake project
3432
- name: Configure CMake
35-
# Use a bash shell so we can use the same syntax for environment variable
36-
# access regardless of the host operating system
33+
working-directory: ${{ runner.workspace }}/build
3734
shell: bash
38-
working-directory: ${{runner.workspace}}/build
39-
# Note the current convention is to use the -S and -B options here to specify source
40-
# and build directories, but this is only available with CMake 3.13 and higher.
41-
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
4235
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
4336

37+
# Build the project using CMake
4438
- name: Build
45-
working-directory: ${{runner.workspace}}/build
39+
working-directory: ${{ runner.workspace }}/build
4640
shell: bash
47-
# Execute the build. You can specify a specific target with "--target <NAME>"
4841
run: cmake --build . --config $BUILD_TYPE
4942

43+
# Run tests defined by the CMake configuration
5044
- name: Test
51-
working-directory: ${{runner.workspace}}/build
45+
working-directory: ${{ runner.workspace }}/build
5246
shell: bash
53-
# Execute tests defined by the CMake configuration.
54-
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
55-
run: ctest -C $BUILD_TYPE
47+
run: ctest -V -C $BUILD_TYPE

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[submodule "examples/pymodbus_tests/pymodbus"]
55
path = examples/pymodbus_tests/pymodbus
66
url = git@github.com:riptideio/pymodbus.git
7-
[submodule "lib/CppUtilities"]
7+
[submodule "external/CppUtilities"]
88
path = external/CppUtilities
99
url = git@github.com:snhobbs/CppUtilities
1010
[submodule "external/googletest"]

README.md

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,74 @@
11
# Modbus
22
C++ Modbus parsing library.
33

4-
# Setting Up a Slave Device
5-
The focus of this library is to allow for a serializable data types to be exposed over
6-
modbus in a clearer manner. Modbus registers are unsigned 16 bit values. Other data types
7-
need to be translated to these 16 bit values and back. The idea of this library is to use
8-
a user defined data store type that controls access to the underlying data types this is especially
9-
useful for preventing unaligned data accesses.
10-
11-
A slave device is composed of controlled and data stores using C++ templates.
12-
Each slave needs a CoilController, HoldingRegisterController, DiscreteInputController, and an InputRegisterController.
13-
Each of these controls access to a data store.
14-
A simple data store for registers would just be an array of uint16_ts. For a coil or discrete input it would be a bit field.
15-
These basic data stores are available but are less powerful than creating a data store for the data types being used.
16-
The basic controller types are:
17-
18-
using CoilController =
19-
Modbus::CoilController<Modbus::BitFieldDataStore<kCoilCount>>;
20-
using HoldingRegisterController =
4+
## Setting Up a Slave Device
5+
This library facilitates exposing serializable data types over Modbus in a more transparent manner. Modbus registers are 16-bit unsigned integers, and other data types must be translated into these 16-bit values and vice versa. The core concept of the library is to use a user-defined data store type that controls access to the underlying data types. This approach is especially useful for preventing unaligned data access.
6+
7+
A slave device in this library consists of controlled data stores, managed via C++ templates. Each slave device requires a `CoilController`, `HoldingRegisterController`, `DiscreteInputController`, and an `InputRegisterController`, with each controller managing access to a specific data store.
8+
9+
A basic data store for registers might simply be an array of `uint16_t` values, while coils or discrete inputs are typically stored as bit fields. Basic data stores are available, but more complex, user-defined data stores can provide additional flexibility and power.
10+
11+
Example of basic controller types:
12+
13+
```cpp
14+
using CoilController =
15+
Modbus::CoilController<Modbus::BitFieldDataStore<kCoilCount>>;
16+
using HoldingRegisterController =
2117
Modbus::HoldingRegisterController<Modbus::RegisterDataStore<kHoldingRegisterCount>>;
22-
using DiscreteInputController =
23-
Modbus::DiscreteInputController<Modbus::BitFieldDataStore<kDiscreteInputCount>>;
24-
using InputRegisterController =
25-
Modbus::InputRegisterController<Modbus::RegisterDataStore<kInputRegisterCount>>;
18+
using DiscreteInputController =
19+
Modbus::DiscreteInputController<Modbus::BitFieldDataStore<kDiscreteInputCount>>;
20+
using InputRegisterController =
21+
Modbus::InputRegisterController<Modbus::RegisterDataStore<kInputRegisterCount>>;
22+
````
2623

27-
## Specialized Data Stores
28-
Using mapped data stores allows the user to expose the actual data types being used with
29-
the serialization encapsulated.
24+
### Specialized Data Stores
3025

26+
To expose actual data types with the serialization encapsulated, you can use mapped data stores. For instance:
27+
28+
```cpp
3129
using HoldingRegisterController =
3230
Modbus::HoldingRegisterController<Modbus::MappedRegisterDataStore<HoldingRegisters::MemoryMapController>>;
3331
using InputRegisterController =
3432
Modbus::InputRegisterController<Modbus::MappedRegisterDataStore<InputRegisters::MemoryMapController>>;
33+
```
34+
35+
## Protocol Layer
3536

37+
A slave device is managed by a subclass of `ProtocolRtuSlave`. The protocol layer handles:
3638

37-
1. Subclass of ProtocolRtuSlave.
38-
- Timeouts
39-
- When to process packets
40-
- IO device control, this layer puts the recieved characters
41-
into the protocol and transmitting the generated responses
42-
2. Data Stores
43-
- The holding registers, coils, discrete inputs, and input registers are
44-
generalized as data stores. The default store mechanism can be used where
45-
the data store is literal, i.e. all bits and registers are stored
46-
and accessed directly. Other data stores might define a memory map
47-
that accesses system variables. This will lower memory use and remove the
48-
need to update the store or poll on changes.
39+
1. **Timeouts**: Managing the timeout between the master and slave.
40+
2. **Packet Processing**: Determining when to process incoming packets.
41+
3. **IO Device Control**: This layer receives characters and inputs them into the protocol, while also handling the transmission of generated responses.
42+
43+
## Data Stores
44+
45+
The Modbus data types—holding registers, coils, discrete inputs, and input registers—are treated as data stores. By default, the data store mechanism directly stores and accesses all bits and registers. However, it is possible to use specialized data stores that define a memory map to access system variables, which reduces memory usage and eliminates the need for periodic updates or polling.
4946

5047
## Testing With Other Libraries
48+
5149
### Using socat
52-
[socat][1] is an easy way to spoof a serial
53-
connection. A bidirectional pipe is setup allowing two processes
54-
to see the pipe as if it was an attached serial device.
5550

56-
**Use** :
51+
[socat](http://www.dest-unreach.org/socat/) can simulate a serial connection between two processes. It creates a bidirectional pipe, allowing both processes to treat the pipe as if it were a physical serial device.
52+
53+
**Example**:
54+
55+
```bash
5756
socat -d -d -d -x PTY,link=/tmp/ptyp0,raw,echo=0,ispeed=b9600 PTY,link=/tmp/ttyp0,raw,echo=0,ospeed=b9600
57+
```
5858

59-
In this example the pipes are setup at /tmp/ptyp0 and /tmp/ttyp0 running at 9600 baud with some debug info (level set by the number of '-d').
60-
The master is started on one pipe and the slave on another and can be treated as connected hardware.
59+
This command sets up two pipes at `/tmp/ptyp0` and `/tmp/ttyp0` running at 9600 baud with debug information. The master can be started on one pipe, and the slave on another, simulating a connected hardware setup.
6160

6261
### Libmodbus
6362

63+
For more information on the Modbus protocol and a C library implementation, check out [Libmodbus](https://libmodbus.org/).
64+
6465
### PyModbus
6566

66-
[1]: http://www.dest-unreach.org/socat/
67-
[2]: https://libmodbus.org/
68-
[3]: https://github.com/Jacajack/liblightmodbus
69-
[4]: https://github.com/riptideio/pymodbus
67+
PyModbus is a Python library that implements the Modbus protocol. It can be used to test and interface with the C++ slave. More information can be found on [GitHub](https://github.com/riptideio/pymodbus).
68+
69+
## References
70+
71+
+ [socat](http://www.dest-unreach.org/socat/)
72+
+ [Libmodbus](https://libmodbus.org/)
73+
+ [PyModbus GitHub](https://github.com/riptideio/pymodbus)
74+
+ [liblightmodbus](https://github.com/Jacajack/liblightmodbus)

tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,4 @@ message("System Path" ${CMAKE_SYSTEM_INCLUDE_PATH})
174174
# StaticAnalysis("${AnalyseFiles}" "./")
175175
#endif()
176176

177-
add_test(NAME tests COMMAND ${TargetName})
177+
add_test(NAME ${TargetName} COMMAND ${TargetName})

0 commit comments

Comments
 (0)