AVModbus.PDU (avmodbus v0.1.0)

Copy Markdown View Source

transport-independent な Modbus request / response codec です。

request は tuple で表現し、同じ protocol core を client / server と RTU / ASCII で共有します。

Summary

Functions

request を serial-line broadcast unit 0 に送信できるか返します。

server 向け request PDU を decode / validate します。

response PDU を request と照合して decode します。

request function code に対する Modbus exception response を encode します。

server handler result を response PDU に encode します。

partial response から expected PDU length を返します。

Types

address()

@type address() :: 0..65535

exception()

@type exception() ::
  :illegal_function
  | :illegal_data_address
  | :illegal_data_value
  | :server_device_failure
  | :acknowledge
  | :server_device_busy
  | :memory_parity_error
  | :gateway_path_unavailable
  | :gateway_target_device_failed_to_respond
  | byte()

request()

@type request() ::
  {:read_coils, address(), pos_integer()}
  | {:read_discrete_inputs, address(), pos_integer()}
  | {:read_holding_registers, address(), pos_integer()}
  | {:read_input_registers, address(), pos_integer()}
  | {:write_single_coil, address(), boolean()}
  | {:write_single_register, address(), word()}
  | {:write_multiple_coils, address(), [boolean()]}
  | {:write_multiple_registers, address(), [word()]}
  | {:mask_write_register, address(), word(), word()}
  | {:read_write_multiple_registers, address(), pos_integer(), address(),
     [word()]}
  | :read_exception_status
  | {:diagnostics, word(), [word()]}
  | :get_comm_event_counter
  | :get_comm_event_log
  | :report_server_id
  | {:read_file_record, [{1..65535, 0..9999, pos_integer()}]}
  | {:write_file_record, [{1..65535, 0..9999, [word()]}]}
  | {:read_fifo_queue, address()}
  | {:read_device_identification, :basic | :regular | :extended | :individual,
     byte()}
  | {:encapsulated_interface_transport, byte(), binary()}
  | {:custom, 1..127, binary()}

result()

@type result() :: :ok | {:ok, term()} | {:error, {:exception, exception()}}

word()

@type word() :: 0..65535

Functions

broadcast_request?(arg1)

@spec broadcast_request?(request()) :: boolean()

request を serial-line broadcast unit 0 に送信できるか返します。

server は unit 0 に response を返さないため、read component を含む request は broadcast できません。

decode_request(arg1)

@spec decode_request(binary()) :: {:ok, request()} | {:error, exception()}

server 向け request PDU を decode / validate します。

defined function で shape が不正な request は wire に返すべき Modbus exception を返します。 undefined public function code は custom request として保持します。

decode_response(request, pdu)

@spec decode_response(request(), binary()) :: {:ok, term()} | :ok | {:error, term()}

response PDU を request と照合して decode します。

encode_exception(function, exception)

@spec encode_exception(byte(), exception()) :: {:ok, binary()} | {:error, term()}

request function code に対する Modbus exception response を encode します。

encode_request(arg1)

@spec encode_request(request()) :: {:ok, binary()} | {:error, term()}

encode_response(request, arg2)

@spec encode_response(request(), result()) :: {:ok, binary()} | {:error, term()}

server handler result を response PDU に encode します。

returned value count や write echo を request と照合し、invalid handler result は wire に出しません。

function(arg1)

@spec function(request()) :: {:ok, 1..127} | {:error, :unsupported_request}

response_length(request, partial_pdu)

@spec response_length(request(), binary()) ::
  {:ok, pos_integer()} | :more | :unknown | :invalid

partial response から expected PDU length を返します。

RTU stream parser は sub-millisecond の inter-frame silent interval scheduling に依存せず frame boundary を判定できます。