12#include <nlohmann/json_fwd.hpp>
14#include <shared_mutex>
82 std::vector<ProcessImageObjectInfo>
outputs;
83 std::vector<ProcessImageObjectInfo>
inputs;
208 std::shared_ptr<mm::comm::FieldbusDriver>
driver;
217 const Device*
find(uint16_t slavePosition)
const;
233 : set_(std::move(set)), device_(device) {}
236 explicit operator bool()
const {
return device_ !=
nullptr; }
243 std::shared_ptr<DeviceSet> set_;
244 Device* device_ =
nullptr;
252 return std::unexpected(std::format(
"device {} not found", slavePosition));
305 std::expected<void, std::string>
init(std::unique_ptr<mm::comm::FieldbusDriver> driver,
326 std::expected<int, std::string>
scan();
345 bool hasDevice(uint16_t slavePosition)
const;
371 std::shared_ptr<DeviceSet>
deviceSet()
const;
415 explicit operator bool()
const {
return entered_; }
569 std::vector<SlaveConfigInfo>
busConfig()
const;
590 std::chrono::steady_clock::duration
timeout);
600 std::expected<std::vector<DeviceStateInfo>, std::string>
deviceStates(
601 const std::vector<uint16_t>& positions);
616 std::expected<std::vector<DeviceDiagnosticsInfo>, std::string>
deviceDiagnostics(
617 const std::vector<uint16_t>& positions);
633 std::expected<std::vector<DcSyncInfo>, std::string>
dcSync(
634 const std::vector<uint16_t>& positions);
646 uint16_t slavePosition);
662 uint16_t slavePosition, std::chrono::nanoseconds
timeout);
703 bool refreshFromBus);
726 uint16_t slavePosition, uint16_t index, uint8_t
subindex,
759 std::span<const OutputStageRequest> requests);
787 std::optional<PdoSampleSpec>
pdoSampleSpec(uint16_t slavePosition, uint16_t index,
836 uint64_t startSeq = 0;
846 std::expected<DumpSpan, std::string> serializeDump(std::ostream& out);
858 std::expected<void, std::string> remapProcessImage();
871 std::expected<std::vector<uint16_t>, std::string> resolveTargets(
872 const std::vector<uint16_t>& positions)
const;
885 int expectedWkcDuring(std::span<const uint16_t> transitioning,
886 std::optional<mm::comm::EtherCatState> target)
const;
890 void updateExpectedWkc();
913 [[nodiscard]]
bool stopExchange();
920 void publishDeviceSet(std::shared_ptr<DeviceSet> set);
931 mutable std::mutex busOperationMutex_;
938 mutable std::mutex currentSetMutex_;
948 std::shared_ptr<DeviceSet> currentSet_;
955 std::vector<std::shared_ptr<const void>> abandoned_;
960 std::atomic<DeviceSet*> publishedSet_{
nullptr};
968 mutable std::shared_mutex processDataMutex_;
971 std::atomic<uint64_t> topologyGeneration_{0};
973 std::atomic<uint64_t> processImageGeneration_{0};
974 std::unique_ptr<ProcessData> pd_;
977 ParameterCache parameterCache_;
979 DeviceManagerConfig config_;
990void to_json(nlohmann::json& j,
const DeviceManager& dm);
One device, plus the set that keeps it alive.
Definition device_manager.h:229
DeviceHandle(std::shared_ptr< DeviceSet > set, Device *device)
Definition device_manager.h:232
Device * operator->() const
Definition device_manager.h:238
Device * get() const
The device, or nullptr. For a caller that must pass it on as a pointer.
Definition device_manager.h:240
Device & operator*() const
Definition device_manager.h:237
Holds a cyclic task's whole body open against a device-set rebuild. RT-safe.
Definition device_manager.h:404
CycleGuard & operator=(const CycleGuard &)=delete
~CycleGuard()
Leaves the cycle, if this guard entered it.
Definition device_manager.cc:507
CycleGuard(const CycleGuard &)=delete
Owns the fieldbus driver and node collection, and drives PDO exchange.
Definition device_manager.h:287
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:1222
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:579
uint64_t topologyGeneration() const
Monotonic counter bumped every time the device set is rebuilt (scan / reset).
Definition device_manager.cc:251
bool hasDevice(uint16_t slavePosition) const
Whether a device holds slavePosition. Thread-safe; no bus access.
Definition device_manager.cc:257
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:1182
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:800
uint64_t recorderHead() const
The recorder ring's next sequence number; recorderHead()-1 is the newest recorded cycle and recorderH...
Definition device_manager.cc:574
std::expected< int, std::string > scan()
Scans the bus for nodes and populates the device list.
Definition device_manager.cc:139
const ParameterCache & parameterCache() const
The on-disk parameter cache, for the management API (list / download / remove).
Definition device_manager.cc:137
Device * findDevice(uint16_t slavePosition)
Device lookup by bus position. O(N) over a handful of devices; nullptr if absent.
Definition device_manager.cc:300
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:584
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:1338
int expectedWorkingCounter() const
The working counter expected from the devices currently exchanging (SAFE-OP/OP).
Definition device_manager.cc:605
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:1233
DeviceHandle deviceAt(uint16_t slavePosition) const
The device at slavePosition, as a handle that keeps it alive. Falsy if absent.
Definition device_manager.cc:261
std::expected< DeviceParameter, std::string > 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:1370
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:1209
void exchangeProcessData()
Exchanges one cycle of process data: sends the current outputs, captures inputs.
Definition device_manager.cc:383
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:1315
DeviceManager()
Definition device_manager.cc:39
uint64_t processImageGeneration() const
Monotonic counter bumped every time a new process image is published (each (re)map).
Definition device_manager.cc:597
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:1130
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:754
uint64_t shortWkcCycles() const
Cycles that answered with a short working counter since the bus came up.
Definition device_manager.cc:611
std::shared_ptr< DeviceSet > deviceSet() const
The current device set, as a pointer that keeps it alive. Never nullptr.
Definition device_manager.cc:267
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:1418
bool processDataHealthy() const
Whether every device that should be exchanging is contributing to the cycle.
Definition device_manager.cc:609
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:1248
std::vector< SlaveConfigInfo > busConfig() const
Snapshots each slave's static ESC configuration (SM, FMMU, mailbox, DC) for the API.
Definition device_manager.cc:811
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:97
bool processDataConfigured() const
Whether configureProcessData published a process image for exchange.
Definition device_manager.cc:593
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:906
void reset()
Stops the fieldbus driver and clears the device list.
Definition device_manager.cc:200
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:1400
std::expected< DeviceParameter, std::string > 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:1344
std::expected< void, std::string > configureProcessData()
Maps process data and publishes the process image for exchange.
Definition device_manager.cc:305
~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:1155
void configureParameterCache(const ParameterCacheConfig &config)
Sets the on-disk parameter-cache policy and location.
Definition device_manager.cc:133
int lastWorkingCounter() const
The working counter from the most recent process-data exchange (0 before any).
Definition device_manager.cc:601
bool initialised() const
Whether a driver is currently held: init() succeeded, and no reset() followed it. Thread-safe.
Definition device_manager.cc:255
ProcessImageInfo processImageInfo() const
Snapshots the published process image and its runtime health for the API.
Definition device_manager.cc:615
Represents a single node on the fieldbus.
Definition device.h:116
On-disk cache of CoE parameter definitions, keyed by device identity.
Definition parameter_cache.h:53
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:36
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:251
std::chrono::milliseconds timeout
Definition somanet_procedures.cc:438
Live distributed-clock synchronisation status for one slave, read from its ESC.
Definition fieldbus_driver.h:351
Static ESC configuration snapshot for one slave, captured by configureProcessData.
Definition fieldbus_driver.h:289
Decoded health diagnostics for one slave, read live from its ESC registers.
Definition fieldbus_driver.h:326
A slave's live distributed-clock sync status plus its resolved device name.
Definition device_manager.h:159
mm::comm::DcSyncDiagnostics dcSync
Decoded DC sync status as read by the driver.
Definition device_manager.h:160
std::string deviceName
Device name for this slave position, empty if unknown.
Definition device_manager.h:161
A slave's live ESC health diagnostics plus its resolved device name.
Definition device_manager.h:146
std::string deviceName
Device name for this slave position, empty if unknown.
Definition device_manager.h:148
mm::comm::SlaveDiagnostics diagnostics
Decoded ESC counters as read by the driver.
Definition device_manager.h:147
Runtime tuning passed to DeviceManager::init. Every field has a sensible default, so a caller can pas...
Definition device_manager.h:170
bool useCompleteAccess
Definition device_manager.h:178
bool readObjectDictionaryOnPreop
Definition device_manager.h:174
uint32_t recorderCapacity
Definition device_manager.h:185
std::string recorderDumpDir
Definition device_manager.h:182
Everything needed to decode one PDO object from a raw process-image snapshot: which image it lives in...
Definition device_manager.h:770
uint16_t dataType
ETG.1020 data-type code, for decoding the extracted bytes.
Definition device_manager.h:774
uint16_t bitLength
Width of the value in bits.
Definition device_manager.h:773
bool isOutput
True if the object is in the output image (RxPDO), false for input.
Definition device_manager.h:771
uint32_t bitOffset
Absolute bit offset within that direction's image.
Definition device_manager.h:772
One published generation of the bus: the driver that owns the socket, and the devices found on it.
Definition device_manager.h:206
Device * find(uint16_t slavePosition)
Device at slavePosition, or nullptr when the set holds none.
Definition device_manager.cc:281
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:208
uint64_t topologyGeneration
The value DeviceManager::topologyGeneration reported when this set was published.
Definition device_manager.h:212
std::vector< Device > devices
The devices in bus order: index 0 is position 1. Frozen once the set is published.
Definition device_manager.h:210
Current AL state snapshot for a single device.
Definition device_manager.h:35
uint16_t alStatus
Raw AL Status register (bits 3:0 = state, bit 4 = error indicator).
Definition device_manager.h:37
uint16_t slavePosition
1-based position on the fieldbus.
Definition device_manager.h:36
uint16_t alState
AL state decoded from alStatus (1=Init, 2=PreOp, 3=Boot, 4=SafeOp, 8=Op).
Definition device_manager.h:38
uint16_t alStatusCode
AL Status Code (ETG.1000.6 §6.4.1); non-zero when error is true.
Definition device_manager.h:40
bool error
True when the AL Status error indicator bit is set.
Definition device_manager.h:39
One object to stage into the output process image, as parsed from a batch write request.
Definition device_manager.h:96
DeviceParameterValue value
Value to write; coerced to the object's declared type.
Definition device_manager.h:100
uint16_t slavePosition
1-based bus position of the owning device.
Definition device_manager.h:97
uint16_t index
CoE object index.
Definition device_manager.h:98
uint8_t subindex
CoE object subindex.
Definition device_manager.h:99
Per-object outcome of a batch output stage.
Definition device_manager.h:109
bool staged
Whether the value was staged into the cyclic output image.
Definition device_manager.h:113
uint8_t subindex
Echoes the request.
Definition device_manager.h:112
uint16_t index
Echoes the request.
Definition device_manager.h:111
uint16_t slavePosition
Echoes the request.
Definition device_manager.h:110
std::string error
Empty on success; otherwise why the object was not staged.
Definition device_manager.h:114
Policy and location for the on-disk parameter cache.
Definition parameter_cache.h:26
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:69
uint64_t shortWkcCycles
Definition device_manager.h:78
std::vector< ProcessImageObjectInfo > inputs
Input-mapped objects in image order.
Definition device_manager.h:83
uint32_t outputBytes
Size of the output image (master→slave).
Definition device_manager.h:71
uint64_t firstShortWkcUs
Epoch microseconds of the first such cycle (0 if none).
Definition device_manager.h:79
bool healthy
Definition device_manager.h:75
uint64_t lastShortWkcUs
Epoch microseconds of the most recent one (0 if none).
Definition device_manager.h:80
std::vector< ProcessImageObjectInfo > outputs
Output-mapped objects in image order.
Definition device_manager.h:82
std::size_t generations
Number of process images retained since the last reset().
Definition device_manager.h:81
int expectedWkc
Working counter expected from the devices currently exchanging.
Definition device_manager.h:73
uint32_t inputBytes
Size of the input image (slave→master).
Definition device_manager.h:72
bool configured
Whether an image is currently published for exchange.
Definition device_manager.h:70
int lastWkc
Working counter from the most recent exchange (0 before any).
Definition device_manager.h:74
One mapped object in the published process image, with its name resolved.
Definition device_manager.h:51
uint8_t subindex
CoE object subindex.
Definition device_manager.h:54
uint32_t bitOffset
Absolute bit offset within the direction's image.
Definition device_manager.h:56
uint16_t bitLength
Width of the value in bits.
Definition device_manager.h:57
uint16_t slavePosition
1-based bus position of the owning device.
Definition device_manager.h:52
std::string name
Object name, or empty if the OD has not been enumerated.
Definition device_manager.h:55
uint16_t index
CoE object index.
Definition device_manager.h:53
The whole bus's process-data layout, resolved to absolute positions.
Definition process_image.h:69
A slave's static ESC configuration plus its resolved device name.
Definition device_manager.h:125
std::string deviceName
SII device name for this slave position, empty if unknown.
Definition device_manager.h:127
uint32_t serialNumber
Serial number from EEPROM.
Definition device_manager.h:135
uint32_t vendorId
Vendor ID from EEPROM.
Definition device_manager.h:132
uint32_t revisionNumber
Revision number from EEPROM.
Definition device_manager.h:134
uint32_t productCode
Product code from EEPROM.
Definition device_manager.h:133
mm::comm::SlaveConfig config
Raw ESC configuration as captured by the driver.
Definition device_manager.h:126
std::string productName
Definition device_manager.h:128