Skip to main content

esp_alloc/
macros.rs

1//! Macros provided for convenience
2
3/// Initialize a global heap allocator providing a heap of the given size in
4/// bytes. This supports attributes.
5///
6/// # Usage
7/// ```rust, no_run
8/// // Use 64kB in the same region stack uses (dram_seg), for the heap.
9/// heap_allocator!(size: 64000);
10/// // Use 64kB for the heap in the memory region reclaimed from the bootloader, which is otherwise unused.
11/// heap_allocator!(#[ram(reclaimed)] size: 64000);
12/// ```
13#[macro_export]
14macro_rules! heap_allocator {
15    ($(#[$m:meta])* size: $size:expr) => {{
16        $(#[$m])*
17        static mut HEAP: core::mem::MaybeUninit<[u8; $size]> = core::mem::MaybeUninit::uninit();
18
19        unsafe {
20            $crate::HEAP.add_region($crate::HeapRegion::new(
21                HEAP.as_mut_ptr() as *mut u8,
22                $size,
23                $crate::MemoryCapability::Internal.into(),
24            ));
25        }
26    }};
27}
28
29/// Initialize a global heap allocator backed by PSRAM
30///
31/// You need a SoC which supports PSRAM and activate the feature to enable
32/// it. You need to pass the PSRAM peripheral and the psram module path.
33///
34/// # Usage
35///
36/// ```rust, no_run
37/// esp_alloc::psram_allocator!(peripherals.PSRAM, hal::psram);
38/// ```
39///
40/// # ⚠️ Limitations
41///
42/// On ESP32, ESP32-S2 and ESP32-S3 the atomic instructions do not work
43/// correctly when the memory they access is located in PSRAM. This means that
44/// the allocator must not be used to allocate `Atomic*` types - either directly
45/// or indirectly. Be very careful when using PSRAM in your global allocator.
46#[macro_export]
47macro_rules! psram_allocator {
48    ($peripheral:expr, $psram_module:path) => {
49        $crate::psram_allocator!($peripheral, $psram_module, Default::default());
50    };
51    ($peripheral:expr, $psram_module:path, $config:expr) => {{
52        use $psram_module as _psram;
53        let psram = _psram::Psram::new($peripheral, $config);
54        $crate::psram_allocator!(&psram);
55    }};
56    (&$psram:ident) => {
57        let (start, size) = $psram.raw_parts();
58        unsafe {
59            $crate::HEAP.add_region($crate::HeapRegion::new(
60                start,
61                size,
62                $crate::MemoryCapability::External.into(),
63            ));
64        }
65    };
66}