A ring buffer designed to work with embedded devices, does not use heap allocations.

Overview

Embedded Ring Buffer

This is a header only ring buffer that is designed to work on embedded devices, it is able to handle non-blocking ISR spooling.

There are two objects, RingBuffer and Block. The block represents a set of items in the ringbuffer. You can write single items to the ring buffer and read many at once. It was designed to handle ISR routines and non-blocking devices therefore bytes can be wrote in an interrupt handler and read in large chunks to output to slower medium like SD cards.

It does not use malloc/free since the size is defined as a template parameter and is written in plain C++98 with no special features used.

Sponsors


How to use it.

Once a block has been used you must Skip() the buffer the number of reads you made, this is so that writing to the buffer does not corrupt the blocks data as it is being used.

Without ISR

int main()
{
    RingBuffer<100, int> buffer;
    Block block;

    /* Write 100 ints */
    for (int i = 0; i < buffer.Length(); i++)
    {
        buffer.Append(i);
    }

    /* Read a block */
    block = buffer.Read(100);
    buffer.Skip(block.Length());

    /* Print out the block */
    for (int i = 0; i < block.Length(); i++)
    {
        std::cout << block.At(i) << std::endl;
    }

    /* Read another block */
    block = buffer.Read(1000);
    buffer.Skip(block.Length());

    /* Print out the block */
    for (int i = 0; i < block.Length(); i++)
    {
        std::cout << block.At(i) << std::endl;
    }


    return 0;
}

With ISR.

RingBuffer<100, int> buffer;
Block block;
bool writing = false;

void SD_WriteCompleted()
{
    buffer.Skip(block.Length()); /* Manually skip the buffer to prevent corruption */
    
    writing = false;
}

void ISR()
{
    /* Perform an action like sample temperature sensor. */

    buffer.Append(0);
}

int main()
{
    while (true)
    {
        if (writing) continue;
        
        /* Read a block */
        block = buffer.Read(100, false); /* NOTE: here the second parameter disables the automatic skipping */

        writing = true;
        
        SD.write(block.Start(), block.Length()); /* non blocking mode */
    }


    return 0;
}

Please reference the doxygen comments for more details.

Issues

Blocks cannot span the 0th index of the buffer.

Since the ring buffer is just an array, to return a block that overlaps the 0th index would mean having 2 regions of the array to process, however the sd card writing (DMA) only works on single arrays at a time. This means that if you have a ringbuffer of 100 items at your reading from position 98, the maximum number of elements a block can return is 2. This may sound unrealistic but this was designed for SD cards that write extremely large blocks at a time (>30KB) using buffers that are large enough to store a considerable number of elements before requiring writing to the sd card. In practice the ring buffers write position will never exceed far from the read position since the SD card is emptying it constantly. You must calculate the timing of your input data and output data carefully for the buffer.

References

Alternatives

Todo

  • Test the buffer thoroughly to debug.
  • Benchmark it.
Owner
Richard Bamford
Richard Bamford
A cross-platform protocol library to communicate with iOS devices

libimobiledevice A library to communicate with services on iOS devices using native protocols. Features libimobiledevice is a cross-platform software

libimobiledevice 5k Jul 1, 2022
UClamp backports and custom tunings for different kernel versions/devices

Linux kernel ============ This file was moved to Documentation/admin-guide/README.rst Please notice that there are several guides for kernel develop

null 25 Jan 14, 2022
sud - a su daemon for corellium devices

sud(aemon) What is this? sud is a simplistic su daemon for Corellium, and maybe other, Android devices. It is older Superuser code, slightly refactore

Corellium 13 May 25, 2022
Simple .INI file parser in C, good for embedded systems

inih (INI Not Invented Here) inih (INI Not Invented Here) is a simple .INI file parser written in C. It's only a couple of pages of code, and it was d

Ben Hoyt 1.8k Jun 24, 2022
Edf is an event-driven framework for embedded system (e.g. FreeRTOS) with state machine and subscriber-publisher pattern.

