1 unstable release
| new 0.1.0 | Feb 16, 2026 |
|---|
#2 in #tcp-transport
Used in 2 crates
160KB
4K
SLoC
rust-mod
A modern Rust Modbus workspace for building automation and industrial integrations.
rust-mod is organized as a crate family:
rustmod-core:no_std-compatible protocol codec layer (PDU + TCP/RTU framing)rustmod-datalink: async transport abstraction + TCP transport implementationrustmod-client: high-level resilient async client APIrustmod-tools: CLI tools built on top of the client
Current Status
Implemented and validated:
- Core Modbus function codes: FC01, FC02, FC03, FC04, FC05, FC06, FC15, FC16, FC22, FC23
- Custom function-code pass-through support for vendor extensions
- FC17 (
Report Server ID) support via client API + simulator service - FC43/MEI 0x0E (
Read Device Identification) typed client API + simulator support - Exception response decoding (including unknown exception codes)
- TCP MBAP framing and RTU CRC/frame codec in
rustmod-core - Async
DataLink::exchangecontract inrustmod-datalink - Production-usable TCP transport (
ModbusTcpTransport) - Optional RTU serial transport (
ModbusRtuTransport,rtufeature) - Optional native RTU serial server (
ModbusRtuServer,rtufeature) - RTU-over-TCP server support (
ModbusRtuOverTcpServer) - In-memory simulator service and point-model helpers for virtual device hosting
- Simulator fixture integration tests for both client and datalink paths
- Correlated tracing hooks and feature-gated metrics counters
- Resilient client with timeout/retry/throttle controls
- Blocking sync TCP facade (
SyncModbusTcpClient) for non-async applications - Safe retry defaults (
RetryPolicy::ReadOnly) to avoid duplicate writes after ambiguous failures - CLI binaries:
readholdingreadinputreadcoilswriteholdingwritecoilscandevices
Workspace Validation
All of the following pass:
cargo check --workspacecargo test --workspacecargo check --workspace --all-featurescargo test --workspace --all-featurescargo clippy --workspace --all-features --all-targets -- -D warningscargo check -p rustmod-core --no-default-featurescargo test -p rustmod-core --no-default-featurescargo clippy --workspace --all-targets -- -D warnings
Quick Start
Build everything:
cargo build --workspace
Read holding registers from a TCP device:
cargo run -p rustmod-tools --bin readholding -- \
--host 127.0.0.1 --port 502 --unit-id 1 --start 107 --quantity 3
Write holding register(s):
# single register (FC06)
cargo run -p rustmod-tools --bin writeholding -- \
--host 127.0.0.1 --port 502 --unit-id 1 --start 10 --values 42
# multiple registers (FC16)
cargo run -p rustmod-tools --bin writeholding -- \
--host 127.0.0.1 --port 502 --unit-id 1 --start 10 --values 42,43,44
Scan unit IDs:
cargo run -p rustmod-tools --bin scandevices -- \
--host 127.0.0.1 --port 502 --unit-start 1 --unit-end 20 --timeout 300
Library Example
use rustmod_client::ModbusClient;
use rustmod_datalink::ModbusTcpTransport;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let link = ModbusTcpTransport::connect("127.0.0.1:502").await?;
let client = ModbusClient::new(link);
let regs = client.read_holding_registers(1, 0x006B, 3).await?;
println!("registers: {regs:?}");
Ok(())
}
Notes
rustmod-coreisno_std-compatible withstd+allocenabled by default.rustmod-datalinksupports TCP, optional RTU client transport, optional RTU serial server, and RTU-over-TCP server.- The simulator components in
rustmod-datalink::simare designed for BACnet+Modbus app simulation workflows and virtual device hosting. - Unknown Modbus exception codes are preserved as
ExceptionCode::Unknown(u8). ModbusClient::custom_requestprovides a compatibility path for vendor/private function codes.ModbusClient::report_server_id(FC17) is available for device identity/status polling.ModbusClient::read_device_identificationsupports typed FC43/MEI 0x0E reads.ModbusClientincludes typed helpers for FC22 (mask_write_register) and FC23 (read_write_multiple_registers).SyncModbusTcpClientprovides a blocking API over the same high-level operations.
Parity Snapshot
Relative to tokio-modbus (0.17.x), rust-mod now has comparable support for:
- Async TCP client operations
- Blocking TCP client facade
- Optional async RTU client transport
- TCP server path suitable for simulator/virtual-device hosting
- Optional RTU serial server path
- RTU-over-TCP server path
- Custom function-code interoperability
- FC17 Report Server ID access
- FC22/FC23 typed operations
- Typed FC43/MEI 0x0E Read Device Identification client support
Still intentionally not at parity:
- Blocking sync RTU facade equivalent to
tokio-modbusrtu-sync - Typed wrappers for some less-common/public function families (can still be used via
custom_request)
Dependencies
~7–20MB
~148K SLoC