diff --git a/esp-alloc/CHANGELOG.md b/esp-alloc/CHANGELOG.md index 85894f3a362..4ce4d03b19c 100644 --- a/esp-alloc/CHANGELOG.md +++ b/esp-alloc/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- a global allocator is created in esp-alloc, now you need to add individual memory regions (up to 3) to the allocator (#2099) + ### Fixed ### Removed diff --git a/esp-alloc/Cargo.toml b/esp-alloc/Cargo.toml index d6beab49b8a..09d1bd2f238 100644 --- a/esp-alloc/Cargo.toml +++ b/esp-alloc/Cargo.toml @@ -23,7 +23,8 @@ default-target = "riscv32imc-unknown-none-elf" features = ["nightly"] [dependencies] -critical-section = "1.1.2" +critical-section = "1.1.3" +enumset = "1.1.5" linked_list_allocator = { version = "0.10.5", default-features = false, features = ["const_mut_refs"] } [features] diff --git a/esp-alloc/src/lib.rs b/esp-alloc/src/lib.rs index 3d4bce93961..c3c6c7f0009 100644 --- a/esp-alloc/src/lib.rs +++ b/esp-alloc/src/lib.rs @@ -1,33 +1,35 @@ -//! A simple `no_std` heap allocator for RISC-V and Xtensa processors from +//! A `no_std` heap allocator for RISC-V and Xtensa processors from //! Espressif. Supports all currently available ESP32 devices. //! //! **NOTE:** using this as your global allocator requires using Rust 1.68 or //! greater, or the `nightly` release channel. //! //! # Using this as your Global Allocator -//! To use EspHeap as your global allocator, you need at least Rust 1.68 or -//! nightly. //! //! ```rust -//! #[global_allocator] -//! static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty(); +//! use esp_alloc as _; //! //! fn init_heap() { //! const HEAP_SIZE: usize = 32 * 1024; //! static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit(); //! //! unsafe { -//! ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE); +//! esp_alloc::INSTANCE.add_region(esp_alloc::HeapRegion::new( +//! HEAP.as_mut_ptr() as *mut u8, +//! HEAP_SIZE, +//! esp_alloc::MemoryCapability::Internal.into(), +//! )); //! } //! } //! ``` //! //! # Using this with the nightly `allocator_api`-feature -//! Sometimes you want to have single allocations in PSRAM, instead of an esp's -//! DRAM. For that, it's convenient to use the nightly `allocator_api`-feature, +//! Sometimes you want to have more control over allocations. +//! +//! For that, it's convenient to use the nightly `allocator_api`-feature, //! which allows you to specify an allocator for single allocations. //! -//! **NOTE:** To use this, you have to enable the create's `nightly` feature +//! **NOTE:** To use this, you have to enable the crate's `nightly` feature //! flag. //! //! Create and initialize an allocator to use in single allocations: @@ -36,7 +38,11 @@ //! //! fn init_psram_heap() { //! unsafe { -//! PSRAM_ALLOCATOR.init(psram::psram_vaddr_start() as *mut u8, psram::PSRAM_BYTES); +//! PSRAM_ALLOCATOR.add_region(esp_alloc::HeapRegion::new( +//! psram::psram_vaddr_start() as *mut u8, +//! psram::PSRAM_BYTES, +//! esp_alloc::MemoryCapability::Internal.into(), +//! )); //! } //! } //! ``` @@ -50,7 +56,7 @@ #![cfg_attr(feature = "nightly", feature(allocator_api))] #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] -pub mod macros; +mod macros; #[cfg(feature = "nightly")] use core::alloc::{AllocError, Allocator}; @@ -61,35 +67,81 @@ use core::{ }; use critical_section::Mutex; +use enumset::{EnumSet, EnumSetType}; use linked_list_allocator::Heap; +/// The global allocator instance +#[global_allocator] +pub static HEAP: EspHeap = EspHeap::empty(); + +const NON_REGION: Option = None; + +#[derive(EnumSetType)] +/// Describes the properties of a memory region +pub enum MemoryCapability { + /// Memory must be internal; specifically it should not disappear when + /// flash/spiram cache is switched off + Internal, + /// Memory must be in SPI RAM + External, +} + +/// A memory region to be used as heap memory +pub struct HeapRegion { + heap: Heap, + capabilities: EnumSet, +} + +impl HeapRegion { + /// Create a new [HeapRegion] with the given capabilities + /// + /// # Safety + /// + /// - The supplied memory region must be available for the entire program + /// (`'static`). + /// - The supplied memory region must be exclusively available to the heap + /// only, no aliasing. + /// - `size > 0`. + pub unsafe fn new( + heap_bottom: *mut u8, + size: usize, + capabilities: EnumSet, + ) -> Self { + let mut heap = Heap::empty(); + heap.init(heap_bottom, size); + + Self { heap, capabilities } + } +} + +/// A memory allocator +/// +/// In addition to what Rust's memory allocator can do it allows to allocate +/// memory in regions satisfying specific needs. pub struct EspHeap { - heap: Mutex>, + heap: Mutex; 3]>>, } impl EspHeap { /// Crate a new UNINITIALIZED heap allocator - /// - /// You must initialize this heap using the - /// [`init`](struct.EspHeap.html#method.init) method before using the - /// allocator. - pub const fn empty() -> EspHeap { + pub const fn empty() -> Self { EspHeap { - heap: Mutex::new(RefCell::new(Heap::empty())), + heap: Mutex::new(RefCell::new([NON_REGION; 3])), } } - /// Initializes the heap - /// - /// This function must be called BEFORE you run any code that makes use of - /// the allocator. + /// Add a memory region to the heap /// /// `heap_bottom` is a pointer to the location of the bottom of the heap. /// /// `size` is the size of the heap in bytes. /// + /// You can add up to three regions per allocator. + /// /// Note that: /// + /// - Memory is allocated from the first suitable memory region first + /// /// - The heap grows "upwards", towards larger addresses. Thus `end_addr` /// must be larger than `start_addr` /// @@ -102,59 +154,147 @@ impl EspHeap { /// `'static` lifetime). /// - The supplied memory region must be exclusively available to the heap /// only, no aliasing. - /// - This function must be called exactly ONCE. /// - `size > 0`. - pub unsafe fn init(&self, heap_bottom: *mut u8, size: usize) { - critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().init(heap_bottom, size)); + pub unsafe fn add_region(&self, region: HeapRegion) { + critical_section::with(|cs| { + let mut regions = self.heap.borrow_ref_mut(cs); + let free = regions + .iter() + .enumerate() + .find(|v| v.1.is_none()) + .map(|v| v.0); + + if let Some(free) = free { + regions[free] = Some(region); + } else { + panic!( + "Exceeded the maximum of {} heap memory regions", + regions.len() + ); + } + }); } - /// Returns an estimate of the amount of bytes in use. + /// Returns an estimate of the amount of bytes in use in all memory regions. pub fn used(&self) -> usize { - critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().used()) + critical_section::with(|cs| { + let regions = self.heap.borrow_ref(cs); + let mut used = 0; + for region in regions.iter() { + if let Some(region) = region.as_ref() { + used += region.heap.used(); + } + } + used + }) } /// Returns an estimate of the amount of bytes available. pub fn free(&self) -> usize { - critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().free()) + self.free_caps(EnumSet::empty()) + } + + /// The free heap satisfying the given requirements + pub fn free_caps(&self, capabilities: EnumSet) -> usize { + critical_section::with(|cs| { + let regions = self.heap.borrow_ref(cs); + let mut free = 0; + for region in regions.iter().filter(|region| { + if region.is_some() { + region + .as_ref() + .unwrap() + .capabilities + .is_superset(capabilities) + } else { + false + } + }) { + if let Some(region) = region.as_ref() { + free += region.heap.free(); + } + } + free + }) + } + + /// Allocate memory in a region satisfying the given requirements. + /// + /// # Safety + /// + /// This function is unsafe because undefined behavior can result + /// if the caller does not ensure that `layout` has non-zero size. + /// + /// The allocated block of memory may or may not be initialized. + pub unsafe fn alloc_caps( + &self, + capabilities: EnumSet, + layout: Layout, + ) -> *mut u8 { + critical_section::with(|cs| { + let mut regions = self.heap.borrow_ref_mut(cs); + let mut iter = (*regions).iter_mut().filter(|region| { + if region.is_some() { + region + .as_ref() + .unwrap() + .capabilities + .is_superset(capabilities) + } else { + false + } + }); + + let res = loop { + if let Some(Some(region)) = iter.next() { + let res = region.heap.allocate_first_fit(layout); + if let Ok(res) = res { + break Some(res); + } + } else { + break None; + } + }; + + res.map_or(ptr::null_mut(), |allocation| allocation.as_ptr()) + }) } } unsafe impl GlobalAlloc for EspHeap { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - critical_section::with(|cs| { - self.heap - .borrow(cs) - .borrow_mut() - .allocate_first_fit(layout) - .ok() - .map_or(ptr::null_mut(), |allocation| allocation.as_ptr()) - }) + self.alloc_caps(EnumSet::empty(), layout) } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + if ptr.is_null() { + return; + } + critical_section::with(|cs| { - self.heap - .borrow(cs) - .borrow_mut() - .deallocate(NonNull::new_unchecked(ptr), layout) - }); + let mut regions = self.heap.borrow_ref_mut(cs); + let mut iter = (*regions).iter_mut(); + + while let Some(Some(region)) = iter.next() { + if region.heap.bottom() <= ptr && region.heap.top() >= ptr { + region.heap.deallocate(NonNull::new_unchecked(ptr), layout); + } + } + }) } } #[cfg(feature = "nightly")] unsafe impl Allocator for EspHeap { fn allocate(&self, layout: Layout) -> Result, AllocError> { - critical_section::with(|cs| { - let raw_ptr = self - .heap - .borrow(cs) - .borrow_mut() - .allocate_first_fit(layout) - .map_err(|_| AllocError)? - .as_ptr(); - let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, layout.size())) - }) + let raw_ptr = unsafe { self.alloc(layout) }; + + if raw_ptr.is_null() { + return Err(AllocError); + } + + let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; + Ok(NonNull::slice_from_raw_parts(ptr, layout.size())) } unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { diff --git a/esp-alloc/src/macros.rs b/esp-alloc/src/macros.rs index 17eec9662b9..47d9c454fa4 100644 --- a/esp-alloc/src/macros.rs +++ b/esp-alloc/src/macros.rs @@ -1,24 +1,25 @@ //! Macros provided for convenience -/// Create a heap allocator providing a heap of the given size in bytes -/// -/// You can only have ONE allocator at most +/// Initialize a global heap allocator providing a heap of the given size in +/// bytes #[macro_export] macro_rules! heap_allocator { ($size:expr) => {{ - #[global_allocator] - static ALLOCATOR: $crate::EspHeap = $crate::EspHeap::empty(); static mut HEAP: core::mem::MaybeUninit<[u8; $size]> = core::mem::MaybeUninit::uninit(); unsafe { - ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, $size); + $crate::HEAP.add_region($crate::HeapRegion::new( + HEAP.as_mut_ptr() as *mut u8, + $size, + $crate::MemoryCapability::Internal.into(), + )); } }}; } -/// Create a heap allocator backed by PSRAM +/// Initialize a global heap allocator backed by PSRAM /// -/// You can only have ONE allocator at most. You need a SoC which supports PSRAM +/// You need a SoC which supports PSRAM /// and activate the feature to enable it. You need to pass the PSRAM peripheral /// and the psram module path. /// @@ -29,13 +30,14 @@ macro_rules! heap_allocator { #[macro_export] macro_rules! psram_allocator { ($peripheral:expr,$psram_module:path) => {{ - #[global_allocator] - static ALLOCATOR: $crate::EspHeap = $crate::EspHeap::empty(); - use $psram_module as _psram; _psram::init_psram($peripheral); unsafe { - ALLOCATOR.init(_psram::psram_vaddr_start() as *mut u8, _psram::PSRAM_BYTES); + $crate::HEAP.add_region($crate::HeapRegion::new( + _psram::psram_vaddr_start() as *mut u8, + _psram::PSRAM_BYTES, + $crate::MemoryCapability::External.into(), + )); } }}; } diff --git a/esp-hal/src/soc/esp32s2/psram.rs b/esp-hal/src/soc/esp32s2/psram.rs index 54fbb2ec2e0..a02b059f6e5 100644 --- a/esp-hal/src/soc/esp32s2/psram.rs +++ b/esp-hal/src/soc/esp32s2/psram.rs @@ -43,6 +43,7 @@ pub const PSRAM_VADDR_START: usize = PSRAM_VADDR as usize; /// Initialize PSRAM to be used for data. #[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))] +#[procmacros::ram] pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

) { #[allow(unused)] enum CacheLayout { diff --git a/esp-hal/src/soc/esp32s3/psram.rs b/esp-hal/src/soc/esp32s3/psram.rs index 59aa01d16e4..c910895e941 100644 --- a/esp-hal/src/soc/esp32s3/psram.rs +++ b/esp-hal/src/soc/esp32s3/psram.rs @@ -57,6 +57,7 @@ pub const PSRAM_BYTES: usize = PSRAM_SIZE as usize * 1024 * 1024; feature = "opsram-8m", feature = "opsram-16m" ))] +#[procmacros::ram] pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

) { const CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE: u32 = 0x4000; const CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS: u8 = 8; diff --git a/esp-wifi/CHANGELOG.md b/esp-wifi/CHANGELOG.md index 8a1064b7581..b85f9612de8 100644 --- a/esp-wifi/CHANGELOG.md +++ b/esp-wifi/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `have-strchr` feature to disable including `strchr` (#2096) ### Changed +- esp-wifi now allocates memory from the global allocator provided by `esp-alloc` (#2099) ### Fixed diff --git a/esp-wifi/Cargo.toml b/esp-wifi/Cargo.toml index e935fe2b4fc..8082e54c956 100644 --- a/esp-wifi/Cargo.toml +++ b/esp-wifi/Cargo.toml @@ -13,6 +13,8 @@ categories = ["embedded", "hardware-support", "no-std"] [dependencies] defmt = { version = "0.3.8", optional = true } +document-features = "0.2.10" +esp-alloc = { version = "0.4.0", path = "../esp-alloc", optional = true } esp-hal = { version = "0.20.0", path = "../esp-hal", default-features = false } esp-hal-embassy = { version = "0.3.0", path = "../esp-hal-embassy", default-features = false, optional = true } smoltcp = { version = "0.11.0", default-features = false, features = [ @@ -24,9 +26,6 @@ log = { version = "0.4.22", optional = true } embedded-svc = { version = "0.27.1", default-features = false, features = [ ], optional = true } enumset = { version = "1.1.5", default-features = false, optional = true } -linked_list_allocator = { version = "0.10.5", default-features = false, features = [ - "const_mut_refs", -] } embedded-io = { version = "0.6.1", default-features = false } embedded-io-async = { version = "0.6.1", optional = true } fugit = "0.3.7" @@ -60,46 +59,59 @@ esp-build = { version = "0.1.0", path = "../esp-build" } esp-metadata = { version = "0.3.0", path = "../esp-metadata" } [features] -default = ["log"] +default = ["log", "esp-alloc"] + +## Use `esp-alloc` for dynamic allocations. +## +## If you opt-out you need to provide implementations for `pub extern "C" fn esp_wifi_free_internal_heap() -> usize` +## and `pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8` +esp-alloc = ["dep:esp-alloc"] -# chip features +# Chip Support Feature Flags +# Target the ESP32-C2. esp32c2 = [ "esp-hal/esp32c2", "esp-hal-embassy?/esp32c2", "esp-wifi-sys/esp32c2", ] +# Target the ESP32-C3. esp32c3 = [ "esp-hal/esp32c3", "esp-hal-embassy?/esp32c3", "esp-wifi-sys/esp32c3", ] +# Target the ESP32-C6. esp32c6 = [ "esp-hal/esp32c6", "esp-hal-embassy?/esp32c6", "esp-wifi-sys/esp32c6", ] +# Target the ESP32-H2. esp32h2 = [ "esp-hal/esp32h2", "esp-hal-embassy?/esp32h2", "esp-wifi-sys/esp32h2", ] +# Target the ESP32. esp32 = [ "esp-hal/esp32", "esp-hal-embassy?/esp32", "esp-wifi-sys/esp32", ] +# Target the ESP32-S2. esp32s2 = [ "esp-hal/esp32s2", "esp-hal-embassy?/esp32s2", "esp-wifi-sys/esp32s2", ] +# Target the ESP32-S3. esp32s3 = [ "esp-hal/esp32s3", "esp-hal-embassy?/esp32s3", "esp-wifi-sys/esp32s3", ] -# async features +## Enable Async support async = [ "dep:embassy-sync", "dep:embassy-futures", @@ -108,34 +120,84 @@ async = [ "dep:bt-hci", ] +## Enable `embassy-net` support embassy-net = ["dep:embassy-net-driver", "async"] -# misc features +## Enable WiFi-BLE coexistence support coex = [] + +## Logs the WiFi logs from the driver at log level info (needs a nightly-compiler) wifi-logs = [] + +## Dumps packet info at log level info dump-packets = [] + +## Provide implementations of smoltcp traits smoltcp = ["dep:smoltcp"] + +## Provide utilities for smoltcp initialization. Adds smoltcp dependency utils = ["smoltcp"] + enumset = [] + +## Enable WiFi support wifi = ["dep:enumset", "dep:no-std-net"] + +## Implement the embedded-svc Wifi trait embedded-svc = ["dep:embedded-svc"] + +## Enable BLE support ble = ["esp-hal/bluetooth"] + +## See USB-SERIAL-JTAG below phy-enable-usb = [] + +## Enable minimum modem sleep. Only affects STA mode ps-min-modem = [] + +## Enable maximum modem sleep. Only affects STA mode ps-max-modem = [] + +## Enable esp-now support esp-now = ["wifi"] + +## IPv6 support. Includes utils feature ipv6 = ["wifi", "utils", "smoltcp?/proto-ipv6"] + +## IPv4 support. Includes utils feature ipv4 = ["wifi", "utils", "smoltcp?/proto-ipv4"] + +## TCP socket support. Includes ipv4 feature tcp = ["ipv4", "smoltcp?/socket-tcp"] + +## UDP socket support. Includes ipv4 feature udp = ["ipv4", "smoltcp?/socket-udp"] + +## ICMP socket support. Includes ipv4 feature icmp = ["ipv4", "smoltcp?/socket-icmp"] + +## IGMP (multicast) support. Includes ipv4 featu igmp = ["ipv4", "smoltcp?/proto-igmp"] + +## DNS support. Includes udp feature dns = ["udp", "smoltcp?/proto-dns", "smoltcp?/socket-dns"] + +## DHCPv4 support, both creating sockets and autoconfiguring network settings. Includes utils feature dhcpv4 = ["wifi", "utils", "smoltcp?/proto-dhcpv4", "smoltcp?/socket-dhcpv4"] + +## Convenience to enable "ipv4", "tcp", "udp", "icmp", "igmp", "dns", "dhcpv4" wifi-default = ["ipv4", "tcp", "udp", "icmp", "igmp", "dns", "dhcpv4"] + +## Enable support for `defmt` defmt = ["dep:defmt", "smoltcp?/defmt", "esp-hal/defmt"] + +## Enable support for the `log` crate log = ["dep:log", "esp-hal/log"] + +## Enable sniffer mode support sniffer = ["wifi"] + +# Don't include `strchr` - not shown in docs have-strchr = [] [package.metadata.docs.rs] diff --git a/esp-wifi/MIGRATING-0.9.md b/esp-wifi/MIGRATING-0.9.md index 3763b185f8e..c33374dcf74 100644 --- a/esp-wifi/MIGRATING-0.9.md +++ b/esp-wifi/MIGRATING-0.9.md @@ -1,8 +1,6 @@ -Migration Guide from 0.9.x to vNext -==================================== +# Migration Guide from 0.9.x to vNext -Initialsation -------------- +## Initialization You no longer have to set up clocks and pass them to `esp_wifi::initialize`. @@ -39,3 +37,26 @@ You no longer have to set up clocks and pass them to `esp_wifi::initialize`. // ... } ``` + +## Memory allocation + +You now need to have a global allocator provided by `esp-alloc` providing allocations from internal memory + +```diff + #![no_std] + #![no_main] + ++extern crate alloc; ++ + use embedded_io::*; ++use esp_alloc as _; + use esp_backtrace as _; + // ... + + #[entry] + fn main() -> ! { ++ esp_alloc::heap_allocator!(72 * 1024); ++ + + // ... +``` diff --git a/esp-wifi/README.md b/esp-wifi/README.md index c7e9fa1501b..3b19baa4877 100644 --- a/esp-wifi/README.md +++ b/esp-wifi/README.md @@ -71,38 +71,6 @@ When using USB-SERIAL-JTAG (for example by selecting `jtag-serial` in [`esp-prin Don't use this feature if you are _not_ using USB-SERIAL-JTAG as it might reduce WiFi performance. -## Features - -| Feature | Meaning | -| -------------- | ---------------------------------------------------------------------------------------------------- | -| wifi-logs | logs the WiFi logs from the driver at log level `info` (needs a nightly-compiler) | -| wifi-default | A convenience feature to enable some reasonable defaults for wifi use. | -| dump-packets | dumps packet info at log level `info` | -| smoltcp | Provide implementations of `smoltcp` traits | -| utils | Provide utilities for smoltcp initialization. Adds `smoltcp` dependency | -| ble | Enable BLE support | -| wifi | Enable WiFi support | -| esp-now | Enable [esp-now](https://www.espressif.com/en/solutions/low-power-solutions/esp-now) support | -| coex | Enable WiFi-BLE coexistence support | -| ipv4 | IPv4 support. Includes `utils` feature | -| ipv6 | IPv6 support. Includes `utils` feature | -| tcp | TCP socket support. Includes `ipv4` feature | -| udp | UDP socket support. Includes `ipv4` feature | -| igmp | IGMP (multicast) support. Includes `ipv4` feature | -| dns | DNS support. Includes `udp` feature | -| dhcpv4 | DHCPv4 support, both creating sockets and autoconfiguring network settings. Includes `utils` feature | -| phy-enable-usb | See [USB-SERIAL-JTAG](#usb-serial-jtag) above | -| ps-min-modem | Enable minimum modem sleep. Only affects STA mode | -| ps-max-modem | Enable maximum modem sleep. Only affects STA mode | -| log | Route log output to the `log` crate | -| defmt | Add `defmt::Format` implementation and output logs via `defmt` | -| embedded-svc | Implement the embedded-svc Wifi trait | - -Note that not all features are available on every MCU. For example, `ble` (and thus, `coex`) is not available on ESP32-S2. - -When using the `dump-packets` feature you can use the extcap in `extras/esp-wifishark` to analyze the frames in Wireshark. -For more information see [extras/esp-wifishark/README.md](../extras/esp-wifishark/README.md) - ## Tuning The defaults used by `esp-wifi` and the examples are rather conservative. It is possible to change a few of the important settings. diff --git a/esp-wifi/src/compat/malloc.rs b/esp-wifi/src/compat/malloc.rs index 0647db0ff90..be4eb3ccc2a 100644 --- a/esp-wifi/src/compat/malloc.rs +++ b/esp-wifi/src/compat/malloc.rs @@ -1,20 +1,16 @@ use core::alloc::Layout; -use crate::HEAP; - #[no_mangle] pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 { trace!("alloc {}", size); let total_size = size + 4; - let layout = Layout::from_size_align_unchecked(total_size, 4); - let ptr = critical_section::with(|cs| { - HEAP.borrow_ref_mut(cs) - .allocate_first_fit(layout) - .ok() - .map_or(core::ptr::null_mut(), |allocation| allocation.as_ptr()) - }); + extern "C" { + fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8; + } + + let ptr = unsafe { esp_wifi_allocate_from_internal_ram(total_size) }; if ptr.is_null() { warn!("Unable to allocate {} bytes", size); @@ -37,10 +33,7 @@ pub unsafe extern "C" fn free(ptr: *mut u8) { let total_size = *(ptr as *const usize); let layout = Layout::from_size_align_unchecked(total_size, 4); - critical_section::with(|cs| { - HEAP.borrow_ref_mut(cs) - .deallocate(core::ptr::NonNull::new_unchecked(ptr), layout) - }); + alloc::alloc::dealloc(ptr, layout); } #[no_mangle] @@ -80,3 +73,22 @@ unsafe extern "C" fn realloc(ptr: *mut u8, new_size: usize) -> *mut u8 { p } } + +#[cfg(feature = "esp-alloc")] +#[doc(hidden)] +#[no_mangle] +pub extern "C" fn esp_wifi_free_internal_heap() -> usize { + esp_alloc::HEAP.free_caps(esp_alloc::MemoryCapability::Internal.into()) +} + +#[cfg(feature = "esp-alloc")] +#[doc(hidden)] +#[no_mangle] +pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8 { + unsafe { + esp_alloc::HEAP.alloc_caps( + esp_alloc::MemoryCapability::Internal.into(), + core::alloc::Layout::from_size_align_unchecked(size, 4), + ) + } +} diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs index 5d8027bd037..66a495e850c 100644 --- a/esp-wifi/src/lib.rs +++ b/esp-wifi/src/lib.rs @@ -1,21 +1,30 @@ +//! # Features flags +//! +//! Note that not all features are available on every MCU. For example, `ble` +//! (and thus, `coex`) is not available on ESP32-S2. +//! +//! When using the `dump-packets` feature you can use the extcap in +//! `extras/esp-wifishark` to analyze the frames in Wireshark. +//! For more information see +//! [extras/esp-wifishark/README.md](../extras/esp-wifishark/README.md) +#![doc = document_features::document_features!(feature_label = r#"{feature}"#)] +#![doc = include_str!("../README.md")] +#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![no_std] #![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))] #![cfg_attr(any(feature = "wifi-logs", nightly), feature(c_variadic))] -#![doc = include_str!("../README.md")] -#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")] #![allow(rustdoc::bare_urls)] // allow until num-derive doesn't generate this warning anymore (unknown_lints because Xtensa // toolchain doesn't know about that lint, yet) #![allow(unknown_lints)] #![allow(non_local_definitions)] +extern crate alloc; + // MUST be the first module mod fmt; -use core::{cell::RefCell, mem::MaybeUninit, ptr::addr_of_mut}; - use common_adapter::{chip_specific::phy_mem_init, init_radio_clock_control, RADIO_CLOCKS}; -use critical_section::Mutex; use esp_hal as hal; #[cfg(not(feature = "esp32"))] use esp_hal::timer::systimer::Alarm; @@ -25,7 +34,6 @@ use hal::{ system::RadioClockController, timer::{timg::Timer as TimgTimer, ErasedTimer, PeriodicTimer}, }; -use linked_list_allocator::Heap; #[cfg(feature = "wifi")] use wifi::WifiError; @@ -73,12 +81,6 @@ const DEFAULT_TICK_RATE_HZ: u32 = 50; #[cfg(not(debug_assertions))] const DEFAULT_TICK_RATE_HZ: u32 = 100; -#[cfg(not(coex))] -const DEFAULT_HEAP_SIZE: usize = 81920; - -#[cfg(coex)] -const DEFAULT_HEAP_SIZE: usize = 90112; - #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[toml_cfg::toml_config] @@ -112,8 +114,6 @@ struct Config { country_code_operating_class: u8, #[default(1492)] mtu: usize, - #[default(DEFAULT_HEAP_SIZE)] - heap_size: usize, #[default(DEFAULT_TICK_RATE_HZ)] tick_rate_hz: u32, #[default(3)] @@ -140,20 +140,6 @@ const _: () = { core::assert!(CONFIG.rx_ba_win < (CONFIG.static_rx_buf_num * 2), "WiFi configuration check: rx_ba_win should not be larger than double of the static_rx_buf_num!"); }; -const HEAP_SIZE: usize = crate::CONFIG.heap_size; - -#[cfg_attr(esp32, link_section = ".dram2_uninit")] -static mut HEAP_DATA: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; - -pub(crate) static HEAP: Mutex> = Mutex::new(RefCell::new(Heap::empty())); - -fn init_heap() { - critical_section::with(|cs| { - HEAP.borrow_ref_mut(cs) - .init_from_slice(unsafe { &mut *addr_of_mut!(HEAP_DATA) as &mut [MaybeUninit] }) - }); -} - type TimeBase = PeriodicTimer<'static, ErasedTimer>; #[derive(Debug, PartialEq, PartialOrd)] @@ -320,7 +306,6 @@ pub fn initialize( crate::common_adapter::chip_specific::enable_wifi_power_domain(); - init_heap(); phy_mem_init(); init_radio_clock_control(radio_clocks); init_rng(rng); diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index dbb896b1abd..b45a2276d03 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -905,7 +905,11 @@ pub unsafe extern "C" fn event_post( /// /// ************************************************************************* pub unsafe extern "C" fn get_free_heap_size() -> u32 { - critical_section::with(|cs| crate::HEAP.borrow_ref(cs).free() as u32) + extern "C" { + fn esp_wifi_free_internal_heap() -> usize; + } + + esp_wifi_free_internal_heap() as u32 } /// ************************************************************************** diff --git a/esp-wifi/tuning.md b/esp-wifi/tuning.md index c73625e1877..ec80d27e408 100644 --- a/esp-wifi/tuning.md +++ b/esp-wifi/tuning.md @@ -44,7 +44,6 @@ You can set the following settings |country_code|Country code. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-country-code)| |country_code_operating_class|If not 0: Operating Class table number. See [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-country-code)| |mtu|MTU, see [documentation](https://docs.rs/smoltcp/0.10.0/smoltcp/phy/struct.DeviceCapabilities.html#structfield.max_transmission_unit)| -|heap_size|Size of the WiFi/BLE heap in bytes| |tick_rate_hz|Tick rate of the internal task scheduler in hertz.| |listen_interval|Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval. For example, if beacon interval is 100 ms and listen interval is 3, the interval for station to listen to beacon is 300 ms| |beacon_timeout|For Station, If the station does not receive a beacon frame from the connected SoftAP during the inactive time, disconnect from SoftAP. Default 6s. Range 6-30| diff --git a/examples/Cargo.toml b/examples/Cargo.toml index eeb9e384ac2..c7c22dd935e 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -14,7 +14,7 @@ cfg-if = "1.0.0" critical-section = "1.1.2" crypto-bigint = { version = "0.5.5", default-features = false } elliptic-curve = { version = "0.13.8", default-features = false, features = ["sec1"] } -embassy-executor = { version = "0.6.0", features = ["task-arena-size-40960"] } +embassy-executor = { version = "0.6.0", features = ["task-arena-size-12288"] } embassy-futures = "0.1.1" embassy-net = { version = "0.4.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] } embassy-sync = "0.6.0" diff --git a/examples/src/bin/dma_extmem2mem.rs b/examples/src/bin/dma_extmem2mem.rs index 5f6ac7580da..1fb0081f631 100644 --- a/examples/src/bin/dma_extmem2mem.rs +++ b/examples/src/bin/dma_extmem2mem.rs @@ -7,6 +7,7 @@ #![no_main] use aligned::{Aligned, A64}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{ delay::Delay, @@ -41,9 +42,6 @@ macro_rules! dma_alloc_buffer { }}; } -#[global_allocator] -static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty(); - fn init_heap(psram: impl esp_hal::peripheral::Peripheral

) { esp_hal::psram::init_psram(psram); info!( @@ -51,10 +49,11 @@ fn init_heap(psram: impl esp_hal::peripheral::Peripheral

! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let delay = Delay::new(); let timg0 = TimerGroup::new(peripherals.TIMG0); diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index 2673feecff0..d4171d51edf 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -14,6 +14,7 @@ #![no_main] use embedded_io::*; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -40,6 +41,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_access_point_with_sta.rs b/examples/src/bin/wifi_access_point_with_sta.rs index ece68d13a1a..4417621cb49 100644 --- a/examples/src/bin/wifi_access_point_with_sta.rs +++ b/examples/src/bin/wifi_access_point_with_sta.rs @@ -15,6 +15,7 @@ #![no_main] use embedded_io::*; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -47,6 +48,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_bench.rs b/examples/src/bin/wifi_bench.rs index f93e24f518d..ae9924840b2 100644 --- a/examples/src/bin/wifi_bench.rs +++ b/examples/src/bin/wifi_bench.rs @@ -14,6 +14,7 @@ #![no_main] use embedded_io::*; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{delay::Delay, prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::println; @@ -57,6 +58,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let server_address: Ipv4Address = HOST_IP.parse().expect("Invalid HOST_IP address"); let timg0 = TimerGroup::new(peripherals.TIMG0); diff --git a/examples/src/bin/wifi_ble.rs b/examples/src/bin/wifi_ble.rs index 11a9a55644f..dfbf3690c32 100644 --- a/examples/src/bin/wifi_ble.rs +++ b/examples/src/bin/wifi_ble.rs @@ -22,6 +22,7 @@ use bleps::{ Ble, HciConnector, }; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{ gpio::{Input, Io, Pull}, @@ -41,6 +42,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_coex.rs b/examples/src/bin/wifi_coex.rs index ee4097949ce..3c70dba79e5 100644 --- a/examples/src/bin/wifi_coex.rs +++ b/examples/src/bin/wifi_coex.rs @@ -25,6 +25,7 @@ use bleps::{ HciConnector, }; use embedded_io::*; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -53,6 +54,26 @@ fn main() -> ! { config }); + static mut HEAP: core::mem::MaybeUninit<[u8; 72 * 1024]> = core::mem::MaybeUninit::uninit(); + + #[link_section = ".dram2_uninit"] + static mut HEAP2: core::mem::MaybeUninit<[u8; 64 * 1024]> = core::mem::MaybeUninit::uninit(); + + unsafe { + esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( + HEAP.as_mut_ptr() as *mut u8, + core::mem::size_of_val(&*core::ptr::addr_of!(HEAP)), + esp_alloc::MemoryCapability::Internal.into(), + )); + + // COEX needs more RAM - add some more + esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( + HEAP2.as_mut_ptr() as *mut u8, + core::mem::size_of_val(&*core::ptr::addr_of!(HEAP2)), + esp_alloc::MemoryCapability::Internal.into(), + )); + } + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_dhcp.rs b/examples/src/bin/wifi_dhcp.rs index b2e8d0f665e..63006626a69 100644 --- a/examples/src/bin/wifi_dhcp.rs +++ b/examples/src/bin/wifi_dhcp.rs @@ -11,7 +11,10 @@ #![no_std] #![no_main] +extern crate alloc; + use embedded_io::*; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -46,6 +49,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_embassy_access_point.rs b/examples/src/bin/wifi_embassy_access_point.rs index a47be1507f3..43879decc2f 100644 --- a/examples/src/bin/wifi_embassy_access_point.rs +++ b/examples/src/bin/wifi_embassy_access_point.rs @@ -9,7 +9,7 @@ //! Because of the huge task-arena size configured this won't work on ESP32-S2 //% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/async esp-wifi/embassy-net esp-wifi/wifi-default esp-wifi/wifi esp-wifi/utils -//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 +//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 #![no_std] #![no_main] @@ -25,6 +25,7 @@ use embassy_net::{ StaticConfigV4, }; use embassy_time::{Duration, Timer}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -61,6 +62,8 @@ async fn main(spawner: Spawner) -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_embassy_access_point_with_sta.rs b/examples/src/bin/wifi_embassy_access_point_with_sta.rs index 3db855649ac..de9cf87b50a 100644 --- a/examples/src/bin/wifi_embassy_access_point_with_sta.rs +++ b/examples/src/bin/wifi_embassy_access_point_with_sta.rs @@ -12,7 +12,7 @@ //! Because of the huge task-arena size configured this won't work on ESP32-S2 //% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/async esp-wifi/embassy-net esp-wifi/wifi-default esp-wifi/wifi esp-wifi/utils -//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 +//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 #![no_std] #![no_main] @@ -28,6 +28,7 @@ use embassy_net::{ StaticConfigV4, }; use embassy_time::{Duration, Timer}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -69,6 +70,8 @@ async fn main(spawner: Spawner) -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_embassy_bench.rs b/examples/src/bin/wifi_embassy_bench.rs index 8ea9e44f2f0..7eaa1997e71 100644 --- a/examples/src/bin/wifi_embassy_bench.rs +++ b/examples/src/bin/wifi_embassy_bench.rs @@ -11,7 +11,7 @@ //! //% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/async esp-wifi/embassy-net esp-wifi/wifi-default esp-wifi/wifi esp-wifi/utils -//% CHIPS: esp32 esp32s3 esp32c3 esp32c6 +//% CHIPS: esp32 esp32s2 esp32s3 esp32c3 esp32c6 #![no_std] #![no_main] @@ -20,6 +20,7 @@ use embassy_executor::Spawner; use embassy_futures::join::join; use embassy_net::{tcp::TcpSocket, Ipv4Address, Stack, StackResources}; use embassy_time::{with_timeout, Duration, Timer}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::println; @@ -72,6 +73,26 @@ async fn main(spawner: Spawner) -> ! { config }); + static mut HEAP: core::mem::MaybeUninit<[u8; 32 * 1024]> = core::mem::MaybeUninit::uninit(); + + #[link_section = ".dram2_uninit"] + static mut HEAP2: core::mem::MaybeUninit<[u8; 64 * 1024]> = core::mem::MaybeUninit::uninit(); + + unsafe { + esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( + HEAP.as_mut_ptr() as *mut u8, + core::mem::size_of_val(&*core::ptr::addr_of!(HEAP)), + esp_alloc::MemoryCapability::Internal.into(), + )); + + // add some more RAM + esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new( + HEAP2.as_mut_ptr() as *mut u8, + core::mem::size_of_val(&*core::ptr::addr_of!(HEAP2)), + esp_alloc::MemoryCapability::Internal.into(), + )); + } + let server_address: Ipv4Address = HOST_IP.parse().expect("Invalid HOST_IP address"); let timg0 = TimerGroup::new(peripherals.TIMG0); diff --git a/examples/src/bin/wifi_embassy_ble.rs b/examples/src/bin/wifi_embassy_ble.rs index c8e7b0c04a8..d70d3414c17 100644 --- a/examples/src/bin/wifi_embassy_ble.rs +++ b/examples/src/bin/wifi_embassy_ble.rs @@ -25,6 +25,7 @@ use bleps::{ gatt, }; use embassy_executor::Spawner; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{ gpio::{Input, Io, Pull}, @@ -44,6 +45,8 @@ async fn main(_spawner: Spawner) -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_embassy_dhcp.rs b/examples/src/bin/wifi_embassy_dhcp.rs index 7e668f726a8..bc4237cb997 100644 --- a/examples/src/bin/wifi_embassy_dhcp.rs +++ b/examples/src/bin/wifi_embassy_dhcp.rs @@ -8,7 +8,7 @@ //! Because of the huge task-arena size configured this won't work on ESP32-S2 //% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/async esp-wifi/embassy-net esp-wifi/wifi-default esp-wifi/wifi esp-wifi/utils -//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 +//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 #![no_std] #![no_main] @@ -16,6 +16,7 @@ use embassy_executor::Spawner; use embassy_net::{tcp::TcpSocket, Ipv4Address, Stack, StackResources}; use embassy_time::{Duration, Timer}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::println; @@ -55,6 +56,8 @@ async fn main(spawner: Spawner) -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_embassy_esp_now.rs b/examples/src/bin/wifi_embassy_esp_now.rs index 03ea884b087..a81d714cd8e 100644 --- a/examples/src/bin/wifi_embassy_esp_now.rs +++ b/examples/src/bin/wifi_embassy_esp_now.rs @@ -5,7 +5,7 @@ //! Because of the huge task-arena size configured this won't work on ESP32-S2 //% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/async esp-wifi/embassy-net esp-wifi/wifi-default esp-wifi/wifi esp-wifi/utils esp-wifi/esp-now -//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 +//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 #![no_std] #![no_main] @@ -13,6 +13,7 @@ use embassy_executor::Spawner; use embassy_futures::select::{select, Either}; use embassy_time::{Duration, Ticker}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::println; @@ -31,6 +32,8 @@ async fn main(_spawner: Spawner) -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_embassy_esp_now_duplex.rs b/examples/src/bin/wifi_embassy_esp_now_duplex.rs index 66b241af1ad..060c58215f1 100644 --- a/examples/src/bin/wifi_embassy_esp_now_duplex.rs +++ b/examples/src/bin/wifi_embassy_esp_now_duplex.rs @@ -5,7 +5,7 @@ //! Because of the huge task-arena size configured this won't work on ESP32-S2 //% FEATURES: embassy embassy-generic-timers esp-wifi esp-wifi/async esp-wifi/embassy-net esp-wifi/wifi-default esp-wifi/wifi esp-wifi/utils esp-wifi/esp-now -//% CHIPS: esp32 esp32s3 esp32c2 esp32c3 esp32c6 +//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6 #![no_std] #![no_main] @@ -13,6 +13,7 @@ use embassy_executor::Spawner; use embassy_sync::{blocking_mutex::raw::NoopRawMutex, mutex::Mutex}; use embassy_time::{Duration, Ticker}; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::println; @@ -41,6 +42,8 @@ async fn main(spawner: Spawner) -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_esp_now.rs b/examples/src/bin/wifi_esp_now.rs index 83ebd654716..51432b49260 100644 --- a/examples/src/bin/wifi_esp_now.rs +++ b/examples/src/bin/wifi_esp_now.rs @@ -8,6 +8,7 @@ #![no_std] #![no_main] +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::println; @@ -27,6 +28,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/examples/src/bin/wifi_sniffer.rs b/examples/src/bin/wifi_sniffer.rs index 49746548f59..99837ea5113 100644 --- a/examples/src/bin/wifi_sniffer.rs +++ b/examples/src/bin/wifi_sniffer.rs @@ -17,7 +17,6 @@ use alloc::{ use core::cell::RefCell; use critical_section::Mutex; -use esp_alloc::heap_allocator; use esp_backtrace as _; use esp_hal::{ prelude::*, @@ -39,8 +38,7 @@ fn main() -> ! { config }); - // Create a heap allocator, with 32kB of space. - heap_allocator!(32_168); + esp_alloc::heap_allocator!(72 * 1024); let timg0 = TimerGroup::new(peripherals.TIMG0); let timer0: ErasedTimer = timg0.timer0.into(); diff --git a/examples/src/bin/wifi_static_ip.rs b/examples/src/bin/wifi_static_ip.rs index bd546d388ef..4f544626bf7 100644 --- a/examples/src/bin/wifi_static_ip.rs +++ b/examples/src/bin/wifi_static_ip.rs @@ -13,6 +13,7 @@ #![no_main] use embedded_io::*; +use esp_alloc as _; use esp_backtrace as _; use esp_hal::{prelude::*, rng::Rng, timer::timg::TimerGroup}; use esp_println::{print, println}; @@ -46,6 +47,8 @@ fn main() -> ! { config }); + esp_alloc::heap_allocator!(72 * 1024); + let timg0 = TimerGroup::new(peripherals.TIMG0); let init = initialize( diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 3f9f223c27e..6514c2c80e5 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -667,7 +667,7 @@ fn lint_packages(workspace: &Path, args: LintPackagesArgs) -> Result<()> { lint_package( &path, &[ - "-Zbuild-std=core", + "-Zbuild-std=core,alloc", &format!("--target={}", chip.target()), "--no-default-features", &features,