瀏覽代碼

[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>
螺丝松掉的人 2 年之前
父節點
當前提交
20459ec4d3
共有 3 個文件被更改,包括 130 次插入27 次删除
  1. 14 17
      components/drivers/include/ipc/ringbuffer.h
  2. 10 10
      components/drivers/ipc/ringbuffer.c
  3. 106 0
      examples/test/ringbuffer_test.c

+ 14 - 17
components/drivers/include/ipc/ringbuffer.h

@@ -37,18 +37,15 @@ struct rt_ringbuffer
      * | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty
      * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
      * 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.
-     *
-     * Ref: http://en.wikipedia.org/wiki/Circular_buffer#Mirroring */
-    rt_uint16_t read_mirror : 1;
-    rt_uint16_t read_index : 15;
-    rt_uint16_t write_mirror : 1;
-    rt_uint16_t write_index : 15;
+     */
+
+    rt_uint32_t read_mirror : 1;
+    rt_uint32_t read_index : 31;
+    rt_uint32_t write_mirror : 1;
+    rt_uint32_t write_index : 31;
     /* as we use msb of index as mirror bit, the size should be signed and
      * could only be positive. */
-    rt_int16_t buffer_size;
+    rt_int32_t buffer_size;
 };
 
 enum rt_ringbuffer_state
@@ -65,19 +62,19 @@ enum rt_ringbuffer_state
  * Please note that the ring buffer implementation of RT-Thread
  * 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);
-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_force(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_uint32_t length);
 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_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_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
 rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
 
 #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);
 #endif
 
@@ -88,14 +85,14 @@ void rt_ringbuffer_destroy(struct rt_ringbuffer *rb);
  *
  * @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);
     return rb->buffer_size;
 }
 
 /** 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

+ 10 - 10
components/drivers/ipc/ringbuffer.c

@@ -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
  *
@@ -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,
                         rt_uint8_t           *pool,
-                        rt_int16_t            size)
+                        rt_int32_t            size)
 {
     RT_ASSERT(rb != RT_NULL);
     RT_ASSERT(size > 0);
@@ -63,9 +63,9 @@ RTM_EXPORT(rt_ringbuffer_init);
  */
 rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb,
                             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);
 
@@ -116,9 +116,9 @@ RTM_EXPORT(rt_ringbuffer_put);
  */
 rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb,
                                   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);
 
@@ -177,7 +177,7 @@ RTM_EXPORT(rt_ringbuffer_put_force);
  */
 rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
                             rt_uint8_t           *ptr,
-                            rt_uint16_t           length)
+                            rt_uint32_t           length)
 {
     rt_size_t size;
 
@@ -192,7 +192,7 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
 
     /* less data */
     if (size < length)
-        length = (rt_uint16_t)size;
+        length = size;
 
     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)
     {
-        rb->read_index += (rt_uint16_t)size;
+        rb->read_index += 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.
  */
-struct rt_ringbuffer *rt_ringbuffer_create(rt_uint16_t size)
+struct rt_ringbuffer *rt_ringbuffer_create(rt_uint32_t size)
 {
     struct rt_ringbuffer *rb;
     rt_uint8_t *pool;

+ 106 - 0
examples/test/ringbuffer_test.c

@@ -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);