EtherCAT.Domain (ethercat v0.4.2)

Copy Markdown View Source

Cyclic process image for one logical EtherCAT domain.

One domain runs per configured domain ID. Slaves register their PDO layout during PREOP, then the domain runs a self-timed LRW exchange each cycle.

EtherCAT.Domain is the public boundary for domain lifecycle and process image access. The domain process owns the open, cycling, and stopped states. The hot-path image API is intentionally separate: write/3, read/2, and sample/2 access the ETS-backed process image directly instead of going through synchronous state-machine calls.

States

  • :open - accepting PDO registrations, not yet cycling
  • :cycling - self-timed LRW tick active
  • :stopped - cycling halted by manual stop or miss threshold

State transitions

stateDiagram-v2
    [*] --> open
    open --> cycling: start_cycling and layout preparation succeed
    cycling --> stopped: stop_cycling or miss threshold is reached
    stopped --> cycling: start_cycling

Within :cycling, cycle health is tracked separately as runtime data:

  • :healthy - the latest LRW cycle was valid
  • {:invalid, reason} - the latest LRW cycle had a transport miss or unusable reply

Timeout-class misses remain :timeout in domain health even when the bus dropped a stale realtime cycle request as :expired; the finer queue-expiry distinction stays in bus telemetry.

Summary

Functions

Return a detailed runtime snapshot for the domain.

Read the current process-image value for one PDO key.

Register one PDO entry in the domain layout while the domain is open.

Read the current process-image value plus freshness metadata for one PDO key.

Start cyclic LRW exchange for the domain.

Return a compact runtime statistics snapshot for the domain.

Stop cyclic LRW exchange for the domain.

Update the live cycle period for the running domain.

Stage an output binary into the domain process image.

Types

domain_id()

@type domain_id() :: atom()

freshness_info()

@type freshness_info() :: %{
  state: :not_ready | :fresh | :stale,
  refreshed_at_us: integer() | nil,
  age_us: non_neg_integer() | nil,
  stale_after_us: pos_integer()
}

pdo_key()

@type pdo_key() :: {slave_name :: atom(), pdo_name :: atom()}

sample_info()

@type sample_info() :: %{
  value: binary(),
  updated_at_us: integer() | nil,
  changed_at_us: integer() | nil,
  freshness: freshness_info() | nil
}

Functions

info(domain_id)

@spec info(domain_id()) ::
  {:ok, map()} | {:error, :not_found | :timeout | {:server_exit, term()}}

Return a detailed runtime snapshot for the domain.

read(domain_id, key)

@spec read(domain_id(), pdo_key()) ::
  {:ok, binary()} | {:error, :not_found | :not_ready}

Read the current process-image value for one PDO key.

Returns {:error, :not_ready} until an input has been populated or an output has been staged.

register_pdo(domain_id, key, size, direction)

@spec register_pdo(domain_id(), pdo_key(), pos_integer(), :input | :output) ::
  {:ok, non_neg_integer()} | {:error, term()}

Register one PDO entry in the domain layout while the domain is open.

Returns the assigned logical byte offset relative to the domain base.

sample(domain_id, key)

@spec sample(domain_id(), pdo_key()) ::
  {:ok, sample_info()} | {:error, :not_found | :not_ready}

Read the current process-image value plus freshness metadata for one PDO key.

start_cycling(domain_id)

@spec start_cycling(domain_id()) :: :ok | {:error, term()}

Start cyclic LRW exchange for the domain.

stats(domain_id)

@spec stats(domain_id()) ::
  {:ok, map()} | {:error, :not_found | :timeout | {:server_exit, term()}}

Return a compact runtime statistics snapshot for the domain.

stop_cycling(domain_id)

@spec stop_cycling(domain_id()) ::
  :ok | {:error, :not_found | :timeout | {:server_exit, term()}}

Stop cyclic LRW exchange for the domain.

The process image remains available after the domain stops.

update_cycle_time(domain_id, cycle_time_us)

@spec update_cycle_time(domain_id(), pos_integer()) :: :ok | {:error, term()}

Update the live cycle period for the running domain.

write(domain_id, key, binary)

@spec write(domain_id(), pdo_key(), binary()) :: :ok | {:error, :not_found}

Stage an output binary into the domain process image.

This is a direct ETS-backed hot-path write and does not go through the domain process mailbox.