sim: Modbus RTU slave model (ModbusSlave) on the RS-485 seam

The device counterpart to warden-modbus's master/scanner: request-frame in,
response-frame out, in host memory. CRC16 is byte-identical to the master
(poly 0xA001, low-first; known vector 01 03 00 00 00 01 -> 84 0A verified).
Implements the data plane — read/write holding & input registers, coils,
discrete inputs (FC 0x01-0x06, 0x0F, 0x10) + Report Slave ID (0x11) — with
exception replies (illegal function/address/value) and the two real-world
faults the master must survive: a device that silently ignores a request
(drop_next) and one that NAKs everything (force_exception). This is what the
modbus-master MC/DC harness drives against; MEI (0x2B/0x0E) is a follow-up.

11 tests, sim crate 25/25 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
This commit is contained in:
BFE Engineering
2026-08-24 18:04:38 -06:00
co-authored by Claude Opus 4.8
parent 4a1ec1d84e
commit 435953799c
3 changed files with 447 additions and 6 deletions
+6 -2
View File
@@ -2,17 +2,21 @@
//!
//! Lets driver and supervisor logic run and be tested on the host, with no panel,
//! by modelling the RV1106 hardware the vendor SDK cannot: the register/SRAM bus
//! ([`membus`]), the RISC-V HPMCU watchdog coprocessor ([`hpmcu`]), and — as they
//! land — the RGA blitter and the NPU.
//! ([`membus`]), the RISC-V HPMCU watchdog coprocessor ([`hpmcu`]), the CRU reset
//! ladder ([`cru`]), and the RS-485 device end ([`modbus`]) — and, as they land,
//! the RGA blitter and the NPU.
//!
//! Design: one [`membus::MemBus`] seam, two backends. On the host, [`membus::SimBus`]
//! is an in-memory word map; on the device, flared's `devmem.rs` implements the same
//! trait over `/dev/mem`, so the same code runs against either. See the repo README.
//! (The [`modbus`] slave rides a byte-stream seam, not the register bus.)
pub mod cru;
pub mod hpmcu;
pub mod membus;
pub mod modbus;
pub use cru::{BootMode, CruSim, ResetCause};
pub use hpmcu::HpmcuSim;
pub use membus::{MemBus, SimBus};
pub use modbus::ModbusSlave;