aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-21 14:42:46 +0000
committerGitHub <[email protected]>2025-09-21 14:42:46 +0000
commit5a94ad0062573f60a14707bba7f3684ad398fc20 (patch)
treeb1f721eeaf2f937a947ede5f2188677b47ca2ed0
parent483a9ad53ae949f7f78cdf8764c990ab434f25e4 (diff)
parenta3ee22be1374222f68893b7c76bbb45914e6fead (diff)
Merge pull request #4688 from 9names/rp2350_msplim_stackguard
Use msplim for RP2350 stackguard
-rw-r--r--embassy-rp/CHANGELOG.md1
-rw-r--r--embassy-rp/src/lib.rs14
-rw-r--r--examples/rp235x/src/bin/multicore_stack_overflow.rs72
3 files changed, 76 insertions, 11 deletions
diff --git a/embassy-rp/CHANGELOG.md b/embassy-rp/CHANGELOG.md
index d1265ffc4..ea62c2387 100644
--- a/embassy-rp/CHANGELOG.md
+++ b/embassy-rp/CHANGELOG.md
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12- Add PIO I2S input 12- Add PIO I2S input
13- Add PIO onewire parasite power strong pullup 13- Add PIO onewire parasite power strong pullup
14- add `wait_for_alarm` and `alarm_scheduled` methods to rtc module ([#4216](https://github.com/embassy-rs/embassy/pull/4216)) 14- add `wait_for_alarm` and `alarm_scheduled` methods to rtc module ([#4216](https://github.com/embassy-rs/embassy/pull/4216))
15- rp235x: use msplim for stack guard instead of MPU
15 16
16## 0.8.0 - 2025-08-26 17## 0.8.0 - 2025-08-26
17 18
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 6fb680b34..d03ba1fef 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -565,18 +565,10 @@ unsafe fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> {
565#[cfg(all(feature = "_rp235x", not(feature = "_test")))] 565#[cfg(all(feature = "_rp235x", not(feature = "_test")))]
566#[inline(always)] 566#[inline(always)]
567unsafe fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> { 567unsafe fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> {
568 let core = unsafe { cortex_m::Peripherals::steal() }; 568 // The RP2350 arm cores are cortex-m33 and can use the MSPLIM register to guard the end of stack.
569 // We'll need to do something else for the riscv cores.
570 cortex_m::register::msplim::write(stack_bottom.addr() as u32);
569 571
570 // Fail if MPU is already configured
571 if core.MPU.ctrl.read() != 0 {
572 return Err(());
573 }
574
575 unsafe {
576 core.MPU.ctrl.write(5); // enable mpu with background default map
577 core.MPU.rbar.write(stack_bottom as u32 & !0xff); // set address
578 core.MPU.rlar.write(((stack_bottom as usize + 255) as u32) | 1);
579 }
580 Ok(()) 572 Ok(())
581} 573}
582 574
diff --git a/examples/rp235x/src/bin/multicore_stack_overflow.rs b/examples/rp235x/src/bin/multicore_stack_overflow.rs
new file mode 100644
index 000000000..dba44aa23
--- /dev/null
+++ b/examples/rp235x/src/bin/multicore_stack_overflow.rs
@@ -0,0 +1,72 @@
1//! This example tests stack overflow handling on core1 of the RP235x chip.
2
3#![no_std]
4#![no_main]
5
6use defmt::*;
7use embassy_executor::Executor;
8use embassy_rp::gpio::{Level, Output};
9use embassy_rp::multicore::{spawn_core1, Stack};
10use embassy_time::Timer;
11use static_cell::StaticCell;
12use {defmt_rtt as _, panic_probe as _};
13
14const CORE1_STACK_LENGTH: usize = 4096;
15
16static mut CORE1_STACK: Stack<CORE1_STACK_LENGTH> = Stack::new();
17static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
18static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
19
20#[cortex_m_rt::entry]
21fn main() -> ! {
22 let p = embassy_rp::init(Default::default());
23 let led = Output::new(p.PIN_25, Level::Low);
24
25 spawn_core1(
26 p.CORE1,
27 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
28 move || {
29 let executor1 = EXECUTOR1.init(Executor::new());
30 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task())));
31 },
32 );
33
34 let executor0 = EXECUTOR0.init(Executor::new());
35 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task(led))));
36}
37
38#[embassy_executor::task]
39async fn core0_task(mut led: Output<'static>) {
40 info!("Hello from core 0");
41 loop {
42 info!("core 0 still alive");
43 led.set_high();
44 Timer::after_millis(500).await;
45 led.set_low();
46 Timer::after_millis(500).await;
47 }
48}
49
50fn blow_my_stack() {
51 // Allocating an array a little larger than our stack should ensure a stack overflow when it is used.
52 let t = [0u8; CORE1_STACK_LENGTH + 64];
53
54 info!("Array initialised without error");
55 // We need to use black_box to otherwise the compiler is too smart and will optimise all of this away.
56 // We shouldn't get to this code - the initialisation above will touch the stack guard.
57 for ref i in t {
58 let _data = core::hint::black_box(*i) + 1;
59 }
60}
61
62#[embassy_executor::task]
63async fn core1_task() {
64 info!("Hello from core 1");
65
66 blow_my_stack();
67
68 loop {
69 info!("core 1 still alive");
70 Timer::after_millis(1000).await;
71 }
72}