diff --git a/components/drivers/include/ipc/ringbuffer.h b/components/drivers/include/ipc/ringbuffer.h index 5a585542a7f..71fc66e0ec6 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 138eff055e5..b5c2c358f2f 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 13007cbe5e9..0a7c343b796 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;