EtherCAT.Bus.Link (ethercat v0.5.0)

Copy Markdown View Source

Shared scheduling helpers for bus link gen_statem implementations.

Both Link.Single and Link.Redundant store :realtime and :reliable queues in their gen_statem data and call these functions for queue management, batching, index stamping, and caller replies.

Each link implementation owns dispatch and send-result handling.

Summary

Functions

Enqueue a submission into the appropriate queue based on its staleness budget.

Expire stale realtime submissions, replying {:error, :expired} to each.

Flush all queued submissions, replying with the given error to each caller.

Match response datagrams against the awaiting list and reply to all callers.

Maximum datagram payload per frame.

Take the next dispatch unit from the queues.

Build the awaiting list and stamped datagrams for a realtime submission.

Build the awaiting list and stamped datagrams for a reliable batch.

Queue depth for a given class.

Reply to all awaiting callers in an exchange with the given result.

Reply to settle callers.

Reply to a list of submissions with the given result.

Stamp datagrams with sequential byte-wrapping indices.

Classify a submission as :realtime or :reliable.

Functions

enqueue(data, submission)

@spec enqueue(map(), EtherCAT.Bus.Link.Submission.t()) :: map()

Enqueue a submission into the appropriate queue based on its staleness budget.

Realtime submissions (those with a stale_after_us) go into the realtime queue. All others go into the reliable queue.

expire_stale_realtime(data, link_name)

@spec expire_stale_realtime(map(), String.t()) :: map()

Expire stale realtime submissions, replying {:error, :expired} to each.

Returns the updated data with expired submissions removed from the queue.

flush_all(data, reply)

@spec flush_all(map(), term()) :: map()

Flush all queued submissions, replying with the given error to each caller.

Returns the updated data with empty queues.

match_and_reply(response_datagrams, awaiting)

@spec match_and_reply([EtherCAT.Bus.Datagram.t()], [{:gen_statem.from(), [byte()]}]) ::
  :ok | :mismatch

Match response datagrams against the awaiting list and reply to all callers.

Returns :ok if all expected datagrams are present, :mismatch otherwise.

max_datagram_bytes()

@spec max_datagram_bytes() :: pos_integer()

Maximum datagram payload per frame.

next_dispatch(data)

@spec next_dispatch(map()) ::
  {:realtime, EtherCAT.Bus.Link.Submission.t(), map()}
  | {:reliable, [EtherCAT.Bus.Link.Submission.t()], map()}
  | :empty

Take the next dispatch unit from the queues.

Realtime submissions have priority and are dispatched one at a time. Reliable submissions are batched into a single frame up to 1400 bytes.

Returns:

  • {:realtime, submission, updated_data} — one realtime submission
  • {:reliable, batch, updated_data} — list of reliable submissions
  • :empty — nothing to dispatch

prepare_realtime(submission, idx)

Build the awaiting list and stamped datagrams for a realtime submission.

prepare_reliable(batch, idx)

Build the awaiting list and stamped datagrams for a reliable batch.

queue_depth(data, atom)

@spec queue_depth(map(), :realtime | :reliable) :: non_neg_integer()

Queue depth for a given class.

reply_awaiting(awaiting, reply)

@spec reply_awaiting([{:gen_statem.from(), [byte()]}], term()) :: :ok

Reply to all awaiting callers in an exchange with the given result.

reply_settle_callers(callers, reply)

@spec reply_settle_callers([term()], term()) :: :ok

Reply to settle callers.

reply_submissions(submissions, reply)

@spec reply_submissions([EtherCAT.Bus.Link.Submission.t()], term()) :: :ok

Reply to a list of submissions with the given result.

stamp_indices(datagrams, start_idx)

Stamp datagrams with sequential byte-wrapping indices.

submission_class(submission)

@spec submission_class(EtherCAT.Bus.Link.Submission.t()) :: :realtime | :reliable

Classify a submission as :realtime or :reliable.