Skip to content

Commit e074495

Browse files
author
zigam
committed
- merging new implementation of ring buffer
2 parents 7ef9548 + 08df84e commit e074495

8 files changed

Lines changed: 890 additions & 336 deletions

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,7 @@ Mkfile.old
5252
dkms.conf
5353

5454
doc/html/*
55-
doc/rtf/*
55+
doc/rtf/*
56+
57+
.vscode
58+
main.c

Doxygen

Lines changed: 52 additions & 102 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 170 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,43 @@
11
# Ring buffer
2-
Ring buffer modules is implemented for general used in embedded C code. It support three data types: uint32_t, int32_t and float32_t. Data type is not importatn at initialization point as it is only how stored information are interpreted by C compiler.
2+
This module constains ring buffer implementation for general purpose usage.
3+
It can work with simple byte size item or larger size items. Module is
4+
written in such a way that all details are hidden from user. Additionally
5+
buffers are created as individual, separated instances so different
6+
instances of buffer can be configured differently in order to addopt application needs.
37

4-
Ring buffer memory space is dynamically allocated and success of allocation is taken into consideration before using that instance. Deallocation on exsisting ring buffer instance is not supported as it's not good practice to free memory in C world.
8+
Override mode is supported where buffer is never full and new values are
9+
always overriding old values regarding of reading rate. This functionality
10+
is very usefull for filter sampling storage purposes.
511

6-
#### Dependencies
12+
Additionally buffers data storage can be allocated statically if dynamic
13+
allocation is not perfered by application. Look at the example of
14+
static allocation of memory.
15+
16+
There are two distinct get functions: "ring_buffer_get" and "ring_buffer_get_by_index".
17+
First one returns oldest item in buffer and acts as a FIFO, meaning that tail increments
18+
at every call of it. On the other side "ring_buffer_get_by_index" returns value relative
19+
to input argument value and does not increment tail pointer! It is important not to
20+
use those two get functionalities simultaniously.
21+
22+
Function "ring_buffer_get_by_index" supports two kind of access types:
23+
24+
1. NORMAL ACCESS: classical aproach, where index is a positive
25+
number and simple represants buffer index. This approach
26+
has no information about time stamps of values inside buffer.
27+
Range: [0, size)
28+
29+
2. INVERS ACCESS: chronologically aproach, where index is a negative number.
30+
Meaning that "-1" value will always returns latest value in
31+
buffer and "-size" index value will return oldest value
32+
in buffer. This feature becomes very handy when performing
33+
digital filtering where ring buffer can represants sample
34+
window and thus easy access from oldest to latest sample
35+
can be achieved with invers access.
36+
Range of index: [-size, -1]
37+
38+
39+
40+
## Dependencies
741

842
Definition of flaot32_t must be provided by user. In current implementation it is defined in "*project_config.h*". Just add following statement to your code where it suits the best.
943

@@ -12,19 +46,141 @@ Definition of flaot32_t must be provided by user. In current implementation it i
1246
typedef float float32_t;
1347
```
1448

15-
#### API
49+
## API
50+
51+
- ring_buffer_status_t **ring_buffer_init** (p_ring_buffer_t * p_ring_buffer, const uint32_t size, const ring_buffer_attr_t * const p_attr);
52+
- ring_buffer_status_t **ring_buffer_is_init** (p_ring_buffer_t buf_inst, bool * const p_is_init);
53+
54+
- ring_buffer_status_t **ring_buffer_add** (p_ring_buffer_t buf_inst, const void * const p_item);
55+
- ring_buffer_status_t **ring_buffer_get** (p_ring_buffer_t buf_inst, void * const p_item);
56+
- ring_buffer_status_t **ring_buffer_get_by_index** (p_ring_buffer_t buf_inst, void * const p_item, const int32_t idx);
57+
- ring_buffer_status_t **ring_buffer_reset** (p_ring_buffer_t buf_inst);
58+
59+
- ring_buffer_status_t **ring_buffer_get_name** (p_ring_buffer_t buf_inst, char * const p_name);
60+
- ring_buffer_status_t **ring_buffer_get_taken** (p_ring_buffer_t buf_inst, uint32_t * const p_taken);
61+
- ring_buffer_status_t **ring_buffer_get_free** (p_ring_buffer_t buf_inst, uint32_t * const p_free);
62+
- ring_buffer_status_t **ring_buffer_get_size** (p_ring_buffer_t buf_inst, uint32_t * const p_size);
63+
- ring_buffer_status_t **ring_buffer_get_item_size** (p_ring_buffer_t buf_inst, uint32_t * const p_item_size);
64+
65+
66+
NOTE: Detailed description of functions can be found in doxygen (doc/**ring_buffer_Vx_x_x.zip**)!
67+
68+
## Usage
1669

17-
API of ring buffer constist of three blocks, those are: initialization, add element to buffer and get element from buffer. Note that getting element from buffer intakes intiger parameter as support normal and invers access. Invers access meas that get function will return time related element from ring buffer. This feature is specially handy when comes to digital filter calculations.
70+
### Initialization examples
1871

19-
#### List of functions:
20-
- ring_buffer_status_t **ring_buffer_init** (p_ring_buffer_t * p_ring_buffer, const uint32_t size);
72+
```C
73+
// My ring buffer instance
74+
p_ring_buffer_t my_ringbuffer = NULL;
75+
76+
// Initialization as default buffer with size of 10 items + Dynamica allocation of memory
77+
if ( eRING_BUFFER_OK != ring_buffer_init( &my_ringbuffer, 10, NULL ))
78+
{
79+
// Init failed...
80+
}
81+
82+
83+
// My second ring buffer instance
84+
p_ring_buffer_t my_ringbuffer_2 = NULL;
85+
ring_buffer_attr_t my_ringbuffer_2_attr;
86+
87+
// Customize ring buffer:
88+
my_ring_buffer_2_attr.name = "Dynamic allocated buffer";
89+
my_ring_buffer_2_attr.p_mem = NULL;
90+
my_ring_buffer_2_attr.item_size = sizeof(float32_t);
91+
my_ring_buffer_2_attr.override = true;
92+
93+
// Initialization as customized buffer with size of 32 items + Dynamic allocation of memory
94+
if ( eRING_BUFFER_OK != ring_buffer_init( &my_ringbuffer_2, 32, &my_ring_buffer_2_attr ))
95+
{
96+
// Init failed...
97+
}
98+
99+
100+
// My third ring buffer instance
101+
p_ring_buffer_t my_ringbuffer_3 = NULL;
102+
ring_buffer_attr_t my_ringbuffer_3_attr;
103+
uint8_t buf_mem[128];
104+
105+
// Customize ring buffer:
106+
my_ring_buffer_3_attr.name = "Static allocated buffer";
107+
my_ring_buffer_3_attr.p_mem = &buf_mem;
108+
my_ring_buffer_3_attr.item_size = sizeof(float32_t);
109+
my_ring_buffer_3_attr.override = true;
110+
111+
// Initialization as customised buffer with size of 32 items + Static allocation of memory
112+
if ( eRING_BUFFER_OK != ring_buffer_init( &my_ringbuffer_2, 32, &my_ring_buffer_2_attr ))
113+
{
114+
// Init failed...
115+
}
116+
117+
```
21118

22-
- ring_buffer_status_t **ring_buffer_add_u32** (p_ring_buffer_t buf_inst, const uint32_t data);
23-
- ring_buffer_status_t **ring_buffer_add_i32** (p_ring_buffer_t buf_inst, const int32_t data );
24-
- ring_buffer_status_t **ring_buffer_add_f** (p_ring_buffer_t buf_inst, const float32_t data);
25-
- uint32_t **ring_buffer_get_u32** (p_ring_buffer_t buf_inst, const int32_t idx);
26-
- int32_t **ring_buffer_get_i32** (p_ring_buffer_t buf_inst, const int32_t idx);
27-
- float32_t **ring_buffer_get_f** (p_ring_buffer_t buf_inst, const int32_t idx);
119+
### Get items out of buffer examples
28120

29-
NOTE: Detailed description of fucntion can be found in doxygen!
121+
```C
122+
// My ring buffer is initialized for byte items
123+
uint8_t item;
124+
125+
// =============================================================
126+
// GETTING VALUE
127+
// =============================================================
128+
129+
// Pump all items out of buffer
130+
ring_buffer_get_taken( my_ring_buffer, &taken );
131+
132+
for ( i = 0; i < taken; i++ )
133+
{
134+
ring_buffer_get( my_ring_buffer, &item );
135+
136+
// Do something with "item" value here...
137+
}
138+
139+
// OR equivalent
140+
141+
while( eRING_BUFFER_EMPTY != ring_buffer_get( my_ring_buffer, &item ))
142+
{
143+
// Do something with "item" value here...
144+
}
145+
146+
147+
// =============================================================
148+
// GETTING VALUE BY INDEX
149+
// =============================================================
150+
151+
// Get value at index 0 from ring buffer - classic access
152+
ring_buffer_get_by_index( my_ringbuffer, &item, 0 );
153+
154+
// Get latest value from ring buffer - inverted access
155+
ring_buffer_get_by_index( my_ringbuffer, &item, -1 );
156+
157+
// Get oldest value from ring buffer - inverted access
158+
ring_buffer_get_by_index( my_ringbuffer, &item, -10 );
159+
160+
161+
// ***** Example of filter usage of getting value by index ****
162+
163+
float32_t sample;
164+
165+
// Make convolution
166+
for ( i = 0; i < filter_inst -> order; i++ )
167+
{
168+
// Get sample
169+
ring_buffer_get_by_index( filter_inst->p_x, &sample, (( -i ) - 1 ));
170+
171+
// Convolve
172+
y += ( filter_inst->p_a[i] * sample );
173+
}
174+
175+
```
176+
177+
### Add item to buffer examples
178+
179+
```C
180+
// My ring buffer is initialized for byte items
181+
uint8_t item = 42;
182+
183+
// Add value to buffer
184+
ring_buffer_add( my_ringbuffer, &item );
185+
```
30186

doc/ring_buffer_rev1.0.1.zip

-241 KB
Binary file not shown.

doc/ring_buffer_rev2.0.0.zip

273 KB
Binary file not shown.

0 commit comments

Comments
 (0)