1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-08-25     armink       the first version
9  */
10 
11 #ifndef _RINGBLK_BUF_H_
12 #define _RINGBLK_BUF_H_
13 
14 #include <rtdef.h>
15 #include <rtconfig.h>
16 
17 /*
18  * Introduction:
19  * The rbb is the ring buffer which is composed with many blocks. It is different from the ring buffer.
20  * The ring buffer is only composed with chars. The rbb put and get supported zero copies. So the rbb
21  * is very suitable for put block and get block by a certain order. Such as DMA block transmit,
22  * communicate frame send/recv, and so on.
23  */
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 enum rt_rbb_status
30 {
31     /* unused status when first initialize or after blk_free() */
32     RT_RBB_BLK_UNUSED,
33     /* initialized status after blk_alloc() */
34     RT_RBB_BLK_INITED,
35     /* put status after blk_put() */
36     RT_RBB_BLK_PUT,
37     /* get status after blk_get() */
38     RT_RBB_BLK_GET,
39 };
40 typedef enum rt_rbb_status rt_rbb_status_t;
41 
42 /**
43  * the block of rbb
44  */
45 struct rt_rbb_blk
46 {
47     rt_rbb_status_t status :8;
48     /* less then 2^24 */
49     rt_size_t size :24;
50     rt_uint8_t *buf;
51     rt_slist_t list;
52 };
53 typedef struct rt_rbb_blk *rt_rbb_blk_t;
54 
55 /**
56  * Rbb block queue: the blocks (from block1->buf to blockn->buf) memory which on this queue is continuous.
57  */
58 struct rt_rbb_blk_queue
59 {
60     rt_rbb_blk_t blocks;
61     rt_size_t blk_num;
62 };
63 typedef struct rt_rbb_blk_queue *rt_rbb_blk_queue_t;
64 
65 /**
66  * ring block buffer
67  */
68 struct rt_rbb
69 {
70     rt_uint8_t *buf;
71     rt_size_t buf_size;
72     /* all of blocks */
73     rt_rbb_blk_t blk_set;
74     rt_size_t blk_max_num;
75     /* saved the initialized and put status blocks */
76     rt_slist_t blk_list;
77     /* point to tail node */
78     rt_slist_t *tail;
79     /* free node list */
80     rt_slist_t free_list;
81     struct rt_spinlock spinlock;
82 };
83 typedef struct rt_rbb *rt_rbb_t;
84 
85 /* rbb (ring block buffer) API */
86 void rt_rbb_init(rt_rbb_t rbb, rt_uint8_t *buf, rt_size_t buf_size, rt_rbb_blk_t block_set, rt_size_t blk_max_num);
87 rt_size_t rt_rbb_get_buf_size(rt_rbb_t rbb);
88 
89 #ifdef RT_USING_HEAP
90 rt_rbb_t rt_rbb_create(rt_size_t buf_size, rt_size_t blk_max_num);
91 void rt_rbb_destroy(rt_rbb_t rbb);
92 #endif
93 
94 /* rbb block API */
95 rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size);
96 void rt_rbb_blk_put(rt_rbb_blk_t block);
97 rt_rbb_blk_t rt_rbb_blk_get(rt_rbb_t rbb);
98 rt_size_t rt_rbb_blk_size(rt_rbb_blk_t block);
99 rt_uint8_t *rt_rbb_blk_buf(rt_rbb_blk_t block);
100 void rt_rbb_blk_free(rt_rbb_t rbb, rt_rbb_blk_t block);
101 
102 /* rbb block queue API */
103 rt_size_t rt_rbb_blk_queue_get(rt_rbb_t rbb, rt_size_t queue_data_len, rt_rbb_blk_queue_t blk_queue);
104 rt_size_t rt_rbb_blk_queue_len(rt_rbb_blk_queue_t blk_queue);
105 rt_uint8_t *rt_rbb_blk_queue_buf(rt_rbb_blk_queue_t blk_queue);
106 void rt_rbb_blk_queue_free(rt_rbb_t rbb, rt_rbb_blk_queue_t blk_queue);
107 rt_size_t rt_rbb_next_blk_queue_len(rt_rbb_t rbb);
108 
109 
110 #ifdef __cplusplus
111 }
112 #endif
113 
114 #endif /* _RINGBLK_BUF_H_ */
115