Crate bbqueue

source ·
Expand description

BBQueue

BBQueue, short for “BipBuffer Queue”, is a (work in progress) Single Producer Single Consumer, lockless, no_std, thread safe, queue, based on BipBuffers.

It is designed (primarily) to be a First-In, First-Out queue for use with DMA on embedded systems.

While Circular/Ring Buffers allow you to send data between two threads (or from an interrupt to main code), you must push the data one piece at a time. With BBQueue, you instead are granted a block of contiguous memory, which can be filled (or emptied) by a DMA engine.

Using in a single threaded context

use bbqueue::{BBQueue, bbq};

fn main() {
    // Create a statically allocated instance
    let bbq = bbq!(1024).unwrap();

    // Obtain a write grant of size 128 bytes
    let wgr = bbq.grant(128).unwrap();

    // Fill the buffer with data
    wgr.buf.copy_from_slice(&[0xAFu8; 128]);

    // Commit the write, to make the data available to be read
    bbq.commit(wgr.buf.len(), wgr);

    // Obtain a read grant of all available and contiguous bytes
    let rgr = bbq.read().unwrap();

    for i in 0..128 {
        assert_eq!(rgr.buf[i], 0xAFu8);
    }

    // Release the bytes, allowing the space
    // to be re-used for writing
    bbq.release(rgr.buf.len(), rgr);
}

Using in a multi-threaded environment (or with interrupts, etc.)

use bbqueue::{BBQueue, bbq};
use std::thread::spawn;

fn main() {
    // Create a statically allocated instance
    let bbq = bbq!(1024).unwrap();
    let (mut tx, mut rx) = bbq.split();

    let txt = spawn(move || {
        for tx_i in 0..128 {
            'inner: loop {
                match tx.grant(4) {
                    Ok(gr) => {
                        gr.buf.copy_from_slice(&[tx_i as u8; 4]);
                        tx.commit(4, gr);
                        break 'inner;
                    }
                    _ => {}
                }
            }
        }
    });

    let rxt = spawn(move || {
        for rx_i in 0..128 {
            'inner: loop {
                match rx.read() {
                    Ok(gr) => {
                        if gr.buf.len() < 4 {
                            rx.release(0, gr);
                            continue 'inner;
                        }

                        assert_eq!(&gr.buf[..4], &[rx_i as u8; 4]);
                        rx.release(4, gr);
                        break 'inner;
                    }
                    _ => {}
                }
            }
        }
    });

    txt.join().unwrap();
    rxt.join().unwrap();
}

Macros

Statically allocate a BBQueue singleton object with a given size (in bytes).

Structs

A single producer, single consumer, thread safe queue
An opaque structure, capable of reading data from the queue
A structure representing a contiguous region of memory that may be read from, and potentially “released” (or cleared) from the queue
A structure representing a contiguous region of memory that may be written to, and potentially “committed” to the queue
An opaque structure, capable of writing data to the queue

Enums

Error type used by the BBQueue interfaces

Type Definitions

Result type used by the BBQueue interfaces