# AVR Memory

This crate is specifically for AVR-base micro-controllers such as
the Arduino Uno (and some other Arduino boards, but not all), which have a
modified Harvard architecture which implies the strict separation of program
code and data while having special instructions to read and write to
program memory.

While, of course, all ordinary data is stored in the data domain where it is
perfectly usable, the harsh constraints of most AVR processors make it very
appealing to use the program memory (also referred to as progmem) for
storing constant values. However, due to the Harvard design, those values
are not usable with normal instructions (i.e. those emitted from normal
Rust code). Instead, special instructions are required to load data from
the program code domain, i.e. the `lpm` (load from program memory)
instruction. And because there is no way to emit it from Rust code, this
crate uses inline assembly to emit that instruction.

However, since a pointer into program code cannot be differentiated from a
normal data pointer, it is entirely up to the programmer to ensure that
these different 'pointer-types' are not accidentally mixed. In other words,
this is `unsafe` in the context of Rust.

# Loading Data from Program Memory

The first part of this crate simply provides a few functions (e.g.
`read_byte`) to load constant data (i.e. a Rust `static` that is
immutable) from the program memory into the data domain, so that
sub-sequentially it is normal usable data, i.e. as owned data on the stack.

Because, as aforementioned, a simple `*const u8` in Rust does not specify
whether is lives in the program code domain or the data domain, all
functions which simply load a given pointer from the program memory are
inherently `unsafe`.

Notice that using a `&u8` reference might make things rather worse than
safe. Because keeping a pointer/reference/address into the program memory
as Rust reference might easily cause it to be dereferenced, even in safe
code. But since that address is only valid in the program code domain (and
Rust doesn't know about it) it would illegally load the address from the
data memory, causing **undefined behavior**!
