Function avr_progmem::read_slice
source · [−]Use read_value() instead
Expand description
Read a slice of type T
from progmem into given slice in data memory.
This function uses either a optimized assembly with loop or just a
byte-wise assembly function which is looped outside depending on
whether the lpm-asm-loop
crate feature is set or not.
If you need to read just a single byte you might use read_byte
or
just generally for any value (including arrays) read_value
.
Example
use avr_progmem::read_slice;
// This static must never be directly dereferenced/accessed!
// So a `let data: [u8;11] = P_ARRAY;` is Undefined Behavior!!!
// Also notice the `*` in front of the string, because we want to store the
// data, not just a reference!
/// Static bytes stored in progmem!
#[link_section = ".progmem.data"]
static P_ARRAY: [u8;11] = *b"Hello World";
// Notice since we use a sub-slice the data better is pre-initialized even
// tho we will override it.
let mut data = [0u8; 5];
// Load the bytes from progmem
// Here, it is sound, because due to the link_section it is indeed in the
// program code memory.
unsafe { read_slice(&P_ARRAY[0..5], &mut data[..]) };
assert_eq!(b"Hello", &data);
Panics
This function panics if the given slices p
and out
have a different
lengths.
This function also panics, if the size of the value (i.e. p.len() * size_of::<T>()
)
is beyond 255 bytes.
However, this is currently just a implementation limitation, which may
be lifted in the future.
Safety
This call is analog to core::ptr::copy(p_addr, out, len as usize)
thus it
has the same basic requirements such as both pointers must be valid for
dereferencing i.e. not dangling and both pointers must
be valid to read or write, respectively, of len
many elements of type T
,
i.e. len * size_of::<T>()
bytes.
Additionally, p_addr
must be a valid pointer into the program memory
domain. And out
must be valid point to a writable location in the data
memory.
While the alignment is not strictly required for AVR, the non-AVR fallback
might be done actually use core::ptr::copy
and therefore the pointers
must be aligned.
Also notice, that the output slice must be correctly initialized, it would
be UB if not. If you don’t want to initialize the data upfront, the
read_value
might be a good alternative.