Motion Master 6.0.0-alpha.111
Next-generation motion control software
Loading...
Searching...
No Matches
mm::comm::spoe::SpoeFieldbusDriver Class Reference

#include <spoe_fieldbus_driver.h>

Inheritance diagram for mm::comm::spoe::SpoeFieldbusDriver:
[legend]
Collaboration diagram for mm::comm::spoe::SpoeFieldbusDriver:
[legend]

Classes

struct  Drive
 

Public Member Functions

 SpoeFieldbusDriver (SpoeFieldbusDriverConfig config)
 
 ~SpoeFieldbusDriver () override
 
 SpoeFieldbusDriver (const SpoeFieldbusDriver &)=delete
 
SpoeFieldbusDriver & operator= (const SpoeFieldbusDriver &)=delete
 
std::expected< void, std::string > init () override
 Opens the network interface and initialises the master context.
 
std::expected< int, std::string > scan () override
 Scans the bus for slaves and configures their sync managers and FMMUs.
 
SlaveInfo slaveInfo (uint16_t position) const override
 Returns the immutable identity fields for the slave at position.
 
uint16_t slaveState (uint16_t position) const override
 Returns the last-known AL status for a slave without any bus I/O.
 
uint16_t mailboxProtocols (uint16_t position) const override
 Returns the slave's advertised mailbox-protocol bits without any bus I/O.
 
std::expected< void, std::string > configureProcessData () override
 Maps the process data and lays out the IOmap (one-time, control-plane).
 
PdoLayout processDataLayout () override
 Returns the current process-data layout established by configureProcessData.
 
int exchangeProcessData (std::span< const uint8_t > outputs, std::span< uint8_t > inputs) override
 Exchanges one cycle of process data: sends outputs, receives into inputs.
 
void stop () override
 Closes the network interface, releasing the master context.
 
std::expected< std::vector< SlaveStateRaw >, std::string > readStates (const std::vector< uint16_t > &positions) override
 Reads the current AL Status for each slave in positions.
 
std::expected< std::vector< uint8_t >, std::string > readSdo (uint16_t slavePosition, uint16_t index, uint8_t subindex) override
 Reads an object dictionary entry via CoE SDO upload.
 
std::expected< void, std::string > writeSdo (uint16_t slavePosition, uint16_t index, uint8_t subindex, std::span< const uint8_t > data) override
 Writes an object dictionary entry to a slave (CoE SDO download).
 
std::expected< OdRead, std::string > readObjectDictionary (uint16_t slavePosition) override
 Enumerates the entire CoE object dictionary of a slave via SDO Info.
 
std::expected< std::vector< uint8_t >, FoeError > readFile (uint16_t slavePosition, const std::string &filename, std::chrono::milliseconds timeout) override
 Reads a file from the slave via File over EtherCAT (FoE).
 
std::expected< void, FoeError > writeFile (uint16_t slavePosition, const std::string &filename, std::span< const uint8_t > data) override
 Writes a file to the slave via File over EtherCAT (FoE).
 
std::expected< void, std::string > readRegister (uint16_t slavePosition, uint16_t address, std::span< uint8_t > data) override
 Reads bytes from an ESC register via a Configured-Address Read (FPRD) datagram.
 
std::expected< void, std::string > writeRegister (uint16_t slavePosition, uint16_t address, std::span< const uint8_t > data) override
 Writes bytes to an ESC register via a Configured-Address Write (FPWR) datagram.
 
void transitionToState (const std::vector< uint16_t > &positions, std::optional< EtherCatState > requiredState, EtherCatState targetState, std::chrono::steady_clock::duration timeout, std::chrono::steady_clock::duration resendInterval, std::function< void()> tick, std::function< bool()> shouldAbort) override
 Commands a set of devices to targetState and blocks until all arrive or timeout elapses.
 
std::optional< std::string > stateChangeRefusal () const override
 Returns why this driver refuses every state change, or nullopt when it accepts them.
 
bool supportsEsc () const override
 True when the devices have an EtherCAT Slave Controller: SII, ESC registers, DC and the ESC diagnostics. No bus I/O.
 
uint64_t droppedInputFrames () const override
 Input frames dropped since the process data was configured, summed over all devices.
 
bool supportsLocate () const override
 True when locate can blink a device's LEDs. No bus I/O.
 
