LwRB latest-develop documentation¶
Welcome to the documentation for version latest-develop.
LwRB is a generic FIFO (First In; First Out) buffer library optimized for embedded systems.
Download library · Getting started · Open Github
Features¶
Written in ANSI C99, compatible with
size_t
for size data typesPlatform independent, no architecture specific code
FIFO (First In First Out) buffer implementation
No dynamic memory allocation, data is static array
Uses optimized memory copy instead of loops to read/write data from/to memory
Thread safe when used as pipe with single write and single read entries
Interrupt safe when used as pipe with single write and single read entries
Suitable for DMA transfers from and to memory with zero-copy overhead between buffer and application memory
Supports data peek, skip for read and advance for write
Implements support for event notifications
User friendly MIT license
Requirements¶
C compiler
Less than
1kB
of non-volatile memory
Contribute¶
Fresh contributions are always welcome. Simple instructions to proceed:
Fork Github repository
Respect C style & coding rules used by the library
Create a pull request to
develop
branch with new features or bug fixes
Alternatively you may:
Report a bug
Ask for a feature request
Example code¶
Minimalistic example code to read and write data to buffer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* Buffer variables */
lwrb_t buff; /* Declare ring buffer structure */
uint8_t buff_data[8]; /* Declare raw buffer data array */
/* Application variables */
uint8_t data[2]; /* Application working data */
size_t len;
/* Application code ... */
lwrb_init(&buff, buff_data, sizeof(buff_data)); /* Initialize buffer */
/* Write 4 bytes of data */
lwrb_write(&buff, "0123", 4);
/* Try to read buffer */
/* len holds number of bytes read */
/* Read until len == 0, when buffer is empty */
while ((len = lwrb_read(&buff, data, sizeof(data))) > 0) {
printf("Successfully read %d bytes\r\n", (int)len);
}
|
License¶
MIT License
Copyright (c) 2020 Tilen MAJERLE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Table of contents¶
Getting started¶
Download library¶
Library is primarly hosted on Github.
Download latest release from releases area on Github
Clone develop branch for latest development
Download from releases¶
All releases are available on Github releases area.
Clone from Github¶
First-time clone¶
Download and install
git
if not alreadyOpen console and navigate to path in the system to clone repository to. Use command
cd your_path
Clone repository with one of available
3
optionsRun
git clone --recurse-submodules https://github.com/MaJerle/lwrb
command to clone entire repository, including submodulesRun
git clone --recurse-submodules --branch develop https://github.com/MaJerle/lwrb
to clone development branch, including submodulesRun
git clone --recurse-submodules --branch master https://github.com/MaJerle/lwrb
to clone latest stable branch, including submodules
Navigate to
examples
directory and run favourite example
Update cloned to latest version¶
Open console and navigate to path in the system where your resources repository is. Use command
cd your_path
Run
git pull origin master --recurse-submodules
command to pull latest changes and to fetch latest changes from submodulesRun
git submodule foreach git pull origin master
to update & merge all submodules
Note
This is preferred option to use when you want to evaluate library and run prepared examples. Repository consists of multiple submodules which can be automatically downloaded when cloning and pulling changes from root repository.
Add library to project¶
At this point it is assumed that you have successfully download library, either cloned it or from releases page.
Copy
lwrb
folder to your projectAdd
lwrb/src/include
folder to include path of your toolchainAdd source files from
lwrb/src/
folder to toolchain buildBuild the project
Minimal example code¶
Run below example to test and verify library
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include "lwrb/lwrb.h"
/* Buffer variables */
lwrb_t buff; /* Declare ring buffer structure */
uint8_t buff_data[8]; /* Declare raw buffer data array */
/* Application variables
uint8_t data[2]; /* Application working data */
/* Application code ... */
lwrb_init(&buff, buff_data, sizeof(buff_data)); /* Initialize buffer */
/* Write 4 bytes of data */
lwrb_write(&buff, "0123", 4);
/* Print number of bytes in buffer */
printf("Bytes in buffer: %d\r\n", (int)lwrb_get_full(&buff));
/* Will print "4" */
|
User manual¶
How it works¶
This section shows different buffer corner cases and provides basic understanding how data are managed internally.
Different buffer corner cases¶
Let’s start with reference of abbreviations in picture:
R
represents Read pointer. Read on read/write operations. Modified on read operation onlyW
represents Write pointer. Read on read/write operations. Modified on write operation onlyS
represents Size of buffer. Used on all operations, never modified (atomic value)Valid number of
W
andR
pointers are between0
andS - 1
Buffer size is
S = 8
, thus valid number range forW
andR
pointers is0 - 7
.R
andW
numbers overflow atS
, thus valid range is always0, 1, 2, 3, ..., S - 2, S - 1, 0, 1, 2, 3, ..., S - 2, S - 1, 0, ...
Example
S = 4
:0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
Maximal number of bytes buffer can hold is always
S - 1
, thus example buffer can hold up to7
bytesR
andW
pointers always point to the next read/write operationWhen
W == R
, buffer is considered empty.When
W == R - 1
, buffer is considered full.W == R - 1
is valid only ifW
andR
overflow at buffer sizeS
.Always add
S
to calculated number and then use modulusS
to get final value
Note
Example 1, add 2
numbers: 2 + 3 = (3 + 2 + S) % S = (3 + 2 + 4) % 4 = (5 + 4) % 4 = 1
Example 2, subtract 2
numbers: 2 - 3 = (2 - 3 + S) % S = (2 - 3 + 4) % 4 = (-1 + 4) % 4 = 3
Different buffer corner cases¶
Different image cases:
Case A: Buffer is empty as
W == R = 0 == 0
Case B: Buffer holds
W - R = 4 - 0 = 4
bytes asW > R
Case C: Buffer is full as
W == R - 1
or7 == 0 - 1
or7 = (0 - 1 + S) % S = (0 - 1 + 8) % 8 = (-1 + 8) % 8 = 7
R
andW
can holdS
different values, from0
toS - 1
, that is modulus ofS
Buffer holds
W - R = 7 - 0 = 7
bytes asW > R
Case D: Buffer holds
S - (R - W) = 8 - (5 - 3) = 6
bytes asR > W
Case E: Buffer is full as
W == R - 1
(4 = 5 - 1
) and holdsS - (R - W) = 8 - (5 - 4) ) = 7
bytes
Events¶
When using LwRB in the application, it may be useful to get notification on different events, such as info when something has been written or read to/from buffer.
Library has support for events that get called each time there has been a modification in the buffer data, that means on every read or write operation.
Some use cases:
Notify application layer that LwRB operation has been executed and send debug message
Unlock semaphore when sufficient amount of bytes have been written/read from/to buffer when application uses operating system
Write notification to message queue at operating system level to wakeup another task
Note
Every operation that modified read or write internal pointers, is considered as read or write operation. An exception is reset event that sets both internal pointers to 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /**
* \brief Buffer event function
*/
void
my_buff_evt_fn(lwrb_t* buff, lwrb_evt_type_t type, size_t len) {
switch (type) {
case LWRB_EVT_RESET:
printf("[EVT] Buffer reset event!\r\n");
break;
case LWRB_EVT_READ:
printf("[EVT] Buffer read event: %d byte(s)!\r\n", (int)len);
break;
case LWRB_EVT_WRITE:
printf("[EVT] Buffer write event: %d byte(s)!\r\n", (int)len);
break;
default: break;
}
}
/* Later in the code... */
lwrb_t buff;
uint8_t buff_data[8];
/* Init buffer and set event function */
lwrb_init(&buff, buff_data, sizeof(buff_data));
lwrb_set_evt_fn(&buff, my_buff_evt_fn);
|
DMA on embedded systems¶
One of the key features of LwRB library is that it can be seamlessly integrated with DMA controllers on embedded systems.
Note
DMA stands for Direct Memory Access controller and is usually used to off-load CPU. More about DMA is available on Wikipedia.
DMA controllers normally use source and destination memory addresses to transfer data in-between. This features, together with LwRB, allows seamless integration and zero-copy of application data at interrupts after DMA transfer has been completed. Some manual work is necessary to be handled, but this is very minor in comparison of writing byte-by-byte to buffer at (for example) each received character.
Below are 2
common use cases:
DMA transfers data from LwRB memory to (usually) some hardware IP
DMA transfers data from hardware IP to memory
Zero-copy data from memory¶
This describes how to pass LwRB output memory address as pointer to DMA (or any other processing function). After all the data are successfully processed, application can skip processed data and free buff for new data being written to it.
Data transfer from memory to hardware IP¶
Case A: Initial state, buffer is full and holds
7
bytesCase B: State after skipping
R
pointer for3
bytes. Buffer now holds4
remaining bytesCase C: Buffer is empty, no more memory available for read operation
Code example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include "lwrb/lwrb.h"
/* Declare buffer variables */
lwrb_t buff;
uint8_t buff_data[8];
size_t len;
uint8_t* data;
/* Initialize buffer, use buff_data as data array */
lwrb_init(&buff, buff_data, sizeof(buff_data));
/* Use write, read operations, process data */
/* ... */
/* IMAGE PART A */
/* At this stage, we have buffer as on image above */
/* R = 5, W = 4, buffer is considered full */
/* Get length of linear memory at read pointer */
/* Function returns 3 as we can read 3 bytes from buffer in sequence */
/* When function returns 0, there is no memory available in the buffer for read anymore */
if ((len = lwrb_get_linear_block_read_length(&buff)) > 0) {
/* Get pointer to first element in linear block at read address */
/* Function returns &buff_data[5] */
data = lwrb_get_linear_block_read_address(&buff);
/* Send data via DMA and wait to finish (for sake of example) */
send_data(data, len);
/* Now skip sent bytes from buffer = move read pointer */
lwrb_skip(&buff, len);
/* Now R points to top of buffer, R = 0 */
/* At this point, we are at image part B */
}
/* IMAGE PART B */
/* Get length of linear memory at read pointer */
/* Function returns 4 as we can read 4 bytes from buffer in sequence */
/* When function returns 0, there is no memory available in the buffer for read anymore */
if ((len = lwrb_get_linear_block_read_length(&buff)) > 0) {
/* Get pointer to first element in linear block at read address */
/* Function returns &buff_data[0] */
data = lwrb_get_linear_block_read_address(&buff);
/* Send data via DMA and wait to finish (for sake of example) */
send_data(data, len);
/* Now skip sent bytes from buffer = move read pointer */
/* Read pointer is moved for len bytes */
lwrb_skip(&buff, len);
/* Now R points to 4, that is R == W and buffer is now empty */
/* At this point, we are at image part C */
}
/* IMAGE PART C */
/* Buffer is considered empty as R == W */
|
Part A on image clearly shows that not all data bytes are linked in single contiguous block of memory. To send all bytes from lwrb, it might be necessary to repeat procedure multiple times
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* Initialization part skipped */
/* Get length of linear memory at read pointer */
/* When function returns 0, there is no memory available in the buffer for read anymore */
while ((len = lwrb_get_linear_block_read_length(&buff)) > 0) {
/* Get pointer to first element in linear block at read address */
data = lwrb_get_linear_block_read_address(&buff);
/* If max length needs to be considered */
/* simply decrease it and use smaller len on skip function */
if (len > max_len) {
len = max_len;
}
/* Send data via DMA and wait to finish (for sake of example) */
send_data(data, len);
/* Now skip sent bytes from buffer = move read pointer */
lwrb_skip(&buff, len);
}
|
Zero-copy data to memory¶
Similar to reading data from buffer with zero-copy overhead, it is possible to write to lwrb with zero-copy overhead too. Only difference is that application now needs pointer to write memory address and length of maximal number of bytes to directly copy in buffer. After processing is successful, buffer advance operation is necessary to manually increase write pointer and to increase number of bytes in buffer.
Case A: Initial state, buffer is empty as
R == W
Based on
W
pointer position, application could write4
bytes to contiguous block of memory
Case B: State after advancing W pointer for 4 bytes. Buffer now holds 4 bytes and has
3
remaining availableCase C: Buffer is full, no more free memory available for write operation
Code example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* Declare buffer variables */
lwrb_t buff;
uint8_t buff_data[8];
size_t len;
uint8_t* data;
/* Initialize buffer, use buff_data as data array */
lwrb_init(&buff, buff_data, sizeof(buff_data));
/* Use write, read operations, process data */
/* ... */
/* IMAGE PART A */
/* At this stage, we have buffer as on image above */
/* R = 4, W = 4, buffer is considered empty */
/* Get length of linear memory at write pointer */
/* Function returns 4 as we can write 4 bytes to buffer in sequence */
/* When function returns 0, there is no memory available in the buffer for write anymore */
if ((len = lwrb_get_linear_block_write_length(&buff)) > 0) {
/* Get pointer to first element in linear block at write address */
/* Function returns &buff_data[4] */
data = lwrb_get_linear_block_write_address(&buff);
/* Receive data via DMA and wait to finish (for sake of example) */
/* Any other hardware may directly write to data array */
/* Data array has len bytes length */
/* Or use memcpy(data, my_array, len); */
receive_data(data, len);
/* Now advance buffer for written bytes to buffer = move write pointer */
/* Write pointer is moved for len bytes */
lwrb_advance(&buff, len);
/* Now W points to top of buffer, W = 0 */
/* At this point, we are at image part B */
}
/* IMAGE PART B */
/* Get length of linear memory at write pointer */
/* Function returns 3 as we can write 3 bytes to buffer in sequence */
/* When function returns 0, there is no memory available in the buffer for write anymore */
if ((len = lwrb_get_linear_block_read_length(&buff)) > 0) {
/* Get pointer to first element in linear block at write address */
/* Function returns &buff_data[0] */
data = lwrb_get_linear_block_read_address(&buff);
/* Receive data via DMA and wait to finish (for sake of example) */
/* Any other hardware may directly write to data array */
/* Data array has len bytes length */
/* Or use memcpy(data, my_array, len); */
receive_data(data, len);
/* Now advance buffer for written bytes to buffer = move write pointer */
/* Write pointer is moved for len bytes */
lwrb_advance(&buff, len);
/* Now W points to 3, R points to 4, that is R == W + 1 and buffer is now full */
/* At this point, we are at image part C */
}
/* IMAGE PART C */
/* Buffer is considered full as R == W + 1 */
|
Example for DMA transfer from memory¶
This is an example showing pseudo code for implementing data transfer using DMA with zero-copy overhead. For read operation purposes, application gets direct access to LwRB read pointer and length of contigouos memory.
It is assumed that after DMA transfer completes, interrupt is generated (embedded system) and buffer is skipped in the interrupt.
Note
Buffer skip operation is used to mark sent data as processed and to free memory for new writes to buffer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* Buffer */
lwrb_t buff;
uint8_t buff_data[8];
/* Working data length */
size_t len;
/* Send data function */
void send_data(void);
int
main(void) {
/* Initialize buffer */
lwrb_init(&buff, buff_data, sizeof(buff_data));
/* Write 4 bytes of data */
lwrb_write(&buff, "0123", 4);
/* Send data over DMA */
send_data();
while (1);
}
/* Send data over DMA */
void
send_data(void) {
/* If len > 0, DMA transfer is on-going */
if (len > 0) {
return;
}
/* Get maximal length of buffer to read data as linear memory */
len = lwrb_get_linear_block_read_length(&buff);
if (len > 0) {
/* Get pointer to read memory */
uint8_t* data = lwrb_get_linear_block_read_address(&buff);
/* Start DMA transfer */
start_dma_transfer(data, len);
}
/* Function does not wait for transfer to finish */
}
/* Interrupt handler */
/* Called on DMA transfer finish */
void
DMA_Interrupt_handler(void) {
/* Transfer finished */
if (len > 0) {
/* Now skip the data (move read pointer) as they were successfully transferred over DMA */
lwrb_skip(&buff, len);
/* Reset length = DMA is not active */
len = 0;
/* Try to send more */
send_data();
}
}
|
Tip
Check STM32 UART DMA TX RX Github repository for use cases.
Tips & tricks¶
Application buffer size¶
Buffer size shall always be 1
byte bigger than anticipated data size.
When application uses buffer for some data block N
times, it is advised to set buffer size to 1
byte more than N * block_size
is.
This is due to R
and W
pointers alignment.
Note
For more information, check How it works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include "lwrb/lwrb.h"
/* Number of data blocks to write */
#define N 3
/* Create custom data structure */
/* Data is array of 2 32-bit words, 8-bytes */
uint32_t d[2];
/* Create buffer structures */
lwrb_t buff_1;
lwrb_t buff_2;
/* Create data for buffers. Use sizeof structure, multiplied by N (for N instances) */
/* Buffer with + 1 bytes bigger memory */
uint8_t buff_data_1[sizeof(d) * N + 1];
/* Buffer without + 1 at the end */
uint8_t buff_data_2[sizeof(d) * N];
/* Write result values */
size_t len_1;
size_t len_2;
/* Initialize buffers */
lwrb_init(&buff_1, buff_data_1, sizeof(buff_data_1));
lwrb_init(&buff_2, buff_data_2, sizeof(buff_data_2));
/* Write data to buffer */
for (size_t i = 0; i < N; ++i) {
/* Prepare data */
d.a = i;
d.b = i * 2;
/* Write data to both buffers, memory copy from d to buffer */
len_1 = lwrb_write(&buff_1, d, sizeof(d));
len_2 = lwrb_write(&buff_2, d, sizeof(d));
/* Print results */
printf("Write buffer 1: %d/%d bytes; buffer 2: %d/%d\r\n",
(int)len_1, (int)sizeof(d),
(int)len_2, (int)sizeof(d));
}
|
When the code is executed, it produces following output:
Write: buffer 1: 8/8; buffer 2: 8/8
Write: buffer 1: 8/8; buffer 2: 8/8
Write: buffer 1: 8/8; buffer 2: 7/8 <-- See here -->
API reference¶
List of all the modules:
LwRB¶
-
group
LWRB
Lightweight ring buffer manager.
Defines
-
LWRB_VOLATILE
¶ Enable buffer structure pointer parameter as volatile To use this feature, uncomment keyword below.
-
LWRB_USE_MAGIC
¶ Adds 2 magic words to make sure if memory is corrupted application can detect wrong data pointer and maximum size.
Typedefs
-
void(* lwrb_evt_fn )(LWRB_VOLATILE struct lwrb *buff, lwrb_evt_type_t evt, size_t bp)
Event callback function type.
- Parameters
[in] buff
: Buffer handle for event[in] evt
: Event type[in] bp
: Number of bytes written or read (when used), depends on event type
Enums
Functions
-
uint8_t lwrb_init (LWRB_VOLATILE lwrb_t *buff, void *buffdata, size_t size)
Initialize buffer handle to default values with size and buffer data array.
- Return
1
on success,0
otherwise- Parameters
[in] buff
: Buffer handle[in] buffdata
: Pointer to memory to use as buffer data[in] size
: Size ofbuffdata
in units of bytes Maximum number of bytes buffer can hold issize - 1
-
uint8_t lwrb_is_ready (LWRB_VOLATILE lwrb_t *buff)
Check if buff is initialized and ready to use.
- Return
1
if ready,0
otherwise- Parameters
[in] buff
: Buffer handle
-
void lwrb_free (LWRB_VOLATILE lwrb_t *buff)
Free buffer memory.
- Note
Since implementation does not use dynamic allocation, it just sets buffer handle to
NULL
- Parameters
[in] buff
: Buffer handle
-
void lwrb_reset (LWRB_VOLATILE lwrb_t *buff)
Resets buffer to default values. Buffer size is not modified.
- Parameters
[in] buff
: Buffer handle
-
void lwrb_set_evt_fn (LWRB_VOLATILE lwrb_t *buff, lwrb_evt_fn fn)
Set event function callback for different buffer operations.
- Parameters
[in] buff
: Buffer handle[in] evt_fn
: Callback function
-
size_t lwrb_write (LWRB_VOLATILE lwrb_t *buff, const void *data, size_t btw)
Write data to buffer. Copies data from
data
array to buffer and marks buffer as full for maximumbtw
number of bytes.- Return
Number of bytes written to buffer. When returned value is less than
btw
, there was no enough memory available to copy full data array- Parameters
[in] buff
: Buffer handle[in] data
: Pointer to data to write into buffer[in] btw
: Number of bytes to write
-
size_t lwrb_read (LWRB_VOLATILE lwrb_t *buff, void *data, size_t btr)
Read data from buffer. Copies data from buffer to
data
array and marks buffer as free for maximumbtr
number of bytes.- Return
Number of bytes read and copied to data array
- Parameters
[in] buff
: Buffer handle[out] data
: Pointer to output memory to copy buffer data to[in] btr
: Number of bytes to read
-
size_t lwrb_peek (LWRB_VOLATILE lwrb_t *buff, size_t skip_count, void *data, size_t btp)
Read from buffer without changing read pointer (peek only)
- Return
Number of bytes peeked and written to output array
- Parameters
[in] buff
: Buffer handle[in] skip_count
: Number of bytes to skip before reading data[out] data
: Pointer to output memory to copy buffer data to[in] btp
: Number of bytes to peek
-
size_t lwrb_get_free (LWRB_VOLATILE lwrb_t *buff)
Get available size in buffer for write operation.
- Return
Number of free bytes in memory
- Parameters
[in] buff
: Buffer handle
-
size_t lwrb_get_full (LWRB_VOLATILE lwrb_t *buff)
Get number of bytes currently available in buffer.
- Return
Number of bytes ready to be read
- Parameters
[in] buff
: Buffer handle
-
void * lwrb_get_linear_block_read_address (LWRB_VOLATILE lwrb_t *buff)
Get linear address for buffer for fast read.
- Return
Linear buffer start address
- Parameters
[in] buff
: Buffer handle
-
size_t lwrb_get_linear_block_read_length (LWRB_VOLATILE lwrb_t *buff)
Get length of linear block address before it overflows for read operation.
- Return
Linear buffer size in units of bytes for read operation
- Parameters
[in] buff
: Buffer handle
-
size_t lwrb_skip (LWRB_VOLATILE lwrb_t *buff, size_t len)
Skip (ignore; advance read pointer) buffer data Marks data as read in the buffer and increases free memory for up to
len
bytes.- Note
Useful at the end of streaming transfer such as DMA
- Return
Number of bytes skipped
- Parameters
[in] buff
: Buffer handle[in] len
: Number of bytes to skip and mark as read
-
void * lwrb_get_linear_block_write_address (LWRB_VOLATILE lwrb_t *buff)
Get linear address for buffer for fast read.
- Return
Linear buffer start address
- Parameters
[in] buff
: Buffer handle
-
size_t lwrb_get_linear_block_write_length (LWRB_VOLATILE lwrb_t *buff)
Get length of linear block address before it overflows for write operation.
- Return
Linear buffer size in units of bytes for write operation
- Parameters
[in] buff
: Buffer handle
-
size_t lwrb_advance (LWRB_VOLATILE lwrb_t *buff, size_t len)
Advance write pointer in the buffer. Similar to skip function but modifies write pointer instead of read.
- Note
Useful when hardware is writing to buffer and application needs to increase number of bytes written to buffer by hardware
- Return
Number of bytes advanced for write operation
- Parameters
[in] buff
: Buffer handle[in] len
: Number of bytes to advance
-
struct
lwrb_t
¶ - #include <lwrb.h>
Buffer structure.
Public Members
-
uint32_t
magic1
¶ Magic 1 word
-
uint8_t *
buff
¶ Pointer to buffer data. Buffer is considered initialized when
buff != NULL
andsize > 0
-
size_t
size
¶ Size of buffer data. Size of actual buffer is
1
byte less than value holds
-
size_t
r
¶ Next read pointer. Buffer is considered empty when
r == w
and full whenw == r - 1
-
size_t
w
¶ Next write pointer. Buffer is considered empty when
r == w
and full whenw == r - 1
-
lwrb_evt_fn
evt_fn
¶ Pointer to event callback function
-
uint32_t
magic2
¶ Magic 2 word
-
uint32_t
-