170: Buffer methods for Vec and as_mut_vec for String r=japaric a=samlich
This adds `set_len` to `Vec`, identical to the `std` version, with the documentation copied from `std`. This is useful for using it as a buffer by writing to the uninitialized portion and then setting the length to include those bytes.
It also adds `as_mut_vec` to `String` (also from `std`), which enables using `String` as a buffer in the same manner.
Co-authored-by: samlich <1349989+samlich@users.noreply.github.com>
161: readme: add instructions for tests r=korken89 a=andresv
It took me some time to figure out which features must be used for tests. So this pull request removes some friction.
162: histbuf: replace slow modulo operations r=korken89 a=andresv
STM32G081 Cortex-M0 64MHz
thumbv6m-none-eabi
Rust 1.43.1
RTFM application where data from ADC channels is added to `HistoryBuffers`:
```Rust
// this is shared with DMA
static mut ADC_DATA: [u16; 6] = [0; 6];
...
// this interrupt fires when DMA has finished sequencing all ADC channels
#[task(binds = DMA_CHANNEL1, resources = [pa9, adc_data, hist0, hist1, hist2, hist3, hist4, hist5])]
fn adc_data_ready(ctx: adc_data_ready::Context) {
let dma = unsafe { &(*stm32::DMA::ptr()) };
// transfer complete flag clear
dma.ifcr.write(|w| w.ctcif1().set_bit());
ctx.resources.pa9.set_high().unwrap();
ctx.resources.hist0.write(ctx.resources.adc_data[0]);
ctx.resources.hist1.write(ctx.resources.adc_data[1]);
ctx.resources.hist2.write(ctx.resources.adc_data[2]);
ctx.resources.hist3.write(ctx.resources.adc_data[3]);
ctx.resources.hist4.write(ctx.resources.adc_data[4]);
ctx.resources.hist5.write(ctx.resources.adc_data[5]);
ctx.resources.pa9.set_low().unwrap();
}
```
Time is measured from `PA9` pin using logic analyzer.
```
[profile.release]
opt-level = "s"
codegen-units = 1
debug = true
lto = true
```
- before `27.6 us`
- with fix `4.4 us`
```
[profile.release]
opt-level = 2
codegen-units = 1
debug = true
lto = true
```
- before `25.9 us`
- with fix `2.9 us`
Co-authored-by: Andres Vahter <andres.vahter@gmail.com>
154: indexmap: expose PowerOfTwo, Bucket and Pos r=japaric a=willem66745
This change allows the create custom structs based on `IndexMap` with size arguments outside
the heapless crate itself.
For example:
```rust
use heapless::consts::*;
use heapless::{ArrayLength, Bucket, FnvIndexMap, Pos, PowerOfTwo};
struct CustomMap<S>
where
S: ArrayLength<Bucket<u8, u16>> + ArrayLength<Option<Pos>> + PowerOfTwo,
{
map: FnvIndexMap<u8, u16, S>,
}
impl<S> CustomMap<S>
where
S: ArrayLength<Bucket<u8, u16>> + ArrayLength<Option<Pos>> + PowerOfTwo,
{
fn new() -> CustomMap<S> {
CustomMap {
map: FnvIndexMap::<_, _, S>::new(),
}
}
}
fn main() {
let mut bla = CustomMap::<U8>::new();
bla.map.insert(8, 16).unwrap();
}
```
I can imagine that exposing these types is not preferable, but at least it would help for my usecase. Or is there a way where exposing these types is not needed?
Co-authored-by: Willem <willem66745@gmail.com>
149: Make Producer<..., SingleCore> Send, like Consumer r=japaric a=BryanKadzban
I assume there's no reason that only multi-core Producers are marked
Send, while Consumers are not (they're pretty symmetrical).
(Context: I'm trying to use an SPSC queue on a single cortex-m0 MCU.
So I can guarantee that a SingleCore queue is safe because there is no
other core it could possibly be shared with. The RTFM framework adds
an assert_send on the producer, since it's shared between init and an
SPI receiver interrupt. It also adds an assert_send on the Consumer,
since it's shared between init and the I2C transmit interrupt, but that one
works since Consumer has this extra C type in the impl already.)
Co-authored-by: Bryan Kadzban <github@kadzban.net>
153: x86_64: "practically" thread-safe Pool r=korken89 a=japaric
### Summary / motivation
this PR makes `Pool` `Sync` on x86_64 with the main goal of being able to test `no_std` code that uses `Pool` (e.g. via the singleton `pool!` macro) on x86_64 (as it's not straight forward to run tests on embedded devices, and even less to CI those tests).
### Details
this PR reduces the chance of Pool running into the ABA problem (which corrupts the underlying lock-free stack) by using 32-bit version tags (search term: IBM ABA-prevention tags). Version tags do not 100% prevent the ABA problem but make it almost impossible to run into it in practice (the bigger the tag, in bits, the less the chance of running into ABA). See module level docs for details and limitations.
As this does not eliminate ABA with 100% certainty perhaps it should live behind a Cargo feature?
It seems to me that hazard pointers may be able to completely get rid of ABA but implementing those, AFAICT, require Thread Local Storage (`#[thread_local]`) which is not supported in `no_std` code.
r? @korken89
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
143: Implement core::fmt::Write for heapless::Vec<u8, N> r=korken89 a=ijl
I didn't see a mention of this in issues or previous pull requests, but I expect it's in scope?
Co-authored-by: ijl <ijl@mailbox.org>
Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
155: Extend ARMv7-R `Pool` support to the bare-metal `armebv7r-` targets r=japaric a=rjsberry
Extends support for singleton `Pool`s to include the `armebv7r-none-eabi` and `armebv7r-none-eabihf` targets.
Co-authored-by: Richard Berry <rjsberry@pm.me>
156: Add optional ufmt impls r=japaric a=dbrgn
By enabling the `ufmt-impl` feature, `uWrite` impls are provided for `String<N>` and `Vec<u8, N>`.
Co-authored-by: Danilo Bargen <mail@dbrgn.ch>
152: Implement Vec::starts_with and Vec::ends_with r=korken89 a=dbrgn
Implementation mostly copied from `std`.
The logic should be covered by documentation tests, so no separate unit tests were added.
Co-authored-by: Danilo Bargen <mail@dbrgn.ch>
136: add the HistoryBuffer type r=korken89 a=birkenfeld
Closes#112
Unfortunately `const` construction won't work since the `Default` or `Clone` bound on `T` can't be used then, so I've not added an internal type to `i.rs`.
Let me know if you think any other traits should be implemented...
Co-authored-by: Georg Brandl <georg@python.org>
147: Implement StableDeref for singleton::Box r=korken89 a=thalesfragoso
There was a discussion in the riot channel about what it's needed for a buffer to be DMA safe, where ra_kete came up with this POC:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=339a9a29fb59c080b42b6d77a902acb6
Where it seems that the requirements described in the [Embedonomicon](https://docs.rust-embedded.org/embedonomicon/dma.html#static-bound) doesn't seem to be enough to prevent stack corruption.
If that is really the case and we decide to use `StableDeref` instead, then a implementation for Box is very important to be able to easily use it on DMA APIs and a new point release would be necessary.
CC @korken89
Co-authored-by: thalesfragoso <thales.fragosoz@gmail.com>
142: Extend the ARMv7-A `Pool` support to the bare-metal `armv7a-` targets. r=japaric a=japaric
The built-in rustc targets ended with names that start with `armv7a-` so #140
does not cover them though the intention was to support them; this commit fixes
that
Co-authored-by: Jorge Aparicio <jorge.aparicio@ferrous-systems.com>
The built-in rustc targets ended with names that start with `armv7a-` so #140
does not cover them though the intention was to support them; this commit fixes
that