Edf means event-driven framework. Event-driven programming is a common pattern in embedded systems. However, if you develop software directly on top o

Arrow89 5 Apr 21, 2022
mpiFileUtils - File utilities designed for scalability and performance.

mpiFileUtils provides both a library called libmfu and a suite of MPI-based tools to manage large datasets, which may vary from large directory trees to large files.

High-Performance Computing 127 Jun 24, 2022
A tool for use with clang to analyze #includes in C and C++ source files

Include What You Use For more in-depth documentation, see docs. Instructions for Users "Include what you use" means this: for every symbol (type, func

null 2.9k Jul 2, 2022
An easy-to-use C library for displaying text progress bars.

What is this thing? progressbar is a C-class (it's a convention, dammit) for displaying attractive progress bars on the command line. It's heavily inf

Trevor Fountain 426 Jun 15, 2022
Utilities and common code for use with raylib

Utilities and shared components for use with raylib

Jeffery Myers 71 Jun 24, 2022
A simple and easy-to-use library to enjoy videogames programming

hb-raylib v3.5 Harbour bindings for raylib 3.5, a simple and easy to use library to learn videogames programming raylib v3.5. The project has an educa

MarcosLMG 0 May 24, 2022
Haxe bindings for raylib, a simple and easy-to-use library to learn videogame programming

Haxe bindings for raylib, a simple and easy-to-use library to learn videogame programming, Currently works only for windows but feel free the expand t

FSasquatch 28 Mar 19, 2022
RapidObj is an easy-to-use, single-header C++17 library that loads and parses Wavefront .obj files.

RapidObj About Integration Prerequisites Manual Integration CMake Integration API RapidObj Result Next Steps OS Support Third Party Tools and Resource

Slobodan Pavlic 69 Jun 30, 2022
Find patterns of vulnerabilities on Windows in order to find 0-day and write exploits of 1-days. We use Microsoft security updates in order to find the patterns.

Back 2 the Future Find patterns of vulnerabilities on Windows in order to find 0-day and write exploits of 1-days. We use Microsoft security updates i

SafeBreach Labs 90 Jun 14, 2022
A Header-Only Engine that tries to use SFML in a deeper level

⚙️ SFML-Low-Level-Engine ⚙️ A header-only library that tries to use SFML at a deeper level ?? Instalation Download the source code and put the GLD fol

!Gustavo! 4 Aug 27, 2021
use ptrace hook Hotspot JavaVM, instrument java bytecode

taycan 通过native层修改java层(JVM),使用JVMTI及JNI API可以修改java任意类、执行任意代码,完成hook、插入内存马、反射等功能。 适用环境 LINUX KERNEL version > 3.2 GLIBC > 2.15 openJDK/OracleJDK 1.8

null 25 Jun 16, 2022
Utilities for use in a DPP based discord bot

DPPUtils NOTE: This repo is in development, use these utilities at your own risk Numerous utilities for use in your DPP bot. List of Utilities Youtube

Daniel Wykerd 6 Apr 3, 2022
A tool for generating build scripts for C++20 projects that use modules.

cpp_module_parser [cmop] A tool for generating build scripts for C++20 projects that use modules. The intent is to provide a backend for premake, for

Alexander Christensen 2 Nov 23, 2021
A basic A* implementation showing how to use C++20 modules alongside UWP and C++/WinRT.

Introduction This is a port from an old application that was original written in a mix of C++14, Java and C++/CX. Originaly the goal was to use a simp

null 9 Mar 2, 2022
Isaac ROS common utilities and scripts for use in conjunction with the Isaac ROS suite of packages.

Isaac ROS Common Isaac ROS common utilities and scripts for use in conjunction with the Isaac ROS suite of packages. Docker Scripts run_dev.sh creates

NVIDIA Isaac ROS 41 Jul 1, 2022