Skip to main content

Pdu

Struct Pdu 

Source
pub struct Pdu { /* private fields */ }
Expand description

A Modbus protocol data unit: a function code followed by its data.

The PDU is the part of a frame that is the same on every transport. On RTU it sits between the unit address and the CRC; wrap one with to_adu to get a frame ready for the wire.

The constructors build the standard requests so callers state intent (“read three holding registers”) rather than packing bytes, encoding addresses and counts in the big-endian order Modbus uses. For a function code this crate does not name, raw carries arbitrary bytes through unchanged. The data is held in a fixed buffer, so a PDU needs no allocation.

§Examples

use pamoja_modbus::Pdu;

let pdu = Pdu::write_single_register(0x0001, 0x0003);
assert_eq!(pdu.as_bytes(), &[0x06, 0x00, 0x01, 0x00, 0x03]);

Implementations§

Source§

impl Pdu

Source

pub const MAX_LEN: usize = 253

The largest a Modbus RTU PDU may be, in bytes: the 256-byte ADU less the one-byte address and the two-byte CRC.

Source

pub const MAX_WRITE_REGISTERS: usize = 123

The most registers a single write-multiple-registers request may carry.

Source

pub const MAX_WRITE_COILS: usize = 1968

The most coils a single write-multiple-coils request may carry.

Source

pub fn read_coils(start: u16, count: u16) -> Pdu

Builds a read-coils request (function 0x01).

§Arguments
  • start - the address of the first coil to read.
  • count - how many coils to read.
§Returns

The request PDU.

Source

pub fn read_discrete_inputs(start: u16, count: u16) -> Pdu

Builds a read-discrete-inputs request (function 0x02).

§Arguments
  • start - the address of the first discrete input to read.
  • count - how many inputs to read.
§Returns

The request PDU.

Source

pub fn read_holding_registers(start: u16, count: u16) -> Pdu

Builds a read-holding-registers request (function 0x03).

§Arguments
  • start - the address of the first holding register to read.
  • count - how many registers to read.
§Returns

The request PDU.

Source

pub fn read_input_registers(start: u16, count: u16) -> Pdu

Builds a read-input-registers request (function 0x04).

§Arguments
  • start - the address of the first input register to read.
  • count - how many registers to read.
§Returns

The request PDU.

Source

pub fn write_single_coil(address: u16, on: bool) -> Pdu

Builds a write-single-coil request (function 0x05).

§Arguments
  • address - the address of the coil to write.
  • on - the value to write: true drives the coil on, false off.
§Returns

The request PDU.

Source

pub fn write_single_register(address: u16, value: u16) -> Pdu

Builds a write-single-register request (function 0x06).

§Arguments
  • address - the address of the holding register to write.
  • value - the 16-bit value to write.
§Returns

The request PDU.

Source

pub fn write_multiple_registers( start: u16, values: &[u16], ) -> Result<Pdu, ModbusError>

Builds a write-multiple-registers request (function 0x10).

§Arguments
  • start - the address of the first holding register to write.
  • values - the 16-bit values to write to consecutive registers.
§Returns

The request PDU.

§Errors

Returns ModbusError::InvalidValueCount if values is empty or holds more than MAX_WRITE_REGISTERS values.

Source

pub fn read_holding_registers_reply(values: &[u16]) -> Result<Pdu, ModbusError>

Builds the reply a device sends to a read-holding-registers request.

This is the answering half of read_holding_registers: the function code, the byte count, then the registers big-endian. It lets a client be written and tested against what a device sends without a device on the line.

§Arguments
  • values - the register values the device reports, in address order.
§Returns

The reply PDU.

§Errors

Returns ModbusError::InvalidValueCount if values is empty or holds more than MAX_WRITE_REGISTERS values.

Source

pub fn read_input_registers_reply(values: &[u16]) -> Result<Pdu, ModbusError>

Builds the reply a device sends to a read-input-registers request.

This is the answering half of read_input_registers.

§Arguments
  • values - the register values the device reports, in address order.
§Returns

The reply PDU.

§Errors

Returns ModbusError::InvalidValueCount if values is empty or holds more than MAX_WRITE_REGISTERS values.

Source

pub fn write_multiple_coils( start: u16, values: &[bool], ) -> Result<Pdu, ModbusError>

Builds a write-multiple-coils request (function 0x0F).

The coils are packed into bytes least-significant bit first, the order Modbus uses; any unused bits in the final byte are left zero.

§Arguments
  • start - the address of the first coil to write.
  • values - the coil states to write, one bool per coil.
§Returns

The request PDU.

§Errors

Returns ModbusError::InvalidValueCount if values is empty or holds more than MAX_WRITE_COILS values.

Source

pub fn raw(function: u8, data: &[u8]) -> Result<Pdu, ModbusError>

Builds a PDU from a raw function code and data, the escape hatch for function codes this crate does not name.

§Arguments
  • function - the function code byte.
  • data - the bytes that follow it, used verbatim.
§Returns

The PDU.

§Errors

Returns ModbusError::FrameTooLong if the function code plus data would not fit a PDU (more than MAX_LEN bytes).

Source

pub fn function_code(&self) -> u8

Returns the function code, the first byte of the PDU.

§Returns

The function code.

Source

pub fn as_bytes(&self) -> &[u8]

Returns the PDU bytes: the function code followed by its data.

§Returns

The PDU as a byte slice.

Source

pub fn to_adu(&self, address: u8) -> Adu

Wraps this PDU into an RTU frame addressed to a unit, appending the CRC.

§Arguments
  • address - the unit (slave) address the frame is for.
§Returns

The Adu ready to send.

Trait Implementations§

Source§

impl Clone for Pdu

Source§

fn clone(&self) -> Pdu

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Pdu

Source§

impl Debug for Pdu

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Pdu

Source§

impl PartialEq for Pdu

Source§

fn eq(&self, other: &Pdu) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for Pdu

Auto Trait Implementations§

§

impl Freeze for Pdu

§

impl RefUnwindSafe for Pdu

§

impl Send for Pdu

§

impl Sync for Pdu

§

impl Unpin for Pdu

§

impl UnsafeUnpin for Pdu

§

impl UnwindSafe for Pdu

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.