Public API for the EtherCAT bus scheduler.
EtherCAT.Bus is the single serialization point for all EtherCAT frame I/O.
Callers build EtherCAT.Bus.Transaction values and submit them as either:
transaction/2— reliable work, eligible for batching with other reliable transactionstransaction/3— realtime work with a staleness budget; stale work is discarded
Realtime and reliable transactions are strictly separated: realtime always has priority, and realtime transactions never share a frame with reliable transactions.
In this API, reliable means non-expiring background work: the bus keeps it
queued until it can be sent or the link fails. It does not mean the transport
can never time out.
realtime means deadline-sensitive work: it gets priority and is dropped
once it has become too old to be useful.
The public API is singleton-first: info/0, transaction/1,
set_frame_timeout/1, settle/0, and quiesce/1 target the registered
EtherCAT.Bus process by default. Explicit server-ref variants remain
available for internal callers and tests.
Summary
Functions
Return low-level bus runtime information, including queue and in-flight state.
Drain the bus, wait through a short quiet window, then drain once more.
Update the frame response timeout in milliseconds.
Wait until the bus is idle, then drain any buffered receive traffic.
Execute a reliable transaction.
Execute a realtime transaction with a staleness budget in microseconds.
Types
@type call_error() :: {:error, :not_started | :timeout | {:server_exit, term()}}
@type server() :: :gen_statem.server_ref()
Functions
@spec info() :: {:ok, map()} | call_error()
Return low-level bus runtime information, including queue and in-flight state.
@spec info(server()) :: {:ok, map()} | call_error()
@spec quiesce(non_neg_integer()) :: :ok | call_error()
Drain the bus, wait through a short quiet window, then drain once more.
This is useful when late transport traffic can still land just after the bus first reports idle, for example after startup/configuration exchanges.
@spec quiesce(server(), non_neg_integer()) :: :ok | call_error()
@spec set_frame_timeout(pos_integer()) :: :ok | call_error() | {:error, term()}
Update the frame response timeout in milliseconds.
@spec set_frame_timeout(server(), pos_integer()) :: :ok | call_error() | {:error, term()}
@spec settle() :: :ok | call_error()
Wait until the bus is idle, then drain any buffered receive traffic.
This is useful after startup/configuration phases where callers want the next transaction to begin from a quiescent transport state.
@spec settle(server()) :: :ok | call_error()
@spec start_link(keyword()) :: :gen_statem.start_ret()
@spec transaction(EtherCAT.Bus.Transaction.t()) :: {:ok, [EtherCAT.Bus.Result.t()]} | call_error() | {:error, term()}
Execute a reliable transaction.
Reliable work may be batched with other reliable transactions when the bus is already busy, but an idle bus sends immediately.
Reliable here means non-expiring background work. The bus will not discard
it due to age while it is queued, but the transaction can still fail due to
timeouts or link loss.
@spec transaction(server(), EtherCAT.Bus.Transaction.t()) :: {:ok, [EtherCAT.Bus.Result.t()]} | call_error() | {:error, term()}
@spec transaction(EtherCAT.Bus.Transaction.t(), pos_integer()) :: {:ok, [EtherCAT.Bus.Result.t()]} | call_error() | {:error, term()}
Execute a realtime transaction with a staleness budget in microseconds.
Realtime work is discarded if it has become stale by the time the bus is ready to dispatch it. Realtime transactions are never mixed with reliable traffic.
stale_after_us is a max queued age relative to submission time, not an
absolute wall-clock deadline.
@spec transaction(server(), EtherCAT.Bus.Transaction.t(), pos_integer()) :: {:ok, [EtherCAT.Bus.Result.t()]} | call_error() | {:error, term()}