[dsmr] Batch UART reads to reduce per-loop overhead (#13826)

This commit is contained in:
J. Nick Koston
2026-02-09 18:32:52 -06:00
committed by GitHub
parent 097901e9c8
commit 87ac263264
2 changed files with 137 additions and 107 deletions
+38 -9
View File
@@ -40,9 +40,7 @@ bool Dsmr::ready_to_request_data_() {
this->start_requesting_data_(); this->start_requesting_data_();
} }
if (!this->requesting_data_) { if (!this->requesting_data_) {
while (this->available()) { this->drain_rx_buffer_();
this->read();
}
} }
} }
return this->requesting_data_; return this->requesting_data_;
@@ -115,25 +113,42 @@ void Dsmr::stop_requesting_data_() {
} else { } else {
ESP_LOGV(TAG, "Stop reading data from P1 port"); ESP_LOGV(TAG, "Stop reading data from P1 port");
} }
while (this->available()) { this->drain_rx_buffer_();
this->read();
}
this->requesting_data_ = false; this->requesting_data_ = false;
} }
} }
void Dsmr::drain_rx_buffer_() {
uint8_t buf[64];
int avail;
while ((avail = this->available()) > 0) {
if (!this->read_array(buf, std::min(static_cast<size_t>(avail), sizeof(buf)))) {
break;
}
}
}
void Dsmr::reset_telegram_() { void Dsmr::reset_telegram_() {
this->header_found_ = false; this->header_found_ = false;
this->footer_found_ = false; this->footer_found_ = false;
this->bytes_read_ = 0; this->bytes_read_ = 0;
this->crypt_bytes_read_ = 0; this->crypt_bytes_read_ = 0;
this->crypt_telegram_len_ = 0; this->crypt_telegram_len_ = 0;
this->last_read_time_ = 0;
} }
void Dsmr::receive_telegram_() { void Dsmr::receive_telegram_() {
while (this->available_within_timeout_()) { while (this->available_within_timeout_()) {
const char c = this->read(); // Read all available bytes in batches to reduce UART call overhead.
uint8_t buf[64];
int avail = this->available();
while (avail > 0) {
size_t to_read = std::min(static_cast<size_t>(avail), sizeof(buf));
if (!this->read_array(buf, to_read))
return;
avail -= to_read;
for (size_t i = 0; i < to_read; i++) {
const char c = static_cast<char>(buf[i]);
// Find a new telegram header, i.e. forward slash. // Find a new telegram header, i.e. forward slash.
if (c == '/') { if (c == '/') {
@@ -184,10 +199,22 @@ void Dsmr::receive_telegram_() {
} }
} }
} }
}
}
void Dsmr::receive_encrypted_telegram_() { void Dsmr::receive_encrypted_telegram_() {
while (this->available_within_timeout_()) { while (this->available_within_timeout_()) {
const char c = this->read(); // Read all available bytes in batches to reduce UART call overhead.
uint8_t buf[64];
int avail = this->available();
while (avail > 0) {
size_t to_read = std::min(static_cast<size_t>(avail), sizeof(buf));
if (!this->read_array(buf, to_read))
return;
avail -= to_read;
for (size_t i = 0; i < to_read; i++) {
const char c = static_cast<char>(buf[i]);
// Find a new telegram start byte. // Find a new telegram start byte.
if (!this->header_found_) { if (!this->header_found_) {
@@ -249,6 +276,8 @@ void Dsmr::receive_encrypted_telegram_() {
return; return;
} }
} }
}
}
bool Dsmr::parse_telegram() { bool Dsmr::parse_telegram() {
MyData data; MyData data;
+1
View File
@@ -85,6 +85,7 @@ class Dsmr : public Component, public uart::UARTDevice {
void receive_telegram_(); void receive_telegram_();
void receive_encrypted_telegram_(); void receive_encrypted_telegram_();
void reset_telegram_(); void reset_telegram_();
void drain_rx_buffer_();
/// Wait for UART data to become available within the read timeout. /// Wait for UART data to become available within the read timeout.
/// ///