|
Motion Master 6.0.0-alpha.86
Next-generation motion control software
|
Classes | |
| struct | Access |
An <Access> element together with its two restriction attributes. More... | |
| struct | EniCoeCmd |
One CoE transfer the master runs at a transition (ENI CoE/InitCmds/InitCmd). More... | |
| struct | EniCyclic |
The cyclic task that exchanges process data (ENI Config/Cyclic). More... | |
| struct | EniCyclicCmd |
One datagram of a cyclic frame (ENI Cyclic/Frame/Cmd). More... | |
| struct | EniDc |
A device's distributed-clock configuration (ENI Slave/DC). More... | |
| struct | EniEcatCmd |
One EtherCAT datagram the master sends at a transition (ENI ECatCmdType). More... | |
| struct | EniEoe |
The virtual Ethernet switch the master runs for Ethernet over EtherCAT (ENI Master/EoE). More... | |
| struct | EniFrame |
One cyclic frame (ENI Cyclic/Frame). More... | |
| struct | EniMailbox |
A device's mailbox configuration (ENI Slave/Mailbox). More... | |
| struct | EniMailboxStates |
The master's cyclic check of every mailbox on the bus (ENI Master/MailboxStates). More... | |
| struct | EniMailboxWindow |
One mailbox window of a device (ENI MailboxSendInfoType / MailboxRecvInfoType). More... | |
| struct | EniMaster |
The master itself (ENI Config/Master). More... | |
| struct | EniNetwork |
A complete network configuration (ENI EtherCATConfig/Config). More... | |
| struct | EniPdo |
One process-data object of a device (ENI PdoType). More... | |
| struct | EniPdoEntry |
One object mapped into a PDO (ENI EntryType). More... | |
| struct | EniPreviousPort |
Where this device sits in the ring (ENI Slave/PreviousPort). More... | |
| struct | EniProcessData |
A device's process-data description (ENI Slave/ProcessData). More... | |
| struct | EniProcessDataWindow |
Where one device's process data sits in the master's image (ENI ProcessData/Send or ProcessData/Recv). More... | |
| struct | EniProcessImage |
The master's process image (ENI Config/ProcessImage). More... | |
| struct | EniProcessImageArea |
One half of the master's process image (ENI ProcessImage/Inputs or /Outputs). More... | |
| struct | EniRead |
| A network read out of an ENI document, and what the document held that this model does not. More... | |
| struct | EniSlave |
One device on the bus (ENI Config/Slave). More... | |
| struct | EniSlaveInfo |
A device's identity (ENI Slave/Info). More... | |
| struct | EniSyncManager |
One Sync Manager of a device (ENI SyncManagerSettings). More... | |
| struct | EniValidate |
The value a read init command must return before the master goes on (ENI Validate). More... | |
| struct | EniVariable |
One named value in the master's process image (ENI ProcessImage Variable). More... | |
| struct | EsiDataType |
A dictionary-scoped type definition (ETG.2000 DataTypeType). More... | |
| struct | EsiDevice |
One device description (ETG.2000 DeviceType) — the dictionary-relevant subset. More... | |
| struct | EsiDictionary |
A CoE object dictionary (ETG.2000 DictionaryType). More... | |
| struct | EsiEntry |
| One (index, subindex) row of a device's fully expanded object dictionary. More... | |
| struct | EsiEntryOptions |
Knobs for buildDeviceEntries. More... | |
| struct | EsiEntrySource |
| Which dictionary an entry came from. More... | |
| struct | EsiEntryTable |
| A device's flat dictionary, plus everything questionable found while building it. More... | |
| struct | EsiEnumOption |
| One label/value pair of an enumerated entry. More... | |
| struct | EsiFile |
| A parsed ESI file. More... | |
| struct | EsiModule |
One module description (ETG.2000 ModuleType). More... | |
| struct | EsiObject |
One object-dictionary object (ETG.2000 ObjectType). More... | |
| struct | EsiParseRequest |
| What a caller wants back from an ESI document. More... | |
| struct | EsiPdo |
A process-data object (ETG.2000 PdoType) — an <RxPdo>, <TxPdo>, or <SafetyParaMapping>, which all reuse the same schema type. More... | |
| struct | EsiProfile |
A device or module profile (ETG.2000 ProfileType). More... | |
| struct | EsiSlots |
The <Slots> block of a modular device (ETG.5001). More... | |
| struct | MailboxCoe |
CoE mailbox capabilities (Mailbox/CoE attributes). More... | |
| struct | PrimitiveType |
| One primitive type: its ESI spelling and the CoE numbering it maps onto. More... | |
| struct | Property |
A name/value annotation (ETG.2000 PropertyType). More... | |
| struct | Text |
| EtherCAT Slave Information (ESI) — the vendor's XML description of a device family. More... | |
| struct | UnitNotation |
| One entry of the built-in ETG.1004 notation catalogue. More... | |
| struct | UnitParts |
| The four bytes of an ETG.1004 unit notation value, split out. More... | |
| struct | UnitType |
A dictionary-local unit definition (ETG.2000 UnitType, Dictionary/UnitTypes). More... | |
Enumerations | |
| enum class | EniTransition : std::uint8_t { II , IP , PP , PO , PS , PI , SS , SP , SO , SI , OS , OP , OI , IB , BI } |
| EtherCAT Network Information (ENI) — the configuration a master replays to start a bus. More... | |
| enum class | EniCmd : std::uint8_t { Nop = 0 , Aprd = 1 , Apwr = 2 , Aprw = 3 , Fprd = 4 , Fpwr = 5 , Fprw = 6 , Brd = 7 , Bwr = 8 , Brw = 9 , Lrd = 10 , Lwr = 11 , Lrw = 12 , Armw = 13 , Frmw = 14 } |
EtherCAT command type of an init or cyclic command (ENI Cmd, ETG.2100 Table 21). More... | |
| enum class | EniRequires : std::uint8_t { None , Frame , Cycle } |
Whether an init command needs a frame or a cycle of its own (ENI <Requires>). More... | |
| enum class | EniState : std::uint8_t { Init , PreOp , SafeOp , Op } |
An AL state a cyclic command is sent in (ENI Cyclic/Frame/Cmd/State). More... | |
| enum class | EniSyncManagerType : std::uint8_t { MailboxOut , MailboxIn , Outputs , Inputs } |
What a Sync Manager carries (ENI SyncManagerSettings/Type). More... | |
| enum class | EniMailboxProtocol : std::uint8_t { Aoe , Eoe , Coe , Soe , Foe , Voe } |
A mailbox protocol a device supports (ENI Mailbox/Protocol). More... | |
| enum class | EniCoeCommandSpecifier : std::uint8_t { Download = 1 , Upload = 2 } |
The CoE command specifier of a mailbox init command (ENI Ccs). More... | |
| enum class | EniPort : std::uint8_t { A , B , C , D } |
A port of the device upstream of this one (ENI Slave/PreviousPort Port). More... | |
| enum class | AccessMode : uint8_t { Ro , Rw , Wo } |
SDO access mode — the text of a <Access> element. Spec default Ro. More... | |
| enum class | StateRestriction : uint8_t { None , PreOp , PreOpSafeOp , PreOpOp , SafeOp , SafeOpOp , Op } |
AL-state restriction on a read or a write (Access/@ReadRestrictions, Access/@WriteRestrictions). More... | |
| enum class | Category : uint8_t { Mandatory , Optional , Conditional } |
Whether an entry must be implemented (Flags/Category). Spec default Optional. More... | |
| enum class | PdoMapping : uint8_t { None , Tx , Rx , TxRx } |
PDO mappability (Flags/PdoMapping). Spec default None — not mappable. More... | |
| enum class | SafetyMapping : uint8_t { None , SafeIn , SafeOut , SafeInOut , SafeParam } |
Safety mappability (Flags/SafetyMapping, ETG.5120). Spec default None. More... | |
| enum class | SdoAccess : uint8_t { SubIndexAccess , CompleteAccess } |
SDO transfer granularity (Object/Flags/SdoAccess). More... | |
| enum class | ObjectCode : uint16_t { Var = 0x07 , Array = 0x08 , Record = 0x09 } |
| CoE object code (ETG.1000.6 §5 Table 41 "Object Code"). More... | |
| enum class | ValueKind : uint8_t { Bool , Int8 , Int16 , Int32 , Int64 , Uint8 , Uint16 , Uint32 , Uint64 , Real32 , Real64 , String , Bytes } |
| The C++ type an entry's value maps to. More... | |
| enum class | EsiCollisionPolicy : uint8_t { LastWins , FirstWins , Error } |
| What to do when two dictionaries declare the same (index, subindex). More... | |
Functions | |
| void | to_json (nlohmann::json &j, const EniNetwork &network) |
| Serialises a network as JSON, for a client that renders rather than replays it. | |
| std::string | eniPhysics (std::uint16_t physicalPort) |
Renders the ENI Physics string for a device from its SII physical-port word. | |
| std::expected< std::string, std::string > | writeEni (const EniNetwork &network) |
| Renders a network as an ENI document. | |
| std::expected< EniRead, std::string > | readEni (std::string_view xml) |
| Reads an ENI document into a network. | |
| std::string_view | esiText (const std::vector< Text > &texts, uint32_t lcId=kDefaultLcId) |
Picks the lcId text from texts, else the unlocalised/default one, else the first. | |
| std::expected< EsiFile, std::string > | parseEsi (std::string_view xml) |
| Parses an ESI XML document. | |
| std::expected< EsiFile, std::string > | parseEsiFile (const std::filesystem::path &path) |
Reads path and parses it with parseEsi. | |
| const EsiDevice * | findEsiDevice (const EsiFile &file, std::string_view type) |
Finds the device whose <Type> text equals type (case-sensitive). | |
| const EsiDevice * | findEsiDeviceByProductCode (const EsiFile &file, uint32_t productCode, std::optional< uint32_t > revisionNo=std::nullopt) |
Finds the device with product code productCode, optionally pinned to a revision. | |
| const EsiModule * | findEsiModule (const EsiFile &file, uint32_t moduleIdent) |
Finds the module with the given ModuleIdent. | |
| std::vector< uint32_t > | esiSlotModuleIdents (const EsiDevice &device) |
Returns every ModuleIdent referenced by any of device's slots, in slot order. | |
| std::string_view | arrayElementTypeName (std::string_view esiName) |
Returns the element type name of an "ARRAY [a..b] OF T" composition, else empty. | |
| bool | isStringTypeName (std::string_view esiName) |
True when esiName is a parameterised string type — STRING(n) / OCTET_STRING(n) / UNICODE_STRING(n). | |
| std::optional< PrimitiveType > | resolvePrimitiveType (std::string_view esiName) |
| Resolves an ESI type name to its CoE code, width and signedness. | |
| ValueKind | resolveValueKind (uint16_t dataType, uint16_t bitSize) |
| Resolves the C++ type an entry holds, from its ETG.1020 code and declared width. | |
| void | to_json (nlohmann::json &j, const PrimitiveType &type) |
Serialises a PrimitiveType to JSON (name, code, bitSize, isSigned). | |
| constexpr std::string_view | objectCodeName (ObjectCode code) |
Returns the ESI/CiA spelling of code — "VAR", "ARRAY" or "RECORD". | |
| constexpr std::string_view | cxxTypeName (ValueKind kind) |
The C++ spelling of kind — "int32_t", "std::string", "std::vector<uint8_t>". | |
| std::expected< EsiEntryTable, std::string > | buildDeviceEntries (const EsiFile &file, const EsiDevice &device, const EsiEntryOptions &options={}) |
| Expands a device into a flat, slot-merged vector of object-dictionary entries. | |
| std::expected< std::vector< uint32_t >, std::string > | parseIdentList (std::string_view csv) |
| Parses a comma-separated list of hex-or-decimal values, as a query parameter carries it. | |
| std::expected< nlohmann::json, std::string > | buildEsiResponse (std::string_view xml, const EsiParseRequest &request, const EsiEntryOptions &options={}) |
| Parses an ESI document and renders it as JSON. | |
| std::string | esiUnitSymbol (uint32_t unit, std::span< const UnitType > local={}) |
| Renders a packed unit notation value as a display symbol. | |
| void | to_json (nlohmann::json &j, const UnitType &unit) |
Serialises a UnitType to JSON (notationIndex, index, name, symbol). | |
| constexpr UnitParts | esiUnitParts (uint32_t unit) |
| Splits a packed ETG.1004 unit notation value into its four bytes. | |
| void | to_json (nlohmann::json &j, const Text &v) |
| Serialises the model to JSON. Keys are lowerCamelCase mirrors of the member names; absent optionals are omitted rather than emitted as null. | |
| void | to_json (nlohmann::json &j, const Property &v) |
| void | to_json (nlohmann::json &j, const Access &v) |
| void | to_json (nlohmann::json &j, const MailboxCoe &v) |
| void | to_json (nlohmann::json &j, const EsiObject::Flags &v) |
| void | to_json (nlohmann::json &j, const EsiDataType::SubItem::Flags &v) |
| void | to_json (nlohmann::json &j, const EsiObject::Info::SubItem &v) |
| void | to_json (nlohmann::json &j, const EsiObject::Info &v) |
| void | to_json (nlohmann::json &j, const EsiObject &v) |
| void | to_json (nlohmann::json &j, const EsiDataType::SubItem &v) |
| void | to_json (nlohmann::json &j, const EsiDataType::ArrayInfo &v) |
| void | to_json (nlohmann::json &j, const EsiDataType::EnumInfo &v) |
| void | to_json (nlohmann::json &j, const EsiDataType &v) |
| void | to_json (nlohmann::json &j, const EsiDictionary &v) |
| void | to_json (nlohmann::json &j, const EsiProfile &v) |
| void | to_json (nlohmann::json &j, const EsiPdo::Entry &v) |
| void | to_json (nlohmann::json &j, const EsiPdo &v) |
| void | to_json (nlohmann::json &j, const EsiSlots::Slot &v) |
| void | to_json (nlohmann::json &j, const EsiSlots::ModulePdoGroup &v) |
| void | to_json (nlohmann::json &j, const EsiSlots &v) |
| void | to_json (nlohmann::json &j, const EsiDevice &v) |
| void | to_json (nlohmann::json &j, const EsiModule &v) |
| void | to_json (nlohmann::json &j, const EsiFile::Vendor &v) |
| void | to_json (nlohmann::json &j, const EsiFile &v) |
| constexpr std::string_view | accessModeName (AccessMode v) |
Symbolic names for the flag enums, in their ESI spelling ("ro", "m", "tr", …). | |
| constexpr std::string_view | categoryName (Category v) |
| constexpr std::string_view | pdoMappingName (PdoMapping v) |
| constexpr std::string_view | safetyMappingName (SafetyMapping v) |
| constexpr std::string_view | sdoAccessName (SdoAccess v) |
| constexpr std::string_view | stateRestrictionName (StateRestriction v) |
| void | to_json (nlohmann::json &j, const EsiEnumOption &v) |
| Serialises an entry to JSON. Raw byte vectors are emitted as uppercase hexBinary strings, the same spelling the ESI itself uses; absent optionals are omitted. | |
| void | to_json (nlohmann::json &j, const EsiEntrySource &v) |
| void | to_json (nlohmann::json &j, const EsiEntry &v) |
| void | to_json (nlohmann::json &j, const EsiEntryTable &v) |
Variables | |
| constexpr uint32_t | kDefaultLcId = 1033 |
The default LcId — 1033, en-US. | |
| constexpr auto | kPrimitiveTypes |
| Catalogue of the ESI primitive types, keyed by their IEC 61131-3 name. | |
|
strong |
|
strong |
|
strong |
EtherCAT command type of an init or cyclic command (ENI Cmd, ETG.2100 Table 21).
The addressing mode is part of the command: Aprd and Apwr address by position in the ring, Fprd and Fpwr by configured station address, the B commands address every device at once, and the L commands address logical memory. A read-write command performs its read before its write.
|
strong |
The CoE command specifier of a mailbox init command (ENI Ccs).
The values are CoE's own, from ETG.1000.6: 1 initiates a download, which writes to the device. ETG.2100 Table 20 states the opposite — it labels 1 as an upload and 2 as a download. The coding here follows ETG.1000.6, which owns the CoE protocol, and the ENI files ETG ships as samples agree with it: each one carries a payload under a Ccs of 1, and an upload request has no payload to carry.
| Enumerator | |
|---|---|
| Download | SDO initiate download: the master writes |
| Upload | SDO initiate upload: the master reads the object. |
|
strong |
A mailbox protocol a device supports (ENI Mailbox/Protocol).
| Enumerator | |
|---|---|
| Aoe | ADS over EtherCAT. |
| Eoe | Ethernet over EtherCAT. |
| Coe | CANopen over EtherCAT. |
| Soe | Servo Profile over EtherCAT. |
| Foe | File Access over EtherCAT. |
| Voe | Vendor-specific over EtherCAT. |
|
strong |
A port of the device upstream of this one (ENI Slave/PreviousPort Port).
The letters are the ENI's own spelling of port numbers 0 to 3. A is spec-legal and schema-invalid: ETG.2100 Table 29 allows all four, and ENI Schema 1.7 enumerates only B, C and D. writeEni therefore refuses A, while a reader should accept it — reading a document somebody else wrote is the case that needs the tolerance.
| Enumerator | |
|---|---|
| A | Port 0. Rejected by the schema; see above. |
| B | Port 1. |
| C | Port 2. |
| D | Port 3. |
|
strong |
|
strong |
|
strong |
|
strong |
EtherCAT Network Information (ENI) — the configuration a master replays to start a bus.
An ESI file describes one device family; an ENI describes one assembled network, and it is what a third-party master consumes. The two documents are not the same kind of thing. An ESI is declarative, and a configuration tool reads it to decide what to do. An ENI is imperative: every configuration step is written as an EtherCAT datagram (EniEcatCmd) or a CoE transfer (EniCoeCmd), tagged with the AL-state transition it belongs to, and a master brings the bus up by replaying them in order. So this library does not describe a network to a master. It hands the master a script.
The model below mirrors the ENI XML Schema 1.7 element by element, in schema order, because every ENI complex type is an xs:sequence — element order is part of the contract, and a document with the right elements in the wrong order does not validate. Reference: ETG.2100 (EtherCAT Network Information Specification) is the prose authority, and EtherCATConfig.xsd is the exact one.
Three conventions run through the format and are handled once, here:
xs:hexBinary — raw bytes in EtherCAT wire order, hex-encoded. An ESC register value is little-endian, so a write of 0x0002 to AL Control is "0200". Every payload is carried as std::vector<uint8_t> in wire order and encoded once, by writeEni.std::optional, or an empty string or vector, is one the schema marks optional, and writeEni omits the element rather than writing a zero. The difference matters: <Cnt>0</Cnt> tells a master to expect a working counter of zero, which no successful datagram returns.EniProcessData, send is the master's output image and recv is its input image (ETG.2100 Table 14). A device's TxPDOs therefore land in recv.writeEni is a pure transform with no fieldbus in it. A caller in mm::node fills the model from a live bus, and this library never learns that a bus exists.
An AL-state transition an init command runs on (ENI TransitionType).
Two letters, the state left and the state entered: IP is INIT to PRE-OP. The pairs with a repeated letter are the states a command may be re-sent in without a transition.
|
strong |
|
strong |
CoE object code (ETG.1000.6 §5 Table 41 "Object Code").
The enumerator values are the wire codes, so static_cast<uint16_t> yields the value a CoE SDO-Information "Get Object Description" response carries in its ObjectCode field, and an EsiEntry drops straight into mm::node::DeviceParameter::objectCode.
ETG.1000.6 also defines DEFTYPE (0x05) and DEFSTRUCT (0x06) for type definitions. Those describe entries of the data type dictionary, not the object dictionary, and an ESI expresses them as <DataType> elements rather than <Object> elements — so they never reach this enum.
| Enumerator | |
|---|---|
| Var | A single value: no subindices beyond 0. |
| Array | Subindex 0 is the entry count; 1..N share one element type. |
| Record | Subindex 0 is the entry count; 1..N each have their own type. |
|
strong |
|
strong |
|
strong |
SDO transfer granularity (Object/Flags/SdoAccess).
Exists only on Object/Flags — SubItemType/Flags has no such element (EtherCATBase.xsd:115-169) — so every subindex of an object necessarily shares the object's value. When the element is absent the default comes from the device's or module's Mailbox/CoE/@CompleteAccess.
| Enumerator | |
|---|---|
| SubIndexAccess | |
| CompleteAccess | |
|
strong |
AL-state restriction on a read or a write (Access/@ReadRestrictions, Access/@WriteRestrictions).
None means the attribute was absent: no restriction beyond the mailbox being up. The XSD enumerates both the modern "PreOP" and the legacy "PreOp" spelling, and ETG.2000 requires a tool to treat them identically, so parsing is case-insensitive.
| Enumerator | |
|---|---|
| None | |
| PreOp | |
| PreOpSafeOp | |
| PreOpOp | |
| SafeOp | |
| SafeOpOp | |
| Op | |
|
strong |
The C++ type an entry's value maps to.
Coarser than the ETG.1020 numbering on purpose: a dozen codes describe the same eight bytes, and what a caller needs is which C++ type holds the value, not which spelling the vendor chose. Bytes is the honest answer for everything with no scalar equivalent — octet strings, GUIDs, domains, the odd 24/40/48/56-bit integers, and anything whose declared width contradicts its code.
|
constexpr |
Symbolic names for the flag enums, in their ESI spelling ("ro", "m", "tr", …).
| std::string_view mm::etg::arrayElementTypeName | ( | std::string_view | esiName | ) |
Returns the element type name of an "ARRAY [a..b] OF T" composition, else empty.
The bounds are not validated or returned: an ESI carries them redundantly in DataType/ArrayInfo, which is the authoritative source.
| std::expected< EsiEntryTable, std::string > mm::etg::buildDeviceEntries | ( | const EsiFile & | file, |
| const EsiDevice & | device, | ||
| const EsiEntryOptions & | options = {} |
||
| ) |
Expands a device into a flat, slot-merged vector of object-dictionary entries.
Walks the device's own dictionary first, then each slot in order; for every object it derives one entry per subindex, applying the ETG.2000 rules for flag inheritance (§Figure 37), subindex derivation, per-subindex type resolution, and description lookup. Per-entry problems become warnings, never failures — see EsiEntryTable::warnings.
| file | The parsed ESI; needed to resolve the slots' ModuleIdent references. |
| device | A device belonging to file. |
| options | Locale, module selection, offsets, collision policy. |
EsiCollisionPolicy::Error is set and a collision occurred. Where an already-emitted entry sits, plus whether the object that produced it invited a module to replace it. The flag belongs to the incumbent — OverwrittenByModule is set by the device on the object it is willing to give up — so it has to be remembered here rather than read off the incoming object.
| std::expected< nlohmann::json, std::string > mm::etg::buildEsiResponse | ( | std::string_view | xml, |
| const EsiParseRequest & | request, | ||
| const EsiEntryOptions & | options = {} |
||
| ) |
Parses an ESI document and renders it as JSON.
The result is the vendor, every module, and every device with its own assembled entry table — each device object carries its identity, slots, counts, its flat "entries" and the "warnings" raised while assembling it. Document-level warnings sit at the top level.
Returning every device is affordable because object-level annotation is stored once, on subindex 0, rather than repeated onto each subindex (see EsiEntry::properties). A device that would otherwise cost megabytes of duplicated description HTML costs a few hundred kilobytes.
| xml | The complete ESI document. |
| request | Module selection, if any. |
| options | Flattening options, applied to every device. |
|
constexpr |
|
constexpr |
The C++ spelling of kind — "int32_t", "std::string", "std::vector<uint8_t>".
Matches the alternatives of mm::node::DeviceParameterValue, so a generated ObjectAddress<T> lines up with what decodeSdoBytes produces for the same object. The duplication is deliberate and one-directional: mm::etg cannot depend on mm::node, and a pure XML parser must not link SOEM to know what UDINT is.
| std::string mm::etg::eniPhysics | ( | std::uint16_t | physicalPort | ) |
Renders the ENI Physics string for a device from its SII physical-port word.
The word holds one nibble per port, low nibble first, coded by ETG.2010 §Physical Port: 0 not used, 1 MII, 3 EBUS, 4 Fast Hot Connect. The ENI writes one character per port instead — 'Y' for MII, 'K' for EBUS, 'B' for Fast Hot Connect and a space for a port that is present but none of these. Unused trailing ports are dropped, so a two-port device reads "YY".
| physicalPort | The SII physical-port word (EEPROM address 0x0010). |
Physics string, empty when no port is in use. | std::vector< uint32_t > mm::etg::esiSlotModuleIdents | ( | const EsiDevice & | device | ) |
Returns every ModuleIdent referenced by any of device's slots, in slot order.
This is the default module set buildDeviceEntries merges. Duplicates are removed, keeping the first occurrence.
| std::string_view mm::etg::esiText | ( | const std::vector< Text > & | texts, |
| uint32_t | lcId = kDefaultLcId |
||
| ) |
Picks the lcId text from texts, else the unlocalised/default one, else the first.
Returns an empty view when texts is empty. The result borrows from texts.
|
constexpr |
Splits a packed ETG.1004 unit notation value into its four bytes.
| std::string mm::etg::esiUnitSymbol | ( | uint32_t | unit, |
| std::span< const UnitType > | local = {} |
||
| ) |
Renders a packed unit notation value as a display symbol.
Composes prefix + numerator + ("/" + denominator, unless the denominator is dimensionless). Every byte is looked up in local first and in the built-in ETG.1004 catalogue second, so a dictionary that redefines a notation index gets its own meaning.
Examples (with no local table): 0xFD260000 → "mV", 0x00B50000 → "Inc", 0xF756B500 → "nNm/Inc", 0x03200000 → "kHz", 0x00B44700 → "rpm".
| unit | The packed value from ObjectInfo/Unit. 0 yields an empty string. |
| local | The enclosing dictionary's <UnitTypes>, or empty when it declares none. |
unit is 0 or names nothing known. Finds the device whose <Type> text equals type (case-sensitive).
file, or nullptr. Valid only while file lives and is unmodified. | const EsiDevice * mm::etg::findEsiDeviceByProductCode | ( | const EsiFile & | file, |
| uint32_t | productCode, | ||
| std::optional< uint32_t > | revisionNo = std::nullopt |
||
| ) |
Finds the device with product code productCode, optionally pinned to a revision.
With revisionNo unset, returns the highest-revision match — the ESI convention for "the
newest description of this product".
file, or nullptr. Valid only while file lives and is unmodified. Finds the module with the given ModuleIdent.
file, or nullptr. Valid only while file lives and is unmodified. | bool mm::etg::isStringTypeName | ( | std::string_view | esiName | ) |
True when esiName is a parameterised string type — STRING(n) / OCTET_STRING(n) / UNICODE_STRING(n).
|
constexpr |
Returns the ESI/CiA spelling of code — "VAR", "ARRAY" or "RECORD".
| std::expected< EsiFile, std::string > mm::etg::parseEsi | ( | std::string_view | xml | ) |
Parses an ESI XML document.
Tolerates a UTF-8 BOM and either line ending. Recoverable inconsistencies do not fail the parse: a malformed object is skipped and recorded in EsiFile::warnings, because one bad element in a 50 000-line vendor file must not cost the other five hundred objects. Only three conditions are hard failures — an XML syntax error, a root element other than <EtherCATInfo>, and a missing Descriptions/Devices.
| xml | The complete document. Not retained; every string is copied. |
| std::expected< EsiFile, std::string > mm::etg::parseEsiFile | ( | const std::filesystem::path & | path | ) |
Reads path and parses it with parseEsi.
| std::expected< std::vector< uint32_t >, std::string > mm::etg::parseIdentList | ( | std::string_view | csv | ) |
Parses a comma-separated list of hex-or-decimal values, as a query parameter carries it.
Accepts the ESI "#x" prefix, a C-style "0x" prefix or plain decimal, and tolerates spaces around the separators. An empty input yields an empty list.
|
constexpr |
| std::expected< EniRead, std::string > mm::etg::readEni | ( | std::string_view | xml | ) |
Reads an ENI document into a network.
Tolerant by design, and the inverse of writeEni over everything the model covers. Only three things fail a read: XML that will not parse, a root element that is not EtherCATConfig, and a missing Config. A malformed value inside the document costs that value and a warning.
**Written to be more permissive than writeEni, on purpose.** A previous port of A is accepted here and refused there, because ETG.2100 allows it and ENI Schema 1.7 does not — a reader takes what the file says, a writer emits only what validates. The same asymmetry applies to the sample documents ETG itself ships, which omit elements their own schema marks mandatory.
| xml | The complete ENI document. |
| std::optional< PrimitiveType > mm::etg::resolvePrimitiveType | ( | std::string_view | esiName | ) |
Resolves an ESI type name to its CoE code, width and signedness.
Handles three shapes:
"UDINT" → {0x0007, 32, false};"STRING(50)" → {0x0009, 400, false} and "OCTET_STRING(8)" → {0x000A, 64, false} (UNICODE_STRING counts 16 bits per element);"ARRAY [0..7] OF BYTE", which resolves to its **element** type (BYTE here). Such a name denotes the ETG.2000 Table 12 "ARRAY INFO" helper type, which never becomes an entry's own type — the entry takes the element type via <BaseType> — so returning the element keeps a caller that asks anyway from getting a surprise.| esiName | The <Type> / <BaseType> / <Name> text. Leading and trailing whitespace is not trimmed; callers pass an already-trimmed view. |
std::nullopt when the name is not a primitive (a composite DTxxxx name, or a spelling this table does not know). | ValueKind mm::etg::resolveValueKind | ( | uint16_t | dataType, |
| uint16_t | bitSize | ||
| ) |
Resolves the C++ type an entry holds, from its ETG.1020 code and declared width.
bitSize is the cross-check, and it is not decoration. A vendor writes "ARRAY [0..24] OF BYTE" and the ESI resolves that to the code for BYTE — so a mapping that trusted the code alone would call a 25-byte object a uint8_t, and every read of it would silently return its first byte. Seven entries of the shipped SOMANET dictionary are exactly that shape (OS command 0x1023, high-resolution data 0x20E1, the FSoE device ID). Whenever the declared width contradicts the code's own, the answer is Bytes.
| dataType | ETG.1020 data type code. |
| bitSize | The entry's declared width in bits; 0 means "unknown", which suppresses the cross-check rather than failing it. |
Bytes for anything with no scalar equivalent.
|
constexpr |
|
constexpr |
|
constexpr |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const Access & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EniNetwork & | network | ||
| ) |
Serialises a network as JSON, for a client that renders rather than replays it.
Keys are the model's own field names in camelCase, like every other JSON this project serves. Two things are spelled out rather than left as numbers, because a reader of the JSON is a person and not a master: every enumeration carries its ENI spelling beside its value (cmd 5 with cmdName "FPWR"), and every byte payload is the hex string the document holds beside its length. Nothing is decoded further here — what an FPWR to 0x0800 means needs the ESC register tables, which this library deliberately does not depend on.
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDataType & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDataType::ArrayInfo & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDataType::EnumInfo & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDataType::SubItem & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDataType::SubItem::Flags & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDevice & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiDictionary & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiEntry & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiEntrySource & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiEntryTable & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiEnumOption & | v | ||
| ) |
Serialises an entry to JSON. Raw byte vectors are emitted as uppercase hexBinary strings, the same spelling the ESI itself uses; absent optionals are omitted.
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiFile & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiFile::Vendor & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiModule & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiObject & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiObject::Flags & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiObject::Info & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiObject::Info::SubItem & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiPdo & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiPdo::Entry & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiProfile & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiSlots & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiSlots::ModulePdoGroup & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const EsiSlots::Slot & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const MailboxCoe & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const PrimitiveType & | type | ||
| ) |
Serialises a PrimitiveType to JSON (name, code, bitSize, isSigned).
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const Property & | v | ||
| ) |
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const Text & | v | ||
| ) |
Serialises the model to JSON. Keys are lowerCamelCase mirrors of the member names; absent optionals are omitted rather than emitted as null.
| void mm::etg::to_json | ( | nlohmann::json & | j, |
| const UnitType & | unit | ||
| ) |
Serialises a UnitType to JSON (notationIndex, index, name, symbol).
| std::expected< std::string, std::string > mm::etg::writeEni | ( | const EniNetwork & | network | ) |
Renders a network as an ENI document.
The output is indented UTF-8 XML with an XML declaration, and it validates against ENI Schema 1.7. Byte payloads are written as uppercase xs:hexBinary, which is the canonical form; the sample files ETG ships use lowercase, and a master must accept either.
| network | The network to render. |
|
inlineconstexpr |
The default LcId — 1033, en-US.
|
inlineconstexpr |
Catalogue of the ESI primitive types, keyed by their IEC 61131-3 name.
Parameterised names (STRING(n), OCTET_STRING(n), UNICODE_STRING(n)) appear here with their base name and bitSize 0; resolvePrimitiveType computes the real width from the parenthesised element count. Composite types (RECORD/ARRAY definitions such as DT1018) are not here — they are declared per dictionary by the ESI itself.