std::expected< void, std::string > locate (uint16_t slavePosition, bool on) override
 Starts or stops blinking the LEDs of a device, so that someone can find it.
 
std::expected< FirmwareActivation, std::string > activateFirmware (uint16_t slavePosition, std::chrono::steady_clock::duration timeout) override
 Makes a device apply the firmware files written to it in BOOT.
 
- Public Member Functions inherited from mm::comm::FieldbusDriver
virtual ~FieldbusDriver ()=default
 
virtual std::vector< SlaveConfig > busConfig () const
 Returns the static ESC configuration of every slave, as last programmed by the master.
 
virtual std::optional< int > readDevicesOnWire ()
 Counts the devices on the wire, or returns nothing when the transport cannot.
 
virtual std::expected< std::vector< SlaveDiagnostics >, std::string > readDiagnostics (const std::vector< uint16_t > &)
 Reads live link-quality and watchdog diagnostics for each slave in positions.
 
virtual std::expected< std::vector< DcSyncDiagnostics >, std::string > readDcSync (const std::vector< uint16_t > &)
 Reads live distributed-clock synchronisation status for each slave in positions.
 
virtual std::expected< std::vector< uint8_t >, std::string > readSdoComplete (uint16_t, uint16_t)
 Reads an entire object in one CoE SDO upload using Complete Access.
 
virtual std::expected< std::vector< uint8_t >, std::string > readSii (uint16_t)
 Reads the raw Slave Information Interface (SII / EEPROM) image of a slave.
 
virtual std::expected< void, std::string > writeSii (uint16_t, std::span< const uint8_t >)
 Writes a raw SII (EEPROM) image to a slave.
 
virtual std::expected< ProcessDataWatchdogConfig, std::string > processDataWatchdog (uint16_t)
 Reads the process-data (sync-manager) watchdog configuration of one slave.
 
virtual std::expected< ProcessDataWatchdogConfig, std::string > setProcessDataWatchdog (uint16_t, std::chrono::nanoseconds)
 Sets the process-data (sync-manager) watchdog timeout of one slave.
 
virtual std::string adapter () const
 The network adapter the bus is on, as the OS names it, or empty for a transport that sends no EtherCAT frames (SPoE). No bus I/O.
 

Additional Inherited Members

- Public Types inherited from mm::comm::FieldbusDriver
enum class  FirmwareActivation : uint8_t { kOnBootExit , kRestarted }
 What activateFirmware did. More...
 

Constructor & Destructor Documentation

◆ SpoeFieldbusDriver() [1/2]

mm::comm::spoe::SpoeFieldbusDriver::SpoeFieldbusDriver ( SpoeFieldbusDriverConfig  config)
explicit

◆ ~SpoeFieldbusDriver()

mm::comm::spoe::SpoeFieldbusDriver::~SpoeFieldbusDriver ( )
override

◆ SpoeFieldbusDriver() [2/2]

mm::comm::spoe::SpoeFieldbusDriver::SpoeFieldbusDriver ( const SpoeFieldbusDriver &  )
delete

Member Function Documentation

◆ activateFirmware()

std::expected< FieldbusDriver::FirmwareActivation, std::string > mm::comm::spoe::SpoeFieldbusDriver::activateFirmware ( uint16_t  ,
std::chrono::steady_clock::duration   
)
overridevirtual

Makes a device apply the firmware files written to it in BOOT.

Over EtherCAT, leaving BOOT does this, so the default does nothing. A transport that needs an explicit request sends it and waits up to timeout for the device to answer again.

Reimplemented from mm::comm::FieldbusDriver.

◆ configureProcessData()

std::expected< void, std::string > mm::comm::spoe::SpoeFieldbusDriver::configureProcessData ( )
overridevirtual

Maps the process data and lays out the IOmap (one-time, control-plane).

Reads each slave's active PDO assignment, computes the process image, programs the FMMUs, and fills the driver-owned IOmap. Slaves must be in PRE-OP (mailbox active) so the assignment can be read. Run again to re-map after the slave set changes (e.g. a device returning from a firmware download) — the previous PdoLayout is invalidated. Serialised with other control-plane operations via the socket mutex. This is the one operation that must not overlap exchangeProcessData — it rewrites the IOmap the RT cycle reads — and, since the lock-free PDO path does not take the socket mutex, that exclusion is enforced by the caller (DeviceManager drains exchange and unpublishes the process image before re-mapping), not by the mutex.

