[][src]Function avr_progmem::read_slice

pub unsafe fn read_slice(p: &[u8], out: &mut [u8])

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"]
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.