Skip to content

Commit 27e4745

Browse files
committed
Add an object you can use to hold the PSP stack.
1 parent 3acafb3 commit 27e4745

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

cortex-m/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub mod interrupt;
111111
pub mod itm;
112112
pub mod peripheral;
113113
pub mod prelude;
114+
pub mod psp;
114115
pub mod register;
115116

116117
pub use crate::peripheral::Peripherals;

cortex-m/src/psp.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//! Process Stack Pointer support
2+
3+
#![allow(clippy::missing_inline_in_public_items)]
4+
5+
use core::cell::UnsafeCell;
6+
7+
/// A stack you can use as your Process Stack (PSP)
8+
///
9+
/// The const-param N is the size **in 32-bit words**
10+
#[repr(align(8), C)]
11+
pub struct Stack<const N: usize> {
12+
space: UnsafeCell<[u32; N]>,
13+
}
14+
15+
impl<const N: usize> Stack<N> {
16+
/// Const-initialise a Stack
17+
///
18+
/// Use a turbofish to specify the size, like:
19+
///
20+
/// ```rust
21+
/// static PSP_STACK: Stack::<4096> = Stack::new();
22+
/// ```
23+
pub const fn new() -> Stack<N> {
24+
Stack {
25+
space: UnsafeCell::new([0; N]),
26+
}
27+
}
28+
29+
/// Return the top of the stack
30+
pub fn get_top(&self) -> *mut u32 {
31+
let start = self.space.get() as *mut u32;
32+
unsafe { start.add(N) }
33+
}
34+
}
35+
36+
unsafe impl<const N: usize> Sync for Stack<N> {}
37+
38+
impl<const N: usize> core::default::Default for Stack<N> {
39+
fn default() -> Self {
40+
Stack::new()
41+
}
42+
}
43+
44+
/// Switch to running on the PSP
45+
#[cfg(cortex_m)]
46+
pub fn switch_to_psp<const N: usize>(psp_stack: &Stack<N>, function: extern "C" fn() -> !) -> ! {
47+
let stack_top = psp_stack.get_top();
48+
unsafe { crate::asm::enter_unprivileged(stack_top, function) }
49+
}

0 commit comments

Comments
 (0)