modbus-impl 0.6.0

A small `no_std` Modbus RTU helper library designed to run on embedded Rust targets
Documentation
  • Coverage
  • 32.56%
    14 out of 43 items documented0 out of 31 items with examples
  • Size
  • Source code size: 23.42 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 484.17 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 5s 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

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)

  • 'set_reg(addr: u16, val: u16)`

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)

  • set_bit(addr: u16, val: bool)

It also provides basic storage types that implement these traits:

  • Hreg<N> for Holding Registers (FC03/FC06)
  • Ireg<N> for Input Registers (FC04)
  • Coil<N> for Coils (FC01/FC05)
  • 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 write requests).
    • parse_pdu() 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_pdu() 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 buffer.
  2. Call:
    • ctx.pharse_pdu::<MAX_QTY>(&req8, &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

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.
  • Only read functions are implemented (01/02/03/04).
  • Write functions now include 05/06
  • Bit packing follows Modbus LSB-first conventions.