Skip to main content
Version: 1.1.1

ecdev::CiA402DriveProfile

CiA 402 (CANopen-over-EtherCAT) servo-drive profile. More...

#include <cia402_drive_profile.hpp>

Inherits from ecdev::IDeviceProfile, ecdev::IMotionProfile, IDeviceLifecycle

Public Classes

Name
structConfig
Per-instance configuration for a [CiA402DriveProfile](/lxmaster/api/classes/CiA402DriveProfile).

Public Types

Name
using DriveOpModeOpMode
Cyclic operation mode this profile drives.

Public Functions

Name
virtual voidwriteOutputs(ProcessImage & image, std::uint64_t cycle_count) override
Write output PDO values for this cycle.
virtual std::int32_ttargetPosition() const override
Last target position commanded to the drive (encoder counts).
virtual std::uint16_tstatusword() const override
Raw DS402 statusword (CiA402 0x6041).
virtual voidsetTargetVelocity(std::int32_t counts_per_sec) override
CSV target velocity in counts/s.
virtual voidsetTargetTorque(std::int32_t per_mille_rated) override
CST target torque in per-mille of rated torque.
virtual voidsetTargetPosition(std::int32_t counts) override
Command a CSP target position.
virtual voidsetOperatingMode(DriveOpMode mode) override
Choose the operating mode.
virtual voidsetAutoFaultRecover(bool enable) override
Set the CiA402 auto fault-reset/recover behaviour.
boolrequiresMotionShutdown() const override
boolrequiresAlShutdown() const override
virtual voidrequestFaultReset() override
One-shot fault-reset edge (acted on only while the drive reports Fault).
virtual voidrequestEnable() override
Request the drive walk to Operation Enabled (cancels a prior disable request).
virtual voidrequestDisable() override
Request the drive walk back to a de-energised resting state.
boolreadyForShutdown() const override
boolreadyForAlShutdown() const override
virtual voidreadInputs(const ProcessImage & image, bool wkc_valid, bool operational) override
Read input PDO values captured this cycle.
virtual const char *profileName() const override
Stable identifier for diagnostics (e.g.
virtual voidprimeOutputs(ProcessImage & image) override
Prime output PDO bytes to safe values immediately before the bus enters SAFE_OP (outputs start being transmitted).
voidprepareShutdown() override
virtual std::stringprepareSafeOp(ISlaveServices & svc, ProcessImage & image) override
Final configuration step before OPERATIONAL: the slave is in SAFE_OP and the PDO IOmap is live but outputs are not yet driven.
virtual std::int32_tmodeDisplay() const override
Drive's modes-of-operation display (CiA402 0x6061; 8=CSP, 9=CSV, 10=CST).
std::uint16_tlastStatusWordForDiagnostics() const override
virtual boolisOperationEnabled() const override
True when the DS402 state machine is in the Operation Enabled state.
virtual boolisFault() const override
True when the drive reports a latched fault (DS402 Fault state, statusword bit 3).
boolhasLeftOperationEnabled() const override
boolcyclicStopRequested() const override
std::stringcyclicStopReason() const override
virtual std::stringconfigurePreOp(ISlaveServices & svc, ProcessImage & image) override
Perform CoE / SDO configuration while the slave is in PRE_OP (bus not cycling).
virtual voidcaptureExitDiagnostics(ISlaveServices & svc) override
End-of-run hook called after the RT thread has joined; safe to perform SDO reads.
virtual IMotionProfile *asMotion() override
Query whether this profile drives a motion (servo) axis.
virtual std::int32_tactualVelocity() const override
Actual velocity reported by the drive (encoder counts/s, CiA402 0x606C).
virtual std::int32_tactualTorque() const override
Drive's reported actual torque (CiA402 0x6077, per-mille of rated).
virtual std::int32_tactualPosition() const override
Actual position reported by the drive (encoder counts, CiA402 0x6064).
CiA402DriveProfile(Config cfg)

Additional inherited members

Public Functions inherited from ecdev::IDeviceProfile

Name
~IDeviceProfile() override =default
virtual voidresolveTopology(const ProcessImage & image)
Resolve the static channel/PDO topology from the ENI-derived process image.
virtual IIoProfile *asIo()
Query whether this profile exposes digital/analog I/O channels.
virtual IEncoderProfile *asEncoder()
Query whether this profile exposes position/velocity encoder readings.

Public Functions inherited from ecdev::IMotionProfile

Name
virtual~IMotionProfile() =default

Detailed Description

class ecdev::CiA402DriveProfile;

CiA 402 (CANopen-over-EtherCAT) servo-drive profile.

Plugs onto a [GenericEniDevice] and provides the drive-class behaviour that used to live in CiA402Device:

  • PreOP validation + operating-mode setup: it confirms the cyclic objects it drives (controlword/statusword/target+actual position) are present in the ENI PDO mapping and fails otherwise. It makes NO configuration assumptions ("ENI is law") with ONE deliberate exception: the operating mode 0x6060, which is application/axis intent rather than bus wiring, so the profile writes it (from [Config::op_mode](/lxmaster/api/classes/CiA402DriveProfile-Config#variable-op-mode)) and reads it back to confirm at PreOP. SM sync-mode (0x1C32/0x1C33), the 0x60C2 interpolation time, and any vendor tuning still arrive as ENI CoE InitCmds replayed by [GenericEniDevice]; DC SYNC0 is activated by the master from the ENI ; the generic 0x1C1x/0x16xx PDO assignment is done by [GenericEniDevice].
  • DS402 controlword state machine ([CiA402Fsm]) on the RT cyclic path.
  • A lock-free snapshot so application threads (through the Axis facade / IMotionProfile) read position/statusword and command targets without touching PDO bytes.

It implements [IMotionProfile](/lxmaster/api/classes/IMotionProfile), which is the only thing the Axis facade depends on, so the controlword/statusword stay hidden inside this profile.

Extending it: this class is intentionally NOT final. To add vendor/extra PDO variables (objects the ENI maps beyond the standard CiA402 set), subclass it, override the relevant lifecycle method (typically readInputs, and optionally resolveTopology/configurePreOp), and CHAIN to the base (CiA402DriveProfile::readInputs(...)) before doing your own work. Resolve your extra objects with ProcessImage::resolve(index, sub) and publish them to application threads through your own lock-free state (atomics). Axis keeps working unchanged because the subclass inherits this profile's [asMotion()](/lxmaster/api/classes/CiA402DriveProfile#function-asmotion). This mirrors the [GenericIoProfile](/lxmaster/api/classes/GenericIoProfile) -> [CiA401IoProfile](/lxmaster/api/classes/CiA401IoProfile) precedent. The application reaches the subclass via ecfacade::DeviceFacade::deviceProfile().

Public Types Documentation

using OpMode

using ecdev::CiA402DriveProfile::OpMode = DriveOpMode;

Cyclic operation mode this profile drives.

CSP commands target position (0x607A); CSV commands target velocity (0x60FF); CST commands target torque (0x6071, INT16). The ENI/ESI must map the matching object and set the drive's modes-of-operation (0x6060) accordingly – the profile only validates the mapping. The per-mode cyclic facts live in the OpModeTraits table in cia402_drive_profile.cpp.

Public Functions Documentation

function writeOutputs

virtual void writeOutputs(
ProcessImage & image,
std::uint64_t cycle_count
) override

Write output PDO values for this cycle.

Parameters:

  • image Live PDO byte map for this slave's output objects; write target values into it.
  • cycle_count Total RT cycles executed since start() (monotonically increasing).

Reimplements: ecdev::IDeviceProfile::writeOutputs

Called on the RT cyclic thread every cycle while OPERATIONAL.

function targetPosition

inline virtual std::int32_t targetPosition() const override

Last target position commanded to the drive (encoder counts).

Reimplements: ecdev::IMotionProfile::targetPosition

RT-safe.

function statusword

inline virtual std::uint16_t statusword() const override

Raw DS402 statusword (CiA402 0x6041).

Reimplements: ecdev::IMotionProfile::statusword

RT-safe.

function setTargetVelocity

inline virtual void setTargetVelocity(
std::int32_t counts_per_sec
) override

CSV target velocity in counts/s.

Reimplements: ecdev::IMotionProfile::setTargetVelocity

Has its own command slot (0x60FF) so a CSP position target and a CSV velocity target can coexist for bumpless live mode switching; only the object matching the active op-mode is honoured by the drive.

function setTargetTorque

inline virtual void setTargetTorque(
std::int32_t per_mille_rated
) override

CST target torque in per-mille of rated torque.

Reimplements: ecdev::IMotionProfile::setTargetTorque

Has its own command slot (0x6071) so it can coexist with position/velocity targets for bumpless live mode switching; only the object matching the active op-mode is honoured by the drive.

function setTargetPosition

inline virtual void setTargetPosition(
std::int32_t counts
) override

Command a CSP target position.

Parameters:

  • counts Target position in encoder counts (CiA402 0x607A).

Reimplements: ecdev::IMotionProfile::setTargetPosition

Implicitly leaves "hold actual" mode.

function setOperatingMode

inline virtual void setOperatingMode(
DriveOpMode mode
) override

Choose the operating mode.

Reimplements: ecdev::IMotionProfile::setOperatingMode

Pre-start this seeds the initial mode; while running it also switches live – when the ENI maps 0x6060 into the RxPDO the profile writes out_.desired_mode every cycle, so CSP/CSV/CST switch while OPERATIONAL. The atomic store is RT-safe; cfg_.op_mode (used only by the legacy no-0x6060 path, which is fixed at PRE_OP) is not read cyclically in PDO mode.

function setAutoFaultRecover

inline virtual void setAutoFaultRecover(
bool enable
) override

Set the CiA402 auto fault-reset/recover behaviour.

Parameters:

  • enable true to automatically reset and re-enable after a mid-run fault; false (default) to treat faults as terminal stops.

Reimplements: ecdev::IMotionProfile::setAutoFaultRecover

Call between prepare() and start(); not RT-safe.

function requiresMotionShutdown

inline bool requiresMotionShutdown() const override

function requiresAlShutdown

inline bool requiresAlShutdown() const override

function requestFaultReset

inline virtual void requestFaultReset() override

One-shot fault-reset edge (acted on only while the drive reports Fault).

Reimplements: ecdev::IMotionProfile::requestFaultReset

function requestEnable

inline virtual void requestEnable() override

Request the drive walk to Operation Enabled (cancels a prior disable request).

Reimplements: ecdev::IMotionProfile::requestEnable

function requestDisable

inline virtual void requestDisable() override

Request the drive walk back to a de-energised resting state.

Reimplements: ecdev::IMotionProfile::requestDisable

function readyForShutdown

inline bool readyForShutdown() const override

function readyForAlShutdown

bool readyForAlShutdown() const override

function readInputs

virtual void readInputs(
const ProcessImage & image,
bool wkc_valid,
bool operational
) override

Read input PDO values captured this cycle.

Parameters:

  • image Live PDO byte map for this slave's input objects.
  • wkc_valid False when the work counter dropped this cycle — the slave may not have responded and input data may be stale.
  • operational False during the OP-entry cooldown cycles after the master enters OPERATIONAL. Motion commands should be suppressed until this is true.

Reimplements: ecdev::IDeviceProfile::readInputs

Called on the RT cyclic thread every cycle while OPERATIONAL. Profiles should guard state updates on wkc_valid and operational to avoid acting on stale data.

function profileName

inline virtual const char * profileName() const override

Stable identifier for diagnostics (e.g.

Return: A null-terminated string literal naming this profile class. Must be stable for the lifetime of the profile object (a string literal in practice).

Reimplements: ecdev::IDeviceProfile::profileName

"CiA402-drive").

function primeOutputs

virtual void primeOutputs(
ProcessImage & image
) override

Prime output PDO bytes to safe values immediately before the bus enters SAFE_OP (outputs start being transmitted).

Parameters:

  • image Live PDO byte map; write safe initial output values into it.

Reimplements: ecdev::IDeviceProfile::primeOutputs

For example, a CiA402 profile writes a Shutdown controlword here so the drive sees a valid initial state before the RT cycle starts. Called on the bring-up thread.

function prepareShutdown

inline void prepareShutdown() override

function prepareSafeOp

virtual std::string prepareSafeOp(
ISlaveServices & svc,
ProcessImage & image
) override

Final configuration step before OPERATIONAL: the slave is in SAFE_OP and the PDO IOmap is live but outputs are not yet driven.

Parameters:

  • svc Slave services handle for SDO reads/writes.
  • image Live process image (IOmap is mapped but outputs are not yet driven).

Return: Empty string on success; a non-empty human-readable reason string aborts bring-up.

Reimplements: ecdev::IDeviceProfile::prepareSafeOp

Use this for last-moment readiness checks or any SDO writes that must happen after the IOmap is mapped. Called on the bring-up thread; never on the RT thread.

function modeDisplay

inline virtual std::int32_t modeDisplay() const override

Drive's modes-of-operation display (CiA402 0x6061; 8=CSP, 9=CSV, 10=CST).

Reimplements: ecdev::IMotionProfile::modeDisplay

0 if unmapped.

function lastStatusWordForDiagnostics

inline std::uint16_t lastStatusWordForDiagnostics() const override

function isOperationEnabled

inline virtual bool isOperationEnabled() const override

True when the DS402 state machine is in the Operation Enabled state.

Reimplements: ecdev::IMotionProfile::isOperationEnabled

RT-safe.

function isFault

inline virtual bool isFault() const override

True when the drive reports a latched fault (DS402 Fault state, statusword bit 3).

Reimplements: ecdev::IMotionProfile::isFault

RT-safe.

function hasLeftOperationEnabled

bool hasLeftOperationEnabled() const override

function cyclicStopRequested

inline bool cyclicStopRequested() const override

function cyclicStopReason

std::string cyclicStopReason() const override

function configurePreOp

virtual std::string configurePreOp(
ISlaveServices & svc,
ProcessImage & image
) override

Perform CoE / SDO configuration while the slave is in PRE_OP (bus not cycling).

Parameters:

  • svc Slave services handle for SDO reads/writes and register access.
  • image Process image for this slave; resolve PDO entry handles here for later cyclic use.

Return: Empty string on success; a non-empty human-readable reason string aborts bring-up.

Reimplements: ecdev::IDeviceProfile::configurePreOp

Resolve process-image handles (PDO objects) for use in the cyclic path. Called on the bring-up thread; never on the RT thread.

function captureExitDiagnostics

virtual void captureExitDiagnostics(
ISlaveServices & svc
) override

End-of-run hook called after the RT thread has joined; safe to perform SDO reads.

Parameters:

  • svc Slave services handle available for post-run SDO reads (e.g. fault codes).

Reimplements: ecdev::IDeviceProfile::captureExitDiagnostics

function asMotion

inline virtual IMotionProfile * asMotion() override

Query whether this profile drives a motion (servo) axis.

Return: A non-null IMotionProfile* if so (used to back an Axis facade handle), or null if this profile does not implement the motion contract.

Reimplements: ecdev::IDeviceProfile::asMotion

function actualVelocity

inline virtual std::int32_t actualVelocity() const override

Actual velocity reported by the drive (encoder counts/s, CiA402 0x606C).

Reimplements: ecdev::IMotionProfile::actualVelocity

Returns 0 if the drive does not map this object. RT-safe.

function actualTorque

inline virtual std::int32_t actualTorque() const override

Drive's reported actual torque (CiA402 0x6077, per-mille of rated).

Reimplements: ecdev::IMotionProfile::actualTorque

0 if the profile does not map it. Diagnostic only.

function actualPosition

inline virtual std::int32_t actualPosition() const override

Actual position reported by the drive (encoder counts, CiA402 0x6064).

Reimplements: ecdev::IMotionProfile::actualPosition

RT-safe.

function CiA402DriveProfile

explicit CiA402DriveProfile(
Config cfg
)

Updated on 2026-07-13 at 20:44:41 +0000