summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun <[email protected]>2026-02-23 00:59:33 +0800
committerRbb666 <[email protected]>2026-02-25 17:53:06 +0800
commitffcd1cb3160b18ba789c6ae620b5e1c5d76052bc (patch)
treed0821617a6a7ddea820a2520a095e23166874c3e
parentf610f18a3c796ba1bc404c886b408b01ca814cef (diff)
fix(drivers/ipc): correct rt_ringbuffer_peek to not consume data
-rw-r--r--components/drivers/include/ipc/ringbuffer.h1
-rw-r--r--components/drivers/ipc/ringbuffer.c48
-rw-r--r--components/drivers/serial/dev_serial_v2.c8
3 files changed, 49 insertions, 8 deletions
diff --git a/components/drivers/include/ipc/ringbuffer.h b/components/drivers/include/ipc/ringbuffer.h
index 5a585542a7..71fc66e0ec 100644
--- a/components/drivers/include/ipc/ringbuffer.h
+++ b/components/drivers/include/ipc/ringbuffer.h
@@ -71,6 +71,7 @@ rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *pt
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint32_t length);
+rt_size_t rt_ringbuffer_get_direct(struct rt_ringbuffer *rb, rt_uint8_t **ptr);
rt_size_t rt_ringbuffer_peek(struct rt_ringbuffer *rb, rt_uint8_t **ptr);
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
diff --git a/components/drivers/ipc/ringbuffer.c b/components/drivers/ipc/ringbuffer.c
index 138eff055e..b5c2c358f2 100644
--- a/components/drivers/ipc/ringbuffer.c
+++ b/components/drivers/ipc/ringbuffer.c
@@ -219,16 +219,18 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
RTM_EXPORT(rt_ringbuffer_get);
/**
- * @brief Get the first readable byte of the ring buffer.
+ * @brief Get data from the ring buffer in zero-copy mode.
*
* @param rb A pointer to the ringbuffer.
* @param ptr When this function return, *ptr is a pointer to the first readable byte of the ring buffer.
*
- * @note It is recommended to read only one byte, otherwise it may cause buffer overflow.
+ * @note This function returns a direct pointer to the internal buffer and consumes the data
+ * (advances read_index). It returns the contiguous readable data length. If data wraps
+ * around the buffer end, call this function again to get the remaining segment.
*
- * @return Return the size of the ring buffer.
+ * @return Return the contiguous readable data size we consumed from the ring buffer.
*/
-rt_size_t rt_ringbuffer_peek(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
+rt_size_t rt_ringbuffer_get_direct(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
{
rt_size_t size;
@@ -259,6 +261,44 @@ rt_size_t rt_ringbuffer_peek(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
return size;
}
+RTM_EXPORT(rt_ringbuffer_get_direct);
+
+/**
+ * @brief Get the first readable byte of the ring buffer.
+ *
+ * @param rb A pointer to the ringbuffer.
+ * @param ptr When this function return, *ptr is a pointer to the first readable byte of the ring buffer.
+ *
+ * @note It is recommended to read only one byte, otherwise it may cause buffer overflow.
+ *
+ * @return Return the size of the ring buffer.
+ */
+rt_size_t rt_ringbuffer_peek(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
+{
+ rt_size_t size;
+
+ RT_ASSERT(rb != RT_NULL);
+
+ *ptr = RT_NULL;
+
+ /* whether has enough data */
+ size = rt_ringbuffer_data_len(rb);
+
+ /* no data */
+ if (size == 0)
+ return 0;
+
+ *ptr = &rb->buffer_ptr[rb->read_index];
+
+ if ((rt_size_t)(rb->buffer_size - rb->read_index) > size)
+ {
+ return size;
+ }
+
+ size = rb->buffer_size - rb->read_index;
+
+ return size;
+}
RTM_EXPORT(rt_ringbuffer_peek);
/**
diff --git a/components/drivers/serial/dev_serial_v2.c b/components/drivers/serial/dev_serial_v2.c
index 13007cbe5e..0a7c343b79 100644
--- a/components/drivers/serial/dev_serial_v2.c
+++ b/components/drivers/serial/dev_serial_v2.c
@@ -2000,13 +2000,13 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
{
rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
- size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
+ size = rt_ringbuffer_get_direct(&rx_fifo->dma_ping_rb, &ptr);
put_len = rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
if (put_len != size)
break;
- size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
+ size = rt_ringbuffer_get_direct(&rx_fifo->dma_ping_rb, &ptr);
if (size == 0)
break;
@@ -2022,11 +2022,11 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
{
rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
- size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
+ size = rt_ringbuffer_get_direct(&rx_fifo->dma_ping_rb, &ptr);
rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size);
- size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
+ size = rt_ringbuffer_get_direct(&rx_fifo->dma_ping_rb, &ptr);
if (size == 0)
break;