Skip to main content

esp_storage/
lib.rs

1//! `esp-storage` contains API functions related to reading, writing and erasing memory for data in
2//! the external flash.
3//!
4//! For higher-level functionality which works with partitions defined in the partition table, see
5//! `esp-bootloader-esp-idf`.
6//!
7//! Encrypted flash read/write is available on chips with hardware flash encryption support when
8//! flash encryption is enabled in eFuses. See [`FlashStorage::read_encrypted`] and
9//! [`FlashStorage::write_encrypted`].
10//!
11//! The `embedded-storage` feature flag only implements traits from [`embedded_storage`]
12//! and always assumes access to non-encrypted flash.
13//!
14//! If you need to use this struct where traits from [`embedded_storage_async`] are needed, you can
15//! use [`embassy_embedded_hal::adapter::BlockingAsync`] or
16//! [`embassy_embedded_hal::adapter::YieldingAsync`] wrappers.
17//!
18//! [`embedded_storage`]: https://docs.rs/embedded-storage/latest/embedded_storage/
19//! [`embedded_storage_async`]: https://docs.rs/embedded-storage-async/latest/embedded_storage_async/
20//! [`embassy_embedded_hal::adapter::BlockingAsync`]: https://docs.rs/embassy-embedded-hal/latest/embassy_embedded_hal/adapter/struct.BlockingAsync.html
21//! [`embassy_embedded_hal::adapter::YieldingAsync`]: https://docs.rs/embassy-embedded-hal/latest/embassy_embedded_hal/adapter/struct.YieldingAsync.html
22//!
23//! ## Buffer alignment and stack usage
24//!
25//! The ESP flash ROM read/write path requires word-aligned (4-byte) buffers.
26//! Several methods accept any `&[u8]` / `&mut [u8]` and, when needed, copy
27//! through a temporary sector-sized buffer on the stack. That cost is not
28//! visible from the slice type and can surprise users in stack-constrained
29//! contexts (for example Embassy tasks with small stacks).
30//!
31//! [`FlashStorage::read_nor`] and [`FlashStorage::write_nor`] only allocate
32//! this fallback when the caller's slice pointer is not word-aligned. Each
33//! fallback is [`FlashStorage::SECTOR_SIZE`] bytes.
34//!
35//! [`FlashStorage::read`], [`FlashStorage::write`], and the encrypted variants
36//! always allocate a sector buffer on the stack for each call.
37//!
38//! ## Feature Flags
39#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
40#![doc(html_logo_url = "https://docs.espressif.com/projects/rust/esp-rs-grey-bg.svg")]
41#![cfg_attr(not(all(test, feature = "emulation")), no_std)]
42
43#[macro_use]
44extern crate esp_metadata_generated;
45
46#[cfg_attr(not(feature = "emulation"), path = "hardware.rs")]
47#[cfg_attr(feature = "emulation", path = "stub.rs")]
48mod chip_specific;
49
50mod buffer;
51mod common;
52
53pub use common::{Flash, FlashStorage, FlashStorageError};
54
55pub mod ll;
56mod nor_flash;
57mod storage;
58
59#[cfg(not(feature = "emulation"))]
60mod mmu;
61
62mod encrypted;
63
64#[cfg(not(feature = "emulation"))]
65#[inline(always)]
66fn maybe_with_critical_section<R>(f: impl FnOnce() -> R) -> R {
67    #[cfg(feature = "critical-section")]
68    {
69        static LOCK: esp_sync::RawMutex = esp_sync::RawMutex::new();
70
71        LOCK.lock(f)
72    }
73
74    #[cfg(not(feature = "critical-section"))]
75    f()
76}
77
78#[cfg(feature = "emulation")]
79fn maybe_with_critical_section<R>(f: impl FnOnce() -> R) -> R {
80    f()
81}
82
83/// Whether flash encryption is enabled or not.
84#[cfg(not(feature = "emulation"))]
85pub fn flash_encryption() -> bool {
86    esp_hal::efuse::flash_encryption()
87}