Stroika Library
3.0d16
Help-Home
Loading...
Searching...
No Matches
IModbusService.h
1
/*
2
* Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3
*/
4
#ifndef _Stroika_Frameworks_Modbus_IModbusService_h_
5
#define _Stroika_Frameworks_Modbus_IModbusService_h_ 1
6
7
#include "Stroika/Frameworks/StroikaPreComp.h"
8
9
#include "Stroika/Foundation/Containers/Mapping.h"
10
#include "Stroika/Foundation/Containers/Set.h"
11
#include "Stroika/Foundation/Execution/Exceptions.h"
12
13
/**
14
*
15
* \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
16
*
17
* \note This code is basically all based on
18
* http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
19
*/
20
21
namespace
Stroika::Frameworks::Modbus
{
22
23
using namespace
Stroika::Foundation
;
24
25
/**
26
*
27
* \note in the Modbus documentation and GUI (of ModScan64) - they list register/coil #s as 1 based,
28
* but the wire protocol uses zero based.
29
*
30
* The numbers used here - NameType - are all the PUBLIC numbers, not the wire protocol numbers.
31
*
32
* The Stroika wire protocol encoder/decoder does the mapping.
33
*/
34
template
<
typename
ID_TYPE,
typename
VALUE_TYPE>
35
struct
ModbusRegisterDescriptor
{
36
/*
37
* AKA address
38
*/
39
using
NameType = ID_TYPE;
40
/**
41
*/
42
using
ValueType = VALUE_TYPE;
43
};
44
45
/**
46
* From http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf page 8
47
* Coils Single bit Read-Write This type of data can be alterable by an application program
48
*/
49
using
CoilsDescriptorType
=
ModbusRegisterDescriptor<uint16_t, bool>
;
50
51
/**
52
* From http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf page 8
53
* Discretes Input Single bit Read-Only ThiThis type of data can be provided by an I/O system
54
*/
55
using
DiscreteInputDescriptorType
=
ModbusRegisterDescriptor<uint16_t, bool>
;
56
57
/**
58
* From http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf page 8
59
* Input Registers 16-bit word Read-Only This type of data can be provided by an I/O system
60
*/
61
using
InputRegisterDescriptorType
=
ModbusRegisterDescriptor<uint16_t, uint16_t>
;
62
63
/**
64
* This is for 2-byte read/write data - data read from the server, and which may be written to the server.
65
*/
66
using
HoldingRegisterDescriptorType
=
ModbusRegisterDescriptor<uint16_t, uint16_t>
;
67
68
/**
69
* From http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf page 49
70
*
71
* \note These really don't appear to capture any application logic or application notion of failure,
72
* and principally deal with communications failure.
73
*
74
* SLAVE_DEVICE_FAILURE may be the only exception, which is somewhat of a blanket - server failed -
75
* HTTP 503 like - (or so it appears).
76
*/
77
enum class
ExceptionCode
: uint8_t {
78
ILLEGAL_FUNCTION = 1,
79
ILLEGAL_DATA_ADDRESS = 2,
80
ILLEGAL_DATA_VALUE = 3,
81
SLAVE_DEVICE_FAILURE = 4,
82
ACKNOWLEDGE = 5,
83
SLAVE_DEVICE_BUSY = 6,
84
MEMORY_PARITY_ERROR = 8,
85
GATEWAY_PATH_UNAVAILABLE = 0xa,
86
GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0xb,
87
};
88
89
/**
90
*/
91
struct
Exception :
Execution::RuntimeErrorException
<> {
92
Exception (
ExceptionCode
exceptionCode);
93
94
ExceptionCode
fExceptionCode;
95
};
96
97
/**
98
* Users of this module simple subclass this interface, and provide answers to reads and writes, and
99
* then can invoke the server object with this, to create a quickie Modbus TCP server.
100
*
101
* \note Many of these APIs return uint16_t, but logically try to return other larger things like floats.
102
* So the ReadInputRegisters () and ReadHoldingRegisters () APIs may return mappings outside
103
* the strict range prescribed by their argument 'names'. Those returned values may or may not
104
* be transported over the wire, depending on the caller request.
105
*/
106
struct
IModbusService
{
107
virtual
~IModbusService
() =
default
;
108
109
template
<
typename
MODBUS_REGISTER_DESCRIPTOR>
110
using
RegisterValuesMapping
=
111
Containers::Mapping<typename MODBUS_REGISTER_DESCRIPTOR::NameType, typename MODBUS_REGISTER_DESCRIPTOR::ValueType>
;
112
template
<
typename
MODBUS_REGISTER_DESCRIPTOR>
113
using
SetRegisterNames
=
Containers::Set<typename MODBUS_REGISTER_DESCRIPTOR::NameType>
;
114
115
/**
116
* Coils are boolean valued. OK to return any subset of argument coils. Illegal to return any not specified in argument list.
117
*/
118
virtual
RegisterValuesMapping<CoilsDescriptorType>
ReadCoils
(
const
SetRegisterNames<CoilsDescriptorType>
& names) = 0;
119
120
/**
121
* Coils are boolean valued.
122
*/
123
virtual
void
WriteCoils
(
const
RegisterValuesMapping<CoilsDescriptorType>
& values) = 0;
124
125
/**
126
* DiscreteInput values are boolean valued.
127
*/
128
virtual
RegisterValuesMapping<DiscreteInputDescriptorType>
ReadDiscreteInput
(
const
SetRegisterNames<DiscreteInputDescriptorType>
& names) = 0;
129
130
/**
131
* InputRegister values are boolean uint16_t, and are read-only.
132
*/
133
virtual
RegisterValuesMapping<InputRegisterDescriptorType>
ReadInputRegisters
(
const
SetRegisterNames<InputRegisterDescriptorType>
& names) = 0;
134
135
/**
136
* HoldingRegister values are boolean uint16_t, and are read-write.
137
*/
138
virtual
RegisterValuesMapping<HoldingRegisterDescriptorType>
ReadHoldingRegisters
(
const
SetRegisterNames<HoldingRegisterDescriptorType>
& names) = 0;
139
140
/**
141
* HoldingRegister values are boolean uint16_t, and are read-write.
142
*/
143
virtual
void
WriteHoldingRegisters
(
const
RegisterValuesMapping<HoldingRegisterDescriptorType>
& values) = 0;
144
};
145
146
}
147
148
/*
149
********************************************************************************
150
***************************** Implementation Details ***************************
151
********************************************************************************
152
*/
153
#include "IModbusService.inl"
154
155
#endif
/*_Stroika_Frameworks_Modbus_IModbusService_h_*/
Stroika::Foundation::Containers::Mapping
Definition
Mapping.h:114
Stroika::Foundation::Containers::Set
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition
Set.h:105
Stroika::Foundation::Execution::RuntimeErrorException
Definition
Exceptions.h:198
Stroika::Foundation
Definition
BloomFilter.h:22
Stroika::Frameworks::Modbus
Definition
IModbusService.h:21
Stroika::Frameworks::Modbus::ExceptionCode
ExceptionCode
Definition
IModbusService.h:77
Stroika::Frameworks::Modbus::IModbusService
Definition
IModbusService.h:106
Stroika::Frameworks::Modbus::IModbusService::ReadInputRegisters
virtual RegisterValuesMapping< InputRegisterDescriptorType > ReadInputRegisters(const SetRegisterNames< InputRegisterDescriptorType > &names)=0
Stroika::Frameworks::Modbus::IModbusService::WriteHoldingRegisters
virtual void WriteHoldingRegisters(const RegisterValuesMapping< HoldingRegisterDescriptorType > &values)=0
Stroika::Frameworks::Modbus::IModbusService::ReadCoils
virtual RegisterValuesMapping< CoilsDescriptorType > ReadCoils(const SetRegisterNames< CoilsDescriptorType > &names)=0
Stroika::Frameworks::Modbus::IModbusService::WriteCoils
virtual void WriteCoils(const RegisterValuesMapping< CoilsDescriptorType > &values)=0
Stroika::Frameworks::Modbus::IModbusService::ReadHoldingRegisters
virtual RegisterValuesMapping< HoldingRegisterDescriptorType > ReadHoldingRegisters(const SetRegisterNames< HoldingRegisterDescriptorType > &names)=0
Stroika::Frameworks::Modbus::IModbusService::ReadDiscreteInput
virtual RegisterValuesMapping< DiscreteInputDescriptorType > ReadDiscreteInput(const SetRegisterNames< DiscreteInputDescriptorType > &names)=0
Stroika::Frameworks::Modbus::ModbusRegisterDescriptor
Definition
IModbusService.h:35
Library
Sources
Stroika
Frameworks
Modbus
IModbusService.h
Generated by
1.9.8