PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
virtual_auma_config.cpp
Go to the documentation of this file.
1
3
5
6#include <algorithm>
7#include <stdexcept>
8#include <string>
9
10namespace profinet::sim
11{
12
13namespace
14{
15
21const gsdml::GSDMLSubmodule& RequireAumaSubmodule(const gsdml::GSDMLDevice& device,
22 const std::string& moduleId,
23 const std::string& submoduleId)
24{
25 const auto* module = device.FindModule(moduleId);
26 if (module == nullptr)
27 {
28 throw std::invalid_argument("AUMA simulator GSDML is missing module: " + moduleId);
29 }
30
31 const auto inlineIt = module->submodules.find(submoduleId);
32 if (inlineIt != module->submodules.end())
33 {
34 return inlineIt->second;
35 }
36
37 const auto* submodule = device.FindSubmodule(submoduleId);
38 if (submodule == nullptr)
39 {
40 throw std::invalid_argument("AUMA simulator GSDML is missing submodule: " + submoduleId);
41 }
42 return *submodule;
43}
44
50std::uint16_t ResolveFixedSlot(const gsdml::GSDMLDevice& device,
51 const std::string& moduleId,
52 const std::uint16_t fallback)
53{
54 for (const auto& reference : device.moduleReferences)
55 {
56 if (reference.moduleId == moduleId && !reference.fixedSlots.empty())
57 {
58 return static_cast<std::uint16_t>(reference.fixedSlots.front());
59 }
60 }
61 return fallback;
62}
63
68std::uint16_t ResolveFixedSubslot(const gsdml::GSDMLSubmodule& submodule,
69 const std::uint16_t fallback)
70{
71 if (!submodule.fixedSubslots.empty())
72 {
73 return static_cast<std::uint16_t>(submodule.fixedSubslots.front());
74 }
75 return fallback;
76}
77
83std::uint16_t ResolveModuleReferenceSubslot(const gsdml::GSDMLModule& module,
84 const std::string& submoduleId,
85 const std::uint16_t fallback)
86{
87 for (const auto& reference : module.submoduleReferences)
88 {
89 if (reference.submoduleId == submoduleId && !reference.fixedSubslots.empty())
90 {
91 return static_cast<std::uint16_t>(reference.fixedSubslots.front());
92 }
93 }
94 return fallback;
95}
96
97} // namespace
98
100 const gsdml::GSDMLDevice& device,
101 const std::uint16_t inputFrameId,
102 const std::uint16_t outputFrameId,
103 const std::uint16_t sendClockFactor,
104 const std::uint16_t reductionRatio,
105 const std::uint16_t watchdogFactor,
106 const std::uint16_t dataHoldFactor)
107{
108 const auto* inputModule = device.FindModule("ID_MODULE_ADI_IN_0");
109 const auto* outputModule = device.FindModule("ID_MODULE_ADI_OUT_0");
110 if (inputModule == nullptr || outputModule == nullptr)
111 {
112 throw std::invalid_argument("AUMA GSDML does not contain the expected ADI modules");
113 }
114
115 const auto* input = &RequireAumaSubmodule(device, inputModule->id, "ID_SUBMOD_ADI_IN_0");
116 const auto* output = &RequireAumaSubmodule(device, outputModule->id, "ID_SUBMOD_ADI_OUT_0");
117
118 if (input->inputLength <= 0 || output->outputLength <= 0)
119 {
120 throw std::invalid_argument("AUMA simulator GSDML contains empty process-data modules");
121 }
122
123 const auto inputSlot = ResolveFixedSlot(device, inputModule->id, 1U);
124 const auto outputSlot = ResolveFixedSlot(device, outputModule->id, 2U);
125 const auto inputSubslot = ResolveModuleReferenceSubslot(
126 *inputModule, input->id, ResolveFixedSubslot(*input, 1U));
127 const auto outputSubslot = ResolveModuleReferenceSubslot(
128 *outputModule, output->id, ResolveFixedSubslot(*output, 1U));
129
130 // The real AUMA SGx GSDML uses 43-byte input and 25-byte output C_SDU limits.
131 // The parser currently exposes the module process-data lengths but not the
132 // DAP IOConfigData MaxInputLength/MaxOutputLength attributes, so these defaults
133 // remain explicit and can be overridden by changing the IOCRs supplied to the
134 // simulator constructor.
135 constexpr std::uint16_t kAumaInputCsduLength = 43U;
136 constexpr std::uint16_t kAumaOutputCsduLength = 25U;
137
139
141 result.input.referenceIOCR = 1U;
142 result.input.frameId = inputFrameId;
143 result.input.sendClockFactor = sendClockFactor;
144 result.input.reductionRatio = reductionRatio;
145 result.input.watchdogFactor = watchdogFactor;
146 result.input.dataLength =
147 std::max<std::uint16_t>(kAumaInputCsduLength,
148 static_cast<std::uint16_t>(input->inputLength + 1));
149 result.input.objects = {
150 {
151 inputSlot,
152 inputSubslot,
153 0U,
154 static_cast<std::uint16_t>(input->inputLength),
155 static_cast<std::uint16_t>(input->inputLength),
156 {},
157 },
158 };
159
161 result.output.referenceIOCR = 2U;
162 result.output.frameId = outputFrameId;
163 result.output.sendClockFactor = sendClockFactor;
164 result.output.reductionRatio = reductionRatio;
165 result.output.watchdogFactor = watchdogFactor;
166 result.output.dataLength =
167 std::max<std::uint16_t>(kAumaOutputCsduLength,
168 static_cast<std::uint16_t>(output->outputLength + 9));
169 result.output.objects = {
170 {
171 outputSlot,
172 outputSubslot,
173 8U,
174 static_cast<std::uint16_t>(output->outputLength),
175 static_cast<std::uint16_t>(output->outputLength + 8),
176 {},
177 },
178 };
179
180 // dataHoldFactor is serialized by rpc::RPCCon::BuildIocrBlock through the
181 // higher-level rpc::IOCRSetup. rt::IOCRConfig models the cyclic data layout only.
182 (void)dataHoldFactor;
183
184 return result;
185}
186
187} // namespace profinet::sim
constexpr std::uint16_t IOCR_TYPE_INPUT
IOCR direction: Device -> Controller.
Definition rt.h:66
constexpr std::uint16_t IOCR_TYPE_OUTPUT
IOCR direction: Controller -> Device.
Definition rt.h:68
VirtualAumaIocrConfiguration MakeVirtualAumaIocrConfiguration(const gsdml::GSDMLDevice &device, std::uint16_t inputFrameId=0x9000, std::uint16_t outputFrameId=0x8001, std::uint16_t sendClockFactor=32, std::uint16_t reductionRatio=8, std::uint16_t watchdogFactor=3, std::uint16_t dataHoldFactor=3)
Build the standard two-module AUMA SGx process-data layout from its GSDML.
Complete parsed GSDML device profile.
Definition gsdml.h:166
const GSDMLModule * FindModule(const std::string &moduleId) const
Look up a module by its GSDML ID.
Definition gsdml.cpp:631
std::vector< IODataObject > objects
IO data objects carried in this IOCR's cyclic frame.
Definition rt.h:163
std::uint16_t dataLength
Total cyclic data length in bytes.
Definition rt.h:160
std::uint16_t typeIOCR
IOCR direction: 1=Input, 2=Output.
Definition rt.h:139
std::uint16_t referenceIOCR
IOCR reference assigned during AR establishment.
Definition rt.h:142
std::uint16_t sendClockFactor
Send clock base factor (31.25us units).
Definition rt.h:148
std::uint16_t frameId
Frame ID assigned to this IOCR.
Definition rt.h:145
std::uint16_t reductionRatio
Reduction ratio relative to the send clock.
Definition rt.h:151
std::uint16_t watchdogFactor
Watchdog factor (missed-frame tolerance before a timeout fault).
Definition rt.h:157
Input and output RTC1 configurations used by the virtual AUMA peer.
rt::IOCRConfig input
Device-to-controller IOCR.
rt::IOCRConfig output
Controller-to-device IOCR.
Helpers for constructing a GSDML-derived AUMA SGx RTC1 test configuration.