PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
virtual_sim_test_helpers.h
Go to the documentation of this file.
1
3#pragma once
4
5#include <chrono>
6#include <cstddef>
7#include <cstdint>
8#include <functional>
9#include <string>
10#include <thread>
11
12#include "profinet/gsdml.h"
14#include "profinet/util.h"
15
17{
18
19inline constexpr MacAddress kControllerMac{0x02, 0x00, 0x00, 0x10, 0x00, 0x01};
20inline constexpr MacAddress kValveMac{0x02, 0x00, 0x00, 0x20, 0x00, 0x01};
21
27inline gsdml::GSDMLDataItem MakeScalarItem(const std::string& dataType,
28 const int length,
29 const std::string& textId)
30{
32 item.dataType = dataType;
33 item.length = length;
34 item.textId = textId;
35 return item;
36}
37
42inline gsdml::GSDMLDataItem MakeBitByte(const std::string& parentTextId,
43 const std::string& bitPrefix)
44{
45 auto item = MakeScalarItem("Unsigned8", 1, parentTextId);
46 item.useAsBits = true;
47 for (std::uint8_t bit = 0; bit < 8U; ++bit)
48 {
49 item.bitDataItems.push_back({bit, bitPrefix + std::to_string(bit)});
50 }
51 return item;
52}
53
57{
58 gsdml::GSDMLDevice device;
59 device.vendorId = 0x013FU;
60 device.deviceId = 0x0002U;
61 device.deviceName = "Auma-SGx-Test";
62 device.dapModuleId = "DAP";
63
64 gsdml::GSDMLModule inputModule;
65 inputModule.id = "ID_MODULE_ADI_IN_0";
66 inputModule.moduleIdentNumber = 0x00008000U;
67
68 gsdml::GSDMLSubmodule inputSubmodule;
69 inputSubmodule.id = "ID_SUBMOD_ADI_IN_0";
70 inputSubmodule.submoduleIdentNumber = 0x00002200U;
71 inputSubmodule.fixedSubslots = {1};
72 inputSubmodule.inputItems = {
73 MakeBitByte("T_ID_LOG", "T_ID_LOG_"),
74 MakeBitByte("T_ID_DRV", "T_ID_DRV_"),
75 MakeScalarItem("Unsigned16", 2, "T_ID_ACTPOS_E2"),
76 MakeBitByte("T_ID_DEVICESTATUS", "T_ID_DEVICESTATUS_"),
77 MakeBitByte("T_ID_OPERATIONSTATUS", "T_ID_OPERATIONSTATUS_"),
78 MakeBitByte("T_ID_WARNING1", "T_ID_WARNING1_"),
79 MakeBitByte("T_ID_FAULT1", "T_ID_FAULT1_"),
80 MakeScalarItem("Unsigned8", 1, "T_ID_RPM"),
81 MakeScalarItem("Unsigned8", 1, "T_ID_RESERVE_INPUT"),
82 };
83 inputSubmodule.inputLength = 9;
84 inputModule.submodules.emplace(inputSubmodule.id, inputSubmodule);
85 device.modules.emplace(inputModule.id, inputModule);
86
87 gsdml::GSDMLModule outputModule;
88 outputModule.id = "ID_MODULE_ADI_OUT_0";
89 outputModule.moduleIdentNumber = 0x00008100U;
90
91 gsdml::GSDMLSubmodule outputSubmodule;
92 outputSubmodule.id = "ID_SUBMOD_ADI_OUT_0";
93 outputSubmodule.submoduleIdentNumber = 0x10001000U;
94 outputSubmodule.fixedSubslots = {1};
95 outputSubmodule.outputItems = {
96 MakeBitByte("T_ID_CMD", "T_ID_CMD_"),
97 MakeScalarItem("Unsigned8", 1, "T_ID_SPEEDSETPOINT"),
98 MakeScalarItem("Unsigned16", 2, "T_ID_POSITIONSETPOINT"),
99 MakeBitByte("T_ID_ADDCMD", "T_ID_ADDCMD_"),
100 MakeBitByte("T_ID_DIRPOS", "T_ID_DIRPOS_"),
101 MakeScalarItem("Unsigned8", 1, "T_ID_RESERVE_OUTPUT"),
102 };
103 outputSubmodule.outputLength = 7;
104 outputModule.submodules.emplace(outputSubmodule.id, outputSubmodule);
105 device.modules.emplace(outputModule.id, outputModule);
106
107 gsdml::GSDMLModuleReference inputReference;
108 inputReference.moduleId = inputModule.id;
109 inputReference.fixedSlots = {1};
110 device.moduleReferences.push_back(inputReference);
111
112 gsdml::GSDMLModuleReference outputReference;
113 outputReference.moduleId = outputModule.id;
114 outputReference.fixedSlots = {2};
115 device.moduleReferences.push_back(outputReference);
116
117 return device;
118}
119
123{
124 gsdml::GSDMLDevice device;
125 device.vendorId = 0x00B0U;
126 device.deviceId = 0x0193U;
127 device.deviceName = "AXC-F-1252-Test";
128 device.dapModuleId = "DIM 1";
129
130 gsdml::GSDMLModule module;
131 module.id = "PNSlot1";
132 module.moduleIdentNumber = 0x00000001U;
133
134 gsdml::GSDMLSubmodule submodule;
135 submodule.id = "PNIO0202";
136 submodule.submoduleIdentNumber = 0x00000009U;
137 submodule.fixedSubslots = {1};
138 submodule.inputItems = {
139 MakeScalarItem("Unsigned32", 4, "DI4"),
140 MakeScalarItem("Integer16", 2, "TEMPERATURE"),
141 MakeScalarItem("Float32", 4, "LEVEL"),
142 MakeBitByte("DI_STATUS", "DI_STATUS_"),
143 MakeScalarItem("VisibleString", 2, "RAW_STATUS"),
144 };
145 submodule.outputItems = {
146 MakeScalarItem("Unsigned32", 4, "DO4"),
147 MakeScalarItem("Float32", 4, "SETPOINT"),
148 MakeBitByte("DO_STATUS", "DO_STATUS_"),
149 };
150 submodule.inputLength = 13;
151 submodule.outputLength = 9;
152 module.submodules.emplace(submodule.id, submodule);
153 device.modules.emplace(module.id, module);
154
156 reference.moduleId = module.id;
157 reference.fixedSlots = {1};
158 device.moduleReferences.push_back(reference);
159
160 return device;
161}
162
167{
168 auto result = MakeVirtualAumaIocrConfiguration(device, 0x9000U, 0x8001U, 32U, 8U, 3U, 3U);
169 result.input.dataLength = 16U;
170 result.output.dataLength = 16U;
171 result.input.objects[0].frameOffset = 0U;
172 result.input.objects[0].offsetIOPS = 9U;
173 result.output.objects[0].frameOffset = 0U;
174 result.output.objects[0].offsetIOPS = 7U;
175 return result;
176}
177
182inline bool WaitUntil(const std::function<bool()>& predicate,
183 std::chrono::milliseconds timeout = std::chrono::milliseconds(500))
184{
185 const auto deadline = std::chrono::steady_clock::now() + timeout;
186 while (std::chrono::steady_clock::now() < deadline)
187 {
188 if (predicate())
189 {
190 return true;
191 }
192 std::this_thread::sleep_for(std::chrono::milliseconds(2));
193 }
194 return predicate();
195}
196
201inline MacAddress MakeIndexedMac(const std::uint8_t prefix, const std::size_t index)
202{
203 return MacAddress{0x02, 0x00, 0x00, prefix,
204 static_cast<std::uint8_t>((index >> 8U) & 0xFFU),
205 static_cast<std::uint8_t>(index & 0xFFU)};
206}
207
208} // namespace profinet::sim::test
Declares the GSDML parser and PROFINET device-description data model.
constexpr MacAddress kControllerMac
MacAddress MakeIndexedMac(const std::uint8_t prefix, const std::size_t index)
Allocate a deterministic locally administered MAC address for an instance index.
gsdml::GSDMLDevice MakePhoenixGsdml()
Build a compact Phoenix GSDML model with four-byte DI/DO process data.
gsdml::GSDMLDataItem MakeScalarItem(const std::string &dataType, const int length, const std::string &textId)
Create a scalar GSDML DataItem.
VirtualAumaIocrConfiguration MakeTestAumaIocrs(const gsdml::GSDMLDevice &device)
Build matching compact RTC1 IOCR configurations for the AUMA test model.
gsdml::GSDMLDevice MakeAumaGsdml()
Build a compact GSDML model using the real AUMA signal identifiers.
constexpr MacAddress kValveMac
bool WaitUntil(const std::function< bool()> &predicate, std::chrono::milliseconds timeout=std::chrono::milliseconds(500))
Wait until a predicate becomes true or the timeout expires.
gsdml::GSDMLDataItem MakeBitByte(const std::string &parentTextId, const std::string &bitPrefix)
Create a GSDML Boolean byte containing eight BitDataItems.
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.
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
Definition util.h:48
One I/O data item within a submodule's cyclic data (GSDML DataItem element).
Definition gsdml.h:35
int length
Length in bytes of this item.
Definition gsdml.h:48
std::string dataType
GSDML DataType attribute, e.g. "Unsigned8", "Integer16", "OctetString".
Definition gsdml.h:37
std::string textId
Human-readable text ID/name for this item, if the GSDML supplied one.
Definition gsdml.h:39
Complete parsed GSDML device profile.
Definition gsdml.h:166
std::map< std::string, GSDMLModule > modules
Every module declared in the GSDML's ModuleList, keyed by GSDML ID.
Definition gsdml.h:196
std::vector< GSDMLModuleReference > moduleReferences
Modules referenced by the DAP's UseableModules list.
Definition gsdml.h:202
std::uint16_t vendorId
PROFINET vendor ID from the GSDML's DeviceIdentity (VendorID attribute).
Definition gsdml.h:172
std::uint16_t deviceId
PROFINET device ID from the GSDML's DeviceIdentity (DeviceID attribute).
Definition gsdml.h:174
std::string deviceName
Device name from the GSDML's DeviceIdentity / DeviceFunction.
Definition gsdml.h:170
std::string dapModuleId
The device access point's own (built-in) identifier to matchs with the submodule.
Definition gsdml.h:177
Reference describing how a module may be used by the DAP.
Definition gsdml.h:150
std::string moduleId
Referenced ModuleItem ID.
Definition gsdml.h:152
std::vector< int > fixedSlots
Slots where the module is fixed.
Definition gsdml.h:158
A GSDML module definition (ModuleItem), possibly offering multiple virtual submodules.
Definition gsdml.h:106
std::string id
GSDML ID attribute (used to resolve ModuleItemTarget references).
Definition gsdml.h:108
std::map< std::string, GSDMLSubmodule > submodules
Virtual submodules this module offers, keyed by their GSDML ID.
Definition gsdml.h:118
std::uint32_t moduleIdentNumber
Module ident number (hex value from the GSDML, parsed to an integer).
Definition gsdml.h:110
A GSDML virtual submodule definition (VirtualSubmoduleItem).
Definition gsdml.h:80
std::uint32_t submoduleIdentNumber
Submodule ident number (hex value from the GSDML, parsed to an integer).
Definition gsdml.h:84
std::vector< GSDMLDataItem > inputItems
Individual input data items, in wire order.
Definition gsdml.h:92
std::string id
GSDML ID attribute (used to resolve VirtualSubmoduleItemTarget references).
Definition gsdml.h:82
int outputLength
Total output data length in bytes (sum of Output DataItems).
Definition gsdml.h:90
std::vector< GSDMLDataItem > outputItems
Individual output data items, in wire order.
Definition gsdml.h:94
int inputLength
Total input data length in bytes (sum of Input DataItems).
Definition gsdml.h:88
std::vector< int > fixedSubslots
Subslots where this inline virtual submodule is fixed.
Definition gsdml.h:99
Input and output RTC1 configurations used by the virtual AUMA peer.
std::uint16_t length
Definition test_dcp.cpp:391
Declares Linux Ethernet, addressing, timing, and utility helpers used by the PROFINET stack.
Helpers for constructing a GSDML-derived AUMA SGx RTC1 test configuration.