#[non_exhaustive]
pub struct ProgMem<T> { /* private fields */ }
Expand description

Best-effort safe wrapper around a value in program memory.

This type wraps a pointer to a value that is stored in program memory, and offers safe functions to load that value from program memory into the data memory domain from where it can be normally used.

Since its constructor is the single most critical point in its API, it is unsafe, despite it is supposed to be a safe wrapper (hence the ‘best-effort’ notation). The caller of the constructor therefore must ensure that the supplied pointer points to a valid value stored in program memory.

Consequently, the only way to use this struct soundly is to define a static with the #[link_section = ".progmem.data"] attribute on it and pass a pointer to that static to ProgMem::new. However, having an accessible static around that is stored in progmem is a very dangerous endeavor.

In order to make working with progmem safer and more convenient, consider using the progmem! macro, that will put the given data into a hidden static in progmem and provide you with an accessible static containing the pointer to it wrapped in ProgMem.

Safety

The target pointer in this struct must point to a valid object of type T that is stored in the program memory domain. The object must be initialized, readable, and immutable (i.e. it must not be changed). Also the target pointer must be valid for the 'static lifetime.

However, the above requirement about the program memory domain only applies to the AVR architecture (#[cfg(target_arch = "avr")]), otherwise normal data access primitives are used. This means that the value must be stored in the regular data memory domain for ALL OTHER architectures! This still holds, even if such other architecture is of the Harvard architecture, because this is an AVR-only crate, not a general Harvard architecture crate!

Implementations

Construct a new instance of this type.

This struct is a pointer wrapper for data in the program memory domain. Therefore when constructing this struct, it must be guaranteed that the pointed data is stored in progmem! This contract is expressed by the fact that this function is unsafe. See the Safety section for details.

You should not need to call this function directly. It is recommended to use the progmem! macro instead (which calls this constructor for you, while enforcing its contract.

Safety

The ProgMem wrapper is build around the invariant that the wrapped pointer is stored in the program code memory domain (on the AVR architecture).

That means that this function is only sound to call, if the value to which target points is stored in a static that is stored in progmem, e.g. by using the attribute #[link_section = ".progmem.data"].

However, the above requirement about the program memory domain only applies to the AVR architecture (#[cfg(target_arch = "avr")]), otherwise normal data access primitives are used, and thus the target pointer needs to point to normal data on those architectures.

Read the inner value from progmem and return a regular value.

Panics

This method panics, if the size of the value (i.e. size_of::<T>()) is beyond 255 bytes. However, this is currently just a implementation limitation, which may be lifted in the future.

Also notice, if you really hit this limit, you would need 256+ bytes on your stack, on the Arduino Uno (at least) that means that you might be close to a stack overflow. Thus it might be better to restructure your data, so you can store it as an array of something, than you can use the load_at and load_sub_array methods instead.

Return the raw pointer to the inner value.

Notice that the returned pointer is indeed a pointer into the progmem domain! It may never be dereferenced via the default Rust operations. That means a unsafe{*pm.get_inner_ptr()} is undefined behavior!

Instead, if you want to use the pointer, you may want to use one of the “raw” functions, see the raw module.

Utilities to work with an array in progmem.

Load a single element from the inner array.

This method is analog to a slice indexing self.load()[idx], so the same requirements apply, like the index idx should be less then the length N of the array, otherwise a panic will be risen.

Panics

This method panics, if the given index idx is grater or equal to the length N of the inner type.

This method also panics, if the size of the value (i.e. size_of::<T>()) is beyond 255 bytes. However, this is currently just a implementation limitation, which may be lifted in the future.

Notice, that here T is the type of the elements not the entire array as it would be with load.

Loads a sub array from the inner array.

This method is analog to a sub-slicing self.load()[idx..(idx+M)] but returning an owned array instead of a slice, simply because it has to copy the data anyway from the progmem into the data domain (i.e. the stack).

Also notice, that since this crate is intended for AVR micro-controllers, static arrays are generally preferred over dynamically allocated types such as a Vec.

Panics

This method panics, if the given index idx is grater or equal to the length N of the inner array, or the end index idx+M is grater than the length N of the inner array.

This method also panics, if the size of the value (i.e. size_of::<[T;M]>()) is beyond 255 bytes. However, this is currently just a implementation limitation, which may be lifted in the future.

Lazily iterate over all elements

Returns an iterator which lazily loads the elements one at a time from progmem. This means this iterator can be used to access huge arrays while only requiring size_of::<T>() amount of stack memory.

Panics

This method panics, if the size of an element (i.e. size_of::<T>()) is beyond 255 bytes. However, this is currently just a implementation limitation, which may be lifted in the future.

Notice, that here T is the type of the elements not the entire array as it would be with load.

Returns the length of the array (i.e. N)

Trait Implementations

Same as ProgMem::iter

Which kind of iterator are we turning this into?

The type of the elements being iterated over.

Creates an iterator from a value. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.