Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ffi/rodbus-schema/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,9 +420,9 @@ fn build_bit_read_callback(
) -> BackTraced<FutureInterfaceHandle> {
let future = lib.define_future_interface(
"bit_read_callback",
"Callbacks received when reading coils or discrete inputs",
doc("Callbacks received when reading coils or discrete inputs").details("On success, the iterator yields exactly the requested number of values in ascending, contiguous address order, beginning at the start of the requested {struct:address_range}. A response containing too few or too many values fails the request."),
common.bit_iterator.clone(),
"response",
"Iterator over the values read from the server, in ascending address order",
common.error_info.clone(),
)?;

Expand All @@ -435,9 +435,9 @@ fn build_register_read_callback(
) -> BackTraced<FutureInterfaceHandle> {
let future = lib.define_future_interface(
"register_read_callback",
"Callbacks received when reading reading holding or input registers",
doc("Callbacks received when reading holding or input registers").details("On success, the iterator yields exactly the requested number of values in ascending, contiguous address order, beginning at the start of the requested {struct:address_range}. A response containing too few or too many values fails the request."),
common.register_iterator.clone(),
"response",
"Iterator over the values read from the server, in ascending address order",
common.error_info.clone(),
)?;

Expand Down
8 changes: 4 additions & 4 deletions ffi/rodbus-schema/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ fn build_bit_value(lib: &mut LibraryBuilder) -> BackTraced<UniversalStructHandle
let bit = lib.declare_universal_struct("bit_value")?;
let bit = lib
.define_universal_struct(bit)?
.add("index", Primitive::U16, "Index of bit")?
.add("index", Primitive::U16, "Address of the bit")?
.add("value", Primitive::Bool, "Value of the bit")?
.doc("Index/value tuple of a bit type")?
.doc(doc("Bit value and its address").details("Modbus messages that carry a block of values (read responses and write multiple requests) encode a starting address and the values in address order, but not a per-value address. The library computes the index from the starting address and the value's position as a convenience."))?
.end_fields()?
.add_full_initializer("init")?
.build()?;
Expand All @@ -163,9 +163,9 @@ fn build_register_value(lib: &mut LibraryBuilder) -> BackTraced<UniversalStructH
let bit = lib.declare_universal_struct("register_value")?;
let register = lib
.define_universal_struct(bit)?
.add("index", Primitive::U16, "Index of register")?
.add("index", Primitive::U16, "Address of the register")?
.add("value", Primitive::U16, "Value of the register")?
.doc("Index/value tuple of a register type")?
.doc(doc("Register value and its address").details("Modbus messages that carry a block of values (read responses and write multiple requests) encode a starting address and the values in address order, but not a per-value address. The library computes the index from the starting address and the value's position as a convenience."))?
.end_fields()?
.add_full_initializer("init")?
.build()?;
Expand Down
6 changes: 5 additions & 1 deletion guide/docs/api/client/requests.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ The sum of the `start` and `count` fields **cannot exceed 65,536**. The library
returning an error.
:::

The asynchronous response contains an iterator over the retrieved values. If an error occurs, the iterator is empty.
The asynchronous response contains an iterator over the retrieved values. A successful response always contains exactly `count` values
in ascending, contiguous address order beginning at `start`. A response containing too few or too many values fails the request.

Each value is paired with its address as a convenience. Modbus read responses don't encode per-value addresses, only the values in
address order, so the library computes each address from `start` and the value's position.

The following example demonstrates reading the first 5 coils from a device:

Expand Down
24 changes: 24 additions & 0 deletions rodbus/src/client/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ impl Channel {
}

/// Read coils from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_coils(
&self,
param: RequestParam,
Expand All @@ -188,6 +191,9 @@ impl Channel {
}

/// Read discrete inputs from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_discrete_inputs(
&self,
param: RequestParam,
Expand All @@ -203,6 +209,9 @@ impl Channel {
}

/// Read holding registers from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_holding_registers(
&self,
param: RequestParam,
Expand All @@ -221,6 +230,9 @@ impl Channel {
}

/// Read input registers from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_input_registers(
&self,
param: RequestParam,
Expand Down Expand Up @@ -339,6 +351,9 @@ impl CallbackSession {
}

/// Read coils from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_coils<C>(&mut self, range: AddressRange, callback: C)
where
C: FnOnce(Result<BitIterator, RequestError>) + Send + Sync + 'static,
Expand All @@ -348,6 +363,9 @@ impl CallbackSession {
}

/// Read discrete inputs from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_discrete_inputs<C>(&mut self, range: AddressRange, callback: C)
where
C: FnOnce(Result<BitIterator, RequestError>) + Send + Sync + 'static,
Expand All @@ -357,6 +375,9 @@ impl CallbackSession {
}

/// Read holding registers from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_holding_registers<C>(&mut self, range: AddressRange, callback: C)
where
C: FnOnce(Result<RegisterIterator, RequestError>) + Send + Sync + 'static,
Expand All @@ -366,6 +387,9 @@ impl CallbackSession {
}

/// Read input registers from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub async fn read_input_registers<C>(&mut self, range: AddressRange, callback: C)
where
C: FnOnce(Result<RegisterIterator, RequestError>) + Send + Sync + 'static,
Expand Down
12 changes: 12 additions & 0 deletions rodbus/src/client/ffi_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ impl FfiChannel {
}

/// Read coils from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub fn read_coils<C>(
&mut self,
param: RequestParam,
Expand All @@ -63,6 +66,9 @@ impl FfiChannel {
}

/// Read discrete inputs from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub fn read_discrete_inputs<C>(
&mut self,
param: RequestParam,
Expand All @@ -76,6 +82,9 @@ impl FfiChannel {
}

/// Read holding registers from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub fn read_holding_registers<C>(
&mut self,
param: RequestParam,
Expand All @@ -89,6 +98,9 @@ impl FfiChannel {
}

/// Read input registers from the server
///
/// On success, the result contains exactly `range.count` values in ascending address order
/// starting at `range.start`. See [`Indexed`] for details.
pub fn read_input_registers<C>(
&mut self,
param: RequestParam,
Expand Down
13 changes: 13 additions & 0 deletions rodbus/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ impl ReadRegistersRange {
}

/// Value and its address
///
/// Modbus messages that carry a block of values (read responses and write multiple requests)
/// encode a starting address and the values in address order, but not a per-value address.
/// The library computes `index` from the starting address and the value's position
/// as a convenience.
///
/// The values of a successful read are always in ascending, contiguous address order,
/// and contain exactly `range.count` values starting at `range.start`. A response
/// containing too few or too many values fails the request.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Indexed<T> {
/// Address of the value
Expand All @@ -70,6 +79,8 @@ pub struct Indexed<T> {
}

/// Zero-copy type used to iterate over a collection of bits
///
/// Values are yielded in ascending address order. See [`Indexed`] for details.
#[derive(Debug, Copy, Clone)]
pub struct BitIterator<'a> {
bytes: &'a [u8],
Expand All @@ -83,6 +94,8 @@ pub(crate) struct BitIteratorDisplay<'a> {
}

/// Zero-copy type used to iterate over a collection of registers
///
/// Values are yielded in ascending address order. See [`Indexed`] for details.
#[derive(Debug, Copy, Clone)]
pub struct RegisterIterator<'a> {
bytes: &'a [u8],
Expand Down
Loading