mirror of
https://github.com/esphome/esphome.git
synced 2026-10-21 13:34:12 +00:00
[udp] Keep the copy buffer in static memory
Code generation declares the UDP link's buffer for packets split across buffers as a static array of max_packet_size bytes, so it is not allocated at run time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3d67696cd5
commit
9f44c65d99
@@ -1,9 +1,11 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import packet_interface
|
||||
from esphome.components.packet_interface import (
|
||||
CONF_MAX_PACKET_SIZE,
|
||||
new_packet_interface,
|
||||
packet_interface_schema,
|
||||
)
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.types import ConfigType
|
||||
|
||||
from .. import CONF_UDP_ID, UDP_SCHEMA, udp_ns
|
||||
@@ -30,4 +32,9 @@ async def to_code(config: ConfigType) -> None:
|
||||
cg.add(udp_var.set_should_listen())
|
||||
# The udp component sends to its addresses through its broadcast socket
|
||||
cg.add(udp_var.set_should_broadcast())
|
||||
await new_packet_interface(config, udp_var)
|
||||
# The copy buffer's size is known here, so it is a static array rather than allocated at run time
|
||||
tx_buffer = f"{config[CONF_ID].id}__tx_buffer"
|
||||
cg.add_global(
|
||||
cg.RawStatement(f"static uint8_t {tx_buffer}[{config[CONF_MAX_PACKET_SIZE]}];")
|
||||
)
|
||||
await new_packet_interface(config, udp_var, cg.RawExpression(tx_buffer))
|
||||
|
||||
@@ -11,7 +11,6 @@ using packet_interface::PacketMetaData;
|
||||
ESPHOME_LOG_TAG(TAG, "udp.packet_interface");
|
||||
|
||||
void UdpPacketInterface::setup() {
|
||||
this->tx_buffer_ = std::make_unique<uint8_t[]>(this->max_packet_size_);
|
||||
this->parent_->add_listener([this](std::span<const uint8_t> data) { this->receive_(data); });
|
||||
}
|
||||
|
||||
@@ -36,8 +35,8 @@ bool UdpPacketInterface::send_to_interface(const PacketBuffer &data, const Packe
|
||||
auto span = data.as_span();
|
||||
return this->parent_->send_packet(span.data(), span.size());
|
||||
}
|
||||
data.copy_to(this->tx_buffer_.get(), size);
|
||||
return this->parent_->send_packet(this->tx_buffer_.get(), size);
|
||||
data.copy_to(this->tx_buffer_, size);
|
||||
return this->parent_->send_packet(this->tx_buffer_, size);
|
||||
}
|
||||
|
||||
} // namespace esphome::udp
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
// udp_component.h declares nothing without USE_NETWORK
|
||||
#ifdef USE_NETWORK
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
#include "esphome/components/packet_interface/packet_interface.h"
|
||||
@@ -20,7 +19,8 @@ namespace esphome::udp {
|
||||
*/
|
||||
class UdpPacketInterface : public packet_interface::PacketInterface {
|
||||
public:
|
||||
explicit UdpPacketInterface(UDPComponent *udp_component) : parent_(udp_component) {}
|
||||
/// @param tx_buffer Holds max_packet_size bytes, for packets split across buffers; must outlive the link
|
||||
UdpPacketInterface(UDPComponent *udp_component, uint8_t *tx_buffer) : parent_(udp_component), tx_buffer_(tx_buffer) {}
|
||||
|
||||
void setup() override;
|
||||
bool send_to_interface(const packet_interface::PacketBuffer &data,
|
||||
@@ -30,8 +30,7 @@ class UdpPacketInterface : public packet_interface::PacketInterface {
|
||||
void receive_(std::span<const uint8_t> data);
|
||||
|
||||
UDPComponent *parent_;
|
||||
// For packets split across buffers, allocated in setup()
|
||||
std::unique_ptr<uint8_t[]> tx_buffer_;
|
||||
uint8_t *const tx_buffer_;
|
||||
};
|
||||
} // namespace esphome::udp
|
||||
#endif
|
||||
|
||||
@@ -22,13 +22,15 @@ using Packet = std::vector<uint8_t>;
|
||||
|
||||
class TestUdp : public UdpPacketInterface {
|
||||
public:
|
||||
explicit TestUdp(UDPComponent *udp) : UdpPacketInterface(udp) {
|
||||
explicit TestUdp(UDPComponent *udp) : UdpPacketInterface(udp, this->tx_buffer_storage) {
|
||||
this->set_max_packet_size(8);
|
||||
this->add_packet_interface_listener(
|
||||
[this](const PacketBuffer &data, const PacketMetaData &) { this->received.push_back(to_vector(data)); });
|
||||
}
|
||||
using UdpPacketInterface::receive_;
|
||||
|
||||
// The base class only keeps the pointer, so the storage can be a member set up after it
|
||||
uint8_t tx_buffer_storage[8]{};
|
||||
std::vector<Packet> received;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user