From 0efea52abc344464e2fee35bdee9b103be45ecc4 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Thu, 23 Jun 2022 23:48:35 +0100 Subject: [PATCH 1/5] Xtensa CS implementation: - CS implementation for single core using PS.INTLEVEL - Added locking for dual core chips using a reetrant mutex. Reentrancy is important for nested critical sections. --- esp-hal-common/Cargo.toml | 6 ++- esp-hal-common/src/lib.rs | 95 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/esp-hal-common/Cargo.toml b/esp-hal-common/Cargo.toml index 15c6fd4ba5a..2176a45773d 100644 --- a/esp-hal-common/Cargo.toml +++ b/esp-hal-common/Cargo.toml @@ -19,6 +19,8 @@ nb = "1.0" paste = "1.0" procmacros = { path = "../esp-hal-procmacros", package = "esp-hal-procmacros" } void = { version = "1.0", default-features = false } +critical-section = { version = "0.2.7",features = ["custom-impl"] } +lock_api = { version = "0.4.7", optional = true } # RISC-V riscv = { version = "0.8", optional = true } @@ -44,7 +46,7 @@ esp32s2_pac = { package = "esp32s2", git = "https://github.com/esp-rs/esp-pacs.g esp32s3_pac = { package = "esp32s3", git = "https://github.com/esp-rs/esp-pacs.git", branch = "with_source", optional = true } [features] -esp32 = [ "esp32_pac/rt", "xtensa", "dual_core", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "smartled"] +esp32 = ["esp32_pac/rt", "xtensa", "dual_core", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "smartled"] esp32c3 = ["esp32c3_pac/rt", "risc_v", "single_core", "smartled"] esp32s2 = ["esp32s2_pac/rt", "xtensa", "single_core", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "smartled"] esp32s3 = ["esp32s3_pac/rt", "xtensa", "dual_core", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "smartled"] @@ -55,7 +57,7 @@ xtensa = ["procmacros/rtc_slow"] # Core Count (should not be enabled directly, but instead by a PAC's feature) single_core = [] -dual_core = [] +dual_core = ["lock_api"] # To support `ufmt` ufmt = ["ufmt-write"] diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 2f024723c62..618556aeb8b 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -17,6 +17,7 @@ //! [esp32s3-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32s3-hal #![no_std] +#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))] #[cfg(feature = "esp32")] pub use esp32_pac as pac; @@ -81,9 +82,103 @@ pub mod cpu_control; /// Enumeration of CPU cores /// The actual number of available cores depends on the target. +#[derive(Copy, Clone, Debug)] pub enum Cpu { /// The first core ProCpu = 0, /// The second core AppCpu, } + +pub fn get_core() -> Cpu { + #[cfg(target_arch = "xtensa")] + match ((xtensa_lx::get_processor_id() >> 13) & 1) != 0 { + false => Cpu::ProCpu, + true => Cpu::AppCpu, + } + #[cfg(target_arch = "riscv32")] // TODO get hart_id + Cpu::ProCpu +} + +// TODO for next release of cs, we need to impl for RISCV too +#[cfg(target_arch = "xtensa")] // +mod critical_section_impl { + struct CriticalSection; + + critical_section::custom_impl!(CriticalSection); + + /// Virtual representation of the PS (processor state) of an Xtensa chip + static mut VPS: u32 = 0; // TODO remove when 32bit tokens are supported in CS + + unsafe impl critical_section::Impl for CriticalSection { + unsafe fn acquire() -> u8 { + core::arch::asm!("rsil {0}, 15", out(reg) VPS); + #[cfg(feature = "dual_core")] + { + let guard = multicore::MULTICORE_LOCK.lock(); + core::mem::forget(guard); // forget it so drop doesn't run + } + 0 + } + + unsafe fn release(_token: u8) { + #[cfg(feature = "dual_core")] + { + debug_assert!(multicore::MULTICORE_LOCK.is_owned_by_current_thread()); + // safety: we logically own the mutex from acquire() + multicore::MULTICORE_LOCK.force_unlock(); + } + core::arch::asm!("wsr.ps {0}", in(reg) VPS) + } + } + + #[cfg(feature = "dual_core")] + mod multicore { + use core::sync::atomic::{AtomicBool, Ordering}; + + use lock_api::{GetThreadId, GuardSend, RawMutex}; + + use crate::get_core; + + /// Reentrant Mutex + /// + /// Currently implemented using an atomic spin lock. + /// In the future we can optimize this raw mutex to use some hardware + /// features. + pub(crate) static MULTICORE_LOCK: lock_api::ReentrantMutex = + lock_api::ReentrantMutex::const_new(RawSpinlock::INIT, RawThreadId::INIT, ()); + + pub(crate) struct RawThreadId; + + unsafe impl lock_api::GetThreadId for RawThreadId { + const INIT: Self = RawThreadId; + + fn nonzero_thread_id(&self) -> core::num::NonZeroUsize { + core::num::NonZeroUsize::new((get_core() as usize) + 1).unwrap() + } + } + + pub(crate) struct RawSpinlock(AtomicBool); + + unsafe impl lock_api::RawMutex for RawSpinlock { + const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); + + // A spinlock guard can be sent to another thread and unlocked there + type GuardMarker = GuardSend; + + fn lock(&self) { + while !self.try_lock() {} + } + + fn try_lock(&self) -> bool { + self.0 + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + .is_ok() + } + + unsafe fn unlock(&self) { + self.0.store(false, Ordering::Release); + } + } + } +} From 6e4c24e7edb35189ffde316c5fb4893a9bd91ac7 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Fri, 24 Jun 2022 11:47:36 +0100 Subject: [PATCH 2/5] rename dual_core & single_core to multicore & unicore --- esp-hal-common/Cargo.toml | 12 ++++++------ esp-hal-common/src/interrupt/xtensa.rs | 12 ++++++------ esp-hal-common/src/lib.rs | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/esp-hal-common/Cargo.toml b/esp-hal-common/Cargo.toml index 2176a45773d..d8cd3c723f1 100644 --- a/esp-hal-common/Cargo.toml +++ b/esp-hal-common/Cargo.toml @@ -46,18 +46,18 @@ esp32s2_pac = { package = "esp32s2", git = "https://github.com/esp-rs/esp-pacs.g esp32s3_pac = { package = "esp32s3", git = "https://github.com/esp-rs/esp-pacs.git", branch = "with_source", optional = true } [features] -esp32 = ["esp32_pac/rt", "xtensa", "dual_core", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "smartled"] -esp32c3 = ["esp32c3_pac/rt", "risc_v", "single_core", "smartled"] -esp32s2 = ["esp32s2_pac/rt", "xtensa", "single_core", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "smartled"] -esp32s3 = ["esp32s3_pac/rt", "xtensa", "dual_core", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "smartled"] +esp32 = ["esp32_pac/rt", "xtensa", "multicore", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "smartled"] +esp32c3 = ["esp32c3_pac/rt", "risc_v", "unicore", "smartled"] +esp32s2 = ["esp32s2_pac/rt", "xtensa", "unicore", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "smartled"] +esp32s3 = ["esp32s3_pac/rt", "xtensa", "multicore", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "smartled"] # Architecture (should not be enabled directly, but instead by a PAC's feature) risc_v = ["riscv", "riscv-atomic-emulation-trap"] xtensa = ["procmacros/rtc_slow"] # Core Count (should not be enabled directly, but instead by a PAC's feature) -single_core = [] -dual_core = ["lock_api"] +unicore = [] +multicore = ["lock_api"] # To support `ufmt` ufmt = ["ufmt-write"] diff --git a/esp-hal-common/src/interrupt/xtensa.rs b/esp-hal-common/src/interrupt/xtensa.rs index 76258b0de8f..3ad9d8b1fba 100644 --- a/esp-hal-common/src/interrupt/xtensa.rs +++ b/esp-hal-common/src/interrupt/xtensa.rs @@ -58,9 +58,9 @@ pub fn enable(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) { let cpu_interrupt_number = which as isize; let intr_map_base = match core { Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), - #[cfg(feature = "dual_core")] + #[cfg(feature = "multicore")] Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map.as_ptr(), - #[cfg(feature = "single_core")] + #[cfg(feature = "unicore")] Cpu::AppCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), }; intr_map_base @@ -75,9 +75,9 @@ pub fn disable(core: Cpu, interrupt: Interrupt) { let interrupt_number = interrupt as isize; let intr_map_base = match core { Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), - #[cfg(feature = "dual_core")] + #[cfg(feature = "multicore")] Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map.as_ptr(), - #[cfg(feature = "single_core")] + #[cfg(feature = "unicore")] Cpu::AppCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), }; intr_map_base.offset(interrupt_number).write_volatile(0); @@ -111,7 +111,7 @@ pub fn get_status(core: Cpu) -> u128 { .bits() as u128) << 64 } - #[cfg(feature = "dual_core")] + #[cfg(feature = "multicore")] Cpu::AppCpu => { ((*core1_interrupt_peripheral()) .app_intr_status_0 @@ -128,7 +128,7 @@ pub fn get_status(core: Cpu) -> u128 { .bits() as u128) << 64 } - #[cfg(feature = "single_core")] + #[cfg(feature = "unicore")] Cpu::AppCpu => { ((*core0_interrupt_peripheral()) .pro_intr_status_0 diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 618556aeb8b..8ecfdf7d818 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -101,19 +101,19 @@ pub fn get_core() -> Cpu { } // TODO for next release of cs, we need to impl for RISCV too -#[cfg(target_arch = "xtensa")] // +#[cfg(target_arch = "xtensa")] mod critical_section_impl { struct CriticalSection; critical_section::custom_impl!(CriticalSection); - /// Virtual representation of the PS (processor state) of an Xtensa chip - static mut VPS: u32 = 0; // TODO remove when 32bit tokens are supported in CS + // Virtual representation of the PS (processor state) of an Xtensa chip + static mut VPS: u32 = 0; // TODO remove when 32bit tokens are supported in CS crate unsafe impl critical_section::Impl for CriticalSection { unsafe fn acquire() -> u8 { core::arch::asm!("rsil {0}, 15", out(reg) VPS); - #[cfg(feature = "dual_core")] + #[cfg(feature = "multicore")] { let guard = multicore::MULTICORE_LOCK.lock(); core::mem::forget(guard); // forget it so drop doesn't run @@ -122,7 +122,7 @@ mod critical_section_impl { } unsafe fn release(_token: u8) { - #[cfg(feature = "dual_core")] + #[cfg(feature = "multicore")] { debug_assert!(multicore::MULTICORE_LOCK.is_owned_by_current_thread()); // safety: we logically own the mutex from acquire() @@ -132,7 +132,7 @@ mod critical_section_impl { } } - #[cfg(feature = "dual_core")] + #[cfg(feature = "multicore")] mod multicore { use core::sync::atomic::{AtomicBool, Ordering}; From 04ca78acf896e456acbc77c697844099da18e8b5 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Fri, 24 Jun 2022 12:00:05 +0100 Subject: [PATCH 3/5] Run clippy on each target --- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++++-------- esp-hal-common/src/lib.rs | 8 ++++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbf5520ba32..d7a79add03a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,25 +52,44 @@ jobs: command: check args: -Zbuild-std=core --examples --manifest-path=${{ matrix.chip }}-hal/Cargo.toml --target=xtensa-${{ matrix.chip }}-none-elf - clippy: - name: Clippy + clippy-riscv: + name: Run clippy on RISC-V builds runs-on: ubuntu-latest strategy: fail-fast: false matrix: - chip: [esp32, esp32c3, esp32s2, esp32s3] + toolchain: [stable, nightly] steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly - default: true + target: riscv32imc-unknown-none-elf + toolchain: ${{ matrix.toolchain }} components: clippy + default: true + - uses: Swatinem/rust-cache@v1 + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: --manifest-path=esp32c3-hal/Cargo.toml --target=riscv32imc-unknown-none-elf -- --no-deps -D warnings --A clippy::too-many-arguments --A clippy::module-inception + + clippy-xtensa: + name: Run clippy on Xtensa builds + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + chip: [esp32, esp32s2, esp32s3] + steps: + - uses: actions/checkout@v2 + - uses: esp-rs/xtensa-toolchain@v1.2 + with: + default: true + ldproxy: false + buildtargets: ${{ matrix.chip }} - uses: Swatinem/rust-cache@v1 - uses: actions-rs/cargo@v1 with: command: clippy - # I find `clippy::too-many-arguments` to be rather rather arbitrary. - # As for `clippy::module-inception`... don't tell me what to do ;) - args: --manifest-path=${{ matrix.chip }}-hal/Cargo.toml -- --no-deps -D warnings --A clippy::too-many-arguments --A clippy::module-inception + args: -Zbuild-std=core --manifest-path=${{ matrix.chip }}-hal/Cargo.toml --target=xtensa-${{ matrix.chip }}-none-elf -- --no-deps -D warnings --A clippy::too-many-arguments --A clippy::module-inception diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 8ecfdf7d818..e228989332b 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -91,12 +91,16 @@ pub enum Cpu { } pub fn get_core() -> Cpu { - #[cfg(target_arch = "xtensa")] + #[cfg(all(target_arch = "xtensa", feature = "multicore"))] match ((xtensa_lx::get_processor_id() >> 13) & 1) != 0 { false => Cpu::ProCpu, true => Cpu::AppCpu, } - #[cfg(target_arch = "riscv32")] // TODO get hart_id + // #[cfg(all(target_arch = "riscv32", feature = "multicore"))] + // TODO get hart_id + + // single core always has ProCpu only + #[cfg(feature = "unicore")] Cpu::ProCpu } From f04d323bf5dc8328f8735682f18efbb50aa62e88 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Fri, 24 Jun 2022 13:23:22 +0100 Subject: [PATCH 4/5] Remove redundant features --- esp-hal-common/Cargo.toml | 12 +++++------- esp-hal-common/src/lib.rs | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/esp-hal-common/Cargo.toml b/esp-hal-common/Cargo.toml index d8cd3c723f1..b63bd3ec35a 100644 --- a/esp-hal-common/Cargo.toml +++ b/esp-hal-common/Cargo.toml @@ -46,14 +46,12 @@ esp32s2_pac = { package = "esp32s2", git = "https://github.com/esp-rs/esp-pacs.g esp32s3_pac = { package = "esp32s3", git = "https://github.com/esp-rs/esp-pacs.git", branch = "with_source", optional = true } [features] -esp32 = ["esp32_pac/rt", "xtensa", "multicore", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "smartled"] -esp32c3 = ["esp32c3_pac/rt", "risc_v", "unicore", "smartled"] -esp32s2 = ["esp32s2_pac/rt", "xtensa", "unicore", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "smartled"] -esp32s3 = ["esp32s3_pac/rt", "xtensa", "multicore", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "smartled"] +esp32 = ["esp32_pac/rt", "multicore", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "procmacros/rtc_slow", "smartled"] +esp32c3 = ["esp32c3_pac/rt", "unicore", "riscv", "riscv-atomic-emulation-trap", "smartled"] +esp32s2 = ["esp32s2_pac/rt", "unicore", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "procmacros/rtc_slow", "smartled"] # TODO support xtensa atomic emulation +esp32s3 = ["esp32s3_pac/rt", "multicore", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "procmacros/rtc_slow", "smartled"] + -# Architecture (should not be enabled directly, but instead by a PAC's feature) -risc_v = ["riscv", "riscv-atomic-emulation-trap"] -xtensa = ["procmacros/rtc_slow"] # Core Count (should not be enabled directly, but instead by a PAC's feature) unicore = [] diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index e228989332b..910b41d8e10 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -38,8 +38,8 @@ pub mod efuse; pub mod gpio; pub mod i2c; -#[cfg_attr(feature = "risc_v", path = "interrupt/riscv.rs")] -#[cfg_attr(feature = "xtensa", path = "interrupt/xtensa.rs")] +#[cfg_attr(target_arch = "riscv32", path = "interrupt/riscv.rs")] +#[cfg_attr(target_arch = "xtensa", path = "interrupt/xtensa.rs")] pub mod interrupt; pub mod prelude; pub mod pulse_control; From 505900f8a37cdd4135ab2e20f0250c986f40f7a8 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Mon, 11 Jul 2022 15:33:29 +0100 Subject: [PATCH 5/5] dep bumps & reentrant fix - Update bare_metal to use git version with RefCellHelper - Use master critical_section for configurable token size & the correct `CriticalSection` struct from `critical_section::with` - Modify multicore s3 example to use `bare_metal::Mutex` & `critical_section` --- esp-hal-common/Cargo.toml | 2 +- esp-hal-common/src/lib.rs | 28 ++++++++++++++-------------- esp32s3-hal/Cargo.toml | 10 ++++++++-- esp32s3-hal/examples/multicore.rs | 17 ++++++----------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/esp-hal-common/Cargo.toml b/esp-hal-common/Cargo.toml index b63bd3ec35a..c54034db68c 100644 --- a/esp-hal-common/Cargo.toml +++ b/esp-hal-common/Cargo.toml @@ -19,7 +19,7 @@ nb = "1.0" paste = "1.0" procmacros = { path = "../esp-hal-procmacros", package = "esp-hal-procmacros" } void = { version = "1.0", default-features = false } -critical-section = { version = "0.2.7",features = ["custom-impl"] } +critical-section = { git = "https://github.com/embassy-rs/critical-section", features = ["token-u32"] } lock_api = { version = "0.4.7", optional = true } # RISC-V diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 910b41d8e10..e3e0155f974 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -109,30 +109,30 @@ pub fn get_core() -> Cpu { mod critical_section_impl { struct CriticalSection; - critical_section::custom_impl!(CriticalSection); - - // Virtual representation of the PS (processor state) of an Xtensa chip - static mut VPS: u32 = 0; // TODO remove when 32bit tokens are supported in CS crate + critical_section::set_impl!(CriticalSection); unsafe impl critical_section::Impl for CriticalSection { - unsafe fn acquire() -> u8 { - core::arch::asm!("rsil {0}, 15", out(reg) VPS); + unsafe fn acquire() -> critical_section::RawToken { + let tkn: critical_section::RawToken; + core::arch::asm!("rsil {0}, 15", out(reg) tkn); #[cfg(feature = "multicore")] { let guard = multicore::MULTICORE_LOCK.lock(); core::mem::forget(guard); // forget it so drop doesn't run } - 0 + tkn } - unsafe fn release(_token: u8) { - #[cfg(feature = "multicore")] - { - debug_assert!(multicore::MULTICORE_LOCK.is_owned_by_current_thread()); - // safety: we logically own the mutex from acquire() - multicore::MULTICORE_LOCK.force_unlock(); + unsafe fn release(token: critical_section::RawToken) { + if token != 0 { + #[cfg(feature = "multicore")] + { + debug_assert!(multicore::MULTICORE_LOCK.is_owned_by_current_thread()); + // safety: we logically own the mutex from acquire() + multicore::MULTICORE_LOCK.force_unlock(); + } + core::arch::asm!("wsr.ps {0}", in(reg) token) } - core::arch::asm!("wsr.ps {0}", in(reg) VPS) } } diff --git a/esp32s3-hal/Cargo.toml b/esp32s3-hal/Cargo.toml index 1bf9055416d..6a5655bcaa6 100644 --- a/esp32s3-hal/Cargo.toml +++ b/esp32s3-hal/Cargo.toml @@ -27,6 +27,9 @@ categories = [ bare-metal = "1.0" embedded-hal = { version = "0.2", features = ["unproven"] } embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.8" } +fugit = "0.3" +nb = "1.0" +void = { version = "1.0", default-features = false } xtensa-lx = { version = "0.7", features = ["esp32s3"] } xtensa-lx-rt = { version = "0.12", features = ["esp32s3"], optional = true } @@ -39,10 +42,13 @@ embedded-graphics = "0.7" panic-halt = "0.2" ssd1306 = "0.7" smart-leds = "0.3" -esp-println = { version = "0.1.0", features = ["esp32s3"] } +esp-println = { version = "0.2.0", features = ["esp32s3"] } +critical-section = { git = "https://github.com/embassy-rs/critical-section" } + +[patch.crates-io] +bare-metal = { version = "1.0", git = "https://github.com/rust-embedded/bare-metal" } [features] default = ["rt"] -eh1 = ["esp-hal-common/eh1"] rt = ["xtensa-lx-rt/esp32s3"] ufmt = ["esp-hal-common/ufmt"] diff --git a/esp32s3-hal/examples/multicore.rs b/esp32s3-hal/examples/multicore.rs index 8c4d3a50a6b..d6f7e5de438 100644 --- a/esp32s3-hal/examples/multicore.rs +++ b/esp32s3-hal/examples/multicore.rs @@ -1,8 +1,6 @@ #![no_std] #![no_main] -use core::sync::atomic::{AtomicI32, Ordering}; - use esp32s3_hal::{ clock::ClockControl, pac::{Peripherals, TIMG1}, @@ -14,8 +12,8 @@ use esp32s3_hal::{ use esp_println::println; use nb::block; use panic_halt as _; -use xtensa_lx::mutex::Mutex; use xtensa_lx_rt::entry; +use core::cell::RefCell; #[entry] fn main() -> ! { @@ -35,7 +33,7 @@ fn main() -> ! { timer0.start(1u64.secs()); timer1.start(500u64.millis()); - let counter = xtensa_lx::mutex::SpinLockMutex::new(AtomicI32::new(0)); + let counter = bare_metal::Mutex::new(RefCell::new(0usize)); let mut cpu_control = CpuControl::new(system.cpu_control); let mut cpu1_fnctn = || { @@ -46,21 +44,18 @@ fn main() -> ! { loop { block!(timer0.wait()).unwrap(); - let count = (&counter).lock(|counter| counter.load(Ordering::Relaxed)); + let count = critical_section::with(|cs| *counter.borrow_ref(cs)); println!("Hello World - Core 0! Counter is {}", count); } } -fn cpu1_task(timer: &mut Timer, counter: &xtensa_lx::mutex::SpinLockMutex) -> ! { +fn cpu1_task(timer: &mut Timer, counter: &bare_metal::Mutex>) -> ! { println!("Hello World - Core 1!"); loop { block!(timer.wait()).unwrap(); - (&*counter).lock(|counter| { - counter.store( - counter.load(Ordering::Relaxed).wrapping_add(1), - Ordering::Relaxed, - ); + critical_section::with(|cs| { + *counter.borrow_ref_mut(cs) += 1; }); } }