bbqueue_ng/lib.rs
1//! # BBQueue(-ng)
2//!
3//! ## EXPERIMENTAL NOTICE
4//!
5//! **NOTE**: This is the experimental next-generation version of bbqueue. This version generally doesn't respect semver, and may have incorrect documentation. If you want something more stable, use the regular version of `bbqueue`!
6//!
7//! ## Probably out of date docs
8//!
9//! BBQueue, short for "BipBuffer Queue", is a Single Producer Single Consumer,
10//! lockless, no_std, thread safe, queue, based on [BipBuffers]. For more info on
11//! the design of the lock-free algorithm used by bbqueue, see [this blog post].
12//!
13//! For a 90 minute guided tour of BBQueue, you can also view this [guide on YouTube].
14//!
15//! [guide on YouTube]: https://www.youtube.com/watch?v=ngTCf2cnGkY
16//! [BipBuffers]: https://www.codeproject.com/Articles/3479/%2FArticles%2F3479%2FThe-Bip-Buffer-The-Circular-Buffer-with-a-Twist
17//! [this blog post]: https://ferrous-systems.com/blog/lock-free-ring-buffer/
18//!
19//! BBQueue is designed (primarily) to be a First-In, First-Out queue for use with DMA on embedded
20//! systems.
21//!
22//! While Circular/Ring Buffers allow you to send data between two threads (or from an interrupt to
23//! main code), you must push the data one piece at a time. With BBQueue, you instead are granted a
24//! block of contiguous memory, which can be filled (or emptied) by a DMA engine.
25//!
26//! ## Local usage
27//!
28//! ```rust, no_run
29//! # use bbqueue_ng::BBBuffer;
30//! #
31//! // Create a buffer with six elements
32//! let bb: BBBuffer<6> = BBBuffer::new();
33//! let (mut prod, mut cons) = bb.try_split().unwrap();
34//!
35//! // Request space for one byte
36//! let mut wgr = prod.grant_exact(1).unwrap();
37//!
38//! // Set the data
39//! wgr[0] = 123;
40//!
41//! assert_eq!(wgr.len(), 1);
42//!
43//! // Make the data ready for consuming
44//! wgr.commit(1);
45//!
46//! // Read all available bytes
47//! let rgr = cons.read().unwrap();
48//!
49//! assert_eq!(rgr[0], 123);
50//!
51//! // Release the space for later writes
52//! rgr.release(1);
53//! ```
54//!
55//! ## Static usage
56//!
57//! ```rust, no_run
58//! # use bbqueue_ng::BBBuffer;
59//! #
60//! // Create a buffer with six elements
61//! static BB: BBBuffer<6> = BBBuffer::new();
62//!
63//! fn main() {
64//! // Split the bbqueue into producer and consumer halves.
65//! // These halves can be sent to different threads or to
66//! // an interrupt handler for thread safe SPSC usage
67//! let (mut prod, mut cons) = BB.try_split().unwrap();
68//!
69//! // Request space for one byte
70//! let mut wgr = prod.grant_exact(1).unwrap();
71//!
72//! // Set the data
73//! wgr[0] = 123;
74//!
75//! assert_eq!(wgr.len(), 1);
76//!
77//! // Make the data ready for consuming
78//! wgr.commit(1);
79//!
80//! // Read all available bytes
81//! let rgr = cons.read().unwrap();
82//!
83//! assert_eq!(rgr[0], 123);
84//!
85//! // Release the space for later writes
86//! rgr.release(1);
87//!
88//! // The buffer cannot be split twice
89//! assert!(BB.try_split().is_err());
90//! }
91//! ```
92//!
93//! ## Features
94//!
95//! By default BBQueue uses atomic operations which are available on most platforms. However on some
96//! (mostly embedded) platforms atomic support is limited and with the default features you will get
97//! a compiler error about missing atomic methods.
98//!
99//! This crate contains special support for Cortex-M0(+) targets with the `thumbv6` feature. By
100//! enabling the feature, unsupported atomic operations will be replaced with critical sections
101//! implemented by disabling interrupts. The critical sections are very short, a few instructions at
102//! most, so they should make no difference to most applications.
103
104#![cfg_attr(not(feature = "std"), no_std)]
105#![deny(missing_docs)]
106#![deny(warnings)]
107
108mod bbbuffer;
109pub use bbbuffer::*;
110
111pub mod framed;
112mod vusize;
113
114use core::result::Result as CoreResult;
115
116/// Result type used by the `BBQueue` interfaces
117pub type Result<T> = CoreResult<T, Error>;
118
119/// Error type used by the `BBQueue` interfaces
120#[derive(Debug, PartialEq, Eq, Copy, Clone)]
121pub enum Error {
122 /// The buffer does not contain sufficient size for the requested action
123 InsufficientSize,
124
125 /// Unable to produce another grant, a grant of this type is already in
126 /// progress
127 GrantInProgress,
128
129 /// Unable to split the buffer, as it has already been split
130 AlreadySplit,
131}