12#include <nlohmann/json_fwd.hpp>
17#include <unordered_map>
76 std::map<uint8_t, DeviceParameterValue>
values;
85 return std::unexpected(
86 std::format(
"object 0x{:04X} has no readable subindex {:02X}",
index,
subindex));
88 if (
const auto* p = std::get_if<T>(&it->second)) {
91 return std::unexpected(
92 std::format(
"parameter 0x{:04X}:{:02X} holds a different type",
index,
subindex));
143 const std::string&
name()
const;
205 std::optional<uint8_t>
escType()
const;
212 std::expected<void, std::string>
locate(
bool on)
const;
216 std::expected<mm::comm::FieldbusDriver::FirmwareActivation, std::string>
activateFirmware(
217 std::chrono::steady_clock::duration
timeout)
const;
236 std::expected<std::vector<uint8_t>, std::string>
readSdo(uint16_t index, uint8_t
subindex)
const;
249 std::span<const uint8_t> data)
const;
260 const std::string& filename,
268 std::expected<void, mm::comm::FoeError>
writeFile(
const std::string& filename,
269 std::span<const uint8_t> data)
const;
278 std::expected<void, std::string>
readRegister(uint16_t address, std::span<uint8_t> data)
const;
287 std::expected<void, std::string>
writeRegister(uint16_t address,
288 std::span<const uint8_t> data)
const;
297 std::expected<std::vector<uint8_t>, std::string>
readSii()
const;
308 std::expected<void, std::string>
writeSii(std::span<const uint8_t> data)
const;
331 bool useCompleteAccess =
true);
406 uint16_t index, uint8_t
subindex, std::span<const uint8_t>
bytes);
448 std::optional<DeviceParameter>
parameter(uint16_t index, uint8_t
subindex)
const;
516 std::expected<void, std::string>
readAllParameters(
bool useCompleteAccess =
true);
538 std::expected<ObjectValues, std::string>
readObject(uint16_t index,
539 bool useCompleteAccess =
true);
576 template <
typename T>
592 template <
typename T>
596 return std::unexpected(v.error());
598 if (
const auto* p = std::get_if<T>(&*v)) {
601 return std::unexpected(
602 std::format(
"parameter 0x{:04X}:{:02X} holds a different type", index,
subindex));
609 template <
typename T>
615 template <
typename T>
617 return writeValue<T>(address.
index, address.
subindex, std::move(newValue));
642 template <
typename T>
645 std::lock_guard<std::mutex> lock(*parametersMutex_);
648 return p->getValue<T>();
651 return readValue<T>(index,
subindex);
700 template <
typename T>
734 template <
typename T>
736 static_assert(std::is_arithmetic_v<T>,
"the cell holds arithmetic types only");
737 static_assert(
sizeof(T) <=
sizeof(uint64_t),
"the cell holds at most eight bytes");
743 std::memcpy(&bits, &newValue,
sizeof(T));
752 template <
typename T>
758 template <
typename T>
760 return setValue<T>(address.
index, address.
subindex, newValue);
781 void publishParameters(std::unordered_map<uint32_t, DeviceParameter>&& built);
793 void readParameterValues(std::vector<DeviceParameter>& defs,
bool useCompleteAccess);
799 void markReadFailed(uint16_t index, uint8_t
subindex, uint16_t declaredType);
810 bool recordDeclaredSubindexRead(
bool ok);
815 bool declaredSubindexReadsWorthTrying()
const;
834 bool readObjectComplete(uint16_t index, std::span<const uint8_t> subindices,
835 bool useCompleteAccess);
845 std::expected<std::vector<PdoMappingObject>, std::string> readPdoAssignment(
846 uint16_t assignmentIndex);
858 std::expected<FlatPdoMapping, std::string> readSiiPdoMapping();
870 std::expected<std::vector<DeviceParameter>, std::string> buildSiiParameterDefinitions();
872 uint16_t slavePosition_;
884 uint32_t productCode_;
885 uint32_t revisionNumber_;
886 uint32_t serialNumber_;
890 uint16_t mailboxProtocols_ = 0;
892 bool supportsEsc_ =
true;
893 bool supportsLocate_ =
false;
894 std::optional<uint8_t> escType_;
895 bool mailboxWriteOnce_ =
false;
916 std::unique_ptr<std::mutex> parametersMutex_;
920 std::expected<void, std::string> readParameterDefinitions(
bool readValues,
921 bool useCompleteAccess);
927 bool parametersUnavailable_ =
false;
950 std::unique_ptr<std::deque<DeviceParameter>> cells_;
953 std::unordered_map<uint32_t, DeviceParameter*> parameters_;
957 std::vector<std::unordered_map<uint32_t, DeviceParameter*>> retiredMaps_;
977void to_json(nlohmann::json& j,
const Device& d);
Abstract interface for an EtherCAT fieldbus driver.
Definition fieldbus_driver.h:474
Represents a single node on the fieldbus.
Definition device.h:120
bool setValue(uint16_t index, uint8_t subindex, T newValue)
Sets a scalar parameter's value as T. Lock-free, non-allocating.
Definition device.h:735
std::expected< void, std::string > locate(bool on) const
Starts or stops blinking this device's LEDs. Delegates to FieldbusDriver::locate.
Definition device.cc:106
std::expected< void, std::string > writeSdo(uint16_t index, uint8_t subindex, std::span< const uint8_t > data) const
Writes an object dictionary entry to the device (CoE SDO download).
Definition device.cc:124
std::expected< DeviceParameterValue, std::string > readParameter(uint16_t index, uint8_t subindex)
Reads a parameter value, keeping the cached store in sync.
Definition device.cc:1111
std::expected< void, std::string > readRegister(uint16_t address, std::span< uint8_t > data) const
Reads bytes from an ESC register on this device.
Definition device.cc:139
std::expected< std::vector< uint8_t >, mm::comm::FoeError > readFile(const std::string &filename, std::chrono::milliseconds timeout=mm::comm::kFoeReadTimeout) const
Reads a file from this device via File over EtherCAT (FoE).
Definition device.cc:129
DeviceParameter * findParameter(uint16_t index, uint8_t subindex)
Parameter lookup by (index, subindex). O(1); nullptr if absent. Takes no lock.
Definition device.cc:1091
std::expected< void, std::string > initializeParameters(bool readValues=false, bool useCompleteAccess=true)
Enumerates the device's CoE object dictionary and populates parameters().
Definition device.cc:157
std::optional< DeviceParameterValue > parameterValue(uint16_t index, uint8_t subindex) const
Returns a copy of a parameter's last known value. No bus access.
Definition device.cc:1064
std::expected< T, std::string > readCachedValue(uint16_t index, uint8_t subindex)
Read-once typed accessor for objects the caller knows are immutable.
Definition device.h:643
uint32_t serialNumber() const
Serial number from EEPROM.
Definition device.cc:72
std::expected< void, std::string > writeParameter(uint16_t index, uint8_t subindex, const DeviceParameterValue &newValue)
Writes a parameter value, always updating the cache first.
Definition device.cc:1387
std::expected< std::vector< uint8_t >, std::string > readSdo(uint16_t index, uint8_t subindex) const
Reads an object dictionary entry from the device (CoE SDO upload).
Definition device.cc:119
bool mailboxWriteOnce() const
Whether the driver writes each mailbox request to this device once. Copied from SlaveInfo at construc...
Definition device.cc:74
std::expected< void, std::string > readAllParameters(bool useCompleteAccess=true)
Refreshes the cached value of every readable parameter, keeping the list intact.
Definition device.cc:1178
std::expected< mm::comm::FieldbusDriver::FirmwareActivation, std::string > activateFirmware(std::chrono::steady_clock::duration timeout) const
Makes this device apply the firmware files written to it in BOOT. Delegates to FieldbusDriver::activa...
Definition device.cc:110
bool hasParameters() const
Whether the object dictionary is enumerated (thread-safe; no bus access).
Definition device.cc:612
bool supportsEsc() const
Whether the device has an EtherCAT Slave Controller: SII, ESC registers, DC and the ESC diagnostics....
Definition device.cc:102
bool supportsCoe() const
Whether the slave advertises a CoE mailbox — a fixed capability, not a live check.
Definition device.cc:98
std::expected< void, std::string > writePdoMapping(const PdoMapping &mapping)
Writes a new PDO mapping to the device via SDO, then reads it back to verify.
Definition device.cc:964
std::expected< void, std::string > writeRegister(uint16_t address, std::span< const uint8_t > data) const
Writes bytes to an ESC register on this device.
Definition device.cc:144
const std::string & name() const
Human-readable node name from SII EEPROM.
Definition device.cc:60
std::expected< void, std::string > writeValue(uint16_t index, uint8_t subindex, T newValue)
Typed convenience wrapper for writeParameter.
Definition device.h:577
bool setValue(ObjectAddress< T > address, T newValue)
setValue<T>() addressed by an ObjectAddress. Lock-free, non-allocating.
Definition device.h:759
std::optional< DeviceParameter > parameter(uint16_t index, uint8_t subindex) const
Looks up one parameter by (index, subindex) and returns a copy of it. O(1).
Definition device.cc:1073
uint32_t revisionNumber() const
Revision number from EEPROM.
Definition device.cc:71
const FlatPdoMapping & flatPdoMapping() const
Returns the device's PDO mapping. Empty until readFlatPdoMapping() succeeds.
Definition device.cc:864
bool exchangesProcessData() const
Whether the device is in a process-data-exchanging state (SAFE-OP or OP, error bit clear).
Definition device.cc:115
std::expected< PdoMapping, std::string > readPdoMapping()
Reads the device's PDO mapping grouped by mapping object (0x16xx / 0x1Axx).
Definition device.cc:718
std::vector< DeviceParameter > parametersOrdered() const
Returns all parameters sorted ascending by (index, subindex).
Definition device.cc:1052
bool parametersUnavailable() const
Whether any initializeParameters call on this device failed since it was scanned (thread-safe; no bus...
Definition device.cc:617
bool supportsLocate() const
Whether locate can blink this device's LEDs. Copied from FieldbusDriver::supportsLocate at constructi...
Definition device.cc:104
std::expected< void, std::string > readFlatPdoMapping()
Reads the device's PDO mapping from its assignment and mapping objects.
Definition device.cc:818
std::expected< DeviceParameterValue, std::string > setValueFromBytes(uint16_t index, uint8_t subindex, std::span< const uint8_t > bytes)
Sets the parameter's value from its raw on-the-wire bytes (the bytes-domain setter).
Definition device.cc:1033
std::expected< ObjectValues, std::string > readObject(uint16_t index, bool useCompleteAccess=true)
Reads every readable sub-entry of one object and returns the decoded values.
Definition device.cc:1334
std::expected< T, std::string > readValue(ObjectAddress< T > address)
readValue<T>() addressed by an ObjectAddress. Blocking; off the RT thread only.
Definition device.h:610
std::optional< uint8_t > escType() const
The low byte of ESC register 0x0000, the slave controller family, or empty when the driver could not ...
Definition device.cc:73
bool mailboxActive() const
Whether the device's CoE/SDO mailbox is currently active (AL state PRE-OP, SAFE-OP,...
Definition device.cc:86
uint32_t productCode() const
Product code from EEPROM.
Definition device.cc:70
std::expected< void, std::string > writeSii(std::span< const uint8_t > data) const
Writes a raw SII (EEPROM) image to this device.
Definition device.cc:153
std::expected< T, std::string > readValue(uint16_t index, uint8_t subindex)
Typed convenience wrapper for readParameter.
Definition device.h:593
std::expected< void, std::string > writeValue(ObjectAddress< T > address, T newValue)
writeValue<T>() addressed by an ObjectAddress. Blocking; off the RT thread only.
Definition device.h:616
bool isCia402() const
Whether this device implements the CiA402 drive profile.
Definition device.cc:76
uint16_t slavePosition() const
Returns the 1-based position of this node on the fieldbus.
Definition device.cc:59
std::string productName() const
Canonical product name, independent of the SII EEPROM contents.
Definition device.cc:61
std::optional< uint16_t > dataType(uint16_t index, uint8_t subindex) const
Returns a parameter's declared ETG.1020 data-type code, thread-safely (cache lock).
Definition device.cc:1082
std::optional< T > value(uint16_t index, uint8_t subindex) const
Reads a scalar parameter's current value as T. Lock-free, non-allocating.
Definition device.h:701
uint32_t vendorId() const
Vendor ID from EEPROM.
Definition device.cc:69
std::optional< T > value(ObjectAddress< T > address) const
value<T>() addressed by an ObjectAddress. Lock-free, non-allocating.
Definition device.h:753
std::expected< void, mm::comm::FoeError > writeFile(const std::string &filename, std::span< const uint8_t > data) const
Writes a file to this device via File over EtherCAT (FoE).
Definition device.cc:134
std::expected< std::vector< uint8_t >, std::string > readSii() const
Reads this device's raw Slave Information Interface (SII / EEPROM) image.
Definition device.cc:149
On-disk cache of CoE parameter definitions, keyed by device identity.
Definition parameter_cache.h:52
driver
Definition config.h:230
mailboxStatusFmmu useCompleteAccess parameterCache
Definition config.h:245
uint8_t subindex
Definition esi_entry.cc:283
constexpr std::chrono::milliseconds kFoeReadTimeout
How long a file read waits for the slave's answer, unless the caller asks for longer.
Definition fieldbus_driver.h:39
Definition bus_health_source.h:7
std::variant< int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, float, double, std::string, std::vector< uint8_t > > DeviceParameterValue
Decoded value of a single device parameter (CoE object dictionary entry).
Definition device_parameter.h:33
DeviceParameterValue defaultValueForDataType(uint16_t dataType)
Returns a zero-equivalent value for the given ETG.1020 dataType.
Definition device_parameter.cc:60
void to_json(nlohmann::json &j, const Cia402Status &s)
Serialises a Cia402Status. Emits state/modeName as human-readable strings alongside the numeric statu...
Definition cia402_drive.cc:13
DeclaredSubindexReads
Whether a device serves the subindices an array or a record declares but does not hold.
Definition device.h:70
@ Synced
value matches the device (last successful read or write).
CompleteAccessSupport
Runtime discovery state of CoE Complete Access support. CA is optional in CoE and the EEPROM capabili...
Definition device.h:42
std::expected< int, std::string > reconcileDetectedModules(const Device &device)
Reconciles a device's Configured Module Ident List with its Detected list.
Definition device.cc:1480
std::chrono::milliseconds timeout
Definition somanet_procedures.cc:464
std::size_t bytes
Definition spoe_connection.cc:24
A structured FoE failure. String-like where a caller only forwards it (operator<<,...
Definition foe_error.h:110
A single object dictionary entry held by a Device.
Definition device_parameter.h:195
SyncState syncState
Freshness of the value relative to the device.
Definition device_parameter.h:215
void storeBits(uint64_t v) const
Stores the scalar cell. Lock-free, non-allocating, relaxed — safe from the RT loop.
Definition device_parameter.h:230
uint16_t dataType
ETG.1020 data type code (e.g. 0x0007 = UNSIGNED32).
Definition device_parameter.h:200
std::optional< T > scalar() const
Reads the value as T straight out of the cell. Lock-free, non-allocating.
Definition device_parameter.h:253
A device's complete PDO mapping across both directions.
Definition pdo_mapping.h:62
The address of one object-dictionary entry, carrying the type that entry holds.
Definition device_parameter.h:63
uint16_t index
CoE object index.
Definition device_parameter.h:64
uint8_t subindex
CoE object subindex.
Definition device_parameter.h:65
Decoded values of one object's readable sub-entries, as returned by Device::readObject.
Definition device.h:74
std::map< uint8_t, DeviceParameterValue > values
Decoded value per readable subindex.
Definition device.h:76
uint16_t index
CoE object index the values belong to.
Definition device.h:75
std::expected< T, std::string > get(uint8_t subindex) const
Returns the value of subindex as T — type-exact, like DeviceParameter::getValue.
Definition device.h:82
A device's desired PDO configuration to write and assign — the write-side input to Device::writePdoMa...
Definition pdo_mapping.h:89
The live process-data runtime: the published image, the cross-thread exchange buffers,...
Definition process_data.h:36