Returns
Void on success, or an error string if no driver is initialised, no process data is mapped, or the image exceeds kMaxProcessImageBytes.

Implements mm::comm::FieldbusDriver.

◆ droppedInputFrames()

uint64_t mm::comm::spoe::SpoeFieldbusDriver::droppedInputFrames ( ) const
overridevirtual

Input frames dropped since the process data was configured, summed over all devices.

A transport that buffers input frames, as SPoE does, drops the oldest when the RT loop falls behind. A memory-mapped master has no such queue, so the default is 0. No bus I/O.

Reimplemented from mm::comm::FieldbusDriver.

◆ exchangeProcessData()

int mm::comm::spoe::SpoeFieldbusDriver::exchangeProcessData ( std::span< const uint8_t >  outputs,
std::span< uint8_t >  inputs 
)
overridevirtual

Exchanges one cycle of process data: sends outputs, receives into inputs.

The caller owns both images; the driver translates them to and from its transport (an IOmap copy for SOEM/IgH, message (de)serialisation for SPoE). outputs.size() must equal PdoLayout::outputBytes and inputs.size() must equal PdoLayout::inputBytes. Called once per GameLoop cycle. Runs lock-free (does not take the socket mutex) — see the class-level note. Must complete within the cycle budget; timing jitter here propagates directly to control latency. Must not be called before configureProcessData or after stop.

Parameters
outputsOutput image to send (master→slave); not retained past the call.
inputsBuffer that receives the input image (slave→master).
Returns
The working counter for the transaction. Compare against PdoLayout::expectedWkc: a lower value means one or more slaves did not contribute this cycle. Returns 0 when no driver is initialised.

Implements mm::comm::FieldbusDriver.

◆ init()

std::expected< void, std::string > mm::comm::spoe::SpoeFieldbusDriver::init ( )
overridevirtual

Opens the network interface and initialises the master context.

Must be called before any other driver method.

Returns
Void on success, or an error string describing the failure.

Implements mm::comm::FieldbusDriver.

◆ locate()

std::expected< void, std::string > mm::comm::spoe::SpoeFieldbusDriver::locate ( uint16_t  ,
bool   
)
overridevirtual

Starts or stops blinking the LEDs of a device, so that someone can find it.

Reimplemented from mm::comm::FieldbusDriver.

◆ mailboxProtocols()

uint16_t mm::comm::spoe::SpoeFieldbusDriver::mailboxProtocols ( uint16_t  ) const
overridevirtual

Returns the slave's advertised mailbox-protocol bits without any bus I/O.

