12#include <nlohmann/json_fwd.hpp>
14#include <shared_mutex>
112 std::vector<ProcessImageObjectInfo>
inputs;
237 std::shared_ptr<mm::comm::FieldbusDriver>
driver;
246 const Device*
find(uint16_t slavePosition)
const;
262 : set_(std::move(set)), device_(device) {}
265 explicit operator bool()
const {
return device_ !=
nullptr; }
272 std::shared_ptr<DeviceSet> set_;
273 Device* device_ =
nullptr;
281 return std::unexpected(std::format(
"device {} not found", slavePosition));
305std::ostream&
operator<<(std::ostream& os,
const ParameterError&
error);
357 std::expected<void, std::string>
init(std::unique_ptr<mm::comm::FieldbusDriver>
driver,
382 std::expected<int, std::string>
scan();
401 bool hasDevice(uint16_t slavePosition)
const;
427 std::shared_ptr<DeviceSet>
deviceSet()
const;
471 explicit operator bool()
const {
return entered_; }
625 std::vector<SlaveConfigInfo>
busConfig()
const;
647 std::chrono::steady_clock::duration
timeout);
667 std::chrono::steady_clock::duration
timeout);
701 std::expected<std::vector<DeviceStateInfo>, std::string>
deviceStates(
702 const std::vector<uint16_t>& positions);
711 std::expected<ScanStatus, std::string>
scanStatus();
726 std::expected<std::vector<DeviceDiagnosticsInfo>, std::string>
deviceDiagnostics(
727 const std::vector<uint16_t>& positions);
743 std::expected<std::vector<DcSyncInfo>, std::string>
dcSync(
744 const std::vector<uint16_t>& positions);
760 uint16_t slavePosition);
776 uint16_t slavePosition, std::chrono::nanoseconds
timeout);
818 bool refreshFromBus);
842 uint16_t slavePosition, uint16_t index, uint8_t
subindex,
875 std::span<const OutputStageRequest> requests);
903 std::optional<PdoSampleSpec>
pdoSampleSpec(uint16_t slavePosition, uint16_t index,
954 uint64_t startSeq = 0;
964 std::expected<DumpSpan, std::string> serializeDump(std::ostream& out);
976 std::expected<void, std::string> remapProcessImage();
986 void readMissingObjectDictionaries(
DeviceSet& set, std::span<const uint16_t> positions,
987 std::string_view occasion);
994 void mapDevicesAlreadyExchanging(
DeviceSet& set);
1007 std::expected<std::vector<uint16_t>, std::string> resolveTargets(
1008 const std::vector<uint16_t>& positions)
const;
1021 int expectedWkcDuring(std::span<const uint16_t> transitioning,
1022 std::optional<mm::comm::EtherCatState> target)
const;
1026 void updateExpectedWkc();
1049 [[nodiscard]]
bool stopExchange();
1056 void publishDeviceSet(std::shared_ptr<DeviceSet> set);
1067 mutable std::mutex busOperationMutex_;
1071 std::vector<uint16_t> observedExchanging_;
1072 uint64_t observedGeneration_ = 0;
1079 mutable std::mutex currentSetMutex_;
1089 std::shared_ptr<DeviceSet> currentSet_;
1096 std::vector<std::shared_ptr<const void>> abandoned_;
1101 std::atomic<DeviceSet*> publishedSet_{
nullptr};
1109 mutable std::shared_mutex processDataMutex_;
1112 std::atomic<uint64_t> topologyGeneration_{0};
1114 std::atomic<uint64_t> processImageGeneration_{0};
1115 std::unique_ptr<ProcessData> pd_;
1118 ParameterCache parameterCache_;
1120 DeviceManagerConfig config_;
1131void to_json(nlohmann::json& j,
const DeviceManager& dm);
Abstract interface for an EtherCAT fieldbus driver.
Definition fieldbus_driver.h:474
One device, plus the set that keeps it alive.
Definition device_manager.h:258
DeviceHandle(std::shared_ptr< DeviceSet > set, Device *device)
Definition device_manager.h:261
Device * operator->() const
Definition device_manager.h:267
Device * get() const
The device, or nullptr. For a caller that must pass it on as a pointer.
Definition device_manager.h:269
Device & operator*() const
Definition device_manager.h:266
Holds a cyclic task's whole body open against a device-set rebuild. RT-safe.
Definition device_manager.h:460
CycleGuard & operator=(const CycleGuard &)=delete
~CycleGuard()
Leaves the cycle, if this guard entered it.
Definition device_manager.cc:548
CycleGuard(const CycleGuard &)=delete
Owns the fieldbus driver and node collection, and drives PDO exchange.
Definition device_manager.h:339
std::expected< mm::comm::ProcessDataWatchdogConfig, std::string > setProcessDataWatchdog(uint16_t slavePosition, std::chrono::nanoseconds timeout)
Sets the process-data (sync-manager) watchdog timeout of one device.
Definition device_manager.cc:1446
uint64_t recorderOldestSeq() const
The oldest sequence number still present in the ring (max(0, head - capacity)). A cursor below this w...
Definition device_manager.cc:620
uint64_t topologyGeneration() const
Monotonic counter bumped every time the device set is rebuilt (scan / reset).
Definition device_manager.cc:263
bool hasDevice(uint16_t slavePosition) const
Whether a device holds slavePosition. Thread-safe; no bus access.
Definition device_manager.cc:269
std::expected< std::vector< DcSyncInfo >, std::string > dcSync(const std::vector< uint16_t > &positions)
Reads live distributed-clock synchronisation status for a set of devices, resolving each slave's devi...
Definition device_manager.cc:1406
std::expected< std::string, std::string > dumpProcessDataBuffer()
Serialises the recorder dump into an in-memory buffer — the same .mmpd bytes dumpProcessData writes t...
Definition device_manager.cc:842
uint64_t recorderHead() const
The recorder ring's next sequence number; recorderHead()-1 is the newest recorded cycle and recorderH...
Definition device_manager.cc:615
std::expected< RestartOutcome, std::string > restartToState(const std::vector< uint16_t > &positions, mm::comm::EtherCatState targetState, std::chrono::steady_clock::duration timeout)
Takes a set of devices to INIT and then up to targetState one AL state at a time.
Definition device_manager.cc:950
std::expected< int, std::string > scan()
Scans the bus for nodes and populates the device list.
Definition device_manager.cc:147
const ParameterCache & parameterCache() const
The on-disk parameter cache, for the management API (list / download / remove).
Definition device_manager.cc:145
Device * findDevice(uint16_t slavePosition)
Device lookup by bus position. O(N) over a handful of devices; nullptr if absent.
Definition device_manager.cc:312
bool supportsEsc() const
Whether the devices have an EtherCAT Slave Controller: SII, ESC registers, DC and the ESC diagnostics...
Definition device_manager.cc:945
std::expected< DeviceParameter, ParameterError > writeDeviceParameter(uint16_t slavePosition, uint16_t index, uint8_t subindex, const DeviceParameterValue &newValue)
Convenience: finds a device by position, writes one of its parameters, returns it.
Definition device_manager.cc:1613
bool readRecord(uint64_t seq, ProcessDataRing::Record &out) const
Copies the recorded cycle for seq into out. Thread-safe on the same terms as recorderHead (the shared...
Definition device_manager.cc:625
bool deviceExchangesProcessData(uint16_t slavePosition) const
Whether the device at slavePosition is currently exchanging (SAFE-OP/OP). Thread-safe; reads the driv...
Definition device_manager.cc:1562
std::expected< DeviceParameter, ParameterError > deviceParameterView(uint16_t slavePosition, uint16_t index, uint8_t subindex, bool refreshFromBus)
Returns a full parameter struct (value + metadata), optionally refreshed from the bus.
Definition device_manager.cc:1582
int expectedWorkingCounter() const
The working counter expected from the devices currently exchanging (SAFE-OP/OP).
Definition device_manager.cc:646
std::expected< void, std::string > initializeDeviceParameters(uint16_t slavePosition, bool readValues)
Enumerates the CoE object dictionary of one device and populates its parameter map....
Definition device_manager.cc:1457
DeviceHandle deviceAt(uint16_t slavePosition) const
The device at slavePosition, as a handle that keeps it alive. Falsy if absent.
Definition device_manager.cc:273
std::expected< mm::comm::ProcessDataWatchdogConfig, std::string > processDataWatchdog(uint16_t slavePosition)
Reads the process-data (sync-manager) watchdog configuration of one device.
Definition device_manager.cc:1433
void exchangeProcessData()
Exchanges one cycle of process data: sends the current outputs, captures inputs.
Definition device_manager.cc:407
std::optional< PdoSampleSpec > pdoSampleSpec(uint16_t slavePosition, uint16_t index, uint8_t subindex) const
Resolves a PDO-mapped object's decode spec from the published image. Thread-safe.
Definition device_manager.cc:1539
DeviceManager()
Definition device_manager.cc:41
uint64_t processImageGeneration() const
Monotonic counter bumped every time a new process image is published (each (re)map).
Definition device_manager.cc:638
std::expected< std::vector< DeviceStateInfo >, std::string > deviceStates(const std::vector< uint16_t > &positions)
Reads the current AL state for a set of devices.
Definition device_manager.cc:1315
std::expected< std::string, std::string > dumpProcessData()
Serialises the recorder's current span to a .mmpd dump file and returns its path.
Definition device_manager.cc:796
uint64_t shortWkcCycles() const
Cycles that answered with a short working counter since the bus came up.
Definition device_manager.cc:652
std::shared_ptr< DeviceSet > deviceSet() const
The current device set, as a pointer that keeps it alive. Never nullptr.
Definition device_manager.cc:279
std::optional< std::string > stateChangeRefusal() const
Returns why the driver refuses every state change, or nullopt when it accepts them,...
Definition device_manager.cc:989
std::vector< OutputStageResult > stageProcessDataOutputs(std::span< const OutputStageRequest > requests)
Stages a batch of output objects into the process image in one call.
Definition device_manager.cc:1673
bool processDataHealthy() const
Whether every device that should be exchanging is contributing to the cycle.
Definition device_manager.cc:650
std::expected< void, std::string > readAllDeviceParameters(uint16_t slavePosition)
Refreshes the cached value of every readable parameter of one device, in place.
Definition device_manager.cc:1472
std::string adapter() const
The network adapter the bus is on, or empty when no driver is held or the transport sends no EtherCAT...
Definition device_manager.cc:1401
std::vector< SlaveConfigInfo > busConfig() const
Snapshots each slave's static ESC configuration (SM, FMMU, mailbox, DC) for the API.
Definition device_manager.cc:853
std::expected< void, std::string > init(std::unique_ptr< mm::comm::FieldbusDriver > driver, const DeviceManagerConfig &config={})
Takes ownership of driver and initialises it.
Definition device_manager.cc:105
bool processDataConfigured() const
Whether configureProcessData published a process image for exchange.
Definition device_manager.cc:634
std::expected< std::vector< DeviceStateInfo >, std::string > transitionToState(const std::vector< uint16_t > &positions, mm::comm::EtherCatState targetState, std::chrono::steady_clock::duration timeout)
Transitions a set of devices to targetState, blocking until all arrive or timeout elapses,...
Definition device_manager.cc:1042
void reset()
Stops the fieldbus driver and clears the device list.
Definition device_manager.cc:212
std::expected< void, std::string > writeDevicePdoMapping(uint16_t slavePosition, const PdoMapping &mapping)
Convenience: finds a device by position and writes its PDO mapping.
Definition device_manager.cc:1655
std::expected< void, std::string > configureProcessData()
Maps process data and publishes the process image for exchange.
Definition device_manager.cc:317
std::expected< void, std::string > followObservedStates()
Brings the process image in line with device states that another master set.
Definition device_manager.cc:994
~DeviceManager()
Defined out-of-line so unique_ptr<ProcessData> can hold an incomplete type.
std::expected< std::vector< DeviceDiagnosticsInfo >, std::string > deviceDiagnostics(const std::vector< uint16_t > &positions)
Reads live ESC health diagnostics (link quality, error counters, watchdogs) for a set of devices,...
Definition device_manager.cc:1374
void configureParameterCache(const ParameterCacheConfig &config)
Sets the on-disk parameter-cache policy and location.
Definition device_manager.cc:141
int lastWorkingCounter() const
The working counter from the most recent process-data exchange (0 before any).
Definition device_manager.cc:642
bool initialised() const
Whether a driver is currently held: init() succeeded, and no reset() followed it. Thread-safe.
Definition device_manager.cc:267
std::expected< ScanStatus, std::string > scanStatus()
Reads whether the bus still matches the last scan.
Definition device_manager.cc:1347
ProcessImageInfo processImageInfo() const
Snapshots the published process image and its runtime health for the API.
Definition device_manager.cc:656
Represents a single node on the fieldbus.
Definition device.h:120
On-disk cache of CoE parameter definitions, keyed by device identity.
Definition parameter_cache.h:52
driver
Definition config.h:230
uint8_t subindex
Definition esi_entry.cc:283
const EsiObject::Info * info
Value metadata, may be null.
Definition esi_entry.cc:288
EtherCatState
EtherCAT Application Layer state values.
Definition fieldbus_driver.h:45
@ Init
INIT — reset state, no communication.
Reachability
Whether a slave answers at the station address the master gave it.
Definition fieldbus_driver.h:91
@ Answering
It answers at its configured station address.
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
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
std::unexpected< std::string > deviceNotFound(uint16_t slavePosition)
The error to return when a bus position resolves to no device.
Definition device_manager.h:280
std::ostream & operator<<(std::ostream &os, const ParameterError &error)
Streams the message, so ASSERT_TRUE(r) << r.error() and spdlog {} work unchanged.
Definition device_manager.cc:1568
FoeError error
Definition soem_fieldbus_driver.cc:1307
std::chrono::milliseconds timeout
Definition somanet_procedures.cc:464
Live distributed-clock synchronisation status for one slave, read from its ESC.
Definition fieldbus_driver.h:419
Static ESC configuration snapshot for one slave, captured by configureProcessData.
Definition fieldbus_driver.h:357
Decoded health diagnostics for one slave, read live from its ESC registers.
Definition fieldbus_driver.h:394
A slave's live distributed-clock sync status plus its resolved device name.
Definition device_manager.h:188
mm::comm::DcSyncDiagnostics dcSync
Decoded DC sync status as read by the driver.
Definition device_manager.h:189
std::string deviceName
Device name for this slave position, empty if unknown.
Definition device_manager.h:190
A slave's live ESC health diagnostics plus its resolved device name.
Definition device_manager.h:175
std::string deviceName
Device name for this slave position, empty if unknown.
Definition device_manager.h:177
mm::comm::SlaveDiagnostics diagnostics
Decoded ESC counters as read by the driver.
Definition device_manager.h:176
Runtime tuning passed to DeviceManager::init. Every field has a sensible default, so a caller can pas...
Definition device_manager.h:199
bool useCompleteAccess
Definition device_manager.h:207
bool readObjectDictionaryOnPreop
Definition device_manager.h:203
uint32_t recorderCapacity
Definition device_manager.h:214
std::string recorderDumpDir
Definition device_manager.h:211
Everything needed to decode one PDO object from a raw process-image snapshot: which image it lives in...
Definition device_manager.h:886
uint16_t dataType
ETG.1020 data-type code, for decoding the extracted bytes.
Definition device_manager.h:890
uint16_t bitLength
Width of the value in bits.
Definition device_manager.h:889
bool isOutput
True if the object is in the output image (RxPDO), false for input.
Definition device_manager.h:887
uint32_t bitOffset
Absolute bit offset within that direction's image.
Definition device_manager.h:888
One published generation of the bus: the driver that owns the socket, and the devices found on it.
Definition device_manager.h:235
Device * find(uint16_t slavePosition)
Device at slavePosition, or nullptr when the set holds none.
Definition device_manager.cc:293
std::shared_ptr< mm::comm::FieldbusDriver > driver
The driver every device in this set talks through. Shared, so a retired set keeps it alive.
Definition device_manager.h:237
uint64_t topologyGeneration
The value DeviceManager::topologyGeneration reported when this set was published.
Definition device_manager.h:241
std::vector< Device > devices
The devices in bus order: index 0 is position 1. Frozen once the set is published.
Definition device_manager.h:239
Current AL state snapshot for a single device.
Definition device_manager.h:36
uint16_t alStatus
Definition device_manager.h:38
uint16_t slavePosition
1-based position on the fieldbus.
Definition device_manager.h:37
uint16_t alState
AL state decoded from alStatus (1=Init, 2=PreOp, 3=Boot, 4=SafeOp, 8=Op).
Definition device_manager.h:40
mm::comm::Reachability reachability
Whether the device answers at its address. When it does not, the other fields are 0.
Definition device_manager.h:44
uint16_t alStatusCode
Definition device_manager.h:42
bool error
True when the AL Status error indicator bit is set.
Definition device_manager.h:41
One object to stage into the output process image, as parsed from a batch write request.
Definition device_manager.h:125
DeviceParameterValue value
Value to write; coerced to the object's declared type.
Definition device_manager.h:129
uint16_t slavePosition
1-based bus position of the owning device.
Definition device_manager.h:126
uint16_t index
CoE object index.
Definition device_manager.h:127
uint8_t subindex
CoE object subindex.
Definition device_manager.h:128
Per-object outcome of a batch output stage.
Definition device_manager.h:138
bool staged
Whether the value was staged into the cyclic output image.
Definition device_manager.h:142
uint8_t subindex
Echoes the request.
Definition device_manager.h:141
uint16_t index
Echoes the request.
Definition device_manager.h:140
uint16_t slavePosition
Echoes the request.
Definition device_manager.h:139
std::string error
Empty on success; otherwise why the object was not staged.
Definition device_manager.h:143
Policy and location for the on-disk parameter cache.
Definition parameter_cache.h:26
Why reading or writing one parameter by its address failed.
Definition device_manager.h:289
Kind
Definition device_manager.h:290
@ kInvalidValue
The value cannot be encoded in the parameter's data type. → 400.
@ kUnknownParameter
The device has no parameter at that index and subindex. → 404.
@ kTransferFailed
The read or the write over the bus failed. → 500.
@ kUnknownDevice
No device holds that bus position. → 404.
Kind kind
Definition device_manager.h:297
const std::string & what() const
Exception-shaped accessor for the message, for call sites that prefer .what().
Definition device_manager.h:301
std::string message
Definition device_manager.h:298
A device's desired PDO configuration to write and assign — the write-side input to Device::writePdoMa...
Definition pdo_mapping.h:89
One recorded cycle, copied out by a reader. inputs / outputs are the raw IOmap bytes for that cycle (...
Definition process_data_ring.h:46
The live process-data runtime: the published image, the cross-thread exchange buffers,...
Definition process_data.h:36
API-facing snapshot of the currently published process image and its runtime health.
Definition device_manager.h:95
uint64_t shortWkcCycles
Definition device_manager.h:104
std::vector< ProcessImageObjectInfo > inputs
Input-mapped objects in image order.
Definition device_manager.h:112
uint32_t outputBytes
Size of the output image (master→slave).
Definition device_manager.h:97
uint64_t firstShortWkcUs
Epoch microseconds of the first such cycle (0 if none).
Definition device_manager.h:105
bool healthy
Definition device_manager.h:101
uint64_t droppedInputFrames
Definition device_manager.h:109
uint64_t lastShortWkcUs
Definition device_manager.h:106
std::vector< ProcessImageObjectInfo > outputs
Output-mapped objects in image order.
Definition device_manager.h:111
std::size_t generations
Number of process images retained since the last reset().
Definition device_manager.h:110
int expectedWkc
Working counter expected from the devices currently exchanging.
Definition device_manager.h:99
uint32_t inputBytes
Size of the input image (slave→master).
Definition device_manager.h:98
bool configured
Whether an image is currently published for exchange.
Definition device_manager.h:96
int lastWkc
Working counter from the most recent exchange (0 before any).
Definition device_manager.h:100
One mapped object in the published process image, with its name resolved.
Definition device_manager.h:77
uint8_t subindex
CoE object subindex.
Definition device_manager.h:80
uint32_t bitOffset
Absolute bit offset within the direction's image.
Definition device_manager.h:82
uint16_t bitLength
Width of the value in bits.
Definition device_manager.h:83
uint16_t slavePosition
1-based bus position of the owning device.
Definition device_manager.h:78
std::string name
Object name, or empty if the OD has not been enumerated.
Definition device_manager.h:81
uint16_t index
CoE object index.
Definition device_manager.h:79
The whole bus's process-data layout, resolved to absolute positions.
Definition process_image.h:69
Where a restart of a set of devices stopped, and the state of each device there.
Definition device_manager.h:51
mm::comm::EtherCatState step
Definition device_manager.h:54
std::vector< DeviceStateInfo > states
The state of every targeted device after that step, in the order targeted.
Definition device_manager.h:56
Whether the devices of the last scan still match the bus.
Definition device_manager.h:60
bool required
True when a device does not answer at its address, or the device count changed.
Definition device_manager.h:62
std::vector< uint16_t > unreachable
Positions whose reachability is not answering.
Definition device_manager.h:66
int devicesScanned
Devices the last scan found.
Definition device_manager.h:65
std::optional< int > devicesOnWire
Devices on the wire now, or nothing when the transport cannot count them.
Definition device_manager.h:64
A slave's static ESC configuration plus its resolved device name.
Definition device_manager.h:154
std::string deviceName
SII device name for this slave position, empty if unknown.
Definition device_manager.h:156
uint32_t serialNumber
Serial number from EEPROM.
Definition device_manager.h:164
uint32_t vendorId
Vendor ID from EEPROM.
Definition device_manager.h:161
uint32_t revisionNumber
Revision number from EEPROM.
Definition device_manager.h:163
uint32_t productCode
Product code from EEPROM.
Definition device_manager.h:162
mm::comm::SlaveConfig config
Raw ESC configuration as captured by the driver.
Definition device_manager.h:155
std::string productName
Definition device_manager.h:157