[modbus] Finalize unreleased API surface before 2026.7 (#17434)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bonne Eggleston
2026-07-08 00:20:14 +00:00
committed by GitHub
co-authored by Claude Fable 5
parent 731e9fda03
commit 731486d9b0
12 changed files with 272 additions and 55 deletions
+28 -6
View File
@@ -56,8 +56,7 @@ void ModbusClientHub::loop() {
(this->rx_buffer_.empty() || this->rx_buffer_[0] != expected_address)) {
ESP_LOGW(TAG, "Stop waiting for response from %" PRIu8 " %" PRIu32 "ms after last send", expected_address,
this->last_receive_check_ - this->last_send_);
if (wfr.device)
wfr.device->on_modbus_no_response();
this->notify_no_response_(wfr);
this->waiting_for_response_.reset();
}
}
@@ -278,11 +277,10 @@ void ModbusClientHub::process_modbus_server_frame(uint8_t address, uint8_t funct
"ms after last send",
address, expected_address, (function_code & FUNCTION_CODE_MASK), expected_function_code,
this->last_modbus_byte_ - this->last_send_);
// Invalidate the waiting device so it won't process this response.
if (wfr.device)
wfr.device->on_modbus_no_response();
// Invalidate the device; the entry survives as an interrupted shell so the late response is ignored.
// A retry requested here stays queued behind the shell until the send-wait timeout clears it.
this->notify_no_response_(wfr);
wfr.interrupted = true;
wfr.device = nullptr;
return;
}
@@ -564,6 +562,30 @@ void ModbusServerHub::send_exception_(uint8_t address, uint8_t function_code, Mo
}
// Raw send for client: pushes to tx queue. Everything except the CRC must be contained in payload.
void ModbusClientHub::notify_no_response_(ModbusDeviceCommand &wfr) {
if (wfr.device == nullptr)
return;
const bool retry = wfr.device->on_modbus_no_response();
// The callback may have detached the device (e.g. clear_tx_queue_for_device()); honor the detach
// over the retry request rather than re-queueing a frame that can no longer be routed.
if (retry && wfr.device != nullptr)
this->requeue_waiting_frame_(wfr);
// The old transaction is over either way; never deliver anything else to the device through it.
wfr.device = nullptr;
}
void ModbusClientHub::requeue_waiting_frame_(ModbusDeviceCommand &wfr) {
const ModbusFrame &frame = wfr.frame;
if (this->tx_buffer_.size() >= MODBUS_TX_BUFFER_SIZE) {
ESP_LOGE(TAG, "Write buffer full, dropped retry for address %" PRIu8, frame.data.data()[0]);
if (wfr.device != nullptr)
wfr.device->on_modbus_not_sent();
return;
}
// Re-queue a copy (not a move): the waiting entry may have to survive as an interrupted shell.
this->tx_buffer_.emplace_back(wfr.device, frame.data.data()[0], frame.data.data() + 1, frame.size() - 3);
}
void ModbusClientHub::queue_raw_(uint8_t address, const uint8_t *pdu, uint16_t pdu_len, ModbusClientDevice *device) {
if (pdu_len == 0) {
if (device)