This page covers the lower-level EtherCAT and commissioning helpers that are available when the normal addSlave.cmd and applyComponent.cmd path is not enough.
Use it when you need:
For the common Max wait time 30 second(s) startup message, see
EtherCAT startup timeout
before changing lower-level EtherCAT settings.
After the EtherCAT master scan completes, ecmc can check selected slaves for a likely upstream cable connected to OUT instead of IN. The check only produces a retained startup warning; it does not interlock motion or modify EtherCAT configuration.
The check is disabled by default and enabled per slave by its hardware snippet, after the slave object has been created. The standard EK1100, EK1101, EKM1101, EK1501-0010, Beckhoff EP/EPP, Technosoft iPOS, Nanotec N6, SmarAct MCS2, Festo CMMT-ST, Kuhnke FIODrive, and MonoDAQ E-gMeter snippets enable it. Other hardware with a verified port layout can opt in the same way:
ecmcConfigOrDie "Cfg.EcSetSlavePortWiringCheckEnable(${ECMC_EC_SLAVE_NUM},1)"
Passing 0 disables the check for that slave. The command is configuration-only
and must be issued before runtime. Wiring warnings are retained in the
configuration log buffer and are included in motion diagnostic dumps at
diagnostic levels 1 and 2.
The global master switch is enabled by default. Disable every port-wiring check without changing the per-slave selections with:
ecmcConfigOrDie "Cfg.EcSetPortWiringCheckEnable(0)"
Setting it to 1 again restores the checks selected by the hardware snippets.
The normal setup uses one EtherCAT domain.
If you need a separate execution rate or execution offset for a set of entries, create another domain:
${SCRIPTEXEC} ${ecmccfg_DIR}addDomain.cmd "EXE_RATE=2,EXE_OFFSET=0,ALLOW_OFFLINE=0"
Important behavior:
addDomain.cmd belong to the new domainEXE_RATE is in realtime cyclesEXE_OFFSET is also in realtime cyclesALLOW_OFFLINE=1 relaxes the domain state requirement, but can affect the rest of the bus and the DC behaviorUse extra domains only when you have a clear reason. For most systems, the default single-domain setup is simpler and safer.
Simulation entries are local ecmc memory-backed EtherCAT entries. They are useful when an axis object needs an EtherCAT-style link, but the value is produced locally rather than by a real slave.
Two entries, ZERO and ONE, are created by default on the internal simulation slave. Additional entries can be added with Cfg.EcAddSimEntry(...).
Global simulation entries:
ecmcConfigOrDie "Cfg.EcAddSimEntry(SIM_LIMIT,U32,0)"
ecmcConfigOrDie "Cfg.LinkEcEntryToObject(SIM_LIMIT,ax1.mon.lowlim)"
ecmcConfigOrDie "Cfg.WriteEcEntryEcPath(SIM_LIMIT,1)"
The global form stores the entry on the internal simulation slave (-1), but the entry can be addressed by name without an ec<master>.s<slave>. prefix. This is the preferred form for local dummy values and PLC-produced values.
Slave-scoped simulation entries are still supported:
ecmcConfigOrDie "Cfg.EcAddSimEntry(5,SIM_LIMIT,U32,0)"
ecmcConfigOrDie "Cfg.LinkEcEntryToObject(ec0.s5.SIM_LIMIT,ax1.mon.lowlim)"
Use the scoped form only when it is helpful to keep the simulated value visually associated with a specific slave in configuration.
Notes:
B1, U16, S32, U64, F32, and F64Cfg.LinkEcEntryToObject(...)ReadEcEntryIDString(<name>) and Cfg.WriteEcEntryEcPath(<name>,<value>)Cfg.EcAddEntryCyclicWrite(...) copies the value of one EtherCAT entry to
another on every realtime cycle. This can be used to route an input or a local
simulation value directly to an EtherCAT output without adding a PLC
expression.
The argument order is destination first, then source:
Cfg.EcAddEntryCyclicWrite(<to-entry-path>,<from-entry-path>)
Cfg.EcAddEntryCyclicWrite(<to-entry-path>,<from-entry-path>,<force>)
Both entries must already exist when the command is issued. The destination must be an EtherCAT output entry or a simulation entry.
Example: copy a digital input on slave 1 to a digital output on slave 6:
ecmcConfigOrDie "Cfg.EcAddEntryCyclicWrite(ec0.s6.binaryOutput01,ec0.s1.binaryInput01)"
force behaviorBy default, the source and destination entries must have identical datatypes:
ecmcConfigOrDie "Cfg.EcAddEntryCyclicWrite(ec0.s6.outputValue,ec0.s1.inputValue)"
Set the optional force argument to a nonzero value to bypass datatype
matching:
ecmcConfigOrDie "Cfg.EcAddEntryCyclicWrite(ec0.s6.outputValue,ec0.s1.inputValue,1)"
In forced mode, ecmc performs a raw bit copy using the smaller bit width of the two entries. It does not perform numeric scaling or datatype conversion. Use this mode only when the raw binary representations are intentionally compatible.
A cyclic write updates its destination every realtime cycle. Do not configure another realtime object to write the same destination unless the resulting write ordering and ownership are explicitly understood.
Use this command during startup diagnostics to list all configured cyclic writes:
ecmcConfigOrDie "Cfg.EcReportEntryCyclicWrites()"
The report includes the source, destination, number of copied bits, and whether
force was enabled. ecmcGrepParam also annotates involved EtherCAT parameters
with r, w, or rw for source, destination, or both.
addEcDataItem.cmd exposes a value directly from already configured process-image data.
Think of it as a typed pointer into the process image.
Example:
${SCRIPTEXEC} ${ecmccfg_DIR}addEcDataItem.cmd \
"STRT_ENTRY_S_ID=5,STRT_ENTRY_NAME=statusWord01,OFFSET_BYTE=0,OFFSET_BITS=0,RW=2,DT=U16,NAME=rawStatus"
Use this when:
Key parameters:
STRT_ENTRY_S_ID: slave positionSTRT_ENTRY_NAME: start entry nameOFFSET_BYTE, OFFSET_BITS: offset from that start entryRW: 1 write, 2 readDT: data type such as B1, U16, S32, F32, F64NAME: runtime name of the created itemBy default, the wrapper also loads a matching EPICS record for the item.
Use addEcSdoRT.cmd when you need on-demand access to one EtherCAT SDO while the IOC is already running in realtime.
This is useful for:
addEcSdoRT.cmd wraps Cfg.EcAddSdoAsync(...).
addEcSdoRT.cmd creates one named asynchronous SDO object in ecmc and then loads EPICS records for it.
For a name like HW_ENABLE, the underlying asyn object path becomes:
ec<master>.s<slave>.sdo.HW_ENABLE
The script then creates these PVs:
...SDO-HW_ENABLE-Val...SDO-HW_ENABLE-RdCmd...SDO-HW_ENABLE-WrtCmd...SDO-HW_ENABLE-Bsy...SDO-HW_ENABLE-ErrIdIn practice:
Val holds the current value to write and the most recent readback valueRdCmd triggers an SDO readWrtCmd triggers an SDO writeBsy indicates that the SDO object is currently busyErrId exposes the most recent SDO error code${SCRIPTEXEC} ${ecmccfg_DIR}addEcSdoRT.cmd \
"SLAVE_ID=<slave>,INDEX=0x<index>,SUBINDEX=0x<sub>,DT=<type>,NAME=<name>"
Supported parameters:
SLAVE_ID: EtherCAT slave position. Optional, defaults to 0INDEX: SDO index, for example 0x8010SUBINDEX: SDO subindex, for example 0x07DT: data type string such as U8, S16, U32, S32, F32, F64NAME: logical object name used in both the asyn path and EPICS PV namesP_SCRIPT: optional naming-prefix script; defaults to ${ECMC_P_SCRIPT}${SCRIPTEXEC} ${ecmccfg_DIR}addEcSdoRT.cmd \
"SLAVE_ID=7,INDEX=0x8010,SUBINDEX=0x07,DT=U16,NAME=DRV_PARAM"
Typical usage from EPICS:
...SDO-DRV_PARAM-Val...SDO-DRV_PARAM-WrtCmd to write it...SDO-DRV_PARAM-RdCmd to refresh the readback...SDO-DRV_PARAM-Bsy and ...SDO-DRV_PARAM-ErrIdThe script chooses the value record template from DT:
F32 and F64 use the floating-point template and asynFloat64asynInt32That means:
aoaoVal is always the central EPICS value record, while RdCmd and WrtCmd control when the actual SDO transfer happensPrefer RT SDO objects when:
Do not use RT SDO objects when:
For startup-time writes, prefer normal SDO configuration with Cfg.EcAddSdo(...), Cfg.EcAddSdoDT(...), or the higher-level slave/component setup.
Use applySlaveDCconfig.cmd when a slave needs explicit distributed-clock configuration:
${SCRIPTEXEC} ${ecmccfg_DIR}applySlaveDCconfig.cmd \
"ASSIGN_ACTIVATE=0x0300,SYNC_0_CYCLE=1000000,SYNC_0_SHIFT=0"
Typical inputs:
ASSIGN_ACTIVATE: DC assign/activate word from the terminal XMLSYNC_0_CYCLE: sync period in nsSYNC_0_SHIFT: sync shift in nsSYNC_1_CYCLE: optional second sync period in nsUse this only when the slave actually needs explicit DC setup. Unnecessary DC customization can make commissioning harder.
Use slaveVerify.cmd during commissioning or in strict production setups to verify that the expected slave is actually present:
${SCRIPTEXEC} ${ecmccfg_DIR}slaveVerify.cmd "RESET=0,READ_FW=1"
The script can:
0x10110x100aThis is useful when:
Some EtherCAT slaves can be updated with Beckhoff firmware files (.efw) over
FoE, File over EtherCAT. Do this only during commissioning or maintenance, with
motion disabled and the affected hardware in a safe state.
Use the firmware file that exactly matches the terminal type and revision. Do
not interrupt power or the EtherCAT connection while foe_write is running.
The write can take a few minutes.
General procedure:
0x100A:0.BOOT..efw file with ethercat foe_write.INIT, then PREOP.0x100A:0 again and verify that the firmware version changed.Example for an EL7062 on master 0, slave position 23:
# Read current firmware version.
ethercat upload -m0 -p23 0x100A 0x0
# Confirm that slave position 23 is the expected terminal.
ethercat slaves | grep EL7062
# Enter BOOT mode.
ethercat states -m0 -p23 BOOT
ethercat slaves | grep EL7062
# Write firmware. This can take a few minutes.
ethercat foe_write -m0 -p23 /ioc/NeedfulThings/beckhoff_firmwares/EL7062-0000_REV0017_SW03.efw
# Return to INIT and then PREOP.
ethercat states -m0 -p23 INIT
ethercat slaves | grep EL7062
ethercat states -m0 -p23 PREOP
ethercat slaves | grep EL7062
# Read back firmware version.
ethercat upload -m0 -p23 0x100A 0x0
Typical firmware readback for this example changes from 02 before the update
to 03 after the update.
Use ignoreSlaves.cmd when the logical topology in the startup file must skip one or more bus positions:
${SCRIPTEXEC} ${ecmccfg_DIR}ignoreSlaves.cmd "COUNT=2"
This does not configure anything by itself. It only advances the slave-position counter used by later slave-related scripts.
Typical use:
For normal systems:
addSlave.cmdapplyComponent.cmd where possibleFor advanced systems:
addEcDataItem.cmd