|
| 1 | +/* |
| 2 | + * Copyright (c) 2006-2018, RT-Thread Development Team |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + * |
| 6 | + * Change Logs: |
| 7 | + * Date Author Notes |
| 8 | + */ |
1 | 9 | #ifndef RINGBUFFER_H__ |
2 | | -#ifndef RINGBUFFER_H__ |
3 | | -#define RINGBUFFER_H__ |
4 | 10 | #define RINGBUFFER_H__ |
5 | 11 |
|
6 | | - |
7 | 12 | #ifdef __cplusplus |
8 | | -#ifdef __cplusplus |
9 | | -extern "C" { |
10 | 13 | extern "C" { |
11 | 14 | #endif |
12 | | -#endif |
13 | 15 |
|
14 | | - |
15 | | -#include <rtthread.h> |
16 | 16 | #include <rtthread.h> |
17 | 17 |
|
18 | | - |
19 | | -/* ring buffer */ |
20 | 18 | /* ring buffer */ |
21 | 19 | struct rt_ringbuffer |
22 | | -struct rt_ringbuffer |
23 | 20 | { |
24 | | -{ |
25 | | - rt_uint8_t *buffer_ptr; |
26 | 21 | rt_uint8_t *buffer_ptr; |
27 | 22 | /* use the msb of the {read,write}_index as mirror bit. You can see this as |
28 | | - /* use the msb of the {read,write}_index as mirror bit. You can see this as |
29 | | - * if the buffer adds a virtual mirror and the pointers point either to the |
30 | 23 | * if the buffer adds a virtual mirror and the pointers point either to the |
31 | 24 | * normal or to the mirrored buffer. If the write_index has the same value |
32 | | - * normal or to the mirrored buffer. If the write_index has the same value |
33 | 25 | * with the read_index, but in a different mirror, the buffer is full. |
34 | | - * with the read_index, but in a different mirror, the buffer is full. |
35 | | - * While if the write_index and the read_index are the same and within the |
36 | 26 | * While if the write_index and the read_index are the same and within the |
37 | 27 | * same mirror, the buffer is empty. The ASCII art of the ringbuffer is: |
38 | | - * same mirror, the buffer is empty. The ASCII art of the ringbuffer is: |
39 | | - * |
40 | 28 | * |
41 | 29 | * mirror = 0 mirror = 1 |
42 | | - * mirror = 0 mirror = 1 |
43 | 30 | * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
44 | | - * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
45 | | - * | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Full |
46 | 31 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Full |
47 | 32 | * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
48 | | - * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
49 | | - * read_idx-^ write_idx-^ |
50 | 33 | * read_idx-^ write_idx-^ |
51 | 34 | * |
52 | | - * |
53 | 35 | * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
54 | | - * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
55 | | - * | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty |
56 | 36 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty |
57 | 37 | * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
58 | | - * +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+ |
59 | | - * read_idx-^ ^-write_idx |
60 | 38 | * read_idx-^ ^-write_idx |
61 | 39 | * |
62 | | - * |
63 | 40 | * The tradeoff is we could only use 32KiB of buffer for 16 bit of index. |
64 | | - * The tradeoff is we could only use 32KiB of buffer for 16 bit of index. |
65 | | - * But it should be enough for most of the cases. |
66 | 41 | * But it should be enough for most of the cases. |
67 | 42 | * |
68 | | - * |
69 | | - * Ref: http://en.wikipedia.org/wiki/Circular_buffer#Mirroring */ |
70 | 43 | * Ref: http://en.wikipedia.org/wiki/Circular_buffer#Mirroring */ |
71 | 44 | rt_uint16_t read_mirror : 1; |
72 | | - rt_uint16_t read_mirror : 1; |
73 | 45 | rt_uint16_t read_index : 15; |
74 | | - rt_uint16_t read_index : 15; |
75 | | - rt_uint16_t write_mirror : 1; |
76 | 46 | rt_uint16_t write_mirror : 1; |
77 | 47 | rt_uint16_t write_index : 15; |
78 | | - rt_uint16_t write_index : 15; |
79 | | - /* as we use msb of index as mirror bit, the size should be signed and |
80 | 48 | /* as we use msb of index as mirror bit, the size should be signed and |
81 | 49 | * could only be positive. */ |
82 | | - * could only be positive. */ |
83 | 50 | rt_int16_t buffer_size; |
84 | | - rt_int16_t buffer_size; |
85 | | -}; |
86 | 51 | }; |
87 | 52 |
|
88 | | - |
89 | 53 | enum rt_ringbuffer_state |
90 | | -enum rt_ringbuffer_state |
91 | | -{ |
92 | 54 | { |
93 | | - RT_RINGBUFFER_EMPTY, |
94 | 55 | RT_RINGBUFFER_EMPTY, |
95 | 56 | RT_RINGBUFFER_FULL, |
96 | | - RT_RINGBUFFER_FULL, |
97 | | - /* half full is neither full nor empty */ |
98 | 57 | /* half full is neither full nor empty */ |
99 | 58 | RT_RINGBUFFER_HALFFULL, |
100 | | - RT_RINGBUFFER_HALFFULL, |
101 | | -}; |
102 | 59 | }; |
103 | 60 |
|
104 | | - |
105 | 61 | /** |
106 | | -/** |
107 | | - * RingBuffer for DeviceDriver |
108 | 62 | * RingBuffer for DeviceDriver |
109 | 63 | * |
110 | | - * |
111 | | - * Please note that the ring buffer implementation of RT-Thread |
112 | 64 | * Please note that the ring buffer implementation of RT-Thread |
113 | 65 | * has no thread wait or resume feature. |
114 | | - * has no thread wait or resume feature. |
115 | 66 | */ |
116 | | - */ |
117 | | -void rt_ringbuffer_init(struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int16_t size); |
118 | 67 | void rt_ringbuffer_init(struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int16_t size); |
119 | 68 | void rt_ringbuffer_reset(struct rt_ringbuffer *rb); |
120 | | -void rt_ringbuffer_reset(struct rt_ringbuffer *rb); |
121 | | -rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length); |
122 | 69 | rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length); |
123 | 70 | rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length); |
124 | | -rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length); |
125 | 71 | rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch); |
126 | | -rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch); |
127 | | -rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch); |
128 | 72 | rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch); |
129 | 73 | rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint16_t length); |
130 | | -rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint16_t length); |
131 | | -rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch); |
132 | 74 | rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch); |
133 | 75 | rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb); |
134 | | -rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb); |
135 | 76 |
|
136 | | - |
137 | | -#ifdef RT_USING_HEAP |
138 | 77 | #ifdef RT_USING_HEAP |
139 | 78 | struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t length); |
140 | | -struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t length); |
141 | | -void rt_ringbuffer_destroy(struct rt_ringbuffer *rb); |
142 | 79 | void rt_ringbuffer_destroy(struct rt_ringbuffer *rb); |
143 | 80 | #endif |
144 | | -#endif |
145 | 81 |
|
146 | | - |
147 | | -rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb) |
148 | 82 | rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb) |
149 | 83 | { |
150 | | -{ |
151 | | - RT_ASSERT(rb != RT_NULL); |
152 | 84 | RT_ASSERT(rb != RT_NULL); |
153 | 85 | return rb->buffer_size; |
154 | | - return rb->buffer_size; |
155 | 86 | } |
156 | | -} |
157 | | - |
158 | 87 |
|
159 | 88 | /** return the size of empty space in rb */ |
160 | 89 | #define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb)) |
|
0 commit comments