Stroika Library 3.0d16
 
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
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>
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 */
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 */
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 */
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 */
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 */
107 virtual ~IModbusService () = default;
108
109 template <typename MODBUS_REGISTER_DESCRIPTOR>
112 template <typename MODBUS_REGISTER_DESCRIPTOR>
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 */
119
120 /**
121 * Coils are boolean valued.
122 */
124
125 /**
126 * DiscreteInput values are boolean valued.
127 */
129
130 /**
131 * InputRegister values are boolean uint16_t, and are read-only.
132 */
134
135 /**
136 * HoldingRegister values are boolean uint16_t, and are read-write.
137 */
139
140 /**
141 * HoldingRegister values are boolean uint16_t, and are read-write.
142 */
144 };
145
146}
147
148/*
149 ********************************************************************************
150 ***************************** Implementation Details ***************************
151 ********************************************************************************
152 */
153#include "IModbusService.inl"
154
155#endif /*_Stroika_Frameworks_Modbus_IModbusService_h_*/
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition Set.h:105
virtual RegisterValuesMapping< InputRegisterDescriptorType > ReadInputRegisters(const SetRegisterNames< InputRegisterDescriptorType > &names)=0
virtual void WriteHoldingRegisters(const RegisterValuesMapping< HoldingRegisterDescriptorType > &values)=0
virtual RegisterValuesMapping< CoilsDescriptorType > ReadCoils(const SetRegisterNames< CoilsDescriptorType > &names)=0
virtual void WriteCoils(const RegisterValuesMapping< CoilsDescriptorType > &values)=0
virtual RegisterValuesMapping< HoldingRegisterDescriptorType > ReadHoldingRegisters(const SetRegisterNames< HoldingRegisterDescriptorType > &names)=0
virtual RegisterValuesMapping< DiscreteInputDescriptorType > ReadDiscreteInput(const SetRegisterNames< DiscreteInputDescriptorType > &names)=0