modbus_rtu/slave/
mod.rs

1mod data_model;     pub use data_model::{DataModel, DataStructure};
2
3use crate::common::{crc, Exception};
4
5
6/// Modbus Slave
7#[derive(Debug)]
8pub struct ModbusSlave<const L1: usize, const L2: usize> {
9    /// The Modbus slave ID.
10    ///
11    /// Valid Modbus IDs range from `1` to `247`. This crate also supports reserved IDs from `248` to `255`.
12    /// If the ID is set to `0`, the device will listen to all Modbus IDs and never respond.
13    ///
14    modbus_id: u8,
15
16    /// Holding registers.
17    ///
18    /// Read-write registers that can be accessed and modified by the Modbus master.
19    /// 
20    holding_registers: DataModel<L1, u16>,
21
22    /// Input registers.
23    ///
24    /// Read-only registers that can be accessed by the Modbus master.
25    /// 
26    input_registers: DataModel<L2, u16>,
27}
28
29
30impl<'a, const L1: usize, const L2: usize> ModbusSlave<L1, L2> {
31    pub fn new(modbus_id: u8, holding_registers: DataModel<L1, u16>, input_registers: DataModel<L2, u16>) -> ModbusSlave<L1, L2> {
32        ModbusSlave { modbus_id, holding_registers, input_registers }
33    }
34
35    pub fn get_modbus_id(&self) -> u8 {
36        self.modbus_id
37    }
38
39    pub fn set_modbus_id(&mut self, modbus_id: u8) {
40        self.modbus_id = modbus_id;
41    }
42
43    pub fn get_holding_registers(&self) -> &DataModel<L1, u16> {
44        &self.holding_registers
45    }
46
47    pub fn get_holding_registers_mut(&mut self) -> &mut DataModel<L1, u16> {
48        &mut self.holding_registers
49    }
50
51    pub fn get_input_registers(&self) -> &DataModel<L2, u16> {
52        &self.input_registers
53    }
54
55    pub fn get_input_registers_mut(&mut self) -> &mut DataModel<L2, u16> {
56        &mut self.input_registers
57    }
58
59    pub fn build_exception_response_packet(&self, fc: u8, exception: Exception) -> [u8; 5] {
60        let mut result: [u8; 5] = [
61            self.modbus_id,
62            fc | 0x80,
63            exception.into(),
64            0x00,
65            0x00,
66        ];
67
68        let crc_bytes = crc::gen_bytes(&result[..3]);
69        result[3..5].copy_from_slice(&crc_bytes);
70
71        result
72    }
73}