modbus-impl 0.7.0

A small `no_std` Modbus RTU helper library designed to run on embedded Rust targets
Documentation
  • Coverage
  • 32.65%
    16 out of 49 items documented0 out of 40 items with examples
  • Size
  • Source code size: 34.12 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 490.04 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 3s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • sndnvaps/modbus-impl
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • sndnvaps

Modbus-Impl (RTU) for rp-usb-serial & rp-pio-serial

A small no_std Modbus RTU helper library designed to run on embedded Rust targets (e.g. RP2040/RP2350) and work with rp-usb-serial USB CDC link & rp-pio-serial PIO-based software serial for RP2040 & RP2350 using arbitrary GPIO pins. It currently focuses on Modbus function codes 01, 02, 03, and 04 (read operations) and builds valid Modbus RTU frames including CRC16.


What it does

At runtime the library processes fixed-length Modbus requests carried over a byte-stream transport (USB CDC). For each incoming request frame it:

  1. Validates CRC16 (Modbus polynomial 0xA001, init 0xFFFF)
  2. Parses the request fields:
    • Unit ID
    • Function code (0x01/0x02/0x03/0x04/0x05/0x06)
    • Start address
    • Quantity
  3. Checks address range using is_valid(addr)
  4. Builds one of:
    • A normal response frame for the requested function, or
    • An exception response frame:
      • Function | 0x80
      • Exception code (ILLEGAL_FUNCTION / ILLEGAL_DATA_ADDRESS / ILLEGAL_DATA_VALUE)
      • CRC16

Supported Modbus Functions

  • 0x01 Read Coils
  • 0x02 Read Discrete Inputs
  • 0x03 Read Holding Registers (16-bit registers, big-endian in the payload)
  • 0x04 Read Input Registers (16-bit registers, big-endian in the payload)
  • 0x05 Write Single Coil
  • 0x06 Write Single Register
  • 0x0F Write Multiple Coils
  • 0x10 Write Multiple Registers

Coils/inputs are packed into bytes using Modbus rules (LSB-first bit packing).


Data Model

The library defines interfaces so you can plug in your own memory map:

RegisterRead

Used for 16-bit register based functions (FC03/FC04):

  • get(addr: u16) -> u16
  • is_valid(addr: u16) -> bool

RegisterWrite

Used for 16-bit register based functions (FC06/FC16)

  • set_reg(addr: u16, val: u16)
  • set_qty(qty: u16)
  • get_qty() -> usize

BitRead

Used for bit based functions (FC01/FC02):

  • get(addr: u16) -> bool
  • is_valid(addr: u16) -> bool

BitWrite

Used for 16 bit based functions (FC05/FC15)

  • set_bit(addr: u16, val: bool)
  • set_qty(qty: u16)
  • get_qty() -> usize

It also provides basic storage types that implement these traits:

  • Hreg<N> for Holding Registers (FC03/FC06/FC16)
  • Ireg<N> for Input Registers (FC04)
  • Coil<N> for Coils (FC01/FC05/FC15)
  • Ists<N> for Discrete Inputs (FC02)

Implementation Overview

Key components:

  • crc16_modbus(data: &[u8]) -> u16
    Implements Modbus RTU CRC16.

  • Frame parsing

    • Requests are assumed to be 8 bytes long (standard RTU frame for function 01/02/03/04 read requests, 05/06/15/16 write requests).
    • parse_pdu() | parse_frame dispatch supports multiple function codes.
  • Response builders

    • build_resp_bit_reads() builds FC01/FC02 responses.
    • build_resp_regs() builds FC03/FC04 responses.
    • build_exception_resp() builds exception responses.
  • ModbusCtx::pharse_frame() The main entry that takes a request frame and outputs either a response or an exception.


Typical Usage Flow

In your main loop you typically:

  1. Receive bytes from rp-usb-serial into an 8-byte or more byte depend on func FrameLen4Func(func, &rx_accum, rx_len); buffer.
  2. Call:
    • ctx.pharse_frame::<MAX_QTY>(frame, &mut resp_buf, &mut exc_buf);
  3. Send the resulting frame back with:
    • RpUsbConsole::write(&resp_or_exc[..len])

Example for use

rp2040-usb-modbus-example

rp2040-usb-modbus-example-2

rp2350-pio-soft-serial-modbus-example


Notes / Limitations

  • This library is RTU-focused but transport-agnostic: it assumes requests arrive as a byte stream and are accumulated into exact 8-byte frames.
  • Read functions are implemented (01/02/03/04).
  • Write functions are implemented (05/06/15/16).
  • Bit packing follows Modbus LSB-first conventions.