Skip to main content

modbus_bridge/
capacity.rs

1//! Frame buffer sizing constants and helpers for Modbus RTU and TCP frames.
2//!
3//! Use the named constants or the `const fn` helpers when you need to know the
4//! exact byte size of a Modbus frame for a given register count — for example,
5//! when allocating application-level buffers or computing memory budgets.
6//!
7//! The [`Bridge`](crate::Bridge) itself uses full-spec internal buffers
8//! (255 bytes for RTU, 261 bytes for TCP) and does not require any sizing from
9//! this module.
10//!
11//! # Sizing rules
12//!
13//! For **bridge mode** (TCP → RTU), use the `TCP_*` constants — TCP frames
14//! carry a 6-byte MBAP header that RTU frames do not, so TCP is always the
15//! larger side.
16//!
17//! For **RTU-only** use cases, the `RTU_*` constants are sufficient.
18//!
19//! # Examples
20//!
21//! Compute a frame size at compile time using the `const fn` helpers:
22//!
23//! ```rust
24//! use modbus_bridge::capacity::{rtu_capacity, tcp_capacity, REG_BYTES_16, REG_BYTES_32};
25//!
26//! // RTU frame size for 8 × 16-bit holding registers
27//! const MY_RTU_BUF: usize = rtu_capacity(8, REG_BYTES_16);
28//! assert_eq!(MY_RTU_BUF, 25); // 8×2 + 9 bytes overhead
29//!
30//! // TCP frame size for the same register count
31//! const MY_TCP_BUF: usize = tcp_capacity(8, REG_BYTES_16);
32//! assert_eq!(MY_TCP_BUF, 31); // 8×2 + 15 bytes overhead
33//!
34//! // RTU frame size for 4 × 32-bit register pairs
35//! const MY_32BIT_BUF: usize = rtu_capacity(4, REG_BYTES_32);
36//! assert_eq!(MY_32BIT_BUF, 25); // 4×4 + 9 bytes overhead
37//! ```
38//!
39//! Or use a named constant directly:
40//!
41//! ```rust
42//! use modbus_bridge::capacity::TCP_8R16;
43//!
44//! assert_eq!(TCP_8R16, 31);
45//! ```
46
47/// Bytes per standard 16-bit Modbus register.
48pub const REG_BYTES_16: usize = 2;
49/// Bytes per 32-bit value stored as two consecutive Modbus registers.
50pub const REG_BYTES_32: usize = 4;
51
52/// Computes the RTU frame buffer size in bytes for `n` registers of `reg_bytes` bytes each.
53///
54/// Sized for the worst case: a Write Multiple Registers request (FC 0x10):
55/// `addr(1) + FC(1) + start(2) + qty(2) + byte_count(1) + data(n×b) + CRC(2) = n×b + 9`
56///
57/// Pass [`REG_BYTES_16`] for standard 16-bit registers or [`REG_BYTES_32`] for
58/// 32-bit values stored across two consecutive registers.
59///
60/// # Examples
61///
62/// ```rust
63/// use modbus_bridge::capacity::{rtu_capacity, REG_BYTES_16};
64///
65/// const BUF: usize = rtu_capacity(10, REG_BYTES_16);
66/// assert_eq!(BUF, 29); // 10×2 + 9
67/// ```
68pub const fn rtu_capacity(n: usize, reg_bytes: usize) -> usize {
69    n * reg_bytes + 9
70}
71
72/// Computes the TCP frame buffer size in bytes for `n` registers of `reg_bytes` bytes each.
73///
74/// Sized for the worst case: a Write Multiple Registers request (FC 0x10) over TCP:
75/// `MBAP(6) + addr(1) + FC(1) + start(2) + qty(2) + byte_count(1) + data(n×b) = n×b + 15`
76///
77/// The MBAP header adds 6 bytes over the equivalent RTU frame, so TCP buffers
78/// are always larger than RTU buffers for the same register count.
79///
80/// # Examples
81///
82/// ```rust
83/// use modbus_bridge::capacity::{tcp_capacity, REG_BYTES_16};
84///
85/// const BUF: usize = tcp_capacity(10, REG_BYTES_16);
86/// assert_eq!(BUF, 35); // 10×2 + 15
87/// ```
88pub const fn tcp_capacity(n: usize, reg_bytes: usize) -> usize {
89    n * reg_bytes + 15
90}
91
92// ── Named RTU constants — 16-bit registers ────────────────────────────────────
93
94/// RTU buffer: 1 × 16-bit register (11 B).
95pub const RTU_1R16: usize = rtu_capacity(1, REG_BYTES_16);
96/// RTU buffer: 4 × 16-bit registers (17 B).
97pub const RTU_4R16: usize = rtu_capacity(4, REG_BYTES_16);
98/// RTU buffer: 8 × 16-bit registers (25 B).
99pub const RTU_8R16: usize = rtu_capacity(8, REG_BYTES_16);
100/// RTU buffer: 10 × 16-bit registers (29 B).
101pub const RTU_10R16: usize = rtu_capacity(10, REG_BYTES_16);
102/// RTU buffer: 16 × 16-bit registers (41 B).
103pub const RTU_16R16: usize = rtu_capacity(16, REG_BYTES_16);
104/// RTU buffer: 32 × 16-bit registers (73 B).
105pub const RTU_32R16: usize = rtu_capacity(32, REG_BYTES_16);
106/// RTU buffer: 64 × 16-bit registers (137 B).
107pub const RTU_64R16: usize = rtu_capacity(64, REG_BYTES_16);
108/// RTU buffer: Modbus spec maximum — 123 × 16-bit registers (255 B).
109pub const RTU_MAX: usize = rtu_capacity(123, REG_BYTES_16);
110
111// ── Named RTU constants — 32-bit register pairs ───────────────────────────────
112
113/// RTU buffer: 1 × 32-bit register pair (13 B).
114pub const RTU_1R32: usize = rtu_capacity(1, REG_BYTES_32);
115/// RTU buffer: 4 × 32-bit register pairs (25 B).
116pub const RTU_4R32: usize = rtu_capacity(4, REG_BYTES_32);
117/// RTU buffer: 8 × 32-bit register pairs (41 B).
118pub const RTU_8R32: usize = rtu_capacity(8, REG_BYTES_32);
119/// RTU buffer: 10 × 32-bit register pairs (49 B).
120pub const RTU_10R32: usize = rtu_capacity(10, REG_BYTES_32);
121/// RTU buffer: 32 × 32-bit register pairs (137 B).
122pub const RTU_32R32: usize = rtu_capacity(32, REG_BYTES_32);
123/// RTU buffer: spec maximum for 32-bit pairs — 61 pairs (253 B).
124pub const RTU_MAX32: usize = rtu_capacity(61, REG_BYTES_32);
125
126// ── Named TCP constants — 16-bit registers ────────────────────────────────────
127
128/// TCP buffer: 1 × 16-bit register (17 B).
129pub const TCP_1R16: usize = tcp_capacity(1, REG_BYTES_16);
130/// TCP buffer: 4 × 16-bit registers (23 B).
131pub const TCP_4R16: usize = tcp_capacity(4, REG_BYTES_16);
132/// TCP buffer: 8 × 16-bit registers (31 B).
133pub const TCP_8R16: usize = tcp_capacity(8, REG_BYTES_16);
134/// TCP buffer: 10 × 16-bit registers (35 B).
135pub const TCP_10R16: usize = tcp_capacity(10, REG_BYTES_16);
136/// TCP buffer: 16 × 16-bit registers (47 B).
137pub const TCP_16R16: usize = tcp_capacity(16, REG_BYTES_16);
138/// TCP buffer: 32 × 16-bit registers (79 B).
139pub const TCP_32R16: usize = tcp_capacity(32, REG_BYTES_16);
140/// TCP buffer: 64 × 16-bit registers (143 B).
141pub const TCP_64R16: usize = tcp_capacity(64, REG_BYTES_16);
142/// TCP buffer: Modbus spec maximum — 123 × 16-bit registers (261 B).
143pub const TCP_MAX: usize = tcp_capacity(123, REG_BYTES_16);
144
145// ── Named TCP constants — 32-bit register pairs ───────────────────────────────
146
147/// TCP buffer: 10 × 32-bit register pairs (55 B).
148pub const TCP_10R32: usize = tcp_capacity(10, REG_BYTES_32);
149/// TCP buffer: spec maximum for 32-bit pairs — 61 pairs (259 B).
150pub const TCP_MAX32: usize = tcp_capacity(61, REG_BYTES_32);