code wiki / shims / nx_modbus_shim.nx

nx_modbus_shim.nx

buildroot/runtime/shims/nx_modbus_shim.nx

18928 B425 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_modbus_shim.nx -- Modbus RTU + TCP protocol shim. WHEELER-IMPLEMENTATION-OF-CANONICAL-SPEC. Wire-spec sources (re-implemented clean-room from published specs; no external code imported per sovereignty audit): - Modbus Application Protocol Specification V1.1b3 (Modbus Org, 2012) - Modbus over Serial Line Specification and Implementation Guide V1.02 - MODBUS Messaging on TCP/IP Implementation Guide V1.0b Second protocol family per INTEROPERABILITY_CHARTER.md §5.2. Proves the 5-file shim template generalises from automotive (OBD-II in §5.1) to industrial (Modbus in §5.2). Status: SEED v0.1.0. 2026-05-27. WINNER-TIER: BASELINE-C provisional INCUMBENTS: libmodbus v3.1.x (LGPL C library; most-deployed), pyModbus v3.x (Python), Modbus.NET (commercial .NET), ModScan / ModSlave (commercial Windows tools) NUMBERS: V1 ships parsing + framing for the 4 dominant function codes (03/04/06/16); paired throughput + latency bench vs libmodbus pending real serial-port hardware GAP: unmeasured today; comparable parse-cost expected (Modbus framing is trivial vs OBD's ISO-TP); Nishi adds value-add via the same substrate consumer pattern as OBD pred-maint PLAN: M-next: paired bench on a real Modbus RTU serial bus + Modbus TCP server vs libmodbus client; re-rate EXEMPTION REASON: n/a; provisional pending measurement V1 SCOPE: - Modbus RTU framing parse + build (serial) - Modbus TCP framing parse + build (MBAP header) - Function code 03 (read holding registers) - Function code 04 (read input registers) - Function code 06 (write single register) - Function code 16 (write multiple registers) - CRC-16-Modbus (bit-by-bit; no precomputed table for sovereignty; ~30 cycles per byte on x86_64)

dependencies 1 imports · 1 importers

nx_syscalls.nx nx_modbus_shim.nx nx_modbus_pred_maint_pipeline.nx

imports: nx_syscalls.nx

imported by: nx_modbus_pred_maint_pipeline.nx

structs

118struct NxModbusShim

consts

57const NX_SHIM_OK: i64 = 0
58const NX_SHIM_BAD_FRAME: i64 = 1
59const NX_SHIM_PROTOCOL_VIOLATION: i64 = 2
60const NX_SHIM_TIMEOUT: i64 = 3
61const NX_SHIM_BACKPRESSURE: i64 = 4
62const NX_SHIM_UNSUPPORTED_PID: i64 = 5 // here: unsupported function code
63const NX_SHIM_NO_WIRE: i64 = 6
66const NX_MODBUS_VERDICT_BASE: i64 = 200
67const NX_MODBUS_BAD_CRC: i64 = 200 // RTU CRC mismatch
68const NX_MODBUS_BAD_MBAP_LEN: i64 = 201 // TCP MBAP length field disagrees with payload
69const NX_MODBUS_BAD_PROTO_ID: i64 = 202 // TCP MBAP protocol_id != 0
70const NX_MODBUS_EXCEPTION_RESP: i64 = 203 // function | 0x80 received; exception_code follows
71const NX_MODBUS_BAD_FUNCTION: i64 = 204 // function code unsupported in V1
72const NX_MODBUS_TRUNCATED: i64 = 205 // frame ends mid-field
73const NX_MODBUS_BAD_QUANTITY: i64 = 206 // read/write count outside spec bounds
76const NX_MODBUS_FC_READ_COILS: i64 = 0x01 // V2+ TODO
77const NX_MODBUS_FC_READ_DISCRETE_INPUTS: i64 = 0x02 // V2+
78const NX_MODBUS_FC_READ_HOLDING_REGS: i64 = 0x03 // V1
79const NX_MODBUS_FC_READ_INPUT_REGS: i64 = 0x04 // V1
80const NX_MODBUS_FC_WRITE_SINGLE_COIL: i64 = 0x05 // V2+
81const NX_MODBUS_FC_WRITE_SINGLE_REG: i64 = 0x06 // V1
82const NX_MODBUS_FC_WRITE_MULTI_COILS: i64 = 0x0F // V2+
83const NX_MODBUS_FC_WRITE_MULTI_REGS: i64 = 0x10 // V1
84const NX_MODBUS_FC_READ_WRITE_MULTI: i64 = 0x17 // V2+
85const NX_MODBUS_FC_EXCEPTION_OFFSET: i64 = 0x80 // function | 0x80 = exception response
88const NX_MODBUS_EXC_ILLEGAL_FUNCTION: i64 = 0x01
89const NX_MODBUS_EXC_ILLEGAL_DATA_ADDR: i64 = 0x02
90const NX_MODBUS_EXC_ILLEGAL_DATA_VALUE: i64 = 0x03
91const NX_MODBUS_EXC_SLAVE_DEVICE_FAILURE: i64 = 0x04
92const NX_MODBUS_EXC_ACKNOWLEDGE: i64 = 0x05
93const NX_MODBUS_EXC_SLAVE_BUSY: i64 = 0x06
94const NX_MODBUS_EXC_GATEWAY_PATH_UNAVAIL: i64 = 0x0A
95const NX_MODBUS_EXC_GATEWAY_TARGET_NO_RESP: i64 = 0x0B
98const NX_MBAP_OFF_TXN_ID: i64 = 0 // u16 BE; client-chosen; echoed by server
99const NX_MBAP_OFF_PROTO_ID: i64 = 2 // u16 BE; MUST be 0x0000
100const NX_MBAP_OFF_LENGTH: i64 = 4 // u16 BE; bytes after length field (unit_id + PDU)
101const NX_MBAP_OFF_UNIT_ID: i64 = 6 // u8; slave address
102const NX_MBAP_HEADER_SIZE: i64 = 7
105const NX_MODBUS_RTU_MIN_LEN: i64 = 4 // addr + func + CRC(2)
106const NX_MODBUS_RTU_MAX_LEN: i64 = 256
107const NX_MODBUS_TCP_MIN_LEN: i64 = 8 // MBAP(7) + function
108const NX_MODBUS_TCP_MAX_LEN: i64 = 260
111const NX_MODBUS_EVT_HOLDING_REG_READ: i64 = 300 // v0=reg_addr, v1=value, v2=unit_id
112const NX_MODBUS_EVT_INPUT_REG_READ: i64 = 301
113const NX_MODBUS_EVT_WRITE_ACK: i64 = 302 // v0=reg_addr, v1=quantity_or_value, v2=unit_id
114const NX_MODBUS_EVT_EXCEPTION: i64 = 303 // v0=function_code, v1=exception_code, v2=unit_id

functions

128func nx_modbus_shim_init(s: *NxModbusShim) -> i64
147func nx_modbus_crc16(buf: *u8, len: i64) -> i64
173func nx_modbus_read_u16_be(buf: *u8, off: i64) -> i64
179func nx_modbus_write_u16_be(buf: *u8, off: i64, value: i64) -> i64
196func nx_modbus_rtu_parse(s: *NxModbusShim, frame: *u8, frame_len: i64,
235func nx_modbus_tcp_parse(s: *NxModbusShim, frame: *u8, frame_len: i64,
274func nx_modbus_dispatch_pdu(s: *NxModbusShim, func_code: i64, unit_id: i64,
336func nx_modbus_parse_read_regs(s: *NxModbusShim, evt_kind: i64, unit_id: i64,
371func nx_modbus_rtu_build_read_holding(s: *NxModbusShim, unit_id: i64,
394func nx_modbus_tcp_build_read_holding(s: *NxModbusShim, txn_id: i64, unit_id: i64,
418func nx_modbus_diag_fn(s: *NxModbusShim, out_vec: *i64) -> i64