diff --git a/esphome/core/ring_buffer.cpp b/esphome/core/ring_buffer.cpp index 2e0802eceb..486cf67f25 100644 --- a/esphome/core/ring_buffer.cpp +++ b/esphome/core/ring_buffer.cpp @@ -37,6 +37,14 @@ std::unique_ptr RingBuffer::create(size_t len, MemoryPreference pref return rb; } +void *RingBuffer::receive_acquire(size_t &length, size_t max_length, TickType_t ticks_to_wait) { + length = 0; + void *buffer_data = xRingbufferReceiveUpTo(this->handle_, &length, ticks_to_wait, max_length); + return buffer_data; +} + +void RingBuffer::receive_release(void *item) { vRingbufferReturnItem(this->handle_, item); } + size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) { size_t bytes_read = 0; diff --git a/esphome/core/ring_buffer.h b/esphome/core/ring_buffer.h index 4acd07d5b0..8ac3ff3811 100644 --- a/esphome/core/ring_buffer.h +++ b/esphome/core/ring_buffer.h @@ -27,6 +27,28 @@ class RingBuffer { */ size_t read(void *data, size_t len, TickType_t ticks_to_wait = 0); + /** + * @brief Acquires a pointer into the ring buffer's internal storage without copying. + * + * The returned pointer is valid until receive_release() is called. Only one item + * may be checked out at a time. + * + * @param[out] length Set to the number of bytes actually acquired (may be less than max_length at wrap boundary) + * @param max_length Maximum number of bytes to acquire + * @param ticks_to_wait Maximum number of FreeRTOS ticks to wait (default: 0) + * @return Pointer into the ring buffer's internal storage, or nullptr if no data is available + */ + void *receive_acquire(size_t &length, size_t max_length, TickType_t ticks_to_wait = 0); + + /** + * @brief Releases a previously acquired ring buffer item. + * + * Must be called exactly once for each successful receive_acquire(). + * + * @param item Pointer returned by receive_acquire() + */ + void receive_release(void *item); + /** * @brief Writes to the ring buffer, overwriting oldest data if necessary. *