mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 04:10:25 +00:00
Merge pull request #4688 from 9names/rp2350_msplim_stackguard
Use msplim for RP2350 stackguard
This commit is contained in:
commit
5a94ad0062
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add PIO I2S input
|
||||
- Add PIO onewire parasite power strong pullup
|
||||
- add `wait_for_alarm` and `alarm_scheduled` methods to rtc module ([#4216](https://github.com/embassy-rs/embassy/pull/4216))
|
||||
- rp235x: use msplim for stack guard instead of MPU
|
||||
|
||||
## 0.8.0 - 2025-08-26
|
||||
|
||||
|
@ -565,18 +565,10 @@ unsafe fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> {
|
||||
#[cfg(all(feature = "_rp235x", not(feature = "_test")))]
|
||||
#[inline(always)]
|
||||
unsafe fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> {
|
||||
let core = unsafe { cortex_m::Peripherals::steal() };
|
||||
// The RP2350 arm cores are cortex-m33 and can use the MSPLIM register to guard the end of stack.
|
||||
// We'll need to do something else for the riscv cores.
|
||||
cortex_m::register::msplim::write(stack_bottom.addr() as u32);
|
||||
|
||||
// Fail if MPU is already configured
|
||||
if core.MPU.ctrl.read() != 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
core.MPU.ctrl.write(5); // enable mpu with background default map
|
||||
core.MPU.rbar.write(stack_bottom as u32 & !0xff); // set address
|
||||
core.MPU.rlar.write(((stack_bottom as usize + 255) as u32) | 1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
72
examples/rp235x/src/bin/multicore_stack_overflow.rs
Normal file
72
examples/rp235x/src/bin/multicore_stack_overflow.rs
Normal file
@ -0,0 +1,72 @@
|
||||
//! This example tests stack overflow handling on core1 of the RP235x chip.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use defmt::*;
|
||||
use embassy_executor::Executor;
|
||||
use embassy_rp::gpio::{Level, Output};
|
||||
use embassy_rp::multicore::{spawn_core1, Stack};
|
||||
use embassy_time::Timer;
|
||||
use static_cell::StaticCell;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
const CORE1_STACK_LENGTH: usize = 4096;
|
||||
|
||||
static mut CORE1_STACK: Stack<CORE1_STACK_LENGTH> = Stack::new();
|
||||
static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
|
||||
static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
|
||||
|
||||
#[cortex_m_rt::entry]
|
||||
fn main() -> ! {
|
||||
let p = embassy_rp::init(Default::default());
|
||||
let led = Output::new(p.PIN_25, Level::Low);
|
||||
|
||||
spawn_core1(
|
||||
p.CORE1,
|
||||
unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
|
||||
move || {
|
||||
let executor1 = EXECUTOR1.init(Executor::new());
|
||||
executor1.run(|spawner| spawner.spawn(unwrap!(core1_task())));
|
||||
},
|
||||
);
|
||||
|
||||
let executor0 = EXECUTOR0.init(Executor::new());
|
||||
executor0.run(|spawner| spawner.spawn(unwrap!(core0_task(led))));
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn core0_task(mut led: Output<'static>) {
|
||||
info!("Hello from core 0");
|
||||
loop {
|
||||
info!("core 0 still alive");
|
||||
led.set_high();
|
||||
Timer::after_millis(500).await;
|
||||
led.set_low();
|
||||
Timer::after_millis(500).await;
|
||||
}
|
||||
}
|
||||
|
||||
fn blow_my_stack() {
|
||||
// Allocating an array a little larger than our stack should ensure a stack overflow when it is used.
|
||||
let t = [0u8; CORE1_STACK_LENGTH + 64];
|
||||
|
||||
info!("Array initialised without error");
|
||||
// We need to use black_box to otherwise the compiler is too smart and will optimise all of this away.
|
||||
// We shouldn't get to this code - the initialisation above will touch the stack guard.
|
||||
for ref i in t {
|
||||
let _data = core::hint::black_box(*i) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn core1_task() {
|
||||
info!("Hello from core 1");
|
||||
|
||||
blow_my_stack();
|
||||
|
||||
loop {
|
||||
info!("core 1 still alive");
|
||||
Timer::after_millis(1000).await;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user