Motion Master 6.0.0-alpha.50
Next-generation motion control software
Loading...
Searching...
No Matches
device.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <expected>
5#include <format>
6#include <memory>
7#include <mutex>
8#include <nlohmann/json_fwd.hpp>
9#include <optional>
10#include <span>
11#include <string>
12#include <unordered_map>
13#include <variant>
14#include <vector>
15
18#include "node/pdo_mapping.h"
19
20namespace mm::node {
21
25struct ProcessData;
26
30class ParameterCache;
31
36class Device {
37 public:
50 ProcessData* processData = nullptr, const ParameterCache* parameterCache = nullptr);
51
53 uint16_t slavePosition() const;
54
56 const std::string& name() const;
57
59 uint32_t vendorId() const;
60
62 uint32_t productCode() const;
63
65 uint32_t revisionNumber() const;
66
68 uint32_t serialNumber() const;
69
80 bool mailboxActive() const;
81
89 bool exchangesProcessData() const;
90
99 std::expected<std::vector<uint8_t>, std::string> readSdo(uint16_t index, uint8_t subindex) const;
100
111 std::expected<void, std::string> writeSdo(uint16_t index, uint8_t subindex,
112 std::span<const uint8_t> data) const;
113
118 std::expected<std::vector<uint8_t>, std::string> readFile(const std::string& filename) const;
119
125 std::expected<void, std::string> writeFile(const std::string& filename,
126 std::span<const uint8_t> data) const;
127
135 std::expected<void, std::string> readRegister(uint16_t address, std::span<uint8_t> data) const;
136
144 std::expected<void, std::string> writeRegister(uint16_t address,
145 std::span<const uint8_t> data) const;
146
154 std::expected<std::vector<uint8_t>, std::string> readSii() const;
155
165 std::expected<void, std::string> writeSii(std::span<const uint8_t> data) const;
166
187 std::expected<void, std::string> initializeParameters(bool readValues = false,
188 bool useCompleteAccess = true);
189
204 std::expected<void, std::string> readFlatPdoMapping();
205
207 const FlatPdoMapping& flatPdoMapping() const;
208
217 std::expected<PdoMapping, std::string> readPdoMapping();
218
248 std::expected<void, std::string> writePdoMapping(const PdoMapping& mapping);
249
263 std::expected<void, std::string> setValue(uint16_t index, uint8_t subindex,
264 DeviceParameterValue newValue);
265
278 std::expected<DeviceParameterValue, std::string> setValueFromBytes(
279 uint16_t index, uint8_t subindex, std::span<const uint8_t> bytes);
280
290 std::expected<std::vector<uint8_t>, std::string> valueAsBytes(uint16_t index,
291 uint8_t subindex) const;
292
295 const std::unordered_map<uint32_t, DeviceParameter>& parameters() const;
296
302 std::vector<DeviceParameter> parametersOrdered() const;
303
310 const DeviceParameter* parameter(uint16_t index, uint8_t subindex) const;
311
321 std::optional<DeviceParameterValue> value(uint16_t index, uint8_t subindex) const;
322
332 std::optional<DeviceParameter> parameterCopy(uint16_t index, uint8_t subindex) const;
333
343 std::optional<uint16_t> dataType(uint16_t index, uint8_t subindex) const;
344
360 std::expected<DeviceParameterValue, std::string> readParameter(uint16_t index, uint8_t subindex);
361
381 std::expected<void, std::string> readAllParameters(bool useCompleteAccess = true);
382
402 std::expected<void, std::string> writeParameter(uint16_t index, uint8_t subindex,
403 DeviceParameterValue newValue);
404
418 template <typename T>
419 std::expected<void, std::string> writeValue(uint16_t index, uint8_t subindex, T newValue) {
420 return writeParameter(index, subindex, DeviceParameterValue{newValue});
421 }
422
434 template <typename T>
435 std::expected<T, std::string> readValue(uint16_t index, uint8_t subindex) {
436 auto v = readParameter(index, subindex);
437 if (!v) {
438 return std::unexpected(v.error());
439 }
440 if (const auto* p = std::get_if<T>(&*v)) {
441 return *p;
442 }
443 return std::unexpected(
444 std::format("parameter 0x{:04X}:{:02X} holds a different type", index, subindex));
445 }
446
447 private:
449 DeviceParameter* findParameter(uint16_t index, uint8_t subindex);
450
459 void readParameterValues(std::vector<DeviceParameter>& defs, bool useCompleteAccess);
460
469 std::expected<std::vector<PdoMappingObject>, std::string> readPdoAssignment(
470 uint16_t assignmentIndex);
471
472 uint16_t slavePosition_;
474 // Live process-data runtime, or nullptr for SDO-only operation. Injected by DeviceManager so
475 // read/writeParameter can prefer PDO over SDO while exchanging. Non-owning; the owner
476 // (DeviceManager) outlives every Device it created. A raw pointer keeps Device
477 // move-constructible.
478 ProcessData* processData_ = nullptr;
479 // On-disk parameter-definition cache, or nullptr to always enumerate live. Non-owning; owned by
480 // DeviceManager, which outlives every Device. Consulted only by initializeParameters.
481 const ParameterCache* parameterCache_ = nullptr;
482 std::string name_;
483 uint32_t vendorId_;
484 uint32_t productCode_;
485 uint32_t revisionNumber_;
486 uint32_t serialNumber_;
487 // Guards parameters_ against the off-RT monitoring threads (the refresher refreshes cached
488 // values, the sampler reads them) racing the control-plane thread. Held only briefly — across
489 // a cache read/write, or a single mailbox transaction in read/writeParameter; never across the
490 // multi-entry object-dictionary enumeration, which builds a local map and swaps it in under
491 // the lock. Lock order, where both are taken: DeviceManager::busMutex_ before this.
492 //
493 // Held by unique_ptr because std::mutex is neither movable nor copyable, and Device is moved
494 // into DeviceManager's std::vector<Device> (which relocates on growth). The indirection keeps
495 // Device move-constructible (the pointer moves); a Device is never copied, only moved.
496 std::unique_ptr<std::mutex> parametersMutex_;
497 std::unordered_map<uint32_t, DeviceParameter> parameters_;
498 FlatPdoMapping flatPdoMapping_;
499};
500
510void to_json(nlohmann::json& j, const Device& d);
511
529std::expected<int, std::string> reconcileDetectedModules(const Device& device);
530
531} // namespace mm::node
Abstract interface for an EtherCAT fieldbus driver.
Definition fieldbus_driver.h:343
Represents a single node on the fieldbus.
Definition device.h:36
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:72
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:756
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:87
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:105
const DeviceParameter * parameter(uint16_t index, uint8_t subindex) const
Looks up a parameter by (index, subindex). O(1).
Definition device.cc:719
uint32_t serialNumber() const
Serial number from EEPROM.
Definition device.cc:45
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:67
std::expected< void, std::string > readAllParameters(bool useCompleteAccess=true)
Refreshes the cached value of every readable parameter, keeping the list intact.
Definition device.cc:798
const std::unordered_map< uint32_t, DeviceParameter > & parameters() const
Returns the parameter map, keyed by makeParameterKey(index, subindex). Empty until initializeParamete...
Definition device.cc:351
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:593
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:92
const std::string & name() const
Human-readable node name from SII EEPROM.
Definition device.cc:41
std::expected< void, std::string > writeValue(uint16_t index, uint8_t subindex, T newValue)
Typed convenience wrapper for writeParameter.
Definition device.h:419
std::optional< DeviceParameter > parameterCopy(uint16_t index, uint8_t subindex) const
Returns a copy of a full parameter struct (value + metadata), no bus access.
Definition device.cc:733
std::optional< DeviceParameterValue > value(uint16_t index, uint8_t subindex) const
Returns a copy of a parameter's cached value (the typed cache getter), no bus access.
Definition device.cc:724
uint32_t revisionNumber() const
Revision number from EEPROM.
Definition device.cc:44
const FlatPdoMapping & flatPdoMapping() const
Returns the device's PDO mapping. Empty until readFlatPdoMapping() succeeds.
Definition device.cc:493
bool exchangesProcessData() const
Whether the device is in a process-data-exchanging state (SAFE-OP or OP, error bit clear).
Definition device.cc:59
std::expected< PdoMapping, std::string > readPdoMapping()
Reads the device's PDO mapping grouped by mapping object (0x16xx / 0x1Axx).
Definition device.cc:451
std::vector< DeviceParameter > parametersOrdered() const
Returns all parameters sorted ascending by (index, subindex).
Definition device.cc:707
std::expected< void, std::string > readFlatPdoMapping()
Reads the device's PDO mapping from its assignment and mapping objects.
Definition device.cc:466
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:677
std::expected< void, std::string > 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:82
std::expected< void, std::string > writeParameter(uint16_t index, uint8_t subindex, DeviceParameterValue newValue)
Writes a parameter value, always updating the cache first.
Definition device.cc:870
bool mailboxActive() const
Whether the device's CoE/SDO mailbox is currently active (AL state PRE-OP, SAFE-OP,...
Definition device.cc:47
uint32_t productCode() const
Product code from EEPROM.
Definition device.cc:43
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:101
std::expected< std::vector< uint8_t >, std::string > valueAsBytes(uint16_t index, uint8_t subindex) const
Returns the parameter's value as its raw on-the-wire bytes (the bytes-domain getter).
Definition device.cc:696
std::expected< T, std::string > readValue(uint16_t index, uint8_t subindex)
Typed convenience wrapper for readParameter.
Definition device.h:435
std::expected< std::vector< uint8_t >, std::string > readFile(const std::string &filename) const
Reads a file from this device via File over EtherCAT (FoE).
Definition device.cc:77
uint16_t slavePosition() const
Returns the 1-based position of this node on the fieldbus.
Definition device.cc:40
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:742
std::expected< void, std::string > setValue(uint16_t index, uint8_t subindex, DeviceParameterValue newValue)
Stores a parameter's value locally, without any bus access (the typed setter).
Definition device.cc:662
uint32_t vendorId() const
Vendor ID from EEPROM.
Definition device.cc:42
std::expected< std::vector< uint8_t >, std::string > readSii() const
Reads this device's raw Slave Information Interface (SII / EEPROM) image.
Definition device.cc:97
On-disk cache of CoE parameter definitions, keyed by device identity.
Definition parameter_cache.h:55
Definition http_server.h:16
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:24
void to_json(nlohmann::json &j, const Device &d)
Serialises a Device to JSON.
Definition device.cc:915
std::expected< int, std::string > reconcileDetectedModules(const Device &device)
Reconciles a device's Configured Module Ident List with its Detected list.
Definition device.cc:946
A single object dictionary entry held by a Device.
Definition device_parameter.h:66
A device's complete PDO mapping across both directions.
Definition pdo_mapping.h:62
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