The same EEPROM-derived value busConfig() reports in MailboxConfig::protocols (SOEM's cached mbx_proto): 0x01 AoE, 0x02 EoE, 0x04 CoE (MailboxConfig::kProtocolCoe), 0x08 FoE, 0x10 SoE, 0x20 VoE. 0 when the slave has no mailbox at all. Lets a caller (e.g. Device) decide whether CoE is even possible before attempting an SDO — a mailbox-less slave (an EtherCAT coupler / simple I/O terminal) returns 0, so its PDO mapping must be read from SII rather than the CoE 0x1C12 / 0x1C13 objects. Unlike a live-state check, this is a fixed capability. The base returns 0 (no mailbox); real mailbox transports override.

Reimplemented from mm::comm::FieldbusDriver.

◆ operator=()

SpoeFieldbusDriver & mm::comm::spoe::SpoeFieldbusDriver::operator= ( const SpoeFieldbusDriver &  )
delete

◆ processDataLayout()

PdoLayout mm::comm::spoe::SpoeFieldbusDriver::processDataLayout ( )
overridevirtual

Returns the current process-data layout established by configureProcessData.

The returned spans alias the driver-owned IOmap and remain valid until the next configureProcessData or stop. Before a successful configureProcessData the layout is empty (zero-sized spans, no slaves).

Implements mm::comm::FieldbusDriver.

◆ readFile()

std::expected< std::vector< uint8_t >, FoeError > mm::comm::spoe::SpoeFieldbusDriver::readFile ( uint16_t  slavePosition,
const std::string &  filename,
std::chrono::milliseconds  timeout 
)
overridevirtual

Reads a file from the slave via File over EtherCAT (FoE).

Sends an FoE read request for filename and collects all data packets from the slave. FoE is available in Boot, Pre-Op, Safe-Op, and Op states (device-dependent); the caller is responsible for ensuring the device is in a suitable state. Called from HTTP handler threads; serialised with other control-plane operations via the socket mutex, and runs concurrently with the lock-free exchangeProcessData.

Parameters
slavePosition1-based slave position on the bus.
filenameFoE filename as recognised by the slave firmware.
timeoutHow long to wait for the slave's answer. Usually kFoeReadTimeout. A read that makes the slave do slow work before it answers needs longer, such as a SOMANET file removal, which answers after the erase. A transport with a longer timeout of its own keeps that one.
Returns
File bytes on success, or a FoeError. This is the one driver operation whose error is structured rather than a plain string, because callers branch on it — see comm/foe_error.h. It still streams and carries .message, so a caller that only forwards the failure reads unchanged.

Implements mm::comm::FieldbusDriver.

◆ readObjectDictionary()

std::expected< OdRead, std::string > mm::comm::spoe::SpoeFieldbusDriver::readObjectDictionary ( uint16_t  slavePosition)
overridevirtual

Enumerates the entire CoE object dictionary of a slave via SDO Info.

Performs the "Get Object List" → "Get Object Description" → "Get Entry Description" sequence (ETG.1000.6 §5.6) and returns one OdEntry per (index, subindex) pair. The slave must be in PRE-OP, SAFE-OP, or OP — i.e. mailbox communication enabled. Many transfers are issued; expect the call to take seconds on a fully populated drive.

Slaves that do not implement the SDO Info service return an error.

A single entry the slave never answers for is left out rather than failing the whole enumeration, and counted in OdRead::missingEntries. A failure of the object list or of an object description does fail the call, because neither leaves a usable dictionary behind.

Parameters
slavePosition1-based slave position on the bus.
Returns
The entries read and the count of those missing, or an error string if the object list or an object description fails after the driver's internal retries.

Implements mm::comm::FieldbusDriver.

◆ readRegister()

std::expected< void, std::string > mm::comm::spoe::SpoeFieldbusDriver::readRegister ( uint16_t  slavePosition,
uint16_t  address,
std::span< uint8_t >  data 
)
overridevirtual

Reads bytes from an ESC register via a Configured-Address Read (FPRD) datagram.

data.size() bytes are read from register address of the slave at slavePosition. Called from HTTP handler threads; serialised with other control-plane operations via the socket mutex, and runs concurrently with the lock-free exchangeProcessData.

Parameters
slavePosition1-based slave position on the bus.
addressESC register address (e.g. 0x0130 for DL Status).
dataOutput buffer; its size determines how many bytes are read.
Returns
Void on success, or an error string if no slave responded.

Implements mm::comm::FieldbusDriver.

◆ readSdo()

std::expected< std::vector< uint8_t >, std::string > mm::comm::spoe::SpoeFieldbusDriver::readSdo ( uint16_t  slavePosition,
uint16_t  index,
uint8_t  subindex 
)
overridevirtual

Reads an object dictionary entry via CoE SDO upload.

Allocates up to 4096 bytes, performs a mailbox SDO upload, and returns the exact bytes the slave sent (resized to the actual transfer size). Called from HTTP handler threads; serialised with other control-plane operations via the socket mutex, but runs concurrently with the lock-free exchangeProcessData — a slow SDO never blocks the RT cycle (the reason the PDO path stays out of the mutex).

Returns an owning std::vector, not a std::span, deliberately: the bytes are produced by this call and their ownership must transfer to the caller, which a non-owning view cannot do (a span would have to alias driver state that the next call clobbers, or storage nothing frees). Nor can the caller lend a sized buffer the way readRegister does — an SDO object's size is unknown until the transfer completes (expedited vs. segmented), which is exactly why the implementation over-allocates and resizes. The return is moved out, so this costs no copy. (std::span is used elsewhere in this interface only for borrowed inputs — e.g. writeSdo / exchangeProcessData — never to hand back freshly produced data.)

Parameters
slavePosition1-based slave position on the bus.
indexCoE object index.
subindexCoE object subindex.
Returns
The bytes transferred on success, or an error string if the mailbox transfer fails.

Implements mm::comm::FieldbusDriver.

◆ readStates()

std::expected< std::vector< FieldbusDriver::SlaveStateRaw >, std::string > mm::comm::spoe::SpoeFieldbusDriver::readStates ( const std::vector< uint16_t > &  positions)
overridevirtual

Reads the current AL Status for each slave in positions.

Refreshes slave state from the hardware in one pass, then returns the raw AL Status register and AL Status Code register for each requested position. AL Status bits 3:0 encode the current state (1=Init, 2=PreOp, 3=Boot, 4=SafeOp, 8=Op); bit 4 is the error indicator. AL Status Code is non-zero when an error is present and identifies the cause (ETG.1000.6 §6.4.1).

A slave that does not answer reports both registers as 0 and says why in reachability, because a value the master read before the slave stopped answering is not its state now.

Parameters
positions1-based slave positions to read.
Returns
Raw state per position in the same order as positions, or an error string if the hardware read fails.

Implements mm::comm::FieldbusDriver.

◆ scan()

std::expected< int, std::string > mm::comm::spoe::SpoeFieldbusDriver::scan ( )
overridevirtual

Scans the bus for slaves and configures their sync managers and FMMUs.

Must be called after a successful init(). Slaves remain in INIT state — state transitions are left entirely to the caller.

Returns
Number of slaves found (0 is a valid result — an empty/unpowered bus, which the master cannot distinguish from a disconnected one), or an error string if the scan fails.

Implements mm::comm::FieldbusDriver.

◆ slaveInfo()

SlaveInfo mm::comm::spoe::SpoeFieldbusDriver::slaveInfo ( uint16_t  position) const
overridevirtual

Returns the immutable identity fields for the slave at position.

Parameters
position1-based slave position on the bus.

Implements mm::comm::FieldbusDriver.

◆ slaveState()

uint16_t mm::comm::spoe::SpoeFieldbusDriver::slaveState ( uint16_t  position) const
overridevirtual

Returns the last-known AL status for a slave without any bus I/O.

Returns the cached AL Status register (bits 3:0 = state, bit 4 = error) from the most recent readStates() or state transition — no network round trip. Returns 0 before any state is known. Call readStates() to refresh the cache from the hardware. Lets callers (e.g. Device) derive online / exchanging status without a redundant cached copy.

Note
Must not block. An implementation is required to answer this without waiting on any lock a bus operation can hold, because the callers are the ones that must stay responsive while the bus is busy — the live monitoring sampler asks it per flush, for every device. An implementation that reached through its control-plane lock would inherit the duration of whatever holds it: a firmware transfer holds that lock for the whole multi-second FoE write, so monitoring for the entire bus would stall while one device is flashed. Publish the value somewhere a reader can take it lock-free instead.

Implements mm::comm::FieldbusDriver.

◆ stateChangeRefusal()

std::optional< std::string > mm::comm::spoe::SpoeFieldbusDriver::stateChangeRefusal ( ) const
overridevirtual

Returns why this driver refuses every state change, or nullopt when it accepts them.

A driver can be configured so that another master owns the device state, as SPoE is in Monitor mode. transitionToState then does nothing, and its outcome reads only as "target not reached". This reason is what a caller shows instead. Answers without bus I/O.

Reimplemented from mm::comm::FieldbusDriver.

◆ stop()

void mm::comm::spoe::SpoeFieldbusDriver::stop ( )
overridevirtual

Closes the network interface, releasing the master context.

Does not command any AL state change — it only closes the transport (for SOEM, ecx_close, which just destroys the mailbox-pool mutex and closes the raw socket; nothing is sent on the wire). Slaves left in SAFE-OP/OP are not driven back to INIT by the master; once process-data frames stop arriving, each slave's own sync-manager watchdog trips and it drops out of OP on its own (the safety guarantee for comms loss, independent of any graceful shutdown). After stop() returns, exchangeProcessData() must not be called again.

Implements mm::comm::FieldbusDriver.

◆ supportsEsc()

bool mm::comm::spoe::SpoeFieldbusDriver::supportsEsc ( ) const
inlineoverridevirtual

True when the devices have an EtherCAT Slave Controller: SII, ESC registers, DC and the ESC diagnostics. No bus I/O.

A transport without one answers those calls with "not supported". This lets a caller skip them, or say why they are missing, without asking first.

Reimplemented from mm::comm::FieldbusDriver.

◆ supportsLocate()

bool mm::comm::spoe::SpoeFieldbusDriver::supportsLocate ( ) const
inlineoverridevirtual

True when locate can blink a device's LEDs. No bus I/O.

Reimplemented from mm::comm::FieldbusDriver.

◆ transitionToState()

void mm::comm::spoe::SpoeFieldbusDriver::transitionToState ( const std::vector< uint16_t > &  positions,
std::optional< EtherCatState >  requiredState,
EtherCatState  targetState,
std::chrono::steady_clock::duration  timeout,
std::chrono::steady_clock::duration  resendInterval,
std::function< void()>  tick,
std::function< bool()>  shouldAbort 
)
overridevirtual

Commands a set of devices to targetState and blocks until all arrive or timeout elapses.

Devices whose current state (error bit masked) does not match requiredState are skipped; pass std::nullopt to command all positions unconditionally.

A device that does not answer at its address is skipped too, with an error logged, because a command it cannot receive only waits out timeout. The one exception is a device the driver can give its address back to itself.

The call polls at ~100 ms intervals, re-sending the command to lagging devices every resendInterval. Devices that do not arrive in time are logged at error level; no exception is thrown. The outcome per device is not returned here — read it back via readStates after the call (this is what DeviceManager::transitionToState does).

Parameters
positions1-based device positions to target.
requiredStatePre-filter: only command devices whose current state equals this value. std::nullopt skips filtering and commands all positions.
targetStateDesired state.
timeoutMaximum time to wait for all devices.
resendIntervalHow often to re-send the command to lagging devices.
tickOptional callback invoked at ~1 ms intervals while waiting. Pass a PDO sender when targeting EtherCatState::Op so the sync-manager watchdog does not fire during the wait.
shouldAbortOptional predicate; when it returns true the wait is abandoned early without logging failures for pending devices.

Implements mm::comm::FieldbusDriver.

◆ writeFile()

std::expected< void, FoeError > mm::comm::spoe::SpoeFieldbusDriver::writeFile ( uint16_t  slavePosition,
const std::string &  filename,
std::span< const uint8_t >  data 
)
overridevirtual

Writes a file to the slave via File over EtherCAT (FoE).

Sends an FoE write request for filename and streams data to the slave. FoE is available in Boot, Pre-Op, Safe-Op, and Op states (device-dependent); the caller is responsible for ensuring the device is in a suitable state. Called from non-RT (HTTP handler) threads; serialized with other control-plane operations via the driver's socket mutex.

Parameters
slavePosition1-based slave position on the bus.
filenameFoE filename as recognised by the slave firmware.
dataFile bytes to write.
Returns
Void on success, or a FoeError (see readFile on why this one is structured).

Implements mm::comm::FieldbusDriver.

◆ writeRegister()

std::expected< void, std::string > mm::comm::spoe::SpoeFieldbusDriver::writeRegister ( uint16_t  slavePosition,
uint16_t  address,
std::span< const uint8_t >  data 
)
overridevirtual

Writes bytes to an ESC register via a Configured-Address Write (FPWR) datagram.

data.size() bytes are written to register address of the slave at slavePosition. Called from HTTP handler threads; serialised with other control-plane operations via the socket mutex, and runs concurrently with the lock-free exchangeProcessData.

Parameters
slavePosition1-based slave position on the bus.
addressESC register address.
dataBytes to write.
Returns
Void on success, or an error string if no slave responded.

Implements mm::comm::FieldbusDriver.

◆ writeSdo()

std::expected< void, std::string > mm::comm::spoe::SpoeFieldbusDriver::writeSdo ( uint16_t  slavePosition,
uint16_t  index,
uint8_t  subindex,
std::span< const uint8_t >  data 
)
overridevirtual

Writes an object dictionary entry to a slave (CoE SDO download).

Performs a mailbox SDO download of data to (index, subindex). The slave must be in PRE-OP, SAFE-OP, or OP (mailbox communication active). Called from non-RT (HTTP handler) threads; serialized with other control-plane operations via the driver's socket mutex, and runs concurrently with the lock-free exchangeProcessData (never blocks the RT cycle).

Parameters
slavePosition1-based slave position on the bus.
indexCoE object index.
subindexCoE object subindex.
dataBytes to write; size must match the object's length.
Returns
Void on success, or an error string if the mailbox transfer fails.

Implements mm::comm::FieldbusDriver.


The documentation for this class was generated from the following files: