[ringbuffer] ringbuffer size boost to 32bit (#6915)
* ringbuffer size boost to 32bit * 添加ringbuffer测试demo related: #682 ---- Co-authored-by: Zxy <1308465141@qq.com> Co-authored-by: Man, Jianting (Meco) <920369182@qq.com>
This commit is contained in:
parent
f58d3c5200
commit
20459ec4d3
|
@ -37,18 +37,15 @@ struct rt_ringbuffer
|
||||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty
|
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty
|
||||||
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
|
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
|
||||||
* read_idx-^ ^-write_idx
|
* read_idx-^ ^-write_idx
|
||||||
*
|
*/
|
||||||
* The tradeoff is we could only use 32KiB of buffer for 16 bit of index.
|
|
||||||
* But it should be enough for most of the cases.
|
rt_uint32_t read_mirror : 1;
|
||||||
*
|
rt_uint32_t read_index : 31;
|
||||||
* Ref: http://en.wikipedia.org/wiki/Circular_buffer#Mirroring */
|
rt_uint32_t write_mirror : 1;
|
||||||
rt_uint16_t read_mirror : 1;
|
rt_uint32_t write_index : 31;
|
||||||
rt_uint16_t read_index : 15;
|
|
||||||
rt_uint16_t write_mirror : 1;
|
|
||||||
rt_uint16_t write_index : 15;
|
|
||||||
/* as we use msb of index as mirror bit, the size should be signed and
|
/* as we use msb of index as mirror bit, the size should be signed and
|
||||||
* could only be positive. */
|
* could only be positive. */
|
||||||
rt_int16_t buffer_size;
|
rt_int32_t buffer_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rt_ringbuffer_state
|
enum rt_ringbuffer_state
|
||||||
|
@ -65,19 +62,19 @@ enum rt_ringbuffer_state
|
||||||
* Please note that the ring buffer implementation of RT-Thread
|
* Please note that the ring buffer implementation of RT-Thread
|
||||||
* has no thread wait or resume feature.
|
* has no thread wait or resume feature.
|
||||||
*/
|
*/
|
||||||
void rt_ringbuffer_init(struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int16_t size);
|
void rt_ringbuffer_init(struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int32_t size);
|
||||||
void rt_ringbuffer_reset(struct rt_ringbuffer *rb);
|
void rt_ringbuffer_reset(struct rt_ringbuffer *rb);
|
||||||
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length);
|
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint32_t length);
|
||||||
rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length);
|
rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint32_t length);
|
||||||
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch);
|
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_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_uint16_t length);
|
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint32_t length);
|
||||||
rt_size_t rt_ringbuffer_peek(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_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
|
||||||
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
|
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
|
||||||
|
|
||||||
#ifdef RT_USING_HEAP
|
#ifdef RT_USING_HEAP
|
||||||
struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t length);
|
struct rt_ringbuffer* rt_ringbuffer_create(rt_uint32_t length);
|
||||||
void rt_ringbuffer_destroy(struct rt_ringbuffer *rb);
|
void rt_ringbuffer_destroy(struct rt_ringbuffer *rb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -88,14 +85,14 @@ void rt_ringbuffer_destroy(struct rt_ringbuffer *rb);
|
||||||
*
|
*
|
||||||
* @return Buffer size.
|
* @return Buffer size.
|
||||||
*/
|
*/
|
||||||
rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb)
|
rt_inline rt_uint32_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb)
|
||||||
{
|
{
|
||||||
RT_ASSERT(rb != RT_NULL);
|
RT_ASSERT(rb != RT_NULL);
|
||||||
return rb->buffer_size;
|
return rb->buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** return the size of empty space in rb */
|
/** return the size of empty space in rb */
|
||||||
#define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - (rt_int16_t)rt_ringbuffer_data_len(rb))
|
#define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb))
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
|
@ -37,7 +37,7 @@ rt_inline enum rt_ringbuffer_state rt_ringbuffer_status(struct rt_ringbuffer *rb
|
||||||
*/
|
*/
|
||||||
void rt_ringbuffer_init(struct rt_ringbuffer *rb,
|
void rt_ringbuffer_init(struct rt_ringbuffer *rb,
|
||||||
rt_uint8_t *pool,
|
rt_uint8_t *pool,
|
||||||
rt_int16_t size)
|
rt_int32_t size)
|
||||||
{
|
{
|
||||||
RT_ASSERT(rb != RT_NULL);
|
RT_ASSERT(rb != RT_NULL);
|
||||||
RT_ASSERT(size > 0);
|
RT_ASSERT(size > 0);
|
||||||
|
@ -63,9 +63,9 @@ RTM_EXPORT(rt_ringbuffer_init);
|
||||||
*/
|
*/
|
||||||
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb,
|
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb,
|
||||||
const rt_uint8_t *ptr,
|
const rt_uint8_t *ptr,
|
||||||
rt_uint16_t length)
|
rt_uint32_t length)
|
||||||
{
|
{
|
||||||
rt_uint16_t size;
|
rt_uint32_t size;
|
||||||
|
|
||||||
RT_ASSERT(rb != RT_NULL);
|
RT_ASSERT(rb != RT_NULL);
|
||||||
|
|
||||||
|
@ -116,9 +116,9 @@ RTM_EXPORT(rt_ringbuffer_put);
|
||||||
*/
|
*/
|
||||||
rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb,
|
rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb,
|
||||||
const rt_uint8_t *ptr,
|
const rt_uint8_t *ptr,
|
||||||
rt_uint16_t length)
|
rt_uint32_t length)
|
||||||
{
|
{
|
||||||
rt_uint16_t space_length;
|
rt_uint32_t space_length;
|
||||||
|
|
||||||
RT_ASSERT(rb != RT_NULL);
|
RT_ASSERT(rb != RT_NULL);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ RTM_EXPORT(rt_ringbuffer_put_force);
|
||||||
*/
|
*/
|
||||||
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
|
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
|
||||||
rt_uint8_t *ptr,
|
rt_uint8_t *ptr,
|
||||||
rt_uint16_t length)
|
rt_uint32_t length)
|
||||||
{
|
{
|
||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
|
||||||
|
|
||||||
/* less data */
|
/* less data */
|
||||||
if (size < length)
|
if (size < length)
|
||||||
length = (rt_uint16_t)size;
|
length = size;
|
||||||
|
|
||||||
if (rb->buffer_size - rb->read_index > length)
|
if (rb->buffer_size - rb->read_index > length)
|
||||||
{
|
{
|
||||||
|
@ -248,7 +248,7 @@ rt_size_t rt_ringbuffer_peek(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
|
||||||
|
|
||||||
if ((rt_size_t)(rb->buffer_size - rb->read_index) > size)
|
if ((rt_size_t)(rb->buffer_size - rb->read_index) > size)
|
||||||
{
|
{
|
||||||
rb->read_index += (rt_uint16_t)size;
|
rb->read_index += size;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ RTM_EXPORT(rt_ringbuffer_reset);
|
||||||
*
|
*
|
||||||
* @return Return a pointer to ring buffer object. When the return value is RT_NULL, it means this creation failed.
|
* @return Return a pointer to ring buffer object. When the return value is RT_NULL, it means this creation failed.
|
||||||
*/
|
*/
|
||||||
struct rt_ringbuffer *rt_ringbuffer_create(rt_uint16_t size)
|
struct rt_ringbuffer *rt_ringbuffer_create(rt_uint32_t size)
|
||||||
{
|
{
|
||||||
struct rt_ringbuffer *rb;
|
struct rt_ringbuffer *rb;
|
||||||
rt_uint8_t *pool;
|
rt_uint8_t *pool;
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2023-02-07 ZXY the first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ipc/ringbuffer.h>
|
||||||
|
|
||||||
|
#define RING_BUFFER_LEN 8
|
||||||
|
static struct ringbuffer *rb;
|
||||||
|
static char *str = "Hello, World new ringbuffer32";
|
||||||
|
typedef struct rb_example {
|
||||||
|
rt_uint32_t a;
|
||||||
|
rt_uint32_t b;
|
||||||
|
rt_uint32_t c;
|
||||||
|
} rb_example_t;
|
||||||
|
|
||||||
|
|
||||||
|
int ringbuffer_example(void)
|
||||||
|
{
|
||||||
|
rb_example_t data = {
|
||||||
|
.a = 1,
|
||||||
|
.b = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_ringbuffer * rb = rt_ringbuffer_create(sizeof(rb_example_t) * 2);
|
||||||
|
RT_ASSERT(rb != RT_NULL);
|
||||||
|
|
||||||
|
rt_kprintf("Put data to ringbuffer, a: %d b: %d size: %d\n", data.a, data.b, sizeof(data));
|
||||||
|
rt_ringbuffer_put(rb, (rt_uint8_t *)&data, sizeof(data));
|
||||||
|
|
||||||
|
|
||||||
|
rb_example_t recv_data;
|
||||||
|
rt_size_t recv = rt_ringbuffer_get(rb, (rt_uint8_t *)&recv_data, sizeof(recv_data));
|
||||||
|
RT_ASSERT(recv == sizeof(recv_data));
|
||||||
|
rt_kprintf("Get data from ringbuffer, a: %d b: %d size: %d\n", recv_data.a, recv_data.b, sizeof(recv_data));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(ringbuffer_example, ringbuffer example);
|
||||||
|
|
||||||
|
|
||||||
|
int ringbuffer_force_example(void)
|
||||||
|
{
|
||||||
|
uint8_t test[6] = {1,2,3,4,5,6};
|
||||||
|
struct rt_ringbuffer * rb;
|
||||||
|
rb = rt_ringbuffer_create(4);
|
||||||
|
RT_ASSERT(rb != RT_NULL);
|
||||||
|
|
||||||
|
rt_kprintf("Put data to ringbuffer, %d %d %d %d %d %d\n", test[0],test[1],test[2],test[3],test[4],test[5]);
|
||||||
|
rt_ringbuffer_put_force(rb, (rt_uint8_t *)&test, sizeof(test));
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t recv_data[4]={0};
|
||||||
|
rt_ringbuffer_get(rb, (rt_uint8_t *)&recv_data, sizeof(test));
|
||||||
|
rt_kprintf("Get data from ringbuffer, %d %d %d %d\n", recv_data[0],recv_data[1],recv_data[2],recv_data[3]);
|
||||||
|
rt_kprintf("write mirror: %d read mirror: %d\n", rb->write_mirror,rb->read_mirror);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(ringbuffer_force_example, ringbuffer example);
|
||||||
|
|
||||||
|
static void consumer_thread_entry(void *arg)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (1 == rt_ringbuffer_getchar(rb, &ch))
|
||||||
|
{
|
||||||
|
rt_kprintf("[Consumer] <- %c\n", ch);
|
||||||
|
}
|
||||||
|
rt_thread_mdelay(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ringbuffer_sample(int argc, char** argv)
|
||||||
|
{
|
||||||
|
rt_thread_t tid;
|
||||||
|
rt_uint16_t i = 0;
|
||||||
|
rb = rt_ringbuffer_create(RING_BUFFER_LEN);
|
||||||
|
if (rb == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("Can't create ringbffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tid = rt_thread_create("consumer", consumer_thread_entry, RT_NULL,
|
||||||
|
1024, RT_THREAD_PRIORITY_MAX/3, 20);
|
||||||
|
if (tid == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_ringbuffer_destroy(rb);
|
||||||
|
}
|
||||||
|
rt_thread_startup(tid);
|
||||||
|
while (str[i] != '\0')
|
||||||
|
{
|
||||||
|
rt_kprintf("[Producer] -> %c\n", str[i]);
|
||||||
|
rt_ringbuffer_putchar(rb, str[i++]);
|
||||||
|
rt_thread_mdelay(500);
|
||||||
|
}
|
||||||
|
rt_thread_delete(tid);
|
||||||
|
rt_ringbuffer_destroy(rb);
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(ringbuffer_sample, Start a producer and a consumer with a ringbuffer);
|
Loading…
Reference in New Issue