px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
px_ring_buf.h
1#ifndef __PX_RING_BUF_H__
2#define __PX_RING_BUF_H__
3/* =============================================================================
4 ____ ___ ____ ___ _ _ ___ __ __ ___ __ __ TM
5 | _ \ |_ _| / ___| / _ \ | \ | | / _ \ | \/ | |_ _| \ \/ /
6 | |_) | | | | | | | | | | \| | | | | | | |\/| | | | \ /
7 | __/ | | | |___ | |_| | | |\ | | |_| | | | | | | | / \
8 |_| |___| \____| \___/ |_| \_| \___/ |_| |_| |___| /_/\_\
9
10 Copyright (c) 2008 Pieter Conradie <https://piconomix.com>
11
12 License: MIT
13 https://github.com/piconomix/px-fwlib/blob/master/LICENSE.md
14
15 Title: px_ring_buf.h : FIFO ring buffer
16 Author(s): Pieter Conradie
17 Creation Date: 2008-08-06
18
19============================================================================= */
20
21/**
22 * @ingroup UTILS
23 * @defgroup PX_RING_BUFFER px_ring_buf.h : FIFO ring buffer
24 *
25 * A data structure that uses a single, fixed-size buffer as if it were
26 * connected end-to-end (circular).
27 *
28 * File(s):
29 * - utils/inc/px_ring_buf.h
30 * - utils/src/px_ring_buf.c
31 *
32 * A fixed-sized array is managed as a FIFO buffer with a "zero-copy" policy,
33 * i.e. data is not shifted (copied) when data is removed or added to the
34 * buffer. If more data is written to the buffer than there is space for, it is
35 * ignored/discarded; no buffer overflow vulnerability.
36 *
37 * In this implementation, the maximum number of bytes that can be stored is
38 * one less than the size of the fixed-size buffer, e.g. if the buffer size is
39 * 8 bytes, then a maximum of 7 bytes can be stored.
40 *
41 * Reference:
42 * - http://en.wikipedia.org/wiki/Circular_buffer
43 *
44 * Example:
45 *
46 * ```
47 * Buffer is empty:
48 *
49 * wr
50 * |
51 * [x][x][x][x][x][x][x][x]
52 * |
53 * rd
54 *
55 * One byte is written ('1') to the buffer:
56 *
57 * wr
58 * |
59 * [x][x][x][x][1][x][x][x]
60 * |
61 * rd
62 *
63 * One byte is read ('1'); buffer is empty again:
64 *
65 * wr
66 * |
67 * [x][x][x][x][x][x][x][x]
68 * |
69 * rd
70 *
71 * 5 bytes are written ('2','3','4','5','6'); buffer wraps:
72 *
73 * wr
74 * |
75 * [5][6][x][x][x][2][3][4]
76 * |
77 * rd
78 *
79 * 2 more bytes are written ('7','8'); buffer is full:
80 *
81 * wr
82 * |
83 * [5][6][7][8][x][2][3][4]
84 * |
85 * rd
86 * ```
87 *
88 * @{
89 */
90
91/* _____STANDARD INCLUDES____________________________________________________ */
92#include <stdlib.h>
93
94/* _____PROJECT INCLUDES_____________________________________________________ */
95#include "px_defs.h"
96
97#ifdef __cplusplus
98extern "C" {
99#endif
100/* _____DEFINITIONS__________________________________________________________ */
101/// Ring buffer index size definition
102typedef uint16_t px_ring_buf_idx_t;
103
104/* _____TYPE DEFINITIONS_____________________________________________________ */
105/// Ring buffer structure
106typedef struct
107{
108 uint8_t * buf; ///< Pointer to fixed-size buffer
109 px_ring_buf_idx_t buf_size; ///< Size of fixed-size buffer
110 volatile px_ring_buf_idx_t idx_wr; ///< Index that is next open position to write to in the buffer
111 volatile px_ring_buf_idx_t idx_rd; ///< Index to the next byte to be read from the buffer
113
114/* _____GLOBAL VARIABLES_____________________________________________________ */
115
116/* _____GLOBAL FUNCTION DECLARATIONS_________________________________________ */
117/**
118 * Initialize the ring buffer.
119 *
120 * @param px_ring_buf Pointer to the ring buffer object
121 * @param buf Fixed-size data buffer
122 * @param buf_size Fixed-size data buffer size
123 */
124void px_ring_buf_init(px_ring_buf_t * px_ring_buf,
125 uint8_t * buf,
126 px_ring_buf_idx_t buf_size);
127
128/**
129 * See if the ring buffer is empty.
130 *
131 * @param px_ring_buf Pointer to the ring buffer object
132 *
133 * @retval true buffer is empty
134 * @retval false buffer contains data
135 */
136bool px_ring_buf_is_empty(const px_ring_buf_t * px_ring_buf);
137
138/**
139 * See if the ring buffer is full.
140 *
141 * @param px_ring_buf Pointer to the ring buffer object
142 *
143 * @retval true buffer is full
144 * @retval false buffer is NOT full
145 */
146bool px_ring_buf_is_full(const px_ring_buf_t * px_ring_buf);
147
148/**
149 * Removed data from ring buffer.
150 *
151 * @param px_ring_buf Pointer to the ring buffer object
152 * @param nr_of_bytes Number of bytes to flush; 0 = flush everything
153 *
154 */
155void px_ring_buf_flush(px_ring_buf_t * px_ring_buf,
156 size_t nr_of_bytes);
157
158/**
159 * Write (store) a byte in the ring buffer.
160 *
161 * @param px_ring_buf Pointer to the ring buffer object
162 * @param data The byte to store in the ring buffer
163 *
164 * @retval true Byte has been stored in the ring buffer
165 * @retval false Buffer is full and byte was not stored
166 */
167bool px_ring_buf_wr_u8(px_ring_buf_t * px_ring_buf,
168 const uint8_t data);
169
170/**
171 * Write (store) data in the ring buffer
172 *
173 * @param px_ring_buf Pointer to the ring buffer object
174 * @param data Pointer to array of data to be stored in the
175 * ring buffer
176 * @param nr_of_bytes Number of data bytes to write
177 *
178 * @return px_ring_buf_idx_t The actual number of data bytes stored, which
179 * may be less than the number specified, because
180 * the buffer is full.
181 */
183 const void * data,
184 size_t nr_of_bytes);
185
186/**
187 * Read (retrieve) a byte from the ring buffer.
188 *
189 * @param px_ring_buf Pointer to the ring buffer object
190 * @param data Pointer to location where byte must be stored
191 *
192 * @retval true Valid byte has been retrieved
193 * @retval false Buffer is empty
194 */
195bool px_ring_buf_rd_u8(px_ring_buf_t * px_ring_buf,
196 uint8_t * data);
197
198/**
199 * Read (retrieve) data from the ring buffer.
200 *
201 * @param px_ring_buf Pointer to the ring buffer object
202 * @param data Pointer to location where data must be stored
203 * @param nr_of_bytes Number of bytes to read
204 *
205 * @return px_ring_buf_idx_t The actual number of bytes retrieved, which may
206 * be less than the number specified, because the
207 * buffer is empty.
208 */
210 void * data,
211 size_t nr_of_bytes);
212
213/**
214 * Peek data from the ring buffer, without advancing the read pointer.
215 *
216 * @param px_ring_buf Pointer to the ring buffer object
217 * @param data Pointer to location where data must be stored
218 * @param nr_of_bytes Number of bytes to peek
219 *
220 * @return px_ring_buf_idx_t The actual number of bytes peeked, which may
221 * be less than the number specified, because the
222 * buffer is empty.
223 */
225 void * data,
226 size_t nr_of_bytes);
227
228/**
229 * Get number of bytes stored in the buffer.
230 *
231 * @param px_ring_buf Pointer to the ring buffer object
232 * @return px_ring_buf_idx_t Number of bytes stored in the buffer
233 */
235
236/**
237 * Get number of free bytes available in buffer.
238 *
239 * Note: an empty buffer has one less byte than the buffer size
240 *
241 * @param px_ring_buf Pointer to the ring buffer object
242 * @return px_ring_buf_idx_t Number of bytes available in the buffer
243 */
245
246/**
247 * Report status of ring buffer.
248 *
249 * @param px_ring_buf Pointer to the ring buffer object
250 */
251void px_ring_buf_log_report(px_ring_buf_t * px_ring_buf);
252
253/* _____MACROS_______________________________________________________________ */
254
255#ifdef __cplusplus
256}
257#endif
258
259/// @}
260#endif
px_ring_buf_idx_t buf_size
Size of fixed-size buffer.
Definition: px_ring_buf.h:109
volatile px_ring_buf_idx_t idx_wr
Index that is next open position to write to in the buffer.
Definition: px_ring_buf.h:110
volatile px_ring_buf_idx_t idx_rd
Index to the next byte to be read from the buffer.
Definition: px_ring_buf.h:111
uint8_t * buf
Pointer to fixed-size buffer.
Definition: px_ring_buf.h:108
px_ring_buf_idx_t px_ring_buf_wr(px_ring_buf_t *px_ring_buf, const void *data, size_t nr_of_bytes)
Write (store) data in the ring buffer.
Definition: px_ring_buf.c:124
void px_ring_buf_init(px_ring_buf_t *px_ring_buf, uint8_t *buf, px_ring_buf_idx_t buf_size)
Initialize the ring buffer.
Definition: px_ring_buf.c:49
bool px_ring_buf_is_full(const px_ring_buf_t *px_ring_buf)
See if the ring buffer is full.
Definition: px_ring_buf.c:65
uint16_t px_ring_buf_idx_t
Ring buffer index size definition.
Definition: px_ring_buf.h:102
px_ring_buf_idx_t px_ring_buf_peek(px_ring_buf_t *px_ring_buf, void *data, size_t nr_of_bytes)
Peek data from the ring buffer, without advancing the read pointer.
Definition: px_ring_buf.c:207
px_ring_buf_idx_t px_ring_buf_get_count_used(px_ring_buf_t *px_ring_buf)
Get number of bytes stored in the buffer.
Definition: px_ring_buf.c:235
bool px_ring_buf_rd_u8(px_ring_buf_t *px_ring_buf, uint8_t *data)
Read (retrieve) a byte from the ring buffer.
Definition: px_ring_buf.c:155
bool px_ring_buf_wr_u8(px_ring_buf_t *px_ring_buf, const uint8_t data)
Write (store) a byte in the ring buffer.
Definition: px_ring_buf.c:102
px_ring_buf_idx_t px_ring_buf_get_count_free(px_ring_buf_t *px_ring_buf)
Get number of free bytes available in buffer.
Definition: px_ring_buf.c:262
px_ring_buf_idx_t px_ring_buf_rd(px_ring_buf_t *px_ring_buf, void *data, size_t nr_of_bytes)
Read (retrieve) data from the ring buffer.
Definition: px_ring_buf.c:176
bool px_ring_buf_is_empty(const px_ring_buf_t *px_ring_buf)
See if the ring buffer is empty.
Definition: px_ring_buf.c:60
void px_ring_buf_flush(px_ring_buf_t *px_ring_buf, size_t nr_of_bytes)
Removed data from ring buffer.
Definition: px_ring_buf.c:70
void px_ring_buf_log_report(px_ring_buf_t *px_ring_buf)
Report status of ring buffer.
Definition: px_ring_buf.c:289
Ring buffer structure.
Definition: px_ring_buf.h:107