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, Request};

// Set a pump controller's pressure setpoint, held in register 40, to 1200 kPa.
let pdu = Pdu::write_single_register(40, 1200);

// The controller reads it back as the request it is.
let request = Request::parse(pdu.as_bytes()).expect("a request the controller can serve");
assert!(matches!(
    request,
    Request::WriteSingleRegister { address: 40, value: 1200 }
));

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 const MAX_READ_REGISTERS: usize = 125

The most holding or input registers a single read may ask for, which fills a reply’s 250 data bytes.

Source

pub const MAX_READ_BITS: usize = 2000

The most coils or discrete inputs a single read may ask for.

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_READ_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_READ_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 read_coils_reply(values: &[bool]) -> Result<Pdu, ModbusError>

Builds the reply a device sends to a read-coils request: the function code, the byte count, then the coils packed least-significant bit first.

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

The reply PDU.

§Errors

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

Source

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

Builds the reply a device sends to a read-discrete-inputs request.

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

The reply PDU.

§Errors

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

Source

pub fn write_multiple_coils_reply(start: u16, quantity: u16) -> Pdu

Builds the reply a device sends to a write-multiple-coils request: the function code, the starting address, and how many coils it wrote.

§Arguments
  • start - the address of the first coil written.
  • quantity - how many coils were written.
§Returns

The reply PDU.

Source

pub fn write_multiple_registers_reply(start: u16, quantity: u16) -> Pdu

Builds the reply a device sends to a write-multiple-registers request.

§Arguments
  • start - the address of the first register written.
  • quantity - how many registers were written.
§Returns

The reply PDU.

Source

pub fn exception(function: u8, exception: Exception) -> Pdu

Builds the exception a device answers with when it refuses a request: the request’s function code with its high bit set, then the exception code.

§Arguments
  • function - the function code of the request refused.
  • exception - why it was refused.
§Returns

The exception PDU.

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

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

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

Inequality operator !=. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.