24 CUSTOM ESPDEPRECATED(
"0x00 is not a function code; use FunctionCode::INVALID for the sentinel. Removed in 2027.3.0",
47using ModbusFunctionCode
ESPDEPRECATED(
"Use modbus::FunctionCode instead. Removed in 2027.2.0",
70using ModbusRegisterType
ESPDEPRECATED(
"Use modbus::EntityType instead. Removed in 2027.2.0",
"2026.8.0") =
EntityType;
89using ModbusExceptionCode
ESPDEPRECATED(
"Use modbus::ExceptionCode instead. Removed in 2027.2.0",
93static constexpr uint16_t MAX_NUM_OF_COILS_TO_WRITE = 1968;
96static constexpr uint16_t MAX_NUM_OF_REGISTERS_TO_WRITE = 123;
99static constexpr uint16_t MAX_NUM_OF_REGISTERS_TO_WRITE_RW = 121;
103static constexpr uint16_t MAX_NUM_OF_COILS_TO_READ = 2000;
104static constexpr uint16_t MAX_NUM_OF_DISCRETE_INPUTS_TO_READ = 2000;
108static constexpr uint16_t MAX_NUM_OF_REGISTERS_TO_READ = 125;
111static constexpr uint16_t MIN_FRAME_SIZE = 4;
112static constexpr uint16_t MIN_PDU_SIZE = 1;
113static constexpr uint16_t MAX_PDU_SIZE = 253;
114static constexpr uint16_t MAX_RAW_SIZE = 254;
116static constexpr uint16_t READ_PDU_SIZE = 5;
118static constexpr uint16_t WRITE_SINGLE_PDU_SIZE = 5;
121static constexpr uint16_t WRITE_MULTIPLE_HEADER_SIZE = 6;
122static constexpr uint16_t MAX_FRAME_SIZE = 256;
125static constexpr uint8_t BROADCAST_ADDRESS = 0;
130static_assert(MAX_PDU_SIZE + 3 == MAX_FRAME_SIZE,
"a framed client PDU must fill the RTU frame limit");
131static_assert(MAX_RAW_SIZE + 2 == MAX_FRAME_SIZE,
"a framed raw server payload must fill the RTU frame limit");
138static_assert(1 +
packed_bit_bytes(MAX_NUM_OF_COILS_TO_READ) <= MAX_RAW_SIZE,
139 "MAX_NUM_OF_COILS_TO_READ yields a read response larger than MAX_RAW_SIZE");
140static_assert(1 +
packed_bit_bytes(MAX_NUM_OF_DISCRETE_INPUTS_TO_READ) <= MAX_RAW_SIZE,
141 "MAX_NUM_OF_DISCRETE_INPUTS_TO_READ yields a read response larger than MAX_RAW_SIZE");
145static_assert(MAX_NUM_OF_COILS_TO_READ == MAX_NUM_OF_DISCRETE_INPUTS_TO_READ,
146 "the coil and discrete-input read ceilings must match");
157 PackedBits(std::span<const uint8_t> data, uint16_t count) : data_(data), count_(count) {}
159 bool operator[](
size_t bit)
const {
return (this->data_[bit / 8] & (1 << (bit % 8))) != 0; }
161 uint16_t
size()
const {
return this->count_; }
165 std::span<const uint8_t>
bytes()
const {
166 return this->data_.first(std::min<size_t>(
packed_bit_bytes(this->count_), this->data_.size()));
170 std::span<const uint8_t> data_;
180 bool operator[](
size_t bit)
const {
return (this->data_[bit / 8] & (1 << (bit % 8))) != 0; }
183 void set(
size_t bit,
bool value) {
184 if (bit >= this->count_ || bit / 8 >= this->data_.size())
187 this->data_[bit / 8] |= (1 << (bit % 8));
189 this->data_[bit / 8] &= ~(1 << (bit % 8));
192 uint16_t
size()
const {
return this->count_; }
196 std::span<uint8_t> data_;
Mutable counterpart of PackedBits: set() writes bits in place (deliberately no proxy operator[]=).
MutablePackedBits(std::span< uint8_t > data, uint16_t count)
void set(size_t bit, bool value)
Set or clear the given bit.
bool operator[](size_t bit) const
Read-only view of Modbus-packed bits: bit 0 of byte 0 is the first bit (LSB first),...
bool operator[](size_t bit) const
Value of the given bit; bit must be < size().
std::span< const uint8_t > bytes() const
The underlying packed bytes: exactly ceil(size() / 8) bytes, even when the view was constructed over ...
uint16_t size() const
Number of bits in the view.
PackedBits(std::span< const uint8_t > data, uint16_t count)
const uint8_t FUNCTION_CODE_MASK
const uint8_t FUNCTION_CODE_EXCEPTION_MASK
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_2_INIT
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_1_INIT
Modbus definitions from specs: https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3....
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_2_END
@ WRITE_MULTIPLE_REGISTERS
@ READ_WRITE_MULTIPLE_REGISTERS
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_1_END
bool operator!=(FunctionCode lhs, uint8_t rhs)
@ GATEWAY_PATH_UNAVAILABLE
@ GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND
bool operator==(FunctionCode lhs, uint8_t rhs)
constexpr size_t packed_bit_bytes(size_t bits)
Bits pack 8 per data byte, rounded up to whole bytes.