mirror of
https://github.com/esphome/esphome.git
synced 2025-09-26 15:12:21 +01:00
wip
This commit is contained in:
@@ -193,7 +193,7 @@ void USBUartComponent::loop() {
|
||||
}
|
||||
|
||||
// Return chunk to pool for reuse
|
||||
this->free_chunks_.push(chunk);
|
||||
this->chunk_pool_.release(chunk);
|
||||
}
|
||||
|
||||
static constexpr int LOG_CHUNK_THRESHOLD = 5;
|
||||
@@ -231,8 +231,8 @@ void USBUartComponent::start_input(USBUartChannel *channel) {
|
||||
}
|
||||
|
||||
if (!channel->dummy_receiver_ && status.data_len > 0) {
|
||||
// Get a free chunk from the pool
|
||||
UsbDataChunk *chunk = this->free_chunks_.pop();
|
||||
// Allocate a chunk from the pool
|
||||
UsbDataChunk *chunk = this->chunk_pool_.allocate();
|
||||
if (chunk == nullptr) {
|
||||
ESP_LOGW(TAG, "No free chunks available, dropping %u bytes", status.data_len);
|
||||
// Mark input as not started so we can retry
|
||||
@@ -249,7 +249,7 @@ void USBUartComponent::start_input(USBUartChannel *channel) {
|
||||
if (!this->usb_data_queue_.push(chunk)) {
|
||||
ESP_LOGW(TAG, "USB data queue full, dropping %u bytes", status.data_len);
|
||||
// Return chunk to pool
|
||||
this->free_chunks_.push(chunk);
|
||||
this->chunk_pool_.release(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "esphome/components/uart/uart_component.h"
|
||||
#include "esphome/components/usb_host/usb_host.h"
|
||||
#include "esphome/core/lock_free_queue.h"
|
||||
#include "esphome/core/event_pool.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace usb_uart {
|
||||
@@ -76,6 +77,12 @@ struct UsbDataChunk {
|
||||
uint8_t data[MAX_CHUNK_SIZE];
|
||||
size_t length;
|
||||
USBUartChannel *channel;
|
||||
|
||||
// Required for EventPool - reset to clean state
|
||||
void release() {
|
||||
this->length = 0;
|
||||
this->channel = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class USBUartChannel : public uart::UARTComponent, public Parented<USBUartComponent> {
|
||||
@@ -114,13 +121,7 @@ class USBUartChannel : public uart::UARTComponent, public Parented<USBUartCompon
|
||||
|
||||
class USBUartComponent : public usb_host::USBClient {
|
||||
public:
|
||||
USBUartComponent(uint16_t vid, uint16_t pid) : usb_host::USBClient(vid, pid) {
|
||||
// Allocate pool of data chunks (never freed - ESPHome reboots instead)
|
||||
for (int i = 0; i < MAX_DATA_CHUNKS; i++) {
|
||||
this->data_chunk_pool_[i] = new UsbDataChunk();
|
||||
this->free_chunks_.push(this->data_chunk_pool_[i]);
|
||||
}
|
||||
}
|
||||
USBUartComponent(uint16_t vid, uint16_t pid) : usb_host::USBClient(vid, pid) {}
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
@@ -135,15 +136,12 @@ class USBUartComponent : public usb_host::USBClient {
|
||||
static constexpr int USB_DATA_QUEUE_SIZE = 32;
|
||||
LockFreeQueue<UsbDataChunk, USB_DATA_QUEUE_SIZE> usb_data_queue_;
|
||||
|
||||
// Pool for allocating data chunks (uses EventPool pattern like BLE)
|
||||
static constexpr int MAX_DATA_CHUNKS = 40;
|
||||
EventPool<UsbDataChunk, MAX_DATA_CHUNKS> chunk_pool_;
|
||||
|
||||
protected:
|
||||
std::vector<USBUartChannel *> channels_{};
|
||||
|
||||
// Pool of pre-allocated data chunks to avoid dynamic allocation
|
||||
static constexpr int MAX_DATA_CHUNKS = 40;
|
||||
UsbDataChunk *data_chunk_pool_[MAX_DATA_CHUNKS];
|
||||
// IMPORTANT: This is used bidirectionally (USB task pops, main loop pushes)
|
||||
// which technically violates SPSC, but works in practice because operations are atomic
|
||||
LockFreeQueue<UsbDataChunk, MAX_DATA_CHUNKS> free_chunks_;
|
||||
};
|
||||
|
||||
class USBUartTypeCdcAcm : public USBUartComponent {
|
||||
|
Reference in New Issue
